* Change the right-hand side of the ‘.’ operator from an attribute to

an attribute path.  This is a refactoring to support default values.
This commit is contained in:
Eelco Dolstra 2011-07-06 12:28:57 +00:00
parent 5580f3817c
commit 2b9e29b1c8
4 changed files with 33 additions and 18 deletions

View File

@ -636,21 +636,35 @@ unsigned long nrLookupSize = 0;
void ExprSelect::eval(EvalState & state, Env & env, Value & v) void ExprSelect::eval(EvalState & state, Env & env, Value & v)
{ {
nrLookups++; Value vTmp;
Value v2; Pos * pos = 0;
state.evalAttrs(env, e, v2); Value * vAttrs = &vTmp;
nrLookupSize += v2.attrs->size();
Bindings::iterator i = v2.attrs->find(name); state.eval(env, e, vTmp);
if (i == v2.attrs->end())
throwEvalError("attribute `%1%' missing", name); try {
try {
state.forceValue(*i->value); 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) { } catch (Error & e) {
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n", if (pos)
name, *i->pos); addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
showAttrPath(attrPath), *pos);
throw; throw;
} }
v = *i->value;
v = *vAttrs;
} }

View File

@ -43,7 +43,7 @@ void ExprVar::show(std::ostream & str)
void ExprSelect::show(std::ostream & str) void ExprSelect::show(std::ostream & str)
{ {
str << "(" << *e << ")." << name; str << "(" << *e << ")." << showAttrPath(attrPath);
} }
void ExprOpHasAttr::show(std::ostream & str) void ExprOpHasAttr::show(std::ostream & str)

View File

@ -122,8 +122,9 @@ struct ExprVar : Expr
struct ExprSelect : Expr struct ExprSelect : Expr
{ {
Expr * e; Expr * e;
Symbol name; AttrPath attrPath;
ExprSelect(Expr * e, const Symbol & name) : e(e), name(name) { }; ExprSelect(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
ExprSelect(Expr * e, const Symbol & name) : e(e) { attrPath.push_back(name); };
COMMON_METHODS COMMON_METHODS
}; };

View File

@ -325,8 +325,8 @@ expr_app
; ;
expr_select expr_select
: expr_select '.' ID : expr_simple '.' attrpath
{ $$ = new ExprSelect($1, data->symbols.create($3)); } { $$ = new ExprSelect($1, *$3); }
| expr_simple { $$ = $1; } | expr_simple { $$ = $1; }
; ;
@ -382,7 +382,7 @@ binds
| binds INHERIT '(' expr ')' ids ';' | binds INHERIT '(' expr ')' ids ';'
{ $$ = $1; { $$ = $1;
/* !!! Should ensure sharing of the expression in $4. */ /* !!! 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()) if ($$->attrs.find(*i) != $$->attrs.end())
dupAttr(*i, makeCurPos(@6, data), $$->attrs[*i].pos); dupAttr(*i, makeCurPos(@6, data), $$->attrs[*i].pos);
$$->attrs[*i] = ExprAttrs::AttrDef(new ExprSelect($4, *i), makeCurPos(@6, data)); $$->attrs[*i] = ExprAttrs::AttrDef(new ExprSelect($4, *i), makeCurPos(@6, data));