about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T23·25+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T23·25+0000
commitd39d3c6264707c466b21dfadd4d48653842a9156 (patch)
treeaf53c72ecf169d82bd501d49b71e8635b35252bd /src
parent267dc693d2ca8dea13199f92c265fc35fdb047f6 (diff)
* Implemented inherit.
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval-test.cc5
-rw-r--r--src/libexpr/eval.cc30
-rw-r--r--src/libexpr/nixexpr.cc26
-rw-r--r--src/libexpr/nixexpr.hh2
4 files changed, 34 insertions, 29 deletions
diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc
index f87113e59704..a7786561e81e 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 f9502d8fba84..aa75a2ef04c9 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<Symbol>::iterator, i, inherited) {
-            Value & v2 = env2.bindings[*i];
-            mkCopy(v2, *state.lookupVar(&env, *i));
+        foreach (list<VarRef>::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<Symbol>::iterator, i, inherited) {
-            Value & v2 = (*v.attrs)[*i];
+        foreach (list<VarRef>::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<Symbol>::iterator, i, attrs->inherited) {
-        Value & v2 = env2.bindings[*i];
-        mkCopy(v2, *state.lookupVar(&env, *i));
-    }
-#endif
+    foreach (list<VarRef>::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 03b849a3897f..3dfbddf5b89f 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<Symbol>::iterator, i, inherited)
-        str << "inherit " << *i << "; ";
+    foreach (list<VarRef>::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<Symbol>::iterator, i, attrs->inherited)
-        str << "inherit " << *i << "; ";
+    foreach (list<VarRef>::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<Symbol>::iterator, i, inherited)
-            newEnv.vars[*i] = displ++;
+        foreach (list<VarRef>::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<VarRef>::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<Symbol>::iterator, i, attrs->inherited)
-        newEnv.vars[*i] = displ++;
+    foreach (list<VarRef>::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 ffea7049fdba..9e5a262d7f46 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -127,7 +127,7 @@ struct ExprAttrs : Expr
     bool recursive;
     typedef std::map<Symbol, Expr *> Attrs;
     Attrs attrs;
-    list<Symbol> inherited;
+    list<VarRef> inherited;
     ExprAttrs() : recursive(false) { };
     COMMON_METHODS
 };