aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcmd/command.cc5
-rw-r--r--src/libexpr/eval.cc25
-rw-r--r--src/libexpr/eval.hh1
3 files changed, 28 insertions, 3 deletions
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<void(const Error & error, const std::map<std::string, Value *> & env)> debuggerHook;
extern std::function<void(const Error & error, const Env & env)> debuggerHook;
+
+
ref<EvalState> EvalCommand::getEvalState()
{
std::cout << " EvalCommand::getEvalState()" << startReplOnEvalErrors << std::endl;
@@ -107,7 +109,8 @@ ref<EvalState> EvalCommand::getEvalState()
if (startReplOnEvalErrors)
debuggerHook = [evalState{ref<EvalState>(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>(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());