aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31 15:38:03 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-31 15:38:03 +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 7f0adb2c4..0296afe60 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;
}