preserve information about whether/how an attribute was inherited
(cherry picked from commit c66ee57edc6cac3571bfbf77d0c0ea4d25b4e805)
Change-Id: Ie8606a8b2f5946c87dd4d16b7b46203e199a4cc1
This commit is contained in:
parent
3e43f4aeff
commit
03f852b2c6
|
@ -1238,11 +1238,11 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
|||
Displacement displ = 0;
|
||||
for (auto & i : attrs) {
|
||||
Value * vAttr;
|
||||
if (hasOverrides && !i.second.inherited) {
|
||||
if (hasOverrides && !i.second.inherited()) {
|
||||
vAttr = state.allocValue();
|
||||
mkThunk(*vAttr, env2, i.second.e);
|
||||
} else
|
||||
vAttr = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
||||
vAttr = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2);
|
||||
env2.values[displ++] = vAttr;
|
||||
v.attrs->push_back(Attr(i.first, vAttr, i.second.pos));
|
||||
}
|
||||
|
@ -1313,7 +1313,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
|||
environment. */
|
||||
Displacement displ = 0;
|
||||
for (auto & i : attrs->attrs)
|
||||
env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
||||
env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2);
|
||||
|
||||
auto dts = state.debugRepl
|
||||
? makeDebugTraceStacker(
|
||||
|
|
|
@ -80,7 +80,7 @@ void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
|
|||
return sa < sb;
|
||||
});
|
||||
for (auto & i : sorted) {
|
||||
if (i->second.inherited)
|
||||
if (i->second.inherited())
|
||||
str << "inherit " << symbols[i->first] << " " << "; ";
|
||||
else {
|
||||
str << symbols[i->first] << " = ";
|
||||
|
@ -151,7 +151,7 @@ void ExprLet::show(const SymbolTable & symbols, std::ostream & str) const
|
|||
{
|
||||
str << "(let ";
|
||||
for (auto & i : attrs->attrs)
|
||||
if (i.second.inherited) {
|
||||
if (i.second.inherited()) {
|
||||
str << "inherit " << symbols[i.first] << "; ";
|
||||
}
|
||||
else {
|
||||
|
@ -341,7 +341,7 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
|||
// No need to sort newEnv since attrs is in sorted order.
|
||||
|
||||
for (auto & i : attrs)
|
||||
i.second.e->bindVars(es, i.second.inherited ? env : newEnv);
|
||||
i.second.e->bindVars(es, i.second.inherited() ? env : newEnv);
|
||||
|
||||
for (auto & i : dynamicAttrs) {
|
||||
i.nameExpr->bindVars(es, newEnv);
|
||||
|
@ -416,7 +416,7 @@ void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
|||
// No need to sort newEnv since attrs->attrs is in sorted order.
|
||||
|
||||
for (auto & i : attrs->attrs)
|
||||
i.second.e->bindVars(es, i.second.inherited ? env : newEnv);
|
||||
i.second.e->bindVars(es, i.second.inherited() ? env : newEnv);
|
||||
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, newEnv));
|
||||
|
|
|
@ -154,13 +154,24 @@ struct ExprAttrs : Expr
|
|||
bool recursive;
|
||||
PosIdx pos;
|
||||
struct AttrDef {
|
||||
bool inherited;
|
||||
enum class Kind {
|
||||
/** `attr = expr;` */
|
||||
Plain,
|
||||
/** `inherit attr1 attrn;` */
|
||||
Inherited,
|
||||
/** `inherit (expr) attr1 attrn;` */
|
||||
InheritedFrom,
|
||||
};
|
||||
|
||||
Kind kind;
|
||||
Expr * e;
|
||||
PosIdx pos;
|
||||
Displacement displ; // displacement
|
||||
AttrDef(Expr * e, const PosIdx & pos, bool inherited=false)
|
||||
: inherited(inherited), e(e), pos(pos) { };
|
||||
AttrDef(Expr * e, const PosIdx & pos, Kind kind = Kind::Plain)
|
||||
: kind(kind), e(e), pos(pos) { };
|
||||
AttrDef() { };
|
||||
|
||||
bool inherited() const { return kind == Kind::Inherited; }
|
||||
};
|
||||
typedef std::map<Symbol, AttrDef> AttrDefs;
|
||||
AttrDefs attrs;
|
||||
|
|
|
@ -88,7 +88,7 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr *
|
|||
if (i->symbol) {
|
||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
|
||||
if (j != attrs->attrs.end()) {
|
||||
if (!j->second.inherited) {
|
||||
if (!j->second.inherited()) {
|
||||
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
|
||||
attrs = attrs2;
|
||||
|
|
|
@ -311,7 +311,9 @@ binds
|
|||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||
state->dupAttr(i.symbol, state->at(@3), $$->attrs[i.symbol].pos);
|
||||
auto pos = state->at(@3);
|
||||
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true));
|
||||
$$->attrs.emplace(
|
||||
i.symbol,
|
||||
ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, ExprAttrs::AttrDef::Kind::Inherited));
|
||||
}
|
||||
delete $3;
|
||||
}
|
||||
|
@ -321,7 +323,12 @@ binds
|
|||
for (auto & i : *$6) {
|
||||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||
state->dupAttr(i.symbol, state->at(@6), $$->attrs[i.symbol].pos);
|
||||
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), state->at(@6)));
|
||||
$$->attrs.emplace(
|
||||
i.symbol,
|
||||
ExprAttrs::AttrDef(
|
||||
new ExprSelect(CUR_POS, $4, i.symbol),
|
||||
state->at(@6),
|
||||
ExprAttrs::AttrDef::Kind::InheritedFrom));
|
||||
}
|
||||
delete $6;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue