about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T15·14+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T15·14+0000
commit81de12bc8fa09a89dae958a3ffc93e7a4c245db1 (patch)
tree7e2a8545dc16229181caa87266bede87b98ebf63
parent110d1557782fac4f8cafa27e5cbbcdebefb7a4c7 (diff)
* Refactoring: move variable uses to a separate class.
-rw-r--r--src/libexpr/eval.cc42
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/nixexpr.cc9
-rw-r--r--src/libexpr/nixexpr.hh13
4 files changed, 31 insertions, 35 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index d934470108..ccd359ba7c 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -236,24 +236,17 @@ void mkPath(Value & v, const char * s)
 }
 
 
-Value * EvalState::lookupVar(Env * env, const Symbol & name)
+Value * EvalState::lookupVar(Env * env, const VarRef & var)
 {
-#if 0
-    /* First look for a regular variable binding for `name'. */
-        Bindings::iterator i = env2->bindings.find(name);
-        if (i != env2->bindings.end()) return &i->second;
-    }
-
-    /* Otherwise, look for a `with' attribute set containing `name'.
-       Inner `withs' take precedence (i.e. `with {x=1;}; with {x=2;};
-       x' evaluates to 2). */
-    for (Env * env2 = env; env2; env2 = env2->up) {
-        Bindings::iterator i = env2->bindings.find(sWith);
-        if (i == env2->bindings.end()) continue;
-        Bindings::iterator j = i->second.attrs->find(name);
-        if (j != i->second.attrs->end()) return &j->second;
-    }
-#endif
+    for (unsigned int l = var.level; l; --l, env = env->up) ;
+    
+    if (var.fromWith) {
+        Bindings::iterator j = env->values[0].attrs->find(var.name);
+        if (j == env->values[0].attrs->end())
+            throwEvalError("undefined variable `%1%'", var.name);
+        return &j->second;
+    } else
+        return &env->values[var.displ];
 }
 
 
@@ -481,18 +474,9 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
 
 void ExprVar::eval(EvalState & state, Env & env, Value & v)
 {
-    Env * env2 = &env;
-    for (unsigned int l = level; l; --l, env2 = env2->up) ;
-    
-    if (fromWith) {
-        Bindings::iterator j = env2->values[0].attrs->find(name);
-        if (j == env2->values[0].attrs->end())
-            throwEvalError("undefined variable `%1%'", name);
-        v = j->second;
-    } else {
-        state.forceValue(env2->values[displ]);
-        v = env2->values[displ];
-    }
+    Value * v2 = state.lookupVar(&env, info);
+    state.forceValue(*v2);
+    v = *v2;
 }
 
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index a24b7345ef..bc61c84ea7 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -238,7 +238,7 @@ private:
     void addPrimOp(const string & name,
         unsigned int arity, PrimOp primOp);
 
-    Value * lookupVar(Env * env, const Symbol & name);
+    Value * lookupVar(Env * env, const VarRef & var);
     
     friend class ExprVar;
     friend class ExprAttrs;
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index ab4fa6cba3..03b849a389 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -38,7 +38,7 @@ void ExprPath::show(std::ostream & str)
 
 void ExprVar::show(std::ostream & str)
 {
-    str << name;
+    str << info.name;
 }
 
 void ExprSelect::show(std::ostream & str)
@@ -157,7 +157,7 @@ void ExprPath::bindVars(const StaticEnv & env)
 {
 }
 
-void ExprVar::bindVars(const StaticEnv & env)
+void VarRef::bind(const StaticEnv & env)
 {
     /* Check whether the variable appears in the environment.  If so,
        set its level and displacement. */
@@ -187,6 +187,11 @@ void ExprVar::bindVars(const StaticEnv & env)
     this->level = withLevel;
 }
 
+void ExprVar::bindVars(const StaticEnv & env)
+{
+    info.bind(env);
+}
+
 void ExprSelect::bindVars(const StaticEnv & env)
 {
     e->bindVars(env);
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index f9ed34f58a..ffea7049fd 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -78,7 +78,7 @@ struct ExprPath : Expr
     COMMON_METHODS
 };
 
-struct ExprVar : Expr
+struct VarRef
 {
     Symbol name;
 
@@ -94,8 +94,15 @@ struct ExprVar : Expr
        levels up from the current one.*/
     unsigned int level;
     unsigned int displ;
-    
-    ExprVar(const Symbol & name) : name(name) { };
+
+    VarRef(const Symbol & name) : name(name) { };
+    void bind(const StaticEnv & env);
+};
+
+struct ExprVar : Expr
+{
+    VarRef info;
+    ExprVar(const Symbol & name) : info(name) { };
     COMMON_METHODS
 };