about summary refs log tree commit diff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-21T15·08+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-21T15·08+0000
commitfe2d869e04372de69719c3989a75247ff44b8fd4 (patch)
treece7df351314663d45adaa6a3b7ba4c64f179c63a /src/libexpr
parentf3b8833a48472c3545ea8673d687ea9cadcedd61 (diff)
* Store user environment manifests as a Nix expression in
  $out/manifest.nix rather than as an ATerm.

  (Hm, I thought I committed this two days ago...)

Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc11
-rw-r--r--src/libexpr/eval.hh11
-rw-r--r--src/libexpr/get-drvs.cc23
-rw-r--r--src/libexpr/get-drvs.hh2
-rw-r--r--src/libexpr/primops.cc31
5 files changed, 38 insertions, 40 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index d259d58a3759..f59ea99e5d41 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -98,6 +98,7 @@ EvalState::EvalState()
     , sType(symbols.create("type"))
     , sMeta(symbols.create("meta"))
     , sName(symbols.create("name"))
+    , sSystem(symbols.create("system"))
     , baseEnv(allocEnv(128))
     , baseEnvDispl(0)
     , staticBaseEnv(false, 0)
@@ -131,12 +132,13 @@ void EvalState::addPrimOp(const string & name,
     unsigned int arity, PrimOp primOp)
 {
     Value v;
+    string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
     v.type = tPrimOp;
     v.primOp.arity = arity;
     v.primOp.fun = primOp;
+    v.primOp.name = strdup(name2.c_str());
     staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
     baseEnv.values[baseEnvDispl++] = v;
-    string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
     (*baseEnv.values[0].attrs)[symbols.create(name2)] = v;
 }
 
@@ -550,7 +552,12 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
                 vArgs[n--] = arg->primOpApp.right;
 
             /* And call the primop. */
-            primOp->primOp.fun(*this, vArgs, v);
+            try {
+                primOp->primOp.fun(*this, vArgs, v);
+            } catch (Error & e) {
+                addErrorPrefix(e, "while evaluating the builtin function `%1%':\n", primOp->primOp.name);
+                throw;
+            }
         } else {
             Value * v2 = allocValues(2);
             v2[0] = fun;
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 6cdc171f5609..a730dc297799 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -92,6 +92,7 @@ struct Value
         Value * val;
         struct {
             PrimOp fun;
+            char * name;
             unsigned int arity;
         } primOp;
         struct {
@@ -138,6 +139,14 @@ static inline void mkCopy(Value & v, Value & src)
 }
 
 
+static inline void mkApp(Value & v, Value & left, Value & right)
+{
+    v.type = tApp;
+    v.app.left = &left;
+    v.app.right = &right;
+}
+
+
 void mkString(Value & v, const char * s);
 void mkString(Value & v, const string & s, const PathSet & context = PathSet());
 void mkPath(Value & v, const char * s);
@@ -162,7 +171,7 @@ public:
 
     SymbolTable symbols;
 
-    const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName;
+    const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sSystem;
 
 private:
     SrcToStore srcToStore; 
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index e9f1063d955f..e0ad91d8a54f 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -70,27 +70,6 @@ void DrvInfo::setMetaInfo(const MetaInfo & meta)
 {
     metaInfoRead = true;
     this->meta = meta;
-    
-#if 0
-    Value * metaAttrs = state.allocValues(1);
-    foreach (MetaInfo::const_iterator, i, meta) {
-        Expr e;
-        switch (i->second.type) {
-            case MetaValue::tpInt: e = makeInt(i->second.intValue); break;
-            case MetaValue::tpString: e = makeStr(i->second.stringValue); break;
-            case MetaValue::tpStrings: {
-                ATermList es = ATempty;
-                foreach (Strings::const_iterator, j, i->second.stringValues)
-                    es = ATinsert(es, makeStr(*j));
-                e = makeList(ATreverse(es));
-                break;
-            }
-            default: abort();
-        }
-        metaAttrs.set(toATerm(i->first), makeAttrRHS(e, makeNoPos()));
-    }
-    attrs->set(toATerm("meta"), makeAttrs(metaAttrs));
-#endif
 }
 
 
@@ -122,7 +101,7 @@ static bool getDerivation(EvalState & state, Value & v,
         if (i == v.attrs->end()) throw TypeError("derivation name missing");
         drv.name = state.forceStringNoCtx(i->second);
 
-        i = v.attrs->find(state.symbols.create("system"));
+        i = v.attrs->find(state.sSystem);
         if (i == v.attrs->end())
             drv.system = "unknown";
         else
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 6f3c381f8e34..ca7d980027e4 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -41,7 +41,7 @@ public:
     /* !!! make this private */
     Bindings * attrs;
 
-    DrvInfo() : metaInfoRead(false) { };
+    DrvInfo() : metaInfoRead(false), attrs(0) { };
 
     string queryDrvPath(EvalState & state) const;
     string queryOutPath(EvalState & state) const;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index b28201593335..a228398e0652 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -89,24 +89,29 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
 {
     startNest(nest, lvlDebug, "finding dependencies");
 
-    Expr attrs = evalExpr(state, args[0]);
+    state.forceAttrs(*args[0]);
 
     /* Get the start set. */
-    Expr startSet = queryAttr(attrs, "startSet");
-    if (!startSet) throw EvalError("attribute `startSet' required");
-    ATermList startSet2 = evalList(state, startSet);
+    Bindings::iterator startSet =
+        args[0]->attrs->find(state.symbols.create("startSet"));
+    if (startSet == args[0]->attrs->end())
+        throw EvalError("attribute `startSet' required");
+    state.forceList(startSet->second);
 
-    set<Expr> workSet; // !!! gc roots
-    for (ATermIterator i(startSet2); i; ++i) workSet.insert(*i);
+    list<Value> workSet;
+    for (unsigned int n = 0; n < startSet->second.list.length; ++n)
+        workSet.push_back(*startSet->second.list.elems[n]);
 
     /* Get the operator. */
-    Expr op = queryAttr(attrs, "operator");
-    if (!op) throw EvalError("attribute `operator' required");
+    Bindings::iterator op =
+        args[0]->attrs->find(state.symbols.create("operator"));
+    if (op == args[0]->attrs->end())
+        throw EvalError("attribute `operator' required");
     
     /* Construct the closure by applying the operator to element of
        `workSet', adding the result to `workSet', continuing until
        no new elements are found. */
-    ATermList res = ATempty;
+    list<Value> res;
     set<Expr> doneKeys; // !!! gc roots
     while (!workSet.empty()) {
 	Expr e = *(workSet.begin());
@@ -322,8 +327,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
                 string s = state.coerceToString(i->second, context, true);
                 drv.env[key] = s;
                 if (key == "builder") drv.builder = s;
-                else if (key == "system") drv.platform = s;
-                else if (key == "name") drvName = s;
+                else if (i->first == state.sSystem) drv.platform = s;
+                else if (i->first == state.sName) drvName = s;
                 else if (key == "outputHash") outputHash = s;
                 else if (key == "outputHashAlgo") outputHashAlgo = s;
                 else if (key == "outputHashMode") {
@@ -830,9 +835,7 @@ static void prim_map(EvalState & state, Value * * args, Value & v)
 
     for (unsigned int n = 0; n < v.list.length; ++n) {
         v.list.elems[n] = &vs[n];
-        vs[n].type = tApp;
-        vs[n].app.left = args[0];
-        vs[n].app.right = args[1]->list.elems[n];
+        mkApp(vs[n], *args[0], *args[1]->list.elems[n]);
     }
 }