diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 59ab1f874..a32c4a24b 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -99,6 +99,8 @@ EvalCommand::EvalCommand() // extern std::function & env)> debuggerHook; extern std::function debuggerHook; + + ref EvalCommand::getEvalState() { std::cout << " EvalCommand::getEvalState()" << startReplOnEvalErrors << std::endl; @@ -107,7 +109,8 @@ ref EvalCommand::getEvalState() if (startReplOnEvalErrors) debuggerHook = [evalState{ref(evalState)}](const Error & error, const Env & env) { printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error.what()); - runRepl(evalState, env); + auto vm = mapEnvBindings(env); + runRepl(evalState, *vm); }; } return ref(evalState); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index eef4974e5..2e885bb7c 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -668,6 +668,28 @@ LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) } } + + +void mapEnvBindings(const Env &env, valmap & vm) +{ + // add bindings for the next level up first. + if (env.up) { + mapEnvBindings(*env.up, vm); + } + + // merge - and write over - higher level bindings. + vm.merge(*env.valuemap); +} + +valmap * mapEnvBindings(const Env &env) +{ + auto vm = new valmap(); + + mapEnvBindings(env, *vm); + + return vm; +} + // LocalNoInline(valmap * mapEnvBindings(Env &env)) // { // // NOT going to use this @@ -1508,8 +1530,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po /* For each formal argument, get the actual argument. If there is no matching actual argument but the formal argument has a default, use the default. */ + size_t attrsUsed = 0; if (debuggerHook) { - size_t attrsUsed = 0; for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { @@ -1531,7 +1553,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po else { auto map = new valmap(); - size_t attrsUsed = 0; for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 448f41def..2d167e6eb 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -44,6 +44,7 @@ struct Env Value * values[0]; }; +valmap * mapEnvBindings(const Env &env); Value & mkString(Value & v, std::string_view s, const PathSet & context = PathSet());