aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2013-12-31 23:56:26 +0000
committerShea Levy <shea@shealevy.com>2013-12-31 23:56:26 +0000
commitcd49fe4f9b338242e1e404fd4dbb0a3ebc1c3a12 (patch)
tree0ffa5f3bb4acd5ec2b4a84b9e62f88e785d4ea46 /src/libexpr/eval.cc
parent6f3a51809a2603574a16573bd46b95e4ff5233bd (diff)
Don't use any syntactic sugar for dynamic attrs
This doesn't change any functionality but moves some behavior out of the parser and into the evaluator in order to simplify the code. Signed-off-by: Shea Levy <shea@shealevy.com>
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index cd3edecaa..3d8ee9934 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -129,6 +129,18 @@ string showType(const Value & v)
}
+Symbol getName(const AttrName & name, EvalState & state, Env & env) {
+ if (name.symbol.set()) {
+ return name.symbol;
+ } else {
+ Value nameValue;
+ name.expr->eval(state, env, nameValue);
+ state.forceStringNoCtx(nameValue);
+ return state.symbols.create(nameValue.string.s);
+ }
+}
+
+
EvalState::EvalState()
: sWith(symbols.create("<with>"))
, sOutPath(symbols.create("outPath"))
@@ -683,17 +695,18 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
foreach (AttrPath::const_iterator, i, attrPath) {
nrLookups++;
Bindings::iterator j;
+ Symbol name = getName(*i, state, env);
if (def) {
state.forceValue(*vAttrs);
if (vAttrs->type != tAttrs ||
- (j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
+ (j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
{
def->eval(state, env, v);
return;
}
} else {
state.forceAttrs(*vAttrs);
- if ((j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
+ if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
throwEvalError("attribute `%1%' missing", showAttrPath(attrPath));
}
vAttrs = j->value;
@@ -724,8 +737,9 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
foreach (AttrPath::const_iterator, i, attrPath) {
state.forceValue(*vAttrs);
Bindings::iterator j;
+ Symbol name = getName(*i, state, env);
if (vAttrs->type != tAttrs ||
- (j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
+ (j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
{
mkBool(v, false);
return;