forked from lix-project/lix
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;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs) {
|
for (auto & i : attrs) {
|
||||||
Value * vAttr;
|
Value * vAttr;
|
||||||
if (hasOverrides && !i.second.inherited) {
|
if (hasOverrides && !i.second.inherited()) {
|
||||||
vAttr = state.allocValue();
|
vAttr = state.allocValue();
|
||||||
mkThunk(*vAttr, env2, i.second.e);
|
mkThunk(*vAttr, env2, i.second.e);
|
||||||
} else
|
} 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;
|
env2.values[displ++] = vAttr;
|
||||||
v.attrs->push_back(Attr(i.first, vAttr, i.second.pos));
|
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. */
|
environment. */
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
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
|
auto dts = state.debugRepl
|
||||||
? makeDebugTraceStacker(
|
? makeDebugTraceStacker(
|
||||||
|
|
|
@ -80,7 +80,7 @@ void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
return sa < sb;
|
return sa < sb;
|
||||||
});
|
});
|
||||||
for (auto & i : sorted) {
|
for (auto & i : sorted) {
|
||||||
if (i->second.inherited)
|
if (i->second.inherited())
|
||||||
str << "inherit " << symbols[i->first] << " " << "; ";
|
str << "inherit " << symbols[i->first] << " " << "; ";
|
||||||
else {
|
else {
|
||||||
str << symbols[i->first] << " = ";
|
str << symbols[i->first] << " = ";
|
||||||
|
@ -151,7 +151,7 @@ void ExprLet::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
{
|
{
|
||||||
str << "(let ";
|
str << "(let ";
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
if (i.second.inherited) {
|
if (i.second.inherited()) {
|
||||||
str << "inherit " << symbols[i.first] << "; ";
|
str << "inherit " << symbols[i.first] << "; ";
|
||||||
}
|
}
|
||||||
else {
|
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.
|
// No need to sort newEnv since attrs is in sorted order.
|
||||||
|
|
||||||
for (auto & i : attrs)
|
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) {
|
for (auto & i : dynamicAttrs) {
|
||||||
i.nameExpr->bindVars(es, newEnv);
|
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.
|
// No need to sort newEnv since attrs->attrs is in sorted order.
|
||||||
|
|
||||||
for (auto & i : attrs->attrs)
|
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)
|
if (es.debugRepl)
|
||||||
es.exprEnvs.insert(std::make_pair(this, newEnv));
|
es.exprEnvs.insert(std::make_pair(this, newEnv));
|
||||||
|
|
|
@ -154,13 +154,24 @@ struct ExprAttrs : Expr
|
||||||
bool recursive;
|
bool recursive;
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
struct AttrDef {
|
struct AttrDef {
|
||||||
bool inherited;
|
enum class Kind {
|
||||||
|
/** `attr = expr;` */
|
||||||
|
Plain,
|
||||||
|
/** `inherit attr1 attrn;` */
|
||||||
|
Inherited,
|
||||||
|
/** `inherit (expr) attr1 attrn;` */
|
||||||
|
InheritedFrom,
|
||||||
|
};
|
||||||
|
|
||||||
|
Kind kind;
|
||||||
Expr * e;
|
Expr * e;
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
Displacement displ; // displacement
|
Displacement displ; // displacement
|
||||||
AttrDef(Expr * e, const PosIdx & pos, bool inherited=false)
|
AttrDef(Expr * e, const PosIdx & pos, Kind kind = Kind::Plain)
|
||||||
: inherited(inherited), e(e), pos(pos) { };
|
: kind(kind), e(e), pos(pos) { };
|
||||||
AttrDef() { };
|
AttrDef() { };
|
||||||
|
|
||||||
|
bool inherited() const { return kind == Kind::Inherited; }
|
||||||
};
|
};
|
||||||
typedef std::map<Symbol, AttrDef> AttrDefs;
|
typedef std::map<Symbol, AttrDef> AttrDefs;
|
||||||
AttrDefs attrs;
|
AttrDefs attrs;
|
||||||
|
|
|
@ -88,7 +88,7 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr *
|
||||||
if (i->symbol) {
|
if (i->symbol) {
|
||||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
|
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
|
||||||
if (j != attrs->attrs.end()) {
|
if (j != attrs->attrs.end()) {
|
||||||
if (!j->second.inherited) {
|
if (!j->second.inherited()) {
|
||||||
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||||
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
|
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
|
||||||
attrs = attrs2;
|
attrs = attrs2;
|
||||||
|
|
|
@ -311,7 +311,9 @@ binds
|
||||||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||||
state->dupAttr(i.symbol, state->at(@3), $$->attrs[i.symbol].pos);
|
state->dupAttr(i.symbol, state->at(@3), $$->attrs[i.symbol].pos);
|
||||||
auto pos = state->at(@3);
|
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;
|
delete $3;
|
||||||
}
|
}
|
||||||
|
@ -321,7 +323,12 @@ binds
|
||||||
for (auto & i : *$6) {
|
for (auto & i : *$6) {
|
||||||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||||
state->dupAttr(i.symbol, state->at(@6), $$->attrs[i.symbol].pos);
|
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;
|
delete $6;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue