diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-08-24T13·39+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-08-24T13·39+0000 |
commit | 943ab38a0d0969004de231a6b3e89df88ffc6ccf (patch) | |
tree | 10852ca08d48ce59858ebc64702f1de8b7b51629 /src/libexpr/eval.cc | |
parent | f41297fdcecaa1ba12d238d1754457d319426579 (diff) |
* Refactoring: move strictEval to libexpr.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r-- | src/libexpr/eval.cc | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c4f5d7f5d64d..07f53a56c7bc 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -584,6 +584,49 @@ Expr evalFile(EvalState & state, const Path & path) } +Expr strictEvalExpr(EvalState & state, Expr e) +{ + 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), pos)); + } + return makeAttrs(ATreverse(as2)); + } + + ATermList formals; + ATerm body, pos; + + if (matchFunction(e, formals, body, pos)) { + ATermList formals2 = ATempty; + + for (ATermIterator i(formals); i; ++i) { + Expr name; ValidValues valids; ATerm dummy; + if (!matchFormal(*i, name, valids, dummy)) abort(); + + ATermList valids2; + if (matchValidValues(valids, valids2)) { + ATermList valids3 = ATempty; + for (ATermIterator j(valids2); j; ++j) + valids3 = ATinsert(valids3, strictEvalExpr(state, *j)); + valids = makeValidValues(ATreverse(valids3)); + } + + formals2 = ATinsert(formals2, makeFormal(name, valids, dummy)); + } + return makeFunction(ATreverse(formals2), body, pos); + } + + return e; +} + + /* Yes, this is a really bad idea... */ extern "C" { unsigned long AT_calcAllocatedSize(); |