mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 16:59:35 +01:00
Merge pull request #14539 from Radvendii/exprattrs-alloc-shvach
libexpr: move ExprAttrs data into Exprs::alloc (take 2)
This commit is contained in:
commit
68d2292f3a
5 changed files with 77 additions and 55 deletions
|
|
@ -205,7 +205,7 @@ bool Value::isTrivial() const
|
||||||
{
|
{
|
||||||
return !isa<tApp, tPrimOpApp>()
|
return !isa<tApp, tPrimOpApp>()
|
||||||
&& (!isa<tThunk>()
|
&& (!isa<tThunk>()
|
||||||
|| (dynamic_cast<ExprAttrs *>(thunk().expr) && ((ExprAttrs *) thunk().expr)->dynamicAttrs.empty())
|
|| (dynamic_cast<ExprAttrs *>(thunk().expr) && ((ExprAttrs *) thunk().expr)->dynamicAttrs->empty())
|
||||||
|| dynamic_cast<ExprLambda *>(thunk().expr) || dynamic_cast<ExprList *>(thunk().expr));
|
|| dynamic_cast<ExprLambda *>(thunk().expr) || dynamic_cast<ExprList *>(thunk().expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1226,26 +1226,26 @@ Env * ExprAttrs::buildInheritFromEnv(EvalState & state, Env & up)
|
||||||
|
|
||||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
auto bindings = state.buildBindings(attrs.size() + dynamicAttrs.size());
|
auto bindings = state.buildBindings(attrs->size() + dynamicAttrs->size());
|
||||||
auto dynamicEnv = &env;
|
auto dynamicEnv = &env;
|
||||||
bool sort = false;
|
bool sort = false;
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
/* Create a new environment that contains the attributes in
|
/* Create a new environment that contains the attributes in
|
||||||
this `rec'. */
|
this `rec'. */
|
||||||
Env & env2(state.mem.allocEnv(attrs.size()));
|
Env & env2(state.mem.allocEnv(attrs->size()));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
dynamicEnv = &env2;
|
dynamicEnv = &env2;
|
||||||
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr;
|
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr;
|
||||||
|
|
||||||
AttrDefs::iterator overrides = attrs.find(state.s.overrides);
|
AttrDefs::iterator overrides = attrs->find(state.s.overrides);
|
||||||
bool hasOverrides = overrides != attrs.end();
|
bool hasOverrides = overrides != attrs->end();
|
||||||
|
|
||||||
/* The recursive attributes are evaluated in the new
|
/* The recursive attributes are evaluated in the new
|
||||||
environment, while the inherited attributes are evaluated
|
environment, while the inherited attributes are evaluated
|
||||||
in the original environment. */
|
in the original environment. */
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs) {
|
for (auto & i : *attrs) {
|
||||||
Value * vAttr;
|
Value * vAttr;
|
||||||
if (hasOverrides && i.second.kind != AttrDef::Kind::Inherited) {
|
if (hasOverrides && i.second.kind != AttrDef::Kind::Inherited) {
|
||||||
vAttr = state.allocValue();
|
vAttr = state.allocValue();
|
||||||
|
|
@ -1272,8 +1272,8 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
"while evaluating the `__overrides` attribute");
|
"while evaluating the `__overrides` attribute");
|
||||||
bindings.grow(state.buildBindings(bindings.capacity() + vOverrides->attrs()->size()));
|
bindings.grow(state.buildBindings(bindings.capacity() + vOverrides->attrs()->size()));
|
||||||
for (auto & i : *vOverrides->attrs()) {
|
for (auto & i : *vOverrides->attrs()) {
|
||||||
AttrDefs::iterator j = attrs.find(i.name);
|
AttrDefs::iterator j = attrs->find(i.name);
|
||||||
if (j != attrs.end()) {
|
if (j != attrs->end()) {
|
||||||
(*bindings.bindings)[j->second.displ] = i;
|
(*bindings.bindings)[j->second.displ] = i;
|
||||||
env2.values[j->second.displ] = i.value;
|
env2.values[j->second.displ] = i.value;
|
||||||
} else
|
} else
|
||||||
|
|
@ -1285,13 +1285,13 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env) : nullptr;
|
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env) : nullptr;
|
||||||
for (auto & i : attrs)
|
for (auto & i : *attrs)
|
||||||
bindings.insert(
|
bindings.insert(
|
||||||
i.first, i.second.e->maybeThunk(state, *i.second.chooseByKind(&env, &env, inheritEnv)), i.second.pos);
|
i.first, i.second.e->maybeThunk(state, *i.second.chooseByKind(&env, &env, inheritEnv)), 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) {
|
||||||
Value nameVal;
|
Value nameVal;
|
||||||
i.nameExpr->eval(state, *dynamicEnv, nameVal);
|
i.nameExpr->eval(state, *dynamicEnv, nameVal);
|
||||||
state.forceValue(nameVal, i.pos);
|
state.forceValue(nameVal, i.pos);
|
||||||
|
|
@ -1325,7 +1325,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
/* Create a new environment that contains the attributes in this
|
/* Create a new environment that contains the attributes in this
|
||||||
`let'. */
|
`let'. */
|
||||||
Env & env2(state.mem.allocEnv(attrs->attrs.size()));
|
Env & env2(state.mem.allocEnv(attrs->attrs->size()));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
|
|
||||||
Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv(state, env2) : nullptr;
|
Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv(state, env2) : nullptr;
|
||||||
|
|
@ -1334,7 +1334,7 @@ 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.chooseByKind(&env2, &env, inheritEnv));
|
env2.values[displ++] = i.second.e->maybeThunk(state, *i.second.chooseByKind(&env2, &env, inheritEnv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -395,9 +395,13 @@ struct ExprAttrs : Expr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<Symbol, AttrDef> AttrDefs;
|
typedef std::pmr::map<Symbol, AttrDef> AttrDefs;
|
||||||
AttrDefs attrs;
|
/**
|
||||||
std::unique_ptr<std::vector<Expr *>> inheritFromExprs;
|
* attrs will never be null. we use std::optional so that we can call emplace() to re-initialize the value with a
|
||||||
|
* new pmr::map using a different allocator (move assignment will copy into the old allocator)
|
||||||
|
*/
|
||||||
|
std::optional<AttrDefs> attrs;
|
||||||
|
std::unique_ptr<std::pmr::vector<Expr *>> inheritFromExprs;
|
||||||
|
|
||||||
struct DynamicAttrDef
|
struct DynamicAttrDef
|
||||||
{
|
{
|
||||||
|
|
@ -409,13 +413,20 @@ struct ExprAttrs : Expr
|
||||||
, pos(pos) {};
|
, pos(pos) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DynamicAttrDef> DynamicAttrDefs;
|
typedef std::pmr::vector<DynamicAttrDef> DynamicAttrDefs;
|
||||||
DynamicAttrDefs dynamicAttrs;
|
/**
|
||||||
|
* dynamicAttrs will never be null. See comment on AttrDefs above.
|
||||||
|
*/
|
||||||
|
std::optional<DynamicAttrDefs> dynamicAttrs;
|
||||||
ExprAttrs(const PosIdx & pos)
|
ExprAttrs(const PosIdx & pos)
|
||||||
: recursive(false)
|
: recursive(false)
|
||||||
, pos(pos) {};
|
, pos(pos)
|
||||||
|
, attrs(AttrDefs{})
|
||||||
|
, dynamicAttrs(DynamicAttrDefs{}) {};
|
||||||
ExprAttrs()
|
ExprAttrs()
|
||||||
: recursive(false) {};
|
: recursive(false)
|
||||||
|
, attrs(AttrDefs{})
|
||||||
|
, dynamicAttrs(DynamicAttrDefs{}) {};
|
||||||
|
|
||||||
PosIdx getPos() const override
|
PosIdx getPos() const override
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,8 @@ inline void ParserState::addAttr(
|
||||||
for (i = attrPath.begin(); i + 1 < attrPath.end(); i++) {
|
for (i = attrPath.begin(); i + 1 < attrPath.end(); i++) {
|
||||||
ExprAttrs * nested;
|
ExprAttrs * nested;
|
||||||
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()) {
|
||||||
nested = dynamic_cast<ExprAttrs *>(j->second.e);
|
nested = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||||
if (!nested) {
|
if (!nested) {
|
||||||
attrPath.erase(i + 1, attrPath.end());
|
attrPath.erase(i + 1, attrPath.end());
|
||||||
|
|
@ -135,11 +135,11 @@ inline void ParserState::addAttr(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nested = exprs.add<ExprAttrs>();
|
nested = exprs.add<ExprAttrs>();
|
||||||
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
(*attrs->attrs)[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nested = exprs.add<ExprAttrs>();
|
nested = exprs.add<ExprAttrs>();
|
||||||
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos));
|
attrs->dynamicAttrs->push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos));
|
||||||
}
|
}
|
||||||
attrs = nested;
|
attrs = nested;
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ inline void ParserState::addAttr(
|
||||||
if (i->symbol) {
|
if (i->symbol) {
|
||||||
addAttr(attrs, attrPath, i->symbol, ExprAttrs::AttrDef(e, pos));
|
addAttr(attrs, attrPath, i->symbol, ExprAttrs::AttrDef(e, pos));
|
||||||
} else {
|
} else {
|
||||||
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, e, pos));
|
attrs->dynamicAttrs->push_back(ExprAttrs::DynamicAttrDef(i->expr, e, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = lexerState.positionToDocComment.find(pos);
|
auto it = lexerState.positionToDocComment.find(pos);
|
||||||
|
|
@ -165,8 +165,8 @@ inline void ParserState::addAttr(
|
||||||
inline void
|
inline void
|
||||||
ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symbol, ExprAttrs::AttrDef && def)
|
ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symbol, ExprAttrs::AttrDef && def)
|
||||||
{
|
{
|
||||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(symbol);
|
ExprAttrs::AttrDefs::iterator j = attrs->attrs->find(symbol);
|
||||||
if (j != attrs->attrs.end()) {
|
if (j != attrs->attrs->end()) {
|
||||||
// This attr path is already defined. However, if both
|
// This attr path is already defined. However, if both
|
||||||
// e and the expr pointed by the attr path are two attribute sets,
|
// e and the expr pointed by the attr path are two attribute sets,
|
||||||
// we want to merge them.
|
// we want to merge them.
|
||||||
|
|
@ -181,8 +181,8 @@ ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symb
|
||||||
// See https://github.com/NixOS/nix/issues/9020.
|
// See https://github.com/NixOS/nix/issues/9020.
|
||||||
if (jAttrs && ae) {
|
if (jAttrs && ae) {
|
||||||
if (ae->inheritFromExprs && !jAttrs->inheritFromExprs)
|
if (ae->inheritFromExprs && !jAttrs->inheritFromExprs)
|
||||||
jAttrs->inheritFromExprs = std::make_unique<std::vector<Expr *>>();
|
jAttrs->inheritFromExprs = std::make_unique<std::pmr::vector<Expr *>>();
|
||||||
for (auto & ad : ae->attrs) {
|
for (auto & ad : *ae->attrs) {
|
||||||
if (ad.second.kind == ExprAttrs::AttrDef::Kind::InheritedFrom) {
|
if (ad.second.kind == ExprAttrs::AttrDef::Kind::InheritedFrom) {
|
||||||
auto & sel = dynamic_cast<ExprSelect &>(*ad.second.e);
|
auto & sel = dynamic_cast<ExprSelect &>(*ad.second.e);
|
||||||
auto & from = dynamic_cast<ExprInheritFrom &>(*sel.e);
|
auto & from = dynamic_cast<ExprInheritFrom &>(*sel.e);
|
||||||
|
|
@ -192,12 +192,12 @@ ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symb
|
||||||
addAttr(jAttrs, attrPath, ad.first, std::move(ad.second));
|
addAttr(jAttrs, attrPath, ad.first, std::move(ad.second));
|
||||||
attrPath.pop_back();
|
attrPath.pop_back();
|
||||||
}
|
}
|
||||||
ae->attrs.clear();
|
ae->attrs->clear();
|
||||||
jAttrs->dynamicAttrs.insert(
|
jAttrs->dynamicAttrs->insert(
|
||||||
jAttrs->dynamicAttrs.end(),
|
jAttrs->dynamicAttrs->end(),
|
||||||
std::make_move_iterator(ae->dynamicAttrs.begin()),
|
std::make_move_iterator(ae->dynamicAttrs->begin()),
|
||||||
std::make_move_iterator(ae->dynamicAttrs.end()));
|
std::make_move_iterator(ae->dynamicAttrs->end()));
|
||||||
ae->dynamicAttrs.clear();
|
ae->dynamicAttrs->clear();
|
||||||
if (ae->inheritFromExprs) {
|
if (ae->inheritFromExprs) {
|
||||||
jAttrs->inheritFromExprs->insert(
|
jAttrs->inheritFromExprs->insert(
|
||||||
jAttrs->inheritFromExprs->end(),
|
jAttrs->inheritFromExprs->end(),
|
||||||
|
|
@ -210,7 +210,7 @@ ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symb
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This attr path is not defined. Let's create it.
|
// This attr path is not defined. Let's create it.
|
||||||
attrs->attrs.emplace(symbol, def);
|
attrs->attrs->emplace(symbol, def);
|
||||||
def.e->setName(symbol);
|
def.e->setName(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,9 @@ void ExprOpHasAttr::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
|
|
||||||
void ExprAttrs::showBindings(const SymbolTable & symbols, std::ostream & str) const
|
void ExprAttrs::showBindings(const SymbolTable & symbols, std::ostream & str) const
|
||||||
{
|
{
|
||||||
typedef const decltype(attrs)::value_type * Attr;
|
typedef const AttrDefs::value_type * Attr;
|
||||||
std::vector<Attr> sorted;
|
std::vector<Attr> sorted;
|
||||||
for (auto & i : attrs)
|
for (auto & i : *attrs)
|
||||||
sorted.push_back(&i);
|
sorted.push_back(&i);
|
||||||
std::sort(sorted.begin(), sorted.end(), [&](Attr a, Attr b) {
|
std::sort(sorted.begin(), sorted.end(), [&](Attr a, Attr b) {
|
||||||
std::string_view sa = symbols[a->first], sb = symbols[b->first];
|
std::string_view sa = symbols[a->first], sb = symbols[b->first];
|
||||||
|
|
@ -122,7 +122,7 @@ void ExprAttrs::showBindings(const SymbolTable & symbols, std::ostream & str) co
|
||||||
str << "; ";
|
str << "; ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : *dynamicAttrs) {
|
||||||
str << "\"${";
|
str << "\"${";
|
||||||
i.nameExpr->show(symbols, str);
|
i.nameExpr->show(symbols, str);
|
||||||
str << "}\" = ";
|
str << "}\" = ";
|
||||||
|
|
@ -401,15 +401,26 @@ ExprAttrs::bindInheritSources(EvalState & es, const std::shared_ptr<const Static
|
||||||
|
|
||||||
void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
|
// Move storage into the Exprs arena
|
||||||
|
{
|
||||||
|
auto arena = es.mem.exprs.alloc;
|
||||||
|
AttrDefs newAttrs{std::move(*attrs), arena};
|
||||||
|
attrs.emplace(std::move(newAttrs), arena);
|
||||||
|
DynamicAttrDefs newDynamicAttrs{std::move(*dynamicAttrs), arena};
|
||||||
|
dynamicAttrs.emplace(std::move(newDynamicAttrs), arena);
|
||||||
|
if (inheritFromExprs)
|
||||||
|
inheritFromExprs = std::make_unique<std::pmr::vector<Expr *>>(std::move(*inheritFromExprs), arena);
|
||||||
|
}
|
||||||
|
|
||||||
if (es.debugRepl)
|
if (es.debugRepl)
|
||||||
es.exprEnvs.insert(std::make_pair(this, env));
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
auto newEnv = [&]() -> std::shared_ptr<const StaticEnv> {
|
auto newEnv = [&]() -> std::shared_ptr<const StaticEnv> {
|
||||||
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, attrs.size());
|
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, 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;
|
return newEnv;
|
||||||
}();
|
}();
|
||||||
|
|
@ -417,20 +428,20 @@ 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.
|
||||||
|
|
||||||
auto inheritFromEnv = bindInheritSources(es, newEnv);
|
auto inheritFromEnv = bindInheritSources(es, newEnv);
|
||||||
for (auto & i : attrs)
|
for (auto & i : *attrs)
|
||||||
i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
|
i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
|
||||||
|
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : *dynamicAttrs) {
|
||||||
i.nameExpr->bindVars(es, newEnv);
|
i.nameExpr->bindVars(es, newEnv);
|
||||||
i.valueExpr->bindVars(es, newEnv);
|
i.valueExpr->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto inheritFromEnv = bindInheritSources(es, env);
|
auto inheritFromEnv = bindInheritSources(es, env);
|
||||||
|
|
||||||
for (auto & i : attrs)
|
for (auto & i : *attrs)
|
||||||
i.second.e->bindVars(es, i.second.chooseByKind(env, env, inheritFromEnv));
|
i.second.e->bindVars(es, i.second.chooseByKind(env, env, inheritFromEnv));
|
||||||
|
|
||||||
for (auto & i : dynamicAttrs) {
|
for (auto & i : *dynamicAttrs) {
|
||||||
i.nameExpr->bindVars(es, env);
|
i.nameExpr->bindVars(es, env);
|
||||||
i.valueExpr->bindVars(es, env);
|
i.valueExpr->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
@ -486,10 +497,10 @@ 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::shared_ptr<const StaticEnv> {
|
||||||
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, attrs->attrs.size());
|
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, 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;
|
return newEnv;
|
||||||
}();
|
}();
|
||||||
|
|
@ -497,7 +508,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.
|
||||||
|
|
||||||
auto inheritFromEnv = attrs->bindInheritSources(es, newEnv);
|
auto inheritFromEnv = attrs->bindInheritSources(es, newEnv);
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : *attrs->attrs)
|
||||||
i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
|
i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
|
||||||
|
|
||||||
if (es.debugRepl)
|
if (es.debugRepl)
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ expr_function
|
||||||
| WITH expr ';' expr_function
|
| WITH expr ';' expr_function
|
||||||
{ $$ = state->exprs.add<ExprWith>(CUR_POS, $2, $4); }
|
{ $$ = state->exprs.add<ExprWith>(CUR_POS, $2, $4); }
|
||||||
| LET binds IN_KW expr_function
|
| LET binds IN_KW expr_function
|
||||||
{ if (!$2->dynamicAttrs.empty())
|
{ if (!$2->dynamicAttrs->empty())
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = HintFmt("dynamic attributes not allowed in let"),
|
.msg = HintFmt("dynamic attributes not allowed in let"),
|
||||||
.pos = state->positions[CUR_POS]
|
.pos = state->positions[CUR_POS]
|
||||||
|
|
@ -413,9 +413,9 @@ binds1
|
||||||
| binds[accum] INHERIT attrs ';'
|
| binds[accum] INHERIT attrs ';'
|
||||||
{ $$ = $accum;
|
{ $$ = $accum;
|
||||||
for (auto & [i, iPos] : $attrs) {
|
for (auto & [i, iPos] : $attrs) {
|
||||||
if ($accum->attrs.find(i.symbol) != $accum->attrs.end())
|
if ($accum->attrs->find(i.symbol) != $accum->attrs->end())
|
||||||
state->dupAttr(i.symbol, iPos, $accum->attrs[i.symbol].pos);
|
state->dupAttr(i.symbol, iPos, (*$accum->attrs)[i.symbol].pos);
|
||||||
$accum->attrs.emplace(
|
$accum->attrs->emplace(
|
||||||
i.symbol,
|
i.symbol,
|
||||||
ExprAttrs::AttrDef(state->exprs.add<ExprVar>(iPos, i.symbol), iPos, ExprAttrs::AttrDef::Kind::Inherited));
|
ExprAttrs::AttrDef(state->exprs.add<ExprVar>(iPos, i.symbol), iPos, ExprAttrs::AttrDef::Kind::Inherited));
|
||||||
}
|
}
|
||||||
|
|
@ -423,13 +423,13 @@ binds1
|
||||||
| binds[accum] INHERIT '(' expr ')' attrs ';'
|
| binds[accum] INHERIT '(' expr ')' attrs ';'
|
||||||
{ $$ = $accum;
|
{ $$ = $accum;
|
||||||
if (!$accum->inheritFromExprs)
|
if (!$accum->inheritFromExprs)
|
||||||
$accum->inheritFromExprs = std::make_unique<std::vector<Expr *>>();
|
$accum->inheritFromExprs = std::make_unique<std::pmr::vector<Expr *>>();
|
||||||
$accum->inheritFromExprs->push_back($expr);
|
$accum->inheritFromExprs->push_back($expr);
|
||||||
auto from = state->exprs.add<ExprInheritFrom>(state->at(@expr), $accum->inheritFromExprs->size() - 1);
|
auto from = state->exprs.add<ExprInheritFrom>(state->at(@expr), $accum->inheritFromExprs->size() - 1);
|
||||||
for (auto & [i, iPos] : $attrs) {
|
for (auto & [i, iPos] : $attrs) {
|
||||||
if ($accum->attrs.find(i.symbol) != $accum->attrs.end())
|
if ($accum->attrs->find(i.symbol) != $accum->attrs->end())
|
||||||
state->dupAttr(i.symbol, iPos, $accum->attrs[i.symbol].pos);
|
state->dupAttr(i.symbol, iPos, (*$accum->attrs)[i.symbol].pos);
|
||||||
$accum->attrs.emplace(
|
$accum->attrs->emplace(
|
||||||
i.symbol,
|
i.symbol,
|
||||||
ExprAttrs::AttrDef(
|
ExprAttrs::AttrDef(
|
||||||
state->exprs.add<ExprSelect>(state->exprs.alloc, iPos, from, i.symbol),
|
state->exprs.add<ExprSelect>(state->exprs.alloc, iPos, from, i.symbol),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue