forked from lix-project/lix
use an expr->StaticEnv table in evalState
This commit is contained in:
parent
86ba0a702c
commit
357fb84dba
|
@ -136,8 +136,9 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
if (error)
|
if (error)
|
||||||
printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what());
|
printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what());
|
||||||
|
|
||||||
if (expr.staticEnv) {
|
auto se = evalState->getStaticEnv(expr);
|
||||||
auto vm = mapStaticEnvBindings(evalState->symbols, *expr.staticEnv.get(), env);
|
if (se) {
|
||||||
|
auto vm = mapStaticEnvBindings(evalState->symbols, *se.get(), env);
|
||||||
runRepl(evalState, *vm);
|
runRepl(evalState, *vm);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -441,8 +441,9 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt)
|
||||||
{
|
{
|
||||||
initEnv();
|
initEnv();
|
||||||
|
|
||||||
if (dt.expr.staticEnv) {
|
auto se = state->getStaticEnv(dt.expr);
|
||||||
auto vm = mapStaticEnvBindings(state->symbols, *dt.expr.staticEnv.get(), dt.env);
|
if (se) {
|
||||||
|
auto vm = mapStaticEnvBindings(state->symbols, *se.get(), dt.env);
|
||||||
|
|
||||||
// add staticenv vars.
|
// add staticenv vars.
|
||||||
for (auto & [name, value] : *(vm.get()))
|
for (auto & [name, value] : *(vm.get()))
|
||||||
|
@ -516,7 +517,7 @@ bool NixRepl::processLine(std::string line)
|
||||||
else if (debuggerHook && (command == ":env")) {
|
else if (debuggerHook && (command == ":env")) {
|
||||||
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
|
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
|
||||||
if (idx == debugTraceIndex) {
|
if (idx == debugTraceIndex) {
|
||||||
printEnvBindings(state->symbols, i.expr, i.env);
|
printEnvBindings(*state, i.expr, i.env);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,7 +534,7 @@ bool NixRepl::processLine(std::string line)
|
||||||
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
||||||
showDebugTrace(std::cout, state->positions, i);
|
showDebugTrace(std::cout, state->positions, i);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
printEnvBindings(state->symbols, i.expr, i.env);
|
printEnvBindings(*state, i.expr, i.env);
|
||||||
loadDebugTraceEnv(i);
|
loadDebugTraceEnv(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -772,12 +772,12 @@ void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add accompanying env for With stuff.
|
void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env)
|
||||||
void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env)
|
|
||||||
{
|
{
|
||||||
// just print the names for now
|
// just print the names for now
|
||||||
if (expr.staticEnv)
|
auto se = es.getStaticEnv(expr);
|
||||||
printEnvBindings(st, *expr.staticEnv.get(), env, 0);
|
if (se)
|
||||||
|
printEnvBindings(es.symbols, *se, env, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm)
|
void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm)
|
||||||
|
|
|
@ -25,7 +25,7 @@ enum RepairFlag : bool;
|
||||||
|
|
||||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||||
|
|
||||||
void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env);
|
void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env);
|
||||||
void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl = 0);
|
void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl = 0);
|
||||||
|
|
||||||
struct PrimOp
|
struct PrimOp
|
||||||
|
@ -130,6 +130,16 @@ public:
|
||||||
bool debugStop;
|
bool debugStop;
|
||||||
bool debugQuit;
|
bool debugQuit;
|
||||||
std::list<DebugTrace> debugTraces;
|
std::list<DebugTrace> debugTraces;
|
||||||
|
std::map<const Expr*, const std::shared_ptr<const StaticEnv> > exprEnvs;
|
||||||
|
const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr &expr) const
|
||||||
|
{
|
||||||
|
auto i = exprEnvs.find(&expr);
|
||||||
|
if (i != exprEnvs.end())
|
||||||
|
return i->second;
|
||||||
|
else
|
||||||
|
return std::shared_ptr<const StaticEnv>();;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class E>
|
template<class E>
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
|
|
@ -296,38 +296,39 @@ std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
|
||||||
|
|
||||||
/* Computing levels/displacements for variables. */
|
/* Computing levels/displacements for variables. */
|
||||||
|
|
||||||
void Expr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void Expr::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprInt::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprInt::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;}
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
void ExprFloat::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
|
||||||
{
|
|
||||||
if (debuggerHook)
|
|
||||||
staticEnv = env;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprString::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprFloat::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprPath::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprString::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprVar::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprPath::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExprVar::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
|
{
|
||||||
|
if (debuggerHook)
|
||||||
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
/* Check whether the variable appears in the environment. If so,
|
/* Check whether the variable appears in the environment. If so,
|
||||||
set its level and displacement. */
|
set its level and displacement. */
|
||||||
|
@ -360,10 +361,10 @@ void ExprVar::bindVars(const EvalState & es, const std::shared_ptr<const StaticE
|
||||||
this->level = withLevel;
|
this->level = withLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprSelect::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprSelect::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
if (def) def->bindVars(es, env);
|
if (def) def->bindVars(es, env);
|
||||||
|
@ -372,10 +373,10 @@ void ExprSelect::bindVars(const EvalState & es, const std::shared_ptr<const Stat
|
||||||
i.expr->bindVars(es, env);
|
i.expr->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprOpHasAttr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprOpHasAttr::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
for (auto & i : attrPath)
|
for (auto & i : attrPath)
|
||||||
|
@ -383,10 +384,10 @@ void ExprOpHasAttr::bindVars(const EvalState & es, const std::shared_ptr<const S
|
||||||
i.expr->bindVars(es, env);
|
i.expr->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprAttrs::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), recursive ? attrs.size() : 0);
|
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), recursive ? attrs.size() : 0);
|
||||||
|
@ -416,19 +417,19 @@ void ExprAttrs::bindVars(const EvalState & es, const std::shared_ptr<const Stati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprList::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprList::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
for (auto & i : elems)
|
for (auto & i : elems)
|
||||||
i->bindVars(es, env);
|
i->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprLambda::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprLambda::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
auto newEnv = std::make_shared<StaticEnv>(
|
auto newEnv = std::make_shared<StaticEnv>(
|
||||||
false, env.get(),
|
false, env.get(),
|
||||||
|
@ -452,20 +453,20 @@ void ExprLambda::bindVars(const EvalState & es, const std::shared_ptr<const Stat
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprCall::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprCall::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
fun->bindVars(es, env);
|
fun->bindVars(es, env);
|
||||||
for (auto e : args)
|
for (auto e : args)
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprLet::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), attrs->attrs.size());
|
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), attrs->attrs.size());
|
||||||
|
|
||||||
|
@ -481,10 +482,10 @@ void ExprLet::bindVars(const EvalState & es, const std::shared_ptr<const StaticE
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprWith::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprWith::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
/* Does this `with' have an enclosing `with'? If so, record its
|
/* Does this `with' have an enclosing `with'? If so, record its
|
||||||
level so that `lookupVar' can look up variables in the previous
|
level so that `lookupVar' can look up variables in the previous
|
||||||
|
@ -499,53 +500,53 @@ void ExprWith::bindVars(const EvalState & es, const std::shared_ptr<const Static
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
attrs->bindVars(es, env);
|
attrs->bindVars(es, env);
|
||||||
auto newEnv = std::make_shared<StaticEnv>(true, env.get());
|
auto newEnv = std::make_shared<StaticEnv>(true, env.get());
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprIf::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprIf::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
cond->bindVars(es, env);
|
cond->bindVars(es, env);
|
||||||
then->bindVars(es, env);
|
then->bindVars(es, env);
|
||||||
else_->bindVars(es, env);
|
else_->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprAssert::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprAssert::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
cond->bindVars(es, env);
|
cond->bindVars(es, env);
|
||||||
body->bindVars(es, env);
|
body->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprOpNot::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprOpNot::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprConcatStrings::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprConcatStrings::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
|
|
||||||
for (auto & i : *this->es)
|
for (auto & i : *this->es)
|
||||||
i.second->bindVars(es, env);
|
i.second->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprPos::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
void ExprPos::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticEnv = env;
|
es.exprEnvs.insert(std::make_pair(this, env));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -144,18 +144,17 @@ struct Expr
|
||||||
{
|
{
|
||||||
virtual ~Expr() { };
|
virtual ~Expr() { };
|
||||||
virtual void show(const SymbolTable & symbols, std::ostream & str) const;
|
virtual void show(const SymbolTable & symbols, std::ostream & str) const;
|
||||||
virtual void bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env);
|
virtual void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env);
|
||||||
virtual void eval(EvalState & state, Env & env, Value & v);
|
virtual void eval(EvalState & state, Env & env, Value & v);
|
||||||
virtual Value * maybeThunk(EvalState & state, Env & env);
|
virtual Value * maybeThunk(EvalState & state, Env & env);
|
||||||
virtual void setName(Symbol name);
|
virtual void setName(Symbol name);
|
||||||
std::shared_ptr<const StaticEnv> staticEnv;
|
|
||||||
virtual PosIdx getPos() const { return noPos; }
|
virtual PosIdx getPos() const { return noPos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMON_METHODS \
|
#define COMMON_METHODS \
|
||||||
void show(const SymbolTable & symbols, std::ostream & str) const; \
|
void show(const SymbolTable & symbols, std::ostream & str) const; \
|
||||||
void eval(EvalState & state, Env & env, Value & v); \
|
void eval(EvalState & state, Env & env, Value & v); \
|
||||||
void bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env);
|
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env);
|
||||||
|
|
||||||
struct ExprInt : Expr
|
struct ExprInt : Expr
|
||||||
{
|
{
|
||||||
|
@ -402,7 +401,7 @@ struct ExprOpNot : Expr
|
||||||
{ \
|
{ \
|
||||||
str << "("; e1->show(symbols, str); str << " " s " "; e2->show(symbols, str); str << ")"; \
|
str << "("; e1->show(symbols, str); str << " " s " "; e2->show(symbols, str); str << ")"; \
|
||||||
} \
|
} \
|
||||||
void bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env) \
|
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) \
|
||||||
{ \
|
{ \
|
||||||
e1->bindVars(es, env); e2->bindVars(es, env); \
|
e1->bindVars(es, env); e2->bindVars(es, env); \
|
||||||
} \
|
} \
|
||||||
|
|
Loading…
Reference in a new issue