From d39d3c6264707c466b21dfadd4d48653842a9156 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 14 Apr 2010 23:25:05 +0000 Subject: [PATCH] * Implemented inherit. --- src/libexpr/eval-test.cc | 5 ++++- src/libexpr/eval.cc | 30 ++++++++++++------------------ src/libexpr/nixexpr.cc | 26 +++++++++++++++++--------- src/libexpr/nixexpr.hh | 2 +- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc index f87113e597..a7786561e8 100644 --- a/src/libexpr/eval-test.cc +++ b/src/libexpr/eval-test.cc @@ -105,9 +105,12 @@ void run(Strings args) doTest(state, "map (x: __add 1 x) [ 1 2 3 ]"); doTest(state, "map (builtins.add 1) [ 1 2 3 ]"); doTest(state, "builtins.hasAttr \"x\" { x = 1; }"); - doTest(state, "let x = 1; as = rec { inherit x; y = as.x; }; in as.y"); + doTest(state, "let x = 1; as = { inherit x; y = as.x; }; in as.y"); + doTest(state, "let x = 1; as = rec { inherit x; y = x; }; in as.y"); doTest(state, "let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y"); doTest(state, "let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x"); + doTest(state, "let x = 1; in let inherit x; in x"); + doTest(state, "with { x = 1; }; let inherit x; y = x; in y"); doTest(state, "builtins.toXML 123"); doTest(state, "builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }"); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f9502d8fba..aa75a2ef04 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -338,7 +338,7 @@ void EvalState::eval(Env & env, Expr * e, Value & v) char x; if (&x < deepestStack) deepestStack = &x; - debug(format("eval: %1%") % *e); + //debug(format("eval: %1%") % *e); checkInterrupt(); @@ -390,14 +390,13 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v) void ExprAttrs::eval(EvalState & state, Env & env, Value & v) { + state.mkAttrs(v); + if (recursive) { /* Create a new environment that contains the attributes in this `rec'. */ Env & env2(state.allocEnv(attrs.size() + inherited.size())); env2.up = &env; - - v.type = tAttrs; - v.attrs = new Bindings; unsigned int displ = 0; @@ -409,26 +408,25 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) mkThunk(env2.values[displ++], env2, i->second); } -#if 0 /* The inherited attributes, on the other hand, are evaluated in the original environment. */ - foreach (list::iterator, i, inherited) { - Value & v2 = env2.bindings[*i]; - mkCopy(v2, *state.lookupVar(&env, *i)); + foreach (list::iterator, i, inherited) { + Value & v2 = (*v.attrs)[i->name]; + Value * v3 = state.lookupVar(&env, *i); + mkCopy(v2, *v3); + mkCopy(env2.values[displ++], *v3); } -#endif } else { - state.mkAttrs(v); foreach (Attrs::iterator, i, attrs) { Value & v2 = (*v.attrs)[i->first]; mkThunk(v2, env, i->second); } - foreach (list::iterator, i, inherited) { - Value & v2 = (*v.attrs)[*i]; + foreach (list::iterator, i, inherited) { + Value & v2 = (*v.attrs)[i->name]; mkCopy(v2, *state.lookupVar(&env, *i)); } } @@ -449,14 +447,10 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) mkThunk(env2.values[displ++], env2, i->second); -#if 0 /* The inherited attributes, on the other hand, are evaluated in the original environment. */ - foreach (list::iterator, i, attrs->inherited) { - Value & v2 = env2.bindings[*i]; - mkCopy(v2, *state.lookupVar(&env, *i)); - } -#endif + foreach (list::iterator, i, attrs->inherited) + mkCopy(env2.values[displ++], *state.lookupVar(&env, *i)); state.eval(env2, body, v); } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 03b849a389..3dfbddf5b8 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -55,8 +55,8 @@ void ExprAttrs::show(std::ostream & str) { if (recursive) str << "rec "; str << "{ "; - foreach (list::iterator, i, inherited) - str << "inherit " << *i << "; "; + foreach (list::iterator, i, inherited) + str << "inherit " << i->name << "; "; foreach (Attrs::iterator, i, attrs) str << i->first << " = " << *i->second << "; "; str << "}"; @@ -91,8 +91,8 @@ void ExprLambda::show(std::ostream & str) void ExprLet::show(std::ostream & str) { str << "let "; - foreach (list::iterator, i, attrs->inherited) - str << "inherit " << *i << "; "; + foreach (list::iterator, i, attrs->inherited) + str << "inherit " << i->name << "; "; foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) str << i->first << " = " << *i->second << "; "; str << "in " << *body; @@ -212,16 +212,22 @@ void ExprAttrs::bindVars(const StaticEnv & env) foreach (ExprAttrs::Attrs::iterator, i, attrs) newEnv.vars[i->first] = displ++; - foreach (list::iterator, i, inherited) - newEnv.vars[*i] = displ++; + foreach (list::iterator, i, inherited) { + newEnv.vars[i->name] = displ++; + i->bind(env); + } foreach (ExprAttrs::Attrs::iterator, i, attrs) i->second->bindVars(newEnv); } - else + else { foreach (ExprAttrs::Attrs::iterator, i, attrs) i->second->bindVars(env); + + foreach (list::iterator, i, inherited) + i->bind(env); + } } void ExprList::bindVars(const StaticEnv & env) @@ -258,8 +264,10 @@ void ExprLet::bindVars(const StaticEnv & env) foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) newEnv.vars[i->first] = displ++; - foreach (list::iterator, i, attrs->inherited) - newEnv.vars[*i] = displ++; + foreach (list::iterator, i, attrs->inherited) { + newEnv.vars[i->name] = displ++; + i->bind(env); + } foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) i->second->bindVars(newEnv); diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index ffea7049fd..9e5a262d7f 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -127,7 +127,7 @@ struct ExprAttrs : Expr bool recursive; typedef std::map Attrs; Attrs attrs; - list inherited; + list inherited; ExprAttrs() : recursive(false) { }; COMMON_METHODS };