* Remove a lot of dead code.
This commit is contained in:
		
							parent
							
								
									7e048eddf5
								
							
						
					
					
						commit
						b7b3dd55f9
					
				
					 4 changed files with 10 additions and 763 deletions
				
			
		|  | @ -27,7 +27,14 @@ std::ostream & operator << (std::ostream & str, Value & v) | |||
|         str << (v.boolean ? "true" : "false"); | ||||
|         break; | ||||
|     case tString: | ||||
|         str << "\"" << v.string.s << "\""; // !!! escaping
 | ||||
|         str << "\""; | ||||
|         for (const char * i = v.string.s; *i; i++) | ||||
|             if (*i == '\"' || *i == '\\') str << "\\" << *i; | ||||
|             else if (*i == '\n') str << "\\n"; | ||||
|             else if (*i == '\r') str << "\\r"; | ||||
|             else if (*i == '\t') str << "\\t"; | ||||
|             else str << *i; | ||||
|         str << "\""; | ||||
|         break; | ||||
|     case tPath: | ||||
|         str << v.path; // !!! escaping?
 | ||||
|  | @ -930,497 +937,6 @@ bool EvalState::eqValues(Value & v1, Value & v2) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| /* Pattern-match `pat' against `arg'.  The result is a set of
 | ||||
|    substitutions (`subs') and a set of recursive substitutions | ||||
|    (`subsRecursive').  The latter can refer to the variables bound by | ||||
|    both `subs' and `subsRecursive'. */ | ||||
| static void patternMatch(EvalState & state, | ||||
|     Pattern pat, Expr arg, ATermMap & subs, ATermMap & subsRecursive) | ||||
| { | ||||
|     ATerm name; | ||||
|     ATermList formals; | ||||
|     ATermBool ellipsis; | ||||
|      | ||||
|     if (matchVarPat(pat, name))  | ||||
|         subs.set(name, arg); | ||||
| 
 | ||||
|     else if (matchAttrsPat(pat, formals, ellipsis, name)) { | ||||
| 
 | ||||
|         arg = evalExpr(state, arg); | ||||
| 
 | ||||
|         if (name != sNoAlias) subs.set(name, arg); | ||||
| 
 | ||||
|         /* Get the actual arguments. */ | ||||
|         ATermMap attrs; | ||||
|         queryAllAttrs(arg, attrs); | ||||
|         unsigned int nrAttrs = attrs.size(); | ||||
| 
 | ||||
|         /* For each formal argument, get the actual argument.  If
 | ||||
|            there is no matching actual argument but the formal | ||||
|            argument has a default, use the default. */ | ||||
|         unsigned int attrsUsed = 0; | ||||
|         for (ATermIterator i(formals); i; ++i) { | ||||
|             Expr name, def; | ||||
|             DefaultValue def2; | ||||
|             if (!matchFormal(*i, name, def2)) abort(); /* can't happen */ | ||||
| 
 | ||||
|             Expr value = attrs[name]; | ||||
| 
 | ||||
|             if (value == 0) { | ||||
|                 if (!matchDefaultValue(def2, def)) def = 0; | ||||
|                 if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing") | ||||
|                     % aterm2String(name)); | ||||
|                 subsRecursive.set(name, def); | ||||
|             } else { | ||||
|                 attrsUsed++; | ||||
|                 attrs.remove(name); | ||||
|                 subs.set(name, value); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         /* Check that each actual argument is listed as a formal
 | ||||
|            argument (unless the attribute match specifies a `...'). */ | ||||
|         if (ellipsis == eFalse && attrsUsed != nrAttrs) | ||||
|             throw TypeError(format("the function does not expect an argument named `%1%'") | ||||
|                 % aterm2String(attrs.begin()->key)); | ||||
|     } | ||||
| 
 | ||||
|     else abort(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Substitute an argument set into the body of a function. */ | ||||
| static Expr substArgs(EvalState & state, | ||||
|     Expr body, Pattern pat, Expr arg) | ||||
| { | ||||
|     ATermMap subs(16), subsRecursive(16); | ||||
|      | ||||
|     patternMatch(state, pat, arg, subs, subsRecursive); | ||||
| 
 | ||||
|     /* If we used any default values, make a recursive attribute set
 | ||||
|        out of the (argument-name, value) tuples.  This is so that we | ||||
|        can support default values that refer to each other, e.g.  ({x, | ||||
|        y ? x + x}: y) {x = "foo";} evaluates to "foofoo". */ | ||||
|     if (subsRecursive.size() != 0) { | ||||
|         ATermList recAttrs = ATempty; | ||||
|         foreach (ATermMap::const_iterator, i, subs) | ||||
|             recAttrs = ATinsert(recAttrs, makeBind(i->key, i->value, makeNoPos())); | ||||
|         foreach (ATermMap::const_iterator, i, subsRecursive) | ||||
|             recAttrs = ATinsert(recAttrs, makeBind(i->key, i->value, makeNoPos())); | ||||
|         Expr rec = makeRec(recAttrs, ATempty); | ||||
|         foreach (ATermMap::const_iterator, i, subsRecursive) | ||||
|             subs.set(i->key, makeSelect(rec, i->key)); | ||||
|     } | ||||
| 
 | ||||
|     return substitute(Substitution(0, &subs), body); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Transform a mutually recursive set into a non-recursive set.  Each
 | ||||
|    attribute is transformed into an expression that has all references | ||||
|    to attributes substituted with selection expressions on the | ||||
|    original set.  E.g., e = `rec {x = f x y; y = x;}' becomes `{x = f | ||||
|    (e.x) (e.y); y = e.x;}'. */ | ||||
| LocalNoInline(ATerm expandRec(EvalState & state, ATerm e, ATermList rbnds, ATermList nrbnds)) | ||||
| { | ||||
|     ATerm name; | ||||
|     Expr e2; | ||||
|     Pos pos; | ||||
|     Expr eOverrides = 0; | ||||
| 
 | ||||
|     /* Create the substitution list. */ | ||||
|     ATermMap subs(ATgetLength(rbnds) + ATgetLength(nrbnds)); | ||||
|     for (ATermIterator i(rbnds); i; ++i) { | ||||
|         if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||
|         subs.set(name, makeSelect(e, name)); | ||||
|     } | ||||
|     for (ATermIterator i(nrbnds); i; ++i) { | ||||
|         if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||
|         if (name == sOverrides) eOverrides = e2; | ||||
|         subs.set(name, e2); | ||||
|     } | ||||
| 
 | ||||
|     /* If the rec contains an attribute called `__overrides', then
 | ||||
|        evaluate it, and add the attributes in that set to the rec. | ||||
|        This allows overriding of recursive attributes, which is | ||||
|        otherwise not possible.  (You can use the // operator to
 | ||||
|        replace an attribute, but other attributes in the rec will | ||||
|        still reference the original value, because that value has been | ||||
|        substituted into the bodies of the other attributes.  Hence we | ||||
|        need __overrides.) */ | ||||
|     ATermMap overrides; | ||||
|     if (eOverrides) { | ||||
|         eOverrides = evalExpr(state, eOverrides); | ||||
|         queryAllAttrs(eOverrides, overrides, false); | ||||
|         foreach (ATermMap::const_iterator, i, overrides) | ||||
|             subs.set(i->key, i->value); | ||||
|     } | ||||
| 
 | ||||
|     Substitution subs_(0, &subs); | ||||
| 
 | ||||
|     /* Create the non-recursive set. */ | ||||
|     ATermMap as(ATgetLength(rbnds) + ATgetLength(nrbnds)); | ||||
|     for (ATermIterator i(rbnds); i; ++i) { | ||||
|         if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||
|         as.set(name, makeAttrRHS(substitute(subs_, e2), pos)); | ||||
|     } | ||||
| 
 | ||||
|     if (eOverrides) | ||||
|         foreach (ATermMap::const_iterator, i, overrides) | ||||
|             as.set(i->key, makeAttrRHS(i->value, makeNoPos())); | ||||
| 
 | ||||
|     /* Copy the non-recursive bindings.  !!! inefficient */ | ||||
|     for (ATermIterator i(nrbnds); i; ++i) { | ||||
|         if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||
|         as.set(name, makeAttrRHS(e2, pos)); | ||||
|     } | ||||
| 
 | ||||
|     return makeAttrs(as); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void flattenList(EvalState & state, Expr e, ATermList & result) | ||||
| { | ||||
|     ATermList es; | ||||
|     e = evalExpr(state, e); | ||||
|     if (matchList(e, es)) | ||||
|         for (ATermIterator i(es); i; ++i) | ||||
|             flattenList(state, *i, result); | ||||
|     else | ||||
|         result = ATinsert(result, e); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ATermList flattenList(EvalState & state, Expr e) | ||||
| { | ||||
|     ATermList result = ATempty; | ||||
|     flattenList(state, e, result); | ||||
|     return ATreverse(result); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Evaluation of various language constructs.  These have been taken
 | ||||
|    out of evalExpr2 to reduce stack space usage.  (GCC is really dumb | ||||
|    about stack space: it just adds up all the local variables and | ||||
|    temporaries of every scope into one huge stack frame.  This is | ||||
|    really bad for deeply recursive functions.) */ | ||||
| 
 | ||||
| 
 | ||||
| LocalNoInline(Expr evalVar(EvalState & state, ATerm name)) | ||||
| { | ||||
|     ATerm primOp = state.primOps.get(name); | ||||
|     if (!primOp) | ||||
|         throw EvalError(format("impossible: undefined variable `%1%'") % aterm2String(name)); | ||||
|     int arity; | ||||
|     ATermBlob fun; | ||||
|     if (!matchPrimOpDef(primOp, arity, fun)) abort(); | ||||
|     if (arity == 0) | ||||
|         /* !!! backtrace for primop call */ | ||||
|         return ((PrimOp) ATgetBlobData(fun)) (state, ATermVector()); | ||||
|     else | ||||
|         return makePrimOp(arity, fun, ATempty); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg)) | ||||
| { | ||||
|     Pattern pat; | ||||
|     ATerm pos; | ||||
|     Expr body; | ||||
|          | ||||
|     /* Evaluate the left-hand side. */ | ||||
|     fun = evalExpr(state, fun); | ||||
| 
 | ||||
|     /* Is it a primop or a function? */ | ||||
|     int arity; | ||||
|     ATermBlob funBlob; | ||||
|     ATermList args; | ||||
|     if (matchPrimOp(fun, arity, funBlob, args)) { | ||||
|         args = ATinsert(args, arg); | ||||
|         if (ATgetLength(args) == arity) { | ||||
|             /* Put the arguments in a vector in reverse (i.e.,
 | ||||
|                actual) order. */ | ||||
|             ATermVector args2(arity); | ||||
|             for (ATermIterator i(args); i; ++i) | ||||
|                 args2[--arity] = *i; | ||||
|             /* !!! backtrace for primop call */ | ||||
|             return ((PrimOp) ATgetBlobData(funBlob)) | ||||
|                 (state, args2); | ||||
|         } else | ||||
|             /* Need more arguments, so propagate the primop. */ | ||||
|             return makePrimOp(arity, funBlob, args); | ||||
|     } | ||||
| 
 | ||||
|     else if (matchFunction(fun, pat, body, pos)) { | ||||
|         try { | ||||
|             return evalExpr(state, substArgs(state, body, pat, arg)); | ||||
|         } catch (Error & e) { | ||||
|             addErrorPrefix(e, "while evaluating the function at %1%:\n", | ||||
|                 showPos(pos)); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|          | ||||
|     else throwTypeError( | ||||
|         "attempt to call something which is neither a function nor a primop (built-in operation) but %1%", | ||||
|         showType(fun)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| LocalNoInline(Expr evalWith(EvalState & state, Expr defs, Expr body, ATerm pos)) | ||||
| { | ||||
|     ATermMap attrs; | ||||
|     try { | ||||
|         defs = evalExpr(state, defs); | ||||
|         queryAllAttrs(defs, attrs); | ||||
|     } catch (Error & e) { | ||||
|         addErrorPrefix(e, "while evaluating the `with' definitions at %1%:\n", | ||||
|             showPos(pos)); | ||||
|         throw; | ||||
|     } | ||||
|     try { | ||||
|         body = substitute(Substitution(0, &attrs), body); | ||||
|         checkVarDefs(state.primOps, body); | ||||
|         return evalExpr(state, body); | ||||
|     } catch (Error & e) { | ||||
|         addErrorPrefix(e, "while evaluating the `with' body at %1%:\n", | ||||
|             showPos(pos)); | ||||
|         throw; | ||||
|     }  | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Implementation of the `==' and `!=' operators. */ | ||||
| LocalNoInline(bool areEqual(EvalState & state, Expr e1, Expr e2)) | ||||
| { | ||||
|     e1 = evalExpr(state, e1); | ||||
|     e2 = evalExpr(state, e2); | ||||
| 
 | ||||
|     /* We cannot test functions/primops for equality, and we currently
 | ||||
|        don't support testing equality between attribute sets or lists | ||||
|        - that would have to be a deep equality test to be sound. */ | ||||
|     AFun sym1 = ATgetAFun(e1); | ||||
|     AFun sym2 = ATgetAFun(e2); | ||||
| 
 | ||||
|     if (sym1 != sym2) return false; | ||||
| 
 | ||||
|     /* Functions are incomparable. */ | ||||
|     if (sym1 == symFunction || sym1 == symPrimOp) return false; | ||||
| 
 | ||||
|     if (!state.allowUnsafeEquality && sym1 == symAttrs) | ||||
|         throw EvalError("comparison of attribute sets is not implemented"); | ||||
| 
 | ||||
|     /* !!! This allows comparisons of infinite data structures to
 | ||||
|        succeed, such as `let x = [x]; in x == x'.  This is | ||||
|        undesirable, since equivalent (?) terms such as `let x = [x]; y | ||||
|        = [y]; in x == y' don't terminate. */ | ||||
|     if (e1 == e2) return true; | ||||
|      | ||||
|     if (sym1 == symList) { | ||||
|         ATermList es1; matchList(e1, es1); | ||||
|         ATermList es2; matchList(e2, es2); | ||||
|         if (ATgetLength(es1) != ATgetLength(es2)) return false; | ||||
|         ATermIterator i(es1), j(es2); | ||||
|         while (*i) { | ||||
|             if (!areEqual(state, *i, *j)) return false; | ||||
|             ++i; ++j; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|      | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Expr evalExpr2(EvalState & state, Expr e) | ||||
| { | ||||
|     /* When changing this function, make sure that you don't cause a
 | ||||
|        (large) increase in stack consumption! */ | ||||
|      | ||||
|     char x; | ||||
|     if (&x < deepestStack) deepestStack = &x; | ||||
|      | ||||
|     Expr e1, e2, e3; | ||||
|     ATerm name, pos; | ||||
|     AFun sym = ATgetAFun(e); | ||||
| 
 | ||||
|     /* Normal forms. */ | ||||
|     if (sym == symStr || | ||||
|         sym == symPath || | ||||
|         sym == symNull || | ||||
|         sym == symInt || | ||||
|         sym == symBool || | ||||
|         sym == symFunction || | ||||
|         sym == symAttrs || | ||||
|         sym == symList || | ||||
|         sym == symPrimOp) | ||||
|         return e; | ||||
|      | ||||
|     /* The `Closed' constructor is just a way to prevent substitutions
 | ||||
|        into expressions not containing free variables. */ | ||||
|     if (matchClosed(e, e1)) | ||||
|         return evalExpr(state, e1); | ||||
| 
 | ||||
|     /* Any encountered variables must be primops (since undefined
 | ||||
|        variables are detected after parsing). */ | ||||
|     if (matchVar(e, name)) return evalVar(state, name); | ||||
| 
 | ||||
|     /* Function application. */ | ||||
|     if (matchCall(e, e1, e2)) return evalCall(state, e1, e2); | ||||
| 
 | ||||
|     /* Attribute selection. */ | ||||
|     if (matchSelect(e, e1, name)) return evalSelect(state, e1, name); | ||||
| 
 | ||||
|     /* Mutually recursive sets. */ | ||||
|     ATermList rbnds, nrbnds; | ||||
|     if (matchRec(e, rbnds, nrbnds)) | ||||
|         return expandRec(state, e, rbnds, nrbnds); | ||||
| 
 | ||||
|     /* Conditionals. */ | ||||
|     if (matchIf(e, e1, e2, e3)) | ||||
|         return evalExpr(state, evalBool(state, e1) ? e2 : e3); | ||||
| 
 | ||||
|     /* Assertions. */ | ||||
|     if (matchAssert(e, e1, e2, pos)) return evalAssert(state, e1, e2, pos); | ||||
| 
 | ||||
|     /* Withs. */ | ||||
|     if (matchWith(e, e1, e2, pos)) return evalWith(state, e1, e2, pos); | ||||
| 
 | ||||
|     /* Generic equality/inequality.  Note that the behaviour on
 | ||||
|        composite data (lists, attribute sets) and functions is | ||||
|        undefined, since the subterms of those terms are not evaluated. | ||||
|        However, we don't want to make (==) strict, because that would | ||||
|        make operations like `big_derivation == null' very slow (unless | ||||
|        we were to evaluate them side-by-side). */ | ||||
|     if (matchOpEq(e, e1, e2)) return makeBool(areEqual(state, e1, e2)); | ||||
|          | ||||
|     if (matchOpNEq(e, e1, e2)) return makeBool(!areEqual(state, e1, e2)); | ||||
|          | ||||
|     /* Negation. */ | ||||
|     if (matchOpNot(e, e1)) | ||||
|         return makeBool(!evalBool(state, e1)); | ||||
| 
 | ||||
|     /* Implication. */ | ||||
|     if (matchOpImpl(e, e1, e2)) | ||||
|         return makeBool(!evalBool(state, e1) || evalBool(state, e2)); | ||||
| 
 | ||||
|     /* Conjunction (logical AND). */ | ||||
|     if (matchOpAnd(e, e1, e2)) | ||||
|         return makeBool(evalBool(state, e1) && evalBool(state, e2)); | ||||
| 
 | ||||
|     /* Disjunction (logical OR). */ | ||||
|     if (matchOpOr(e, e1, e2)) | ||||
|         return makeBool(evalBool(state, e1) || evalBool(state, e2)); | ||||
| 
 | ||||
|     /* Attribute set update (//). */ | ||||
|     if (matchOpUpdate(e, e1, e2)) | ||||
|         return updateAttrs(evalExpr(state, e1), evalExpr(state, e2)); | ||||
| 
 | ||||
|     /* Attribute existence test (?). */ | ||||
|     if (matchOpHasAttr(e, e1, name)) return evalHasAttr(state, e1, name); | ||||
| 
 | ||||
|     /* String or path concatenation. */ | ||||
|     if (sym == symOpPlus || sym == symConcatStrings) | ||||
|         return evalPlusConcat(state, e); | ||||
| 
 | ||||
|     /* Backwards compatability: subpath operator (~). */ | ||||
|     if (matchSubPath(e, e1, e2)) return evalSubPath(state, e1, e2); | ||||
| 
 | ||||
|     /* List concatenation. */ | ||||
|     if (matchOpConcat(e, e1, e2)) return evalOpConcat(state, e1, e2); | ||||
| 
 | ||||
|     /* Barf. */ | ||||
|     abort(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Expr evalExpr(EvalState & state, Expr e) | ||||
| { | ||||
|     checkInterrupt(); | ||||
| 
 | ||||
| #if 0 | ||||
|     startNest(nest, lvlVomit, | ||||
|         format("evaluating expression: %1%") % e); | ||||
| #endif | ||||
| 
 | ||||
|     state.nrEvaluated++; | ||||
| 
 | ||||
|     /* Consult the memo table to quickly get the normal form of
 | ||||
|        previously evaluated expressions. */ | ||||
|     Expr nf = state.normalForms.get(e); | ||||
|     if (nf) { | ||||
|         if (nf == makeBlackHole()) | ||||
|             throwEvalError("infinite recursion encountered"); | ||||
|         state.nrCached++; | ||||
|         return nf; | ||||
|     } | ||||
| 
 | ||||
|     /* Otherwise, evaluate and memoize. */ | ||||
|     state.normalForms.set(e, makeBlackHole()); | ||||
|     try { | ||||
|         nf = evalExpr2(state, e); | ||||
|     } catch (Error & err) { | ||||
|         state.normalForms.remove(e); | ||||
|         throw; | ||||
|     } | ||||
|     state.normalForms.set(e, nf); | ||||
|     return nf; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Expr strictEvalExpr(EvalState & state, Expr e, ATermMap & nfs); | ||||
| 
 | ||||
| 
 | ||||
| static Expr strictEvalExpr_(EvalState & state, Expr e, ATermMap & nfs) | ||||
| { | ||||
|     e = evalExpr(state, e); | ||||
| 
 | ||||
|     ATermList as; | ||||
|     if (matchAttrs(e, as)) { | ||||
|         ATermList as2 = ATempty; | ||||
|         for (ATermIterator i(as); i; ++i) { | ||||
|             ATerm name; Expr e; ATerm pos; | ||||
|             if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */ | ||||
|             as2 = ATinsert(as2, makeBind(name, strictEvalExpr(state, e, nfs), pos)); | ||||
|         } | ||||
|         return makeAttrs(ATreverse(as2)); | ||||
|     } | ||||
|      | ||||
|     ATermList es; | ||||
|     if (matchList(e, es)) { | ||||
|         ATermList es2 = ATempty; | ||||
|         for (ATermIterator i(es); i; ++i) | ||||
|             es2 = ATinsert(es2, strictEvalExpr(state, *i, nfs)); | ||||
|         return makeList(ATreverse(es2)); | ||||
|     } | ||||
|      | ||||
|     return e; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Expr strictEvalExpr(EvalState & state, Expr e, ATermMap & nfs) | ||||
| { | ||||
|     Expr nf = nfs.get(e); | ||||
|     if (nf) return nf; | ||||
| 
 | ||||
|     nf = strictEvalExpr_(state, e, nfs); | ||||
| 
 | ||||
|     nfs.set(e, nf); | ||||
|      | ||||
|     return nf; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Expr strictEvalExpr(EvalState & state, Expr e) | ||||
| { | ||||
|     ATermMap strictNormalForms; | ||||
|     return strictEvalExpr(state, e, strictNormalForms); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| void EvalState::printStats() | ||||
| { | ||||
|     char x; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue