diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-07-06 12:28:57 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-07-06 12:28:57 +0000 |
commit | 2b9e29b1c8b6b8e4884a46a3ba71ee795f1f97cd (patch) | |
tree | 9b4dd1efce2222e6fdf29ceaaca1f477b77e532b /src | |
parent | 5580f3817c37135dcc633d84d1360a17a8878a58 (diff) |
* Change the right-hand side of the ‘.’ operator from an attribute to
an attribute path. This is a refactoring to support default values.
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 38 | ||||
-rw-r--r-- | src/libexpr/nixexpr.cc | 2 | ||||
-rw-r--r-- | src/libexpr/nixexpr.hh | 5 | ||||
-rw-r--r-- | src/libexpr/parser.y | 6 |
4 files changed, 33 insertions, 18 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c307f2a42..4d3a369aa 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -636,21 +636,35 @@ unsigned long nrLookupSize = 0; void ExprSelect::eval(EvalState & state, Env & env, Value & v) { - nrLookups++; - Value v2; - state.evalAttrs(env, e, v2); - nrLookupSize += v2.attrs->size(); - Bindings::iterator i = v2.attrs->find(name); - if (i == v2.attrs->end()) - throwEvalError("attribute `%1%' missing", name); - try { - state.forceValue(*i->value); + Value vTmp; + Pos * pos = 0; + Value * vAttrs = &vTmp; + + state.eval(env, e, vTmp); + + try { + + foreach (AttrPath::const_iterator, i, attrPath) { + nrLookups++; + state.forceAttrs(*vAttrs); + nrLookupSize += vAttrs->attrs->size(); + Bindings::iterator j; + if ((j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end()) + throwEvalError("attribute `%1%' missing", showAttrPath(attrPath)); + vAttrs = j->value; + pos = j->pos; + } + + state.forceValue(*vAttrs); + } catch (Error & e) { - addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n", - name, *i->pos); + if (pos) + addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n", + showAttrPath(attrPath), *pos); throw; } - v = *i->value; + + v = *vAttrs; } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 595761870..2632d9f3f 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -43,7 +43,7 @@ void ExprVar::show(std::ostream & str) void ExprSelect::show(std::ostream & str) { - str << "(" << *e << ")." << name; + str << "(" << *e << ")." << showAttrPath(attrPath); } void ExprOpHasAttr::show(std::ostream & str) diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 205f579da..725e30c6f 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -122,8 +122,9 @@ struct ExprVar : Expr struct ExprSelect : Expr { Expr * e; - Symbol name; - ExprSelect(Expr * e, const Symbol & name) : e(e), name(name) { }; + AttrPath attrPath; + ExprSelect(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { }; + ExprSelect(Expr * e, const Symbol & name) : e(e) { attrPath.push_back(name); }; COMMON_METHODS }; diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 073fac1be..49bd7bfa5 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -325,8 +325,8 @@ expr_app ; expr_select - : expr_select '.' ID - { $$ = new ExprSelect($1, data->symbols.create($3)); } + : expr_simple '.' attrpath + { $$ = new ExprSelect($1, *$3); } | expr_simple { $$ = $1; } ; @@ -382,7 +382,7 @@ binds | binds INHERIT '(' expr ')' ids ';' { $$ = $1; /* !!! Should ensure sharing of the expression in $4. */ - foreach (AttrPath::iterator, i, *$6) { + foreach (vector<Symbol>::iterator, i, *$6) { if ($$->attrs.find(*i) != $$->attrs.end()) dupAttr(*i, makeCurPos(@6, data), $$->attrs[*i].pos); $$->attrs[*i] = ExprAttrs::AttrDef(new ExprSelect($4, *i), makeCurPos(@6, data)); |