about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T22·59+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-14T22·59+0000
commit267dc693d2ca8dea13199f92c265fc35fdb047f6 (patch)
tree580534be3b6b2cb5de74135f19128a3115e99a48
parent81de12bc8fa09a89dae958a3ffc93e7a4c245db1 (diff)
* Fix builtins.
-rw-r--r--src/libexpr/eval.cc20
-rw-r--r--src/libexpr/eval.hh9
-rw-r--r--src/libexpr/parser.y3
-rw-r--r--src/libexpr/primops.cc26
4 files changed, 30 insertions, 28 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index ccd359ba7c37..f9502d8fba84 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -43,7 +43,7 @@ std::ostream & operator << (std::ostream & str, Value & v)
         break;
     case tAttrs:
         str << "{ ";
-        foreach (Bindings::iterator, i, *v.attrs) 
+        foreach (Bindings::iterator, i, *v.attrs)
             str << (string) i->first << " = " << i->second << "; ";
         str << "}";
         break;
@@ -99,6 +99,8 @@ EvalState::EvalState()
     , sMeta(symbols.create("meta"))
     , sName(symbols.create("name"))
     , baseEnv(allocEnv(128))
+    , baseEnvDispl(0)
+    , staticBaseEnv(false, 0)
 {
     nrValues = nrEnvs = nrEvaluated = recursionDepth = maxRecursionDepth = 0;
     deepestStack = (char *) -1;
@@ -117,28 +119,24 @@ EvalState::~EvalState()
 
 void EvalState::addConstant(const string & name, Value & v)
 {
-#if 0
-    baseEnv.bindings[symbols.create(name)] = v;
+    staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
+    baseEnv.values[baseEnvDispl++] = v;
     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
-    (*baseEnv.bindings[symbols.create("builtins")].attrs)[symbols.create(name2)] = v;
-    nrValues += 2;
-#endif
+    (*baseEnv.values[0].attrs)[symbols.create(name2)] = v;
 }
 
 
 void EvalState::addPrimOp(const string & name,
     unsigned int arity, PrimOp primOp)
 {
-#if 0
     Value v;
     v.type = tPrimOp;
     v.primOp.arity = arity;
     v.primOp.fun = primOp;
-    baseEnv.bindings[symbols.create(name)] = v;
+    staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
+    baseEnv.values[baseEnvDispl++] = v;
     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
-    (*baseEnv.bindings[symbols.create("builtins")].attrs)[symbols.create(name2)] = v;
-    nrValues += 2;
-#endif
+    (*baseEnv.values[0].attrs)[symbols.create(name2)] = v;
 }
 
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index bc61c84ea746..551ae8d488ac 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -231,6 +231,15 @@ private:
        values. */
     Env & baseEnv;
 
+    unsigned int baseEnvDispl;
+
+public:
+    
+    /* The same, but used during parsing to resolve variables. */
+    StaticEnv staticBaseEnv; // !!! should be private
+
+private:
+    
     void createBaseEnv();
     
     void addConstant(const string & name, Value & v);
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index b3624435231f..06fcc72fc542 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -461,8 +461,7 @@ static Expr * parse(EvalState & state, const char * text,
     if (res) throw ParseError(data.error);
 
     try {
-        StaticEnv env(false, 0);
-        data.result->bindVars(env);
+        data.result->bindVars(state.staticBaseEnv);
     } catch (Error & e) {
         throw ParseError(format("%1%, in `%2%'") % e.msg() % path);
     }
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 83af7ada9315..0d7459feef46 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -999,15 +999,13 @@ void EvalState::createBaseEnv()
 {
     baseEnv.up = 0;
 
-#if 0    
-    Value & builtins = baseEnv.bindings[symbols.create("builtins")];
-    builtins.type = tAttrs;
-    builtins.attrs = new Bindings;
-#endif
-
     /* Add global constants such as `true' to the base environment. */
     Value v;
 
+    /* `builtins' must be first! */
+    mkAttrs(v);
+    addConstant("builtins", v);
+
     mkBool(v, true);
     addConstant("true", v);
     
@@ -1023,14 +1021,6 @@ void EvalState::createBaseEnv()
     mkString(v, thisSystem.c_str());
     addConstant("__currentSystem", v);
 
-    /* Add a wrapper around the derivation primop that computes the
-       `drvPath' and `outPath' attributes lazily. */
-#if 0
-    string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }";
-    mkThunk(v, baseEnv, parseExprFromString(*this, s, "/"));
-    addConstant("derivation", v);
-#endif
-
     // Miscellaneous
     addPrimOp("import", 1, prim_import);
     addPrimOp("isNull", 1, prim_isNull);
@@ -1053,6 +1043,12 @@ void EvalState::createBaseEnv()
     // Derivations
     addPrimOp("derivationStrict", 1, prim_derivationStrict);
 
+    /* Add a wrapper around the derivation primop that computes the
+       `drvPath' and `outPath' attributes lazily. */
+    string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }";
+    mkThunk(v, baseEnv, parseExprFromString(*this, s, "/"));
+    addConstant("derivation", v);
+
     // Paths
     addPrimOp("__toPath", 1, prim_toPath);
 #if 0
@@ -1105,7 +1101,7 @@ void EvalState::createBaseEnv()
 
     // Versions
     addPrimOp("__parseDrvName", 1, prim_parseDrvName);
-    addPrimOp("__compareVersions", 2, prim_compareVersions);
+    addPrimOp("__compareVersions", 2, prim_compareVersions);    
 }