quit repl from step mode

This commit is contained in:
Ben Burdette 2022-02-15 09:49:25 -07:00
parent e761bf0601
commit c9bc3735f6
4 changed files with 26 additions and 7 deletions

View file

@ -89,6 +89,7 @@ string removeWhitespace(string s)
s = chomp(s); s = chomp(s);
size_t n = s.find_first_not_of(" \n\r\t"); size_t n = s.find_first_not_of(" \n\r\t");
if (n != string::npos) s = string(s, n); if (n != string::npos) s = string(s, n);
return s; return s;
} }
@ -231,8 +232,12 @@ void NixRepl::mainLoop(const std::vector<std::string> & files)
// When continuing input from previous lines, don't print a prompt, just align to the same // When continuing input from previous lines, don't print a prompt, just align to the same
// number of chars as the prompt. // number of chars as the prompt.
if (!getLine(input, input.empty() ? "nix-repl> " : " ")) if (!getLine(input, input.empty() ? "nix-repl> " : " "))
{
// ctrl-D should exit the debugger.
state->debugStop = false;
state->debugQuit = true;
break; break;
}
try { try {
if (!removeWhitespace(input).empty() && !processLine(input)) return; if (!removeWhitespace(input).empty() && !processLine(input)) return;
} catch (ParseError & e) { } catch (ParseError & e) {
@ -481,12 +486,12 @@ bool NixRepl::processLine(string line)
} }
} }
else if (arg == "step") { else if (arg == "step") {
// set flag and exit repl. // set flag to stop at next DebugTrace; exit repl.
state->debugStop = true; state->debugStop = true;
return false; return false;
} }
else if (arg == "go") { else if (arg == "go") {
// set flag and exit repl. // set flag to run to next breakpoint or end of program; exit repl.
state->debugStop = false; state->debugStop = false;
return false; return false;
} }
@ -605,8 +610,11 @@ bool NixRepl::processLine(string line)
printValue(std::cout, v, 1000000000) << std::endl; printValue(std::cout, v, 1000000000) << std::endl;
} }
else if (command == ":q" || command == ":quit") else if (command == ":q" || command == ":quit") {
state->debugStop = false;
state->debugQuit = true;
return false; return false;
}
else if (command == ":doc") { else if (command == ":doc") {
Value v; Value v;

View file

@ -438,6 +438,7 @@ EvalState::EvalState(
, store(store) , store(store)
, buildStore(buildStore ? buildStore : store) , buildStore(buildStore ? buildStore : store)
, debugStop(false) , debugStop(false)
, debugQuit(false)
, regexCache(makeRegexCache()) , regexCache(makeRegexCache())
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
, valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr)) , valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))

View file

@ -116,6 +116,7 @@ public:
RootValue vImportedDrvToDerivation = nullptr; RootValue vImportedDrvToDerivation = nullptr;
bool debugStop; bool debugStop;
bool debugQuit;
std::list<DebugTrace> debugTraces; std::list<DebugTrace> debugTraces;
void debug_throw(Error e); void debug_throw(Error e);

View file

@ -718,6 +718,15 @@ static RegisterPrimOp primop_break({
auto &dt = state.debugTraces.front(); auto &dt = state.debugTraces.front();
debuggerHook(&error, dt.env, dt.expr); debuggerHook(&error, dt.env, dt.expr);
if (state.debugQuit) {
// if the user elects to quit the repl, throw an exception.
throw Error(ErrorInfo{
.level = lvlInfo,
.msg = hintfmt("quit from debugger"),
.errPos = pos,
});
}
// returning the value we were passed. // returning the value we were passed.
v = *args[0]; v = *args[0];
} }