forked from lix-project/lix
* 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:
parent
5580f3817c
commit
2b9e29b1c8
|
@ -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) {
|
||||||
|
if (pos)
|
||||||
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
|
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
|
||||||
name, *i->pos);
|
showAttrPath(attrPath), *pos);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
v = *i->value;
|
|
||||||
|
v = *vAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Reference in a new issue