diff --git a/lix/libexpr/nixexpr.cc b/lix/libexpr/nixexpr.cc index ecbe66f0b..d5cd76f97 100644 --- a/lix/libexpr/nixexpr.cc +++ b/lix/libexpr/nixexpr.cc @@ -313,23 +313,78 @@ JSON printAttrPathToJson(const SymbolTable & symbols, const AttrPath & attrPath) /* Computing levels/displacements for variables. */ -void Expr::bindVars(Evaluator & es, const std::shared_ptr & env) +namespace { +struct VarBinder : ExprVisitor { - abort(); + Evaluator & es; + std::shared_ptr env; + + VarBinder(Evaluator & eval, std::shared_ptr env) : es(eval), env(env) {} + + auto withEnv(std::shared_ptr env, auto fn) + { + std::swap(env, this->env); + KJ_DEFER(std::swap(env, this->env);); + return fn(); + } + + using ExprVisitor::visit; + + void visit(ExprLiteral & e, std::unique_ptr & ptr) override; + void visit(ExprVar & e, std::unique_ptr & ptr) override; + void visit(ExprInheritFrom & e, std::unique_ptr & ptr) override; + void visit(ExprSelect & e, std::unique_ptr & ptr) override; + void visit(ExprOpHasAttr & e, std::unique_ptr & ptr) override; + void visit(ExprSet & e, std::unique_ptr & ptr) override; + void visit(ExprList & e, std::unique_ptr & ptr) override; + void visit(ExprLambda & e, std::unique_ptr & ptr) override; + void visit(ExprCall & e, std::unique_ptr & ptr) override; + void visit(ExprLet & e, std::unique_ptr & ptr) override; + void visit(ExprWith & e, std::unique_ptr & ptr) override; + void visit(ExprIf & e, std::unique_ptr & ptr) override; + void visit(ExprAssert & e, std::unique_ptr & ptr) override; + void visit(ExprOpNot & e, std::unique_ptr & ptr) override; +#define BINOP(type) \ + /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \ + void visit(type & e, std::unique_ptr & ptr) override \ + { \ + visit(e.e1); \ + visit(e.e2); \ + } + BINOP(ExprOpEq) + BINOP(ExprOpNEq) + BINOP(ExprOpAnd) + BINOP(ExprOpOr) + BINOP(ExprOpImpl) + BINOP(ExprOpUpdate) + BINOP(ExprOpConcatLists) +#undef BINOP + void visit(ExprConcatStrings & e, std::unique_ptr & ptr) override; + void visit(ExprPos & e, std::unique_ptr & ptr) override; + void visit(ExprBlackHole & e, std::unique_ptr & ptr) override {} +}; } -void ExprLiteral::bindVars(Evaluator & es, const std::shared_ptr & env) +std::unique_ptr Expr::finalize( + std::unique_ptr parsed, Evaluator & es, const std::shared_ptr & env +) { - if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + VarBinder{es, env}.visit(parsed); + return parsed; } -void ExprVar::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprLiteral & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); +} - fromWith = nullptr; +void VarBinder::visit(ExprVar & e, std::unique_ptr & ptr) +{ + if (es.debug) + es.debug->exprEnvs.insert(std::make_pair(&e, env)); + + e.fromWith = nullptr; /* Check whether the variable appears in the environment. If so, set its level and displacement. */ @@ -340,21 +395,21 @@ void ExprVar::bindVars(Evaluator & es, const std::shared_ptr & if (curEnv->isWith) { if (withLevel == -1) withLevel = level; } else { - auto i = curEnv->find(name); + auto i = curEnv->find(e.name); if (i != curEnv->vars.end()) { - if (this->needsRoot && !curEnv->isRoot) { + if (e.needsRoot && !curEnv->isRoot) { throw ParseError({ .msg = HintFmt( "Shadowing symbol '%s' used in internal expressions is not allowed. Use %s to disable this error.", - es.symbols[name], + es.symbols[e.name], "--extra-deprecated-features shadow-internal-symbols" ), - .pos = es.positions[pos] + .pos = es.positions[e.pos] }); } - this->level = level; - displ = i->second; + e.level = level; + e.displ = i->second; return; } } @@ -366,40 +421,40 @@ void ExprVar::bindVars(Evaluator & es, const std::shared_ptr & if (withLevel == -1) es.errors.make( "undefined variable '%1%'", - es.symbols[name] - ).atPos(pos).throw_(); - for (auto * e = env.get(); e && !fromWith; e = e->up) - fromWith = e->isWith; - this->level = withLevel; + es.symbols[e.name] + ).atPos(e.pos).throw_(); + for (auto * se = env.get(); se && !e.fromWith; se = se->up) + e.fromWith = se->isWith; + e.level = withLevel; } -void ExprInheritFrom::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprInheritFrom & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); } -void ExprSelect::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprSelect & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - e->bindVars(es, env); - if (def) def->bindVars(es, env); - for (auto & i : attrPath) + visit(e.e); + if (e.def) visit(e.def); + for (auto & i : e.attrPath) if (!i.symbol) - i.expr->bindVars(es, env); + visit(i.expr); } -void ExprOpHasAttr::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprOpHasAttr & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - e->bindVars(es, env); - for (auto & i : attrPath) + visit(e.e); + for (auto & i : e.attrPath) if (!i.symbol) - i.expr->bindVars(es, env); + visit(i.expr); } std::shared_ptr ExprAttrs::buildRecursiveEnv(const std::shared_ptr & env) @@ -412,8 +467,7 @@ std::shared_ptr ExprAttrs::buildRecursiveEnv(const std::shared_ return newEnv; } -std::shared_ptr ExprAttrs::bindInheritSources( - Evaluator & es, const std::shared_ptr & env) +std::shared_ptr ExprAttrs::bindInheritSources(ExprVisitor & e, const StaticEnv & env) { if (!inheritFromExprs) return nullptr; @@ -426,143 +480,151 @@ std::shared_ptr ExprAttrs::bindInheritSources( // and displacement, and nothing else is allowed to access it. ideally we'd // not even *have* an expr that grabs anything from this env since it's fully // invisible, but the evaluator does not allow for this yet. - auto inner = std::make_shared(nullptr, env.get(), 0); + auto inner = std::make_shared(nullptr, &env, 0); for (auto & from : *inheritFromExprs) - from->bindVars(es, env); + e.visit(from); return inner; } -void ExprSet::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprSet & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - auto innerEnv = recursive ? buildRecursiveEnv(env) : env; - auto inheritFromEnv = bindInheritSources(es, innerEnv); + auto innerEnv = e.recursive ? e.buildRecursiveEnv(env) : env; + auto inheritFromEnv = withEnv(innerEnv, [&] { return e.bindInheritSources(*this, *innerEnv); }); // No need to sort newEnv since attrs is in sorted order. - for (auto & i : attrs) - i.second.e->bindVars(es, i.second.chooseByKind(innerEnv, env, inheritFromEnv)); - - for (auto & i : dynamicAttrs) { - i.nameExpr->bindVars(es, innerEnv); - i.valueExpr->bindVars(es, innerEnv); + for (auto & i : e.attrs) { + withEnv(i.second.chooseByKind(innerEnv, env, inheritFromEnv), [&] { + visit(i.second.e); + }); } + + withEnv(innerEnv, [&] { + for (auto & i : e.dynamicAttrs) { + visit(i.nameExpr); + visit(i.valueExpr); + } + }); } -void ExprList::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprList & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - for (auto & i : elems) - i->bindVars(es, env); + for (auto & i : e.elems) + visit(i); } -void ExprLambda::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprLambda & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - auto newEnv = pattern->buildEnv(env.get()); - pattern->bindVars(es, newEnv); - body->bindVars(es, newEnv); + withEnv(e.pattern->buildEnv(env.get()), [&] { + e.pattern->accept(*this); + visit(e.body); + }); } -void ExprCall::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprCall & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - fun->bindVars(es, env); - for (auto & e : args) - e->bindVars(es, env); + visit(e.fun); + for (auto & se : e.args) + visit(se); } -void ExprLet::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprLet & e, std::unique_ptr & ptr) { - auto newEnv = buildRecursiveEnv(env); + auto newEnv = e.buildRecursiveEnv(env); // No need to sort newEnv since attrs is in sorted order. - auto inheritFromEnv = bindInheritSources(es, newEnv); - for (auto & i : attrs) - i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv)); + auto inheritFromEnv = withEnv(newEnv, [&] { return e.bindInheritSources(*this, *newEnv); }); + for (auto & i : e.attrs) { + withEnv(i.second.chooseByKind(newEnv, env, inheritFromEnv), [&] { + visit(i.second.e); + }); + } if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - body->bindVars(es, newEnv); + withEnv(std::move(newEnv), [&] { visit(e.body); }); } -void ExprWith::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprWith & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - parentWith = nullptr; - for (auto * e = env.get(); e && !parentWith; e = e->up) - parentWith = e->isWith; + e.parentWith = nullptr; + for (auto * se = env.get(); se && !e.parentWith; se = se->up) + e.parentWith = se->isWith; /* Does this `with' have an enclosing `with'? If so, record its level so that `lookupVar' can look up variables in the previous `with' if this one doesn't contain the desired attribute. */ const StaticEnv * curEnv; Level level; - prevWith = 0; + e.prevWith = 0; for (curEnv = env.get(), level = 1; curEnv; curEnv = curEnv->up, level++) if (curEnv->isWith) { - prevWith = level; + e.prevWith = level; break; } - attrs->bindVars(es, env); - auto newEnv = std::make_shared(this, env.get()); - body->bindVars(es, newEnv); + visit(e.attrs); + withEnv(std::make_shared(&e, env.get()), [&] { visit(e.body); }); } -void ExprIf::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprIf & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - cond->bindVars(es, env); - then->bindVars(es, env); - else_->bindVars(es, env); + visit(e.cond); + visit(e.then); + visit(e.else_); } -void ExprAssert::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprAssert & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - cond->bindVars(es, env); - body->bindVars(es, env); + visit(e.cond); + visit(e.body); } -void ExprOpNot::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprOpNot & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - e->bindVars(es, env); + visit(e.e); } -void ExprConcatStrings::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprConcatStrings & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); - for (auto & i : this->es) - i.second->bindVars(es, env); + for (auto & i : e.es) + visit(i.second); } -void ExprPos::bindVars(Evaluator & es, const std::shared_ptr & env) +void VarBinder::visit(ExprPos & e, std::unique_ptr & ptr) { if (es.debug) - es.debug->exprEnvs.insert(std::make_pair(this, env)); + es.debug->exprEnvs.insert(std::make_pair(&e, env)); } /* Function argument destructuring */ @@ -574,7 +636,6 @@ std::shared_ptr SimplePattern::buildEnv(const StaticEnv * up) return newEnv; } -void SimplePattern::bindVars(Evaluator & es, const std::shared_ptr & env) { } void SimplePattern::accept(ExprVisitor & ev) { } std::shared_ptr AttrsPattern::buildEnv(const StaticEnv * up) @@ -595,12 +656,6 @@ std::shared_ptr AttrsPattern::buildEnv(const StaticEnv * up) return newEnv; } -void AttrsPattern::bindVars(Evaluator & es, const std::shared_ptr & env) -{ - for (auto & i : formals) - if (i.def) i.def->bindVars(es, env); -} - void AttrsPattern::accept(ExprVisitor & ev) { for (auto & i : formals) diff --git a/lix/libexpr/nixexpr.hh b/lix/libexpr/nixexpr.hh index c85ffef3f..93bb04e90 100644 --- a/lix/libexpr/nixexpr.hh +++ b/lix/libexpr/nixexpr.hh @@ -2,6 +2,7 @@ ///@file #include +#include #include #include "lix/libexpr/value.hh" @@ -116,8 +117,11 @@ public: Expr & operator=(const Expr &) = delete; virtual ~Expr() { }; + static std::unique_ptr finalize( + std::unique_ptr parsed, Evaluator & es, const std::shared_ptr & env + ); + virtual JSON toJSON(const SymbolTable & symbols) const; - virtual void bindVars(Evaluator & es, const std::shared_ptr & env); virtual void accept(ExprVisitor & ev, std::unique_ptr & ptr) = 0; virtual void eval(EvalState & state, Env & env, Value & v); virtual Value * maybeThunk(EvalState & state, Env & env); @@ -155,7 +159,6 @@ public: Value * maybeThunk(EvalState & state, Env & env) override; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -205,7 +208,6 @@ struct ExprVar : Expr Value * maybeThunk(EvalState & state, Env & env) override; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -226,7 +228,6 @@ struct ExprInheritFrom : Expr JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -247,7 +248,6 @@ struct ExprSelect : Expr ExprSelect(const PosIdx & pos, std::unique_ptr e, const PosIdx namePos, Symbol name) : Expr(pos), e(std::move(e)) { attrPath.push_back(AttrName(namePos, name)); }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -258,7 +258,6 @@ struct ExprOpHasAttr : Expr ExprOpHasAttr(const PosIdx & pos, std::unique_ptr e, AttrPath attrPath) : Expr(pos), e(std::move(e)), attrPath(std::move(attrPath)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -317,8 +316,7 @@ struct ExprAttrs DynamicAttrDefs dynamicAttrs; std::shared_ptr buildRecursiveEnv(const std::shared_ptr & env); - std::shared_ptr bindInheritSources( - Evaluator & es, const std::shared_ptr & env); + std::shared_ptr bindInheritSources(ExprVisitor & e, const StaticEnv & env); Env * buildInheritFromEnv(EvalState & state, Env & up); void addBindingsToJSON(JSON & out, const SymbolTable & symbols) const; }; @@ -330,16 +328,15 @@ struct ExprSet : Expr, ExprAttrs { ExprSet() { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; struct ExprReplBindings { std::map> symbols; - void bindVars(Evaluator & es, const std::shared_ptr & env) { + void finalize(Evaluator & es, const std::shared_ptr & env) { for (auto & [_, e] : symbols) - e->bindVars(es, env); + e = Expr::finalize(std::move(e), es, env); } }; @@ -349,7 +346,6 @@ struct ExprList : Expr ExprList(PosIdx pos) : Expr(pos) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } Value * maybeThunk(EvalState & state, Env & env) override; }; @@ -364,7 +360,6 @@ struct Pattern { virtual ~Pattern() = default; virtual std::shared_ptr buildEnv(const StaticEnv * up) = 0; - virtual void bindVars(Evaluator & es, const std::shared_ptr & env) = 0; virtual void accept(ExprVisitor & ev) = 0; virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) = 0; @@ -380,7 +375,6 @@ struct SimplePattern : Pattern } virtual std::shared_ptr buildEnv(const StaticEnv * up) override; - virtual void bindVars(Evaluator & es, const std::shared_ptr & env) override; virtual void accept(ExprVisitor & ev) override; virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) override; @@ -402,7 +396,6 @@ struct AttrsPattern : Pattern bool ellipsis; virtual std::shared_ptr buildEnv(const StaticEnv * up) override; - virtual void bindVars(Evaluator & es, const std::shared_ptr & env) override; virtual void accept(ExprVisitor & ev) override; virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) override; @@ -468,7 +461,6 @@ struct ExprLambda : Expr JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -481,7 +473,6 @@ struct ExprCall : Expr { } JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -490,7 +481,6 @@ struct ExprLet : Expr, ExprAttrs std::unique_ptr body; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -502,7 +492,6 @@ struct ExprWith : Expr ExprWith(const PosIdx & pos, std::unique_ptr attrs, std::unique_ptr body) : Expr(pos), attrs(std::move(attrs)), body(std::move(body)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -512,7 +501,6 @@ struct ExprIf : Expr ExprIf(const PosIdx & pos, std::unique_ptr cond, std::unique_ptr then, std::unique_ptr else_) : Expr(pos), cond(std::move(cond)), then(std::move(then)), else_(std::move(else_)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -522,7 +510,6 @@ struct ExprAssert : Expr ExprAssert(const PosIdx & pos, std::unique_ptr cond, std::unique_ptr body) : Expr(pos), cond(std::move(cond)), body(std::move(body)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -532,7 +519,6 @@ struct ExprOpNot : Expr ExprOpNot(const PosIdx & pos, std::unique_ptr e) : Expr(pos), e(std::move(e)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -551,10 +537,6 @@ struct ExprOpNot : Expr };\ } \ void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } \ - void bindVars(Evaluator & es, const std::shared_ptr & env) override \ - { \ - e1->bindVars(es, env); e2->bindVars(es, env); \ - } \ void eval(EvalState & state, Env & env, Value & v) override; \ }; @@ -574,7 +556,6 @@ struct ExprConcatStrings : Expr : Expr(pos), forceString(forceString), es(std::move(es)) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -583,7 +564,6 @@ struct ExprPos : Expr ExprPos(const PosIdx & pos) : Expr(pos) { }; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std ::shared_ptr & env) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; @@ -591,7 +571,6 @@ struct ExprPos : Expr struct ExprBlackHole : Expr { void eval(EvalState & state, Env & env, Value & v) override; - void bindVars(Evaluator & es, const std::shared_ptr & env) override {} void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; diff --git a/lix/libexpr/parser/parser.cc b/lix/libexpr/parser/parser.cc index 4fc43aed1..2766abfe2 100644 --- a/lix/libexpr/parser/parser.cc +++ b/lix/libexpr/parser/parser.cc @@ -38,7 +38,7 @@ Expr * Evaluator::parse( p::parse(inp, x, s); auto [_pos, result] = x.finish(s); - result->bindVars(*this, staticEnv); + result = Expr::finalize(std::move(result), *this, staticEnv); return result.release(); } catch (p::parse_error & e) { // NOLINT(lix-foreign-exceptions) auto pos = e.positions().back(); @@ -73,8 +73,8 @@ Evaluator::parse_repl( p::parse(inp, x, s); std::visit(overloaded { - [&] (ExprReplBindings & result) { result.bindVars(*this, staticEnv); }, - [&] (auto & result) { result->bindVars(*this, staticEnv); } + [&] (ExprReplBindings & result) { result.finalize(*this, staticEnv); }, + [&] (auto & result) { result = Expr::finalize(std::move(result), *this, staticEnv); } }, x); return x; } catch (p::parse_error & e) { // NOLINT(lix-foreign-exceptions)