diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2010-04-13T13·42+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2010-04-13T13·42+0000 |
commit | 7d47498b5ea1ad4685bad954e5407f628f7f5595 (patch) | |
tree | 0451c3cd9301030af94a805f476d8b5926edd4d6 /src/libexpr/eval.cc | |
parent | ac1e8f40d4a5c380d68bb6f1c7cef6f1e7987c1a (diff) |
* Evaluate lets directly (i.e. without desugaring to `rec { attrs...;
<let-body> = e; }.<let-body>). This prevents the unnecessary allocation of an attribute set.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r-- | src/libexpr/eval.cc | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ffeae8d7311b..fbd618d4173b 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -456,6 +456,31 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) } +void ExprLet::eval(EvalState & state, Env & env, Value & v) +{ + /* Create a new environment that contains the attributes in this + `let'. */ + Env & env2(state.allocEnv()); + env2.up = &env; + + /* The recursive attributes are evaluated in the new + environment. */ + foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) { + Value & v2 = env2.bindings[i->first]; + mkThunk(v2, env2, i->second); + } + + /* The inherited attributes, on the other hand, are evaluated in + the original environment. */ + foreach (list<Symbol>::iterator, i, attrs->inherited) { + Value & v2 = env2.bindings[*i]; + mkCopy(v2, *state.lookupVar(&env, *i)); + } + + state.eval(env2, body, v); +} + + void ExprList::eval(EvalState & state, Env & env, Value & v) { state.mkList(v, elems.size()); |