forked from lix-project/lix
break() primop; step and go debug commands
This commit is contained in:
parent
990bec78d3
commit
412d58f0bb
4 changed files with 40 additions and 2 deletions
|
@ -439,7 +439,11 @@ bool NixRepl::processLine(string line)
|
||||||
<< " :d <cmd> Debug mode commands\n"
|
<< " :d <cmd> Debug mode commands\n"
|
||||||
<< " :d stack Show call stack\n"
|
<< " :d stack Show call stack\n"
|
||||||
<< " :d env Show env stack\n"
|
<< " :d env Show env stack\n"
|
||||||
<< " :d error Show current error\n";
|
<< " :d error Show current error\n"
|
||||||
|
<< " :d go Go until end of program, exception, or builtins.break().\n"
|
||||||
|
<< " :d step Go one step\n"
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (command == ":d" || command == ":debug") {
|
else if (command == ":d" || command == ":debug") {
|
||||||
|
@ -476,6 +480,16 @@ bool NixRepl::processLine(string line)
|
||||||
notice("error information not available");
|
notice("error information not available");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (arg == "step") {
|
||||||
|
// set flag and exit repl.
|
||||||
|
state->debugStop = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (arg == "go") {
|
||||||
|
// set flag and exit repl.
|
||||||
|
state->debugStop = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (command == ":a" || command == ":add") {
|
else if (command == ":a" || command == ":add") {
|
||||||
|
|
|
@ -417,6 +417,7 @@ EvalState::EvalState(
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, store(store)
|
, store(store)
|
||||||
, buildStore(buildStore ? buildStore : store)
|
, buildStore(buildStore ? buildStore : store)
|
||||||
|
, debugStop(true)
|
||||||
, regexCache(makeRegexCache())
|
, regexCache(makeRegexCache())
|
||||||
, baseEnv(allocEnv(128))
|
, baseEnv(allocEnv(128))
|
||||||
, staticBaseEnv(new StaticEnv(false, 0))
|
, staticBaseEnv(new StaticEnv(false, 0))
|
||||||
|
@ -930,7 +931,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState &evalState, DebugTrace t)
|
||||||
:evalState(evalState), trace(t)
|
:evalState(evalState), trace(t)
|
||||||
{
|
{
|
||||||
evalState.debugTraces.push_front(t);
|
evalState.debugTraces.push_front(t);
|
||||||
if (debuggerHook)
|
if (evalState.debugStop && debuggerHook)
|
||||||
debuggerHook(0, t.env, t.expr);
|
debuggerHook(0, t.env, t.expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
RootValue vCallFlake = nullptr;
|
RootValue vCallFlake = nullptr;
|
||||||
RootValue vImportedDrvToDerivation = nullptr;
|
RootValue vImportedDrvToDerivation = nullptr;
|
||||||
|
|
||||||
|
bool debugStop;
|
||||||
std::list<DebugTrace> debugTraces;
|
std::list<DebugTrace> debugTraces;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -710,6 +710,28 @@ static RegisterPrimOp primop_genericClosure(RegisterPrimOp::Info {
|
||||||
.fun = prim_genericClosure,
|
.fun = prim_genericClosure,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static RegisterPrimOp primop_break({
|
||||||
|
.name = "break",
|
||||||
|
.args = {},
|
||||||
|
.doc = R"(
|
||||||
|
In debug mode, pause Nix expression evaluation and enter the repl.
|
||||||
|
)",
|
||||||
|
.fun = [](EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
|
{
|
||||||
|
// PathSet context;
|
||||||
|
// string s = state.coerceToString(pos, *args[0], context);
|
||||||
|
if (debuggerHook && !state.debugTraces.empty())
|
||||||
|
{
|
||||||
|
auto &dt = state.debugTraces.front();
|
||||||
|
// std::optional<ErrPos> pos;
|
||||||
|
// const Expr &expr;
|
||||||
|
// const Env &env;
|
||||||
|
// hintformat hint;
|
||||||
|
debuggerHook(nullptr, dt.env, dt.expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
static RegisterPrimOp primop_abort({
|
static RegisterPrimOp primop_abort({
|
||||||
.name = "abort",
|
.name = "abort",
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
|
|
Loading…
Reference in a new issue