add ExprAttrs::AttrDef::chooseByKind
in place of inherited() — not quite useful yet since we don't
distinguish plain and inheritFrom attr kinds so far.
(cherry picked from commit 1f542adb3e18e7078e6a589182a53a47d971748a)
Change-Id: If948c9d43e875de18f213a73a06a36f7c335b536
This commit is contained in:
parent
03f852b2c6
commit
1cf0fa0633
|
@ -1240,9 +1240,9 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
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, *i.second.chooseByKind(&env2, &env, &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.chooseByKind(&env2, &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));
|
||||||
}
|
}
|
||||||
|
@ -1274,9 +1274,14 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs) {
|
||||||
v.attrs->push_back(Attr(i.first, i.second.e->maybeThunk(state, env), i.second.pos));
|
v.attrs->push_back(Attr(
|
||||||
|
i.first,
|
||||||
|
i.second.e->maybeThunk(state, *i.second.chooseByKind(&env, &env, &env)),
|
||||||
|
i.second.pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Dynamic attrs apply *after* rec and __overrides. */
|
/* Dynamic attrs apply *after* rec and __overrides. */
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : dynamicAttrs) {
|
||||||
|
@ -1312,8 +1317,11 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
while the inherited attributes are evaluated in the original
|
while the inherited attributes are evaluated in the original
|
||||||
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.chooseByKind(&env2, &env, &env2));
|
||||||
|
}
|
||||||
|
|
||||||
auto dts = state.debugRepl
|
auto dts = state.debugRepl
|
||||||
? makeDebugTraceStacker(
|
? makeDebugTraceStacker(
|
||||||
|
|
|
@ -332,16 +332,19 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
||||||
es.exprEnvs.insert(std::make_pair(this, env));
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), recursive ? attrs.size() : 0);
|
auto newEnv = [&] () -> std::shared_ptr<const StaticEnv> {
|
||||||
|
auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs.size());
|
||||||
|
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
newEnv->vars.emplace_back(i.first, i.second.displ = displ++);
|
newEnv->vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
return newEnv;
|
||||||
|
}();
|
||||||
|
|
||||||
// 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.chooseByKind(newEnv, env, newEnv));
|
||||||
|
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : dynamicAttrs) {
|
||||||
i.nameExpr->bindVars(es, newEnv);
|
i.nameExpr->bindVars(es, newEnv);
|
||||||
|
@ -350,7 +353,7 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
i.second.e->bindVars(es, env);
|
i.second.e->bindVars(es, i.second.chooseByKind(env, env, env));
|
||||||
|
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : dynamicAttrs) {
|
||||||
i.nameExpr->bindVars(es, env);
|
i.nameExpr->bindVars(es, env);
|
||||||
|
@ -407,16 +410,19 @@ void ExprCall::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
||||||
|
|
||||||
void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
|
auto newEnv = [&] () -> std::shared_ptr<const StaticEnv> {
|
||||||
auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs->attrs.size());
|
auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs->attrs.size());
|
||||||
|
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
newEnv->vars.emplace_back(i.first, i.second.displ = displ++);
|
newEnv->vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
return newEnv;
|
||||||
|
}();
|
||||||
|
|
||||||
// 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.chooseByKind(newEnv, env, newEnv));
|
||||||
|
|
||||||
if (es.debugRepl)
|
if (es.debugRepl)
|
||||||
es.exprEnvs.insert(std::make_pair(this, newEnv));
|
es.exprEnvs.insert(std::make_pair(this, newEnv));
|
||||||
|
|
|
@ -172,6 +172,20 @@ struct ExprAttrs : Expr
|
||||||
AttrDef() { };
|
AttrDef() { };
|
||||||
|
|
||||||
bool inherited() const { return kind == Kind::Inherited; }
|
bool inherited() const { return kind == Kind::Inherited; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const T & chooseByKind(const T & plain, const T & inherited, const T & inheritedFrom) const
|
||||||
|
{
|
||||||
|
switch (kind) {
|
||||||
|
case Kind::Plain:
|
||||||
|
return plain;
|
||||||
|
case Kind::Inherited:
|
||||||
|
return inherited;
|
||||||
|
default:
|
||||||
|
case Kind::InheritedFrom:
|
||||||
|
return inheritedFrom;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<Symbol, AttrDef> AttrDefs;
|
typedef std::map<Symbol, AttrDef> AttrDefs;
|
||||||
AttrDefs attrs;
|
AttrDefs attrs;
|
||||||
|
|
Loading…
Reference in a new issue