about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc10
-rw-r--r--src/libexpr/eval.hh8
-rw-r--r--src/libexpr/primops.cc36
3 files changed, 17 insertions, 37 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2bfcdac07edc..4277c65ea7b9 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -159,14 +159,6 @@ LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2,
 }
 
 
-static void mkThunk(Value & v, Env & env, Expr expr)
-{
-    v.type = tThunk;
-    v.thunk.env = &env;
-    v.thunk.expr = expr;
-}
-
-
 void mkString(Value & v, const char * s)
 {
     v.type = tString;
@@ -179,7 +171,7 @@ void mkString(Value & v, const string & s, const PathSet & context)
 {
     mkString(v, s.c_str());
     if (!context.empty()) {
-        unsigned int len = 0, n = 0;
+        unsigned int n = 0;
         v.string.context = new const char *[context.size() + 1];
         foreach (PathSet::const_iterator, i, context) 
             v.string.context[n++] = strdup(i->c_str());
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 13ea269fc69d..34b658ce13e4 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -104,6 +104,14 @@ static inline void mkBool(Value & v, bool b)
 }
 
 
+static inline void mkThunk(Value & v, Env & env, Expr expr)
+{
+    v.type = tThunk;
+    v.thunk.env = &env;
+    v.thunk.expr = expr;
+}
+
+
 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);
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 65b736787463..98a31dc3a565 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -448,34 +448,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
     state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
 
     /* !!! assumes a single output */
-    //state.mkAttrs(v);
-    state.cloneAttrs(*args[0], v);
+    state.mkAttrs(v);
     mkString((*v.attrs)[toATerm("outPath")], outPath, singleton<PathSet>(drvPath));
     mkString((*v.attrs)[toATerm("drvPath")], drvPath, singleton<PathSet>("=" + drvPath));
-    mkString((*v.attrs)[toATerm("type")], "derivation"); // !!! remove
-}
-
-
-static void prim_derivationLazy(EvalState & state, Value * * args, Value & v)
-{
-    state.forceAttrs(*args[0]);
-
-    state.cloneAttrs(*args[0], v);
-
-    mkString((*v.attrs)[toATerm("type")], "derivation");
-
-    /* !!! */
-
-#if 0    
-    Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
-
-    attrs.set(toATerm("outPath"),
-        makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos()));
-    attrs.set(toATerm("drvPath"),
-        makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos()));
-    
-    return makeAttrs(attrs);
-#endif
 }
 
 
@@ -1039,6 +1014,12 @@ 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. */
+    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);
+
     // Miscellaneous
     addPrimOp("import", 1, prim_import);
     addPrimOp("isNull", 1, prim_isNull);
@@ -1059,8 +1040,7 @@ void EvalState::createBaseEnv()
     addPrimOp("__trace", 2, prim_trace);
 
     // Derivations
-    addPrimOp("derivation", 1, prim_derivationStrict);
-    //addPrimOp("derivation", 1, prim_derivationLazy);
+    addPrimOp("derivationStrict", 1, prim_derivationStrict);
 
     // Paths
     addPrimOp("__toPath", 1, prim_toPath);