about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31T15·38+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31T15·38+0000
commit3d94be61ea562dea2098b6570f711386179913ef (patch)
tree9afd60cf782d5824efc4bafba98af1ee6af937f4 /src/libexpr/eval.cc
parent51876789131e81dca9807c00773158160c3824c2 (diff)
* Implemented derivations.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 7f0adb2c4c..0296afe601 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -261,6 +261,14 @@ void EvalState::mkAttrs(Value & v)
 }
 
 
+void EvalState::cloneAttrs(Value & src, Value & dst)
+{
+    mkAttrs(dst);
+    foreach (Bindings::iterator, i, *src.attrs)
+        (*dst.attrs)[i->first] = i->second; // !!! sharing?
+}
+
+
 void EvalState::evalFile(const Path & path, Value & v)
 {
     startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
@@ -488,17 +496,14 @@ void EvalState::eval(Env & env, Expr e, Value & v)
 
     /* Attribute set update (//). */
     else if (matchOpUpdate(e, e1, e2)) {
-        mkAttrs(v);
-        
         Value v2;
-        eval(env, e2, v2);
-        foreach (Bindings::iterator, i, *v2.attrs)
-            (*v.attrs)[i->first] = i->second;
-        
         eval(env, e1, v2);
+        
+        cloneAttrs(v2, v);
+        
+        eval(env, e2, v2);
         foreach (Bindings::iterator, i, *v2.attrs)
-            if (v.attrs->find(i->first) == v.attrs->end())
-                (*v.attrs)[i->first] = i->second;
+            (*v.attrs)[i->first] = i->second; // !!! sharing
     }
 
     /* Attribute existence test (?). */
@@ -673,6 +678,15 @@ int EvalState::forceInt(Value & v)
 }
 
 
+bool EvalState::forceBool(Value & v)
+{
+    forceValue(v);
+    if (v.type != tBool)
+        throw TypeError(format("value is %1% while a Boolean was expected") % showType(v));
+    return v.boolean;
+}
+
+
 void EvalState::forceAttrs(Value & v)
 {
     forceValue(v);
@@ -697,15 +711,22 @@ void EvalState::forceFunction(Value & v)
 }
 
 
-string EvalState::forceStringNoCtx(Value & v)
+string EvalState::forceString(Value & v)
 {
     forceValue(v);
     if (v.type != tString)
         throw TypeError(format("value is %1% while a string was expected") % showType(v));
+    return string(v.string.s);
+}
+
+
+string EvalState::forceStringNoCtx(Value & v)
+{
+    string s = forceString(v);
     if (v.string.context)
         throw EvalError(format("the string `%1%' is not allowed to refer to a store path (such as `%2%')")
             % v.string.s % v.string.context[0]);
-    return string(v.string.s);
+    return s;
 }