From f32c687f03e9764e55831d894b719fdf0104cf25 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 28 Apr 2021 15:50:11 -0600 Subject: move repl.cc to libcmd for linkage --- src/libcmd/repl.cc | 832 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 832 insertions(+) create mode 100644 src/libcmd/repl.cc (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc new file mode 100644 index 000000000..b1f250e73 --- /dev/null +++ b/src/libcmd/repl.cc @@ -0,0 +1,832 @@ +#include +#include +#include +#include + +#include + +#ifdef READLINE +#include +#include +#else +// editline < 1.15.2 don't wrap their API for C++ usage +// (added in https://github.com/troglobit/editline/commit/91398ceb3427b730995357e9d120539fb9bb7461). +// This results in linker errors due to to name-mangling of editline C symbols. +// For compatibility with these versions, we wrap the API here +// (wrapping multiple times on newer versions is no problem). +extern "C" { +#include +} +#endif + +#include "ansicolor.hh" +#include "shared.hh" +#include "eval.hh" +#include "eval-inline.hh" +#include "attr-path.hh" +#include "store-api.hh" +#include "common-eval-args.hh" +#include "get-drvs.hh" +#include "derivations.hh" +#include "affinity.hh" +#include "globals.hh" +#include "command.hh" +#include "finally.hh" +#include "markdown.hh" + +#if HAVE_BOEHMGC +#define GC_INCLUDE_NEW +#include +#endif + +namespace nix { + +struct NixRepl + #if HAVE_BOEHMGC + : gc + #endif +{ + string curDir; + ref state; + Bindings * autoArgs; + + Strings loadedFiles; + + const static int envSize = 32768; + StaticEnv staticEnv; + Env * env; + int displ; + StringSet varNames; + + const Path historyFile; + + NixRepl(ref state); + ~NixRepl(); + void mainLoop(const std::vector & files); + StringSet completePrefix(string prefix); + bool getLine(string & input, const std::string &prompt); + StorePath getDerivationPath(Value & v); + bool processLine(string line); + void loadFile(const Path & path); + void initEnv(); + void reloadFiles(); + void addAttrsToScope(Value & attrs); + void addVarToScope(const Symbol & name, Value * v); + Expr * parseString(string s); + void evalString(string s, Value & v); + + typedef set ValuesSeen; + std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth); + std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen); +}; + + +string removeWhitespace(string s) +{ + s = chomp(s); + size_t n = s.find_first_not_of(" \n\r\t"); + if (n != string::npos) s = string(s, n); + return s; +} + + +NixRepl::NixRepl(ref state) + : state(state) + , staticEnv(false, &state->staticBaseEnv) + , historyFile(getDataDir() + "/nix/repl-history") +{ + curDir = absPath("."); +} + + +NixRepl::~NixRepl() +{ + write_history(historyFile.c_str()); +} + +static NixRepl * curRepl; // ugly + +static char * completionCallback(char * s, int *match) { + auto possible = curRepl->completePrefix(s); + if (possible.size() == 1) { + *match = 1; + auto *res = strdup(possible.begin()->c_str() + strlen(s)); + if (!res) throw Error("allocation failure"); + return res; + } else if (possible.size() > 1) { + auto checkAllHaveSameAt = [&](size_t pos) { + auto &first = *possible.begin(); + for (auto &p : possible) { + if (p.size() <= pos || p[pos] != first[pos]) + return false; + } + return true; + }; + size_t start = strlen(s); + size_t len = 0; + while (checkAllHaveSameAt(start + len)) ++len; + if (len > 0) { + *match = 1; + auto *res = strdup(std::string(*possible.begin(), start, len).c_str()); + if (!res) throw Error("allocation failure"); + return res; + } + } + + *match = 0; + return nullptr; +} + +static int listPossibleCallback(char *s, char ***avp) { + auto possible = curRepl->completePrefix(s); + + if (possible.size() > (INT_MAX / sizeof(char*))) + throw Error("too many completions"); + + int ac = 0; + char **vp = nullptr; + + auto check = [&](auto *p) { + if (!p) { + if (vp) { + while (--ac >= 0) + free(vp[ac]); + free(vp); + } + throw Error("allocation failure"); + } + return p; + }; + + vp = check((char **)malloc(possible.size() * sizeof(char*))); + + for (auto & p : possible) + vp[ac++] = check(strdup(p.c_str())); + + *avp = vp; + + return ac; +} + +namespace { + // Used to communicate to NixRepl::getLine whether a signal occurred in ::readline. + volatile sig_atomic_t g_signal_received = 0; + + void sigintHandler(int signo) { + g_signal_received = signo; + } +} + +void NixRepl::mainLoop(const std::vector & files) +{ + string error = ANSI_RED "error:" ANSI_NORMAL " "; + std::cout << "Welcome to Nix version " << nixVersion << ". Type :? for help." << std::endl << std::endl; + + if (!files.empty()) { + for (auto & i : files) + loadedFiles.push_back(i); + + reloadFiles(); + if (!loadedFiles.empty()) std::cout << std::endl; + } + + // Allow nix-repl specific settings in .inputrc + rl_readline_name = "nix-repl"; + createDirs(dirOf(historyFile)); +#ifndef READLINE + el_hist_size = 1000; +#endif + read_history(historyFile.c_str()); + curRepl = this; +#ifndef READLINE + rl_set_complete_func(completionCallback); + rl_set_list_possib_func(listPossibleCallback); +#endif + + std::string input; + + while (true) { + // When continuing input from previous lines, don't print a prompt, just align to the same + // number of chars as the prompt. + if (!getLine(input, input.empty() ? "nix-repl> " : " ")) + break; + + try { + if (!removeWhitespace(input).empty() && !processLine(input)) return; + } catch (ParseError & e) { + if (e.msg().find("unexpected end of file") != std::string::npos) { + // For parse errors on incomplete input, we continue waiting for the next line of + // input without clearing the input so far. + continue; + } else { + printMsg(lvlError, e.msg()); + } + } catch (Error & e) { + printMsg(lvlError, e.msg()); + } catch (Interrupted & e) { + printMsg(lvlError, e.msg()); + } + + // We handled the current input fully, so we should clear it + // and read brand new input. + input.clear(); + std::cout << std::endl; + } +} + + +bool NixRepl::getLine(string & input, const std::string &prompt) +{ + struct sigaction act, old; + sigset_t savedSignalMask, set; + + auto setupSignals = [&]() { + act.sa_handler = sigintHandler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + if (sigaction(SIGINT, &act, &old)) + throw SysError("installing handler for SIGINT"); + + sigemptyset(&set); + sigaddset(&set, SIGINT); + if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask)) + throw SysError("unblocking SIGINT"); + }; + auto restoreSignals = [&]() { + if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr)) + throw SysError("restoring signals"); + + if (sigaction(SIGINT, &old, 0)) + throw SysError("restoring handler for SIGINT"); + }; + + setupSignals(); + char * s = readline(prompt.c_str()); + Finally doFree([&]() { free(s); }); + restoreSignals(); + + if (g_signal_received) { + g_signal_received = 0; + input.clear(); + return true; + } + + if (!s) + return false; + input += s; + input += '\n'; + return true; +} + + +StringSet NixRepl::completePrefix(string prefix) +{ + StringSet completions; + + size_t start = prefix.find_last_of(" \n\r\t(){}[]"); + std::string prev, cur; + if (start == std::string::npos) { + prev = ""; + cur = prefix; + } else { + prev = std::string(prefix, 0, start + 1); + cur = std::string(prefix, start + 1); + } + + size_t slash, dot; + + if ((slash = cur.rfind('/')) != string::npos) { + try { + auto dir = std::string(cur, 0, slash); + auto prefix2 = std::string(cur, slash + 1); + for (auto & entry : readDirectory(dir == "" ? "/" : dir)) { + if (entry.name[0] != '.' && hasPrefix(entry.name, prefix2)) + completions.insert(prev + dir + "/" + entry.name); + } + } catch (Error &) { + } + } else if ((dot = cur.rfind('.')) == string::npos) { + /* This is a variable name; look it up in the current scope. */ + StringSet::iterator i = varNames.lower_bound(cur); + while (i != varNames.end()) { + if (string(*i, 0, cur.size()) != cur) break; + completions.insert(prev + *i); + i++; + } + } else { + try { + /* This is an expression that should evaluate to an + attribute set. Evaluate it to get the names of the + attributes. */ + string expr(cur, 0, dot); + string cur2 = string(cur, dot + 1); + + Expr * e = parseString(expr); + Value v; + e->eval(*state, *env, v); + state->forceAttrs(v); + + for (auto & i : *v.attrs) { + string name = i.name; + if (string(name, 0, cur2.size()) != cur2) continue; + completions.insert(prev + expr + "." + name); + } + + } catch (ParseError & e) { + // Quietly ignore parse errors. + } catch (EvalError & e) { + // Quietly ignore evaluation errors. + } catch (UndefinedVarError & e) { + // Quietly ignore undefined variable errors. + } + } + + return completions; +} + + +bool isVarName(const string & s) +{ + if (s.size() == 0) return false; + char c = s[0]; + if ((c >= '0' && c <= '9') || c == '-' || c == '\'') return false; + for (auto & i : s) + if (!((i >= 'a' && i <= 'z') || + (i >= 'A' && i <= 'Z') || + (i >= '0' && i <= '9') || + i == '_' || i == '-' || i == '\'')) + return false; + return true; +} + + +StorePath NixRepl::getDerivationPath(Value & v) { + auto drvInfo = getDerivation(*state, v, false); + if (!drvInfo) + throw Error("expression does not evaluate to a derivation, so I can't build it"); + Path drvPathRaw = drvInfo->queryDrvPath(); + if (drvPathRaw == "") + throw Error("expression did not evaluate to a valid derivation (no drv path)"); + StorePath drvPath = state->store->parseStorePath(drvPathRaw); + if (!state->store->isValidPath(drvPath)) + throw Error("expression did not evaluate to a valid derivation (invalid drv path)"); + return drvPath; +} + + +bool NixRepl::processLine(string line) +{ + if (line == "") return true; + + string command, arg; + + if (line[0] == ':') { + size_t p = line.find_first_of(" \n\r\t"); + command = string(line, 0, p); + if (p != string::npos) arg = removeWhitespace(string(line, p)); + } else { + arg = line; + } + + if (command == ":?" || command == ":help") { + // FIXME: convert to Markdown, include in the 'nix repl' manpage. + std::cout + << "The following commands are available:\n" + << "\n" + << " Evaluate and print expression\n" + << " = Bind expression to variable\n" + << " :a Add attributes from resulting set to scope\n" + << " :b Build derivation\n" + << " :e Open the derivation in $EDITOR\n" + << " :i Build derivation, then install result into current profile\n" + << " :l Load Nix expression and add it to scope\n" + << " :p Evaluate and print expression recursively\n" + << " :q Exit nix-repl\n" + << " :r Reload all files\n" + << " :s Build dependencies of derivation, then start nix-shell\n" + << " :t Describe result of evaluation\n" + << " :u Build derivation, then start nix-shell\n" + << " :doc Show documentation of a builtin function\n"; + } + + else if (command == ":a" || command == ":add") { + Value v; + evalString(arg, v); + addAttrsToScope(v); + } + + else if (command == ":l" || command == ":load") { + state->resetFileCache(); + loadFile(arg); + } + + else if (command == ":r" || command == ":reload") { + state->resetFileCache(); + reloadFiles(); + } + + else if (command == ":e" || command == ":edit") { + Value v; + evalString(arg, v); + + Pos pos; + + if (v.type() == nPath || v.type() == nString) { + PathSet context; + auto filename = state->coerceToString(noPos, v, context); + pos.file = state->symbols.create(filename); + } else if (v.isLambda()) { + pos = v.lambda.fun->pos; + } else { + // assume it's a derivation + pos = findDerivationFilename(*state, v, arg); + } + + // Open in EDITOR + auto args = editorFor(pos); + auto editor = args.front(); + args.pop_front(); + runProgram(editor, true, args); + + // Reload right after exiting the editor + state->resetFileCache(); + reloadFiles(); + } + + else if (command == ":t") { + Value v; + evalString(arg, v); + std::cout << showType(v) << std::endl; + + } else if (command == ":u") { + Value v, f, result; + evalString(arg, v); + evalString("drv: (import {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); + state->callFunction(f, v, result, Pos()); + + StorePath drvPath = getDerivationPath(result); + runProgram(settings.nixBinDir + "/nix-shell", true, {state->store->printStorePath(drvPath)}); + } + + else if (command == ":b" || command == ":i" || command == ":s") { + Value v; + evalString(arg, v); + StorePath drvPath = getDerivationPath(v); + Path drvPathRaw = state->store->printStorePath(drvPath); + + if (command == ":b") { + /* We could do the build in this process using buildPaths(), + but doing it in a child makes it easier to recover from + problems / SIGINT. */ + try { + runProgram(settings.nixBinDir + "/nix", true, {"build", "--no-link", drvPathRaw}); + auto drv = state->store->readDerivation(drvPath); + std::cout << std::endl << "this derivation produced the following outputs:" << std::endl; + for (auto & i : drv.outputsAndOptPaths(*state->store)) + std::cout << fmt(" %s -> %s\n", i.first, state->store->printStorePath(*i.second.second)); + } catch (ExecError &) { + } + } else if (command == ":i") { + runProgram(settings.nixBinDir + "/nix-env", true, {"-i", drvPathRaw}); + } else { + runProgram(settings.nixBinDir + "/nix-shell", true, {drvPathRaw}); + } + } + + else if (command == ":p" || command == ":print") { + Value v; + evalString(arg, v); + printValue(std::cout, v, 1000000000) << std::endl; + } + + else if (command == ":q" || command == ":quit") + return false; + + else if (command == ":doc") { + Value v; + evalString(arg, v); + if (auto doc = state->getDoc(v)) { + std::string markdown; + + if (!doc->args.empty() && doc->name) { + auto args = doc->args; + for (auto & arg : args) + arg = "*" + arg + "*"; + + markdown += + "**Synopsis:** `builtins." + (std::string) (*doc->name) + "` " + + concatStringsSep(" ", args) + "\n\n"; + } + + markdown += trim(stripIndentation(doc->doc)); + + std::cout << renderMarkdownToTerminal(markdown); + } else + throw Error("value does not have documentation"); + } + + else if (command != "") + throw Error("unknown command '%1%'", command); + + else { + size_t p = line.find('='); + string name; + if (p != string::npos && + p < line.size() && + line[p + 1] != '=' && + isVarName(name = removeWhitespace(string(line, 0, p)))) + { + Expr * e = parseString(string(line, p + 1)); + Value *v = new Value(*state->allocValue()); + v->mkThunk(env, e); + addVarToScope(state->symbols.create(name), v); + } else { + Value v; + evalString(line, v); + printValue(std::cout, v, 1) << std::endl; + } + } + + return true; +} + + +void NixRepl::loadFile(const Path & path) +{ + loadedFiles.remove(path); + loadedFiles.push_back(path); + Value v, v2; + state->evalFile(lookupFileArg(*state, path), v); + state->autoCallFunction(*autoArgs, v, v2); + addAttrsToScope(v2); +} + + +void NixRepl::initEnv() +{ + env = &state->allocEnv(envSize); + env->up = &state->baseEnv; + displ = 0; + staticEnv.vars.clear(); + + varNames.clear(); + for (auto & i : state->staticBaseEnv.vars) + varNames.insert(i.first); +} + + +void NixRepl::reloadFiles() +{ + initEnv(); + + Strings old = loadedFiles; + loadedFiles.clear(); + + bool first = true; + for (auto & i : old) { + if (!first) std::cout << std::endl; + first = false; + std::cout << format("Loading '%1%'...") % i << std::endl; + loadFile(i); + } +} + + +void NixRepl::addAttrsToScope(Value & attrs) +{ + state->forceAttrs(attrs); + for (auto & i : *attrs.attrs) + addVarToScope(i.name, i.value); + std::cout << format("Added %1% variables.") % attrs.attrs->size() << std::endl; +} + + +void NixRepl::addVarToScope(const Symbol & name, Value * v) +{ + if (displ >= envSize) + throw Error("environment full; cannot add more variables"); + staticEnv.vars[name] = displ; + env->values[displ++] = v; + varNames.insert((string) name); +} + + +Expr * NixRepl::parseString(string s) +{ + Expr * e = state->parseExprFromString(s, curDir, staticEnv); + return e; +} + + +void NixRepl::evalString(string s, Value & v) +{ + Expr * e = parseString(s); + e->eval(*state, *env, v); + state->forceValue(v); +} + + +std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth) +{ + ValuesSeen seen; + return printValue(str, v, maxDepth, seen); +} + + +std::ostream & printStringValue(std::ostream & str, const char * string) { + str << "\""; + for (const char * i = string; *i; i++) + if (*i == '\"' || *i == '\\') str << "\\" << *i; + else if (*i == '\n') str << "\\n"; + else if (*i == '\r') str << "\\r"; + else if (*i == '\t') str << "\\t"; + else str << *i; + str << "\""; + return str; +} + + +// FIXME: lot of cut&paste from Nix's eval.cc. +std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen) +{ + str.flush(); + checkInterrupt(); + + state->forceValue(v); + + switch (v.type()) { + + case nInt: + str << ANSI_CYAN << v.integer << ANSI_NORMAL; + break; + + case nBool: + str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL; + break; + + case nString: + str << ANSI_YELLOW; + printStringValue(str, v.string.s); + str << ANSI_NORMAL; + break; + + case nPath: + str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping? + break; + + case nNull: + str << ANSI_CYAN "null" ANSI_NORMAL; + break; + + case nAttrs: { + seen.insert(&v); + + bool isDrv = state->isDerivation(v); + + if (isDrv) { + str << "«derivation "; + Bindings::iterator i = v.attrs->find(state->sDrvPath); + PathSet context; + Path drvPath = i != v.attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : "???"; + str << drvPath << "»"; + } + + else if (maxDepth > 0) { + str << "{ "; + + typedef std::map Sorted; + Sorted sorted; + for (auto & i : *v.attrs) + sorted[i.name] = i.value; + + for (auto & i : sorted) { + if (isVarName(i.first)) + str << i.first; + else + printStringValue(str, i.first.c_str()); + str << " = "; + if (seen.find(i.second) != seen.end()) + str << "«repeated»"; + else + try { + printValue(str, *i.second, maxDepth - 1, seen); + } catch (AssertionError & e) { + str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL; + } + str << "; "; + } + + str << "}"; + } else + str << "{ ... }"; + + break; + } + + case nList: + seen.insert(&v); + + str << "[ "; + if (maxDepth > 0) + for (unsigned int n = 0; n < v.listSize(); ++n) { + if (seen.find(v.listElems()[n]) != seen.end()) + str << "«repeated»"; + else + try { + printValue(str, *v.listElems()[n], maxDepth - 1, seen); + } catch (AssertionError & e) { + str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL; + } + str << " "; + } + else + str << "... "; + str << "]"; + break; + + case nFunction: + if (v.isLambda()) { + std::ostringstream s; + s << v.lambda.fun->pos; + str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL; + } else if (v.isPrimOp()) { + str << ANSI_MAGENTA "«primop»" ANSI_NORMAL; + } else if (v.isPrimOpApp()) { + str << ANSI_BLUE "«primop-app»" ANSI_NORMAL; + } else { + abort(); + } + break; + + case nFloat: + str << v.fpoint; + break; + + default: + str << ANSI_RED "«unknown»" ANSI_NORMAL; + break; + } + + return str; +} + +void runRepl( + ref evalState, + const std::map & extraEnv) +{ + auto repl = std::make_unique(evalState); + + repl->initEnv(); + + std::set names; + + for (auto & [name, value] : extraEnv) { + names.insert(ANSI_BOLD + name + ANSI_NORMAL); + repl->addVarToScope(repl->state->symbols.create(name), value); + } + + printError("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)); + + repl->mainLoop({}); +} + +struct CmdRepl : StoreCommand, MixEvalArgs +{ + std::vector files; + + CmdRepl() + { + expectArgs({ + .label = "files", + .handler = {&files}, + .completer = completePath + }); + } + + std::string description() override + { + return "start an interactive environment for evaluating Nix expressions"; + } + + std::string doc() override + { + return + #include "repl.md" + ; + } + + void run(ref store) override + { + evalSettings.pureEval = false; + + auto evalState = make_ref(searchPath, store); + + auto repl = std::make_unique(evalState); + repl->autoArgs = getAutoArgs(*repl->state); + repl->mainLoop(files); + } +}; + +static auto rCmdRepl = registerCommand("repl"); + +} -- cgit v1.2.3 From a8df23975293a9c0b4d7a55b46d0047f955e0f1c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 8 Jun 2021 14:44:53 -0600 Subject: highlight the extra vars --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index b1f250e73..29be71e13 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -785,7 +785,7 @@ void runRepl( repl->addVarToScope(repl->state->symbols.create(name), value); } - printError("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)); + printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); repl->mainLoop({}); } -- cgit v1.2.3 From edb5a280243974c2094ed62cec104b55b97add43 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 11 Jun 2021 18:55:40 -0600 Subject: hintfmt for eye searing varnames --- src/libcmd/repl.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 29be71e13..57174bf0e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -781,11 +781,13 @@ void runRepl( std::set names; for (auto & [name, value] : extraEnv) { - names.insert(ANSI_BOLD + name + ANSI_NORMAL); + // names.insert(ANSI_BOLD + name + ANSI_NORMAL); + names.insert(name); repl->addVarToScope(repl->state->symbols.create(name), value); } printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); + // printError("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)); repl->mainLoop({}); } -- cgit v1.2.3 From 21071bfdeb0a5bc2b75018c91a4c2f138f233e33 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 14 Sep 2021 10:49:22 -0600 Subject: shared_ptr for StaticEnv --- src/libcmd/repl.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 57174bf0e..e1b58cc76 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -53,7 +53,8 @@ struct NixRepl Strings loadedFiles; const static int envSize = 32768; - StaticEnv staticEnv; + std::shared_ptr staticEnv; + // StaticEnv staticEnv; Env * env; int displ; StringSet varNames; @@ -92,7 +93,7 @@ string removeWhitespace(string s) NixRepl::NixRepl(ref state) : state(state) - , staticEnv(false, &state->staticBaseEnv) + , staticEnv(new StaticEnv(false, state->staticBaseEnv.get())) , historyFile(getDataDir() + "/nix/repl-history") { curDir = absPath("."); @@ -567,10 +568,10 @@ void NixRepl::initEnv() env = &state->allocEnv(envSize); env->up = &state->baseEnv; displ = 0; - staticEnv.vars.clear(); + staticEnv->vars.clear(); varNames.clear(); - for (auto & i : state->staticBaseEnv.vars) + for (auto & i : state->staticBaseEnv->vars) varNames.insert(i.first); } @@ -605,7 +606,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value * v) { if (displ >= envSize) throw Error("environment full; cannot add more variables"); - staticEnv.vars[name] = displ; + staticEnv->vars[name] = displ; env->values[displ++] = v; varNames.insert((string) name); } -- cgit v1.2.3 From e54f17eb46bc487abc38e70dfc2f1c617fb59d32 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 22 Oct 2021 14:27:04 -0600 Subject: remove more debug code --- src/libcmd/repl.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index e1b58cc76..bfc131d27 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -54,7 +54,6 @@ struct NixRepl const static int envSize = 32768; std::shared_ptr staticEnv; - // StaticEnv staticEnv; Env * env; int displ; StringSet varNames; -- cgit v1.2.3 From e82aec4efcd06cbd60d57f401fb7e93ab595128c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 30 Nov 2021 14:15:02 -0700 Subject: fix merge issues --- src/libcmd/repl.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 6faa9f9fa..910f0f694 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -205,6 +205,7 @@ void NixRepl::mainLoop(const std::vector & files) if (!files.empty()) { for (auto & i : files) loadedFiles.push_back(i); + } reloadFiles(); if (!loadedFiles.empty()) notice(""); @@ -639,7 +640,7 @@ void NixRepl::addAttrsToScope(Value & attrs) { state->forceAttrs(attrs); for (auto & i : *attrs.attrs) - addVarToScope(i.name, *i.value); + addVarToScope(i.name, i.value); notice("Added %1% variables.", attrs.attrs->size()); } @@ -650,7 +651,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value * v) throw Error("environment full; cannot add more variables"); staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); - env->values[displ++] = &v; + env->values[displ++] = v; varNames.insert((string) name); } -- cgit v1.2.3 From f317019edda7afac8590e68d4d979b03a2cdbf62 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 20 Dec 2021 12:32:21 -0700 Subject: :d error --- src/libcmd/repl.cc | 93 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 16 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 910f0f694..0eea2389b 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -50,6 +50,8 @@ struct NixRepl ref state; Bindings * autoArgs; + std::optional> debugError; + Strings loadedFiles; const static int envSize = 32768; @@ -70,6 +72,7 @@ struct NixRepl void loadFile(const Path & path); void loadFlake(const std::string & flakeRef); void initEnv(); + void loadFiles(); void reloadFiles(); void addAttrsToScope(Value & attrs); void addVarToScope(const Symbol & name, Value * v); @@ -199,6 +202,9 @@ namespace { void NixRepl::mainLoop(const std::vector & files) { + std::cout << "iinitial mainLoop; " << std::endl; + // printStaticEnvBindings(*staticEnv, 0); + string error = ANSI_RED "error:" ANSI_NORMAL " "; notice("Welcome to Nix " + nixVersion + ". Type :? for help.\n"); @@ -207,7 +213,7 @@ void NixRepl::mainLoop(const std::vector & files) loadedFiles.push_back(i); } - reloadFiles(); + loadFiles(); if (!loadedFiles.empty()) notice(""); // Allow nix-repl specific settings in .inputrc @@ -225,6 +231,9 @@ void NixRepl::mainLoop(const std::vector & files) std::string input; + std::cout << "pre MAINLOOP; " << std::endl; + // printStaticEnvBindings(*staticEnv, 0); + while (true) { // When continuing input from previous lines, don't print a prompt, just align to the same // number of chars as the prompt. @@ -415,21 +424,40 @@ bool NixRepl::processLine(string line) std::cout << "The following commands are available:\n" << "\n" - << " Evaluate and print expression\n" - << " = Bind expression to variable\n" - << " :a Add attributes from resulting set to scope\n" - << " :b Build derivation\n" - << " :e Open package or function in $EDITOR\n" - << " :i Build derivation, then install result into current profile\n" - << " :l Load Nix expression and add it to scope\n" - << " :lf Load Nix flake and add it to scope\n" - << " :p Evaluate and print expression recursively\n" - << " :q Exit nix-repl\n" - << " :r Reload all files\n" - << " :s Build dependencies of derivation, then start nix-shell\n" - << " :t Describe result of evaluation\n" - << " :u Build derivation, then start nix-shell\n" - << " :doc Show documentation of a builtin function\n"; + << " Evaluate and print expression\n" + << " = Bind expression to variable\n" + << " :a Add attributes from resulting set to scope\n" + << " :b Build derivation\n" + << " :e Open package or function in $EDITOR\n" + << " :i Build derivation, then install result into current profile\n" + << " :l Load Nix expression and add it to scope\n" + << " :lf Load Nix flake and add it to scope\n" + << " :p Evaluate and print expression recursively\n" + << " :q Exit nix-repl\n" + << " :r Reload all files\n" + << " :s Build dependencies of derivation, then start nix-shell\n" + << " :t Describe result of evaluation\n" + << " :u Build derivation, then start nix-shell\n" + << " :doc Show documentation of a builtin function\n" + << " :d Debug mode commands\n" + << " :d stack Show call stack\n" + << " :d stack Detail for step N\n" + << " :d error Show current error\n"; + } + + else if (command == ":d" || command == ":debug") { + std::cout << "debug: '" << arg << "'" << std::endl; + if (arg == "stack") { + } + else if (arg == "error") { + if (this->debugError.has_value()) { + showErrorInfo(std::cout, (*debugError)->info(), true); + } + else + { + notice("error information not available"); + } + } } else if (command == ":a" || command == ":add") { @@ -561,11 +589,13 @@ bool NixRepl::processLine(string line) line[p + 1] != '=' && isVarName(name = removeWhitespace(string(line, 0, p)))) { + std::cout << "isvarname" << std::endl; Expr * e = parseString(string(line, p + 1)); Value *v = new Value(*state->allocValue()); v->mkThunk(env, e); addVarToScope(state->symbols.create(name), v); } else { + std::cout << "evalstring" << std::endl; Value v; evalString(line, v); printValue(std::cout, v, 1) << std::endl; @@ -623,6 +653,12 @@ void NixRepl::reloadFiles() { initEnv(); + loadFiles(); +} + + +void NixRepl::loadFiles() +{ Strings old = loadedFiles; loadedFiles.clear(); @@ -649,12 +685,28 @@ void NixRepl::addVarToScope(const Symbol & name, Value * v) { if (displ >= envSize) throw Error("environment full; cannot add more variables"); + if (auto oldVar = staticEnv->find(name); oldVar != staticEnv->vars.end()) + staticEnv->vars.erase(oldVar); staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); env->values[displ++] = v; varNames.insert((string) name); + notice("Added variable to scope: %1%", name); + } +// version from master. +// void NixRepl::addVarToScope(const Symbol & name, Value & v) +// { +// if (displ >= envSize) +// throw Error("environment full; cannot add more variables"); +// if (auto oldVar = staticEnv.find(name); oldVar != staticEnv.vars.end()) +// staticEnv.vars.erase(oldVar); +// staticEnv.vars.emplace_back(name, displ); +// staticEnv.sort(); +// env->values[displ++] = &v; +// varNames.insert((string) name); +// } Expr * NixRepl::parseString(string s) { @@ -665,8 +717,11 @@ Expr * NixRepl::parseString(string s) void NixRepl::evalString(string s, Value & v) { + std::cout << "pre partstirns:l" << std::endl; Expr * e = parseString(s); + std::cout << "pre e->eval" << std::endl; e->eval(*state, *env, v); + std::cout << "prev fv" << std::endl; state->forceValue(v); } @@ -817,10 +872,13 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, + std::optional> debugError, const std::map & extraEnv) { auto repl = std::make_unique(evalState); + repl->debugError = debugError; + repl->initEnv(); std::set names; @@ -834,6 +892,9 @@ void runRepl( printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); // printError("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)); + std::cout << " pre repl->mainLoop({});" << std::endl; + // printStaticEnvBindings(*repl->staticEnv, 0); + repl->mainLoop({}); } -- cgit v1.2.3 From b4a59a5eec5bdb94ee2bbc8365f024d5787abd60 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Dec 2021 15:38:49 -0700 Subject: DebugStackTracker class in one place --- src/libcmd/repl.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 0eea2389b..2a925df64 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -451,6 +451,7 @@ bool NixRepl::processLine(string line) } else if (arg == "error") { if (this->debugError.has_value()) { + // TODO user --show-trace setting? showErrorInfo(std::cout, (*debugError)->info(), true); } else -- cgit v1.2.3 From bc20e54e0044e08c68a7af1f1e12d001baba8a74 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Dec 2021 19:40:08 -0700 Subject: stack traces basically working --- src/libcmd/repl.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 2a925df64..3289aea3e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -448,6 +448,26 @@ bool NixRepl::processLine(string line) else if (command == ":d" || command == ":debug") { std::cout << "debug: '" << arg << "'" << std::endl; if (arg == "stack") { + std::cout << "eval stack:" << std::endl; + for (auto iter = this->state->debugTraces.begin(); + iter != this->state->debugTraces.end(); ++iter) { + std::cout << "\n" << "… " << iter->hint.str() << "\n"; + + if (iter->pos.has_value() && (*iter->pos)) { + auto pos = iter->pos.value(); + std::cout << "\n"; + printAtPos(pos, std::cout); + + auto loc = getCodeLines(pos); + if (loc.has_value()) { + std::cout << "\n"; + printCodeLines(std::cout, "", pos, *loc); + std::cout << "\n"; + } + } + } + + } else if (arg == "error") { if (this->debugError.has_value()) { -- cgit v1.2.3 From e5eebda19475ab4f25346128e5428c27e526c7ce Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Dec 2021 13:36:39 -0700 Subject: DebugTrace --- src/libcmd/repl.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 3289aea3e..6859e5c07 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -50,7 +50,7 @@ struct NixRepl ref state; Bindings * autoArgs; - std::optional> debugError; + const Error *debugError; Strings loadedFiles; @@ -470,13 +470,12 @@ bool NixRepl::processLine(string line) } else if (arg == "error") { - if (this->debugError.has_value()) { - // TODO user --show-trace setting? - showErrorInfo(std::cout, (*debugError)->info(), true); + if (this->debugError) { + showErrorInfo(std::cout, debugError->info(), true); } else { - notice("error information not available"); + notice("error information not available"); } } } @@ -893,7 +892,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, - std::optional> debugError, + const Error *debugError, const std::map & extraEnv) { auto repl = std::make_unique(evalState); -- cgit v1.2.3 From ff82ba98b41eb3e4b1ce96ed02504acea03eb29c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 14:06:04 -0700 Subject: don't add builtins to extras, initEnv() in regular repl --- src/libcmd/repl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 6859e5c07..b14f43ec4 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -901,8 +901,8 @@ void runRepl( repl->initEnv(); + // add 'extra' vars. std::set names; - for (auto & [name, value] : extraEnv) { // names.insert(ANSI_BOLD + name + ANSI_NORMAL); names.insert(name); @@ -951,6 +951,7 @@ struct CmdRepl : StoreCommand, MixEvalArgs auto repl = std::make_unique(evalState); repl->autoArgs = getAutoArgs(*repl->state); + repl->initEnv(); repl->mainLoop(files); } }; -- cgit v1.2.3 From 2a66c120e66953bf8d6cf6866eb2783549527d40 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 14:48:34 -0700 Subject: by refernce for addVarToScope --- src/libcmd/repl.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index b14f43ec4..188bf75e4 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -75,7 +75,7 @@ struct NixRepl void loadFiles(); void reloadFiles(); void addAttrsToScope(Value & attrs); - void addVarToScope(const Symbol & name, Value * v); + void addVarToScope(const Symbol & name, Value & v); Expr * parseString(string s); void evalString(string s, Value & v); @@ -613,7 +613,7 @@ bool NixRepl::processLine(string line) Expr * e = parseString(string(line, p + 1)); Value *v = new Value(*state->allocValue()); v->mkThunk(env, e); - addVarToScope(state->symbols.create(name), v); + addVarToScope(state->symbols.create(name), *v); } else { std::cout << "evalstring" << std::endl; Value v; @@ -696,12 +696,12 @@ void NixRepl::addAttrsToScope(Value & attrs) { state->forceAttrs(attrs); for (auto & i : *attrs.attrs) - addVarToScope(i.name, i.value); + addVarToScope(i.name, *i.value); notice("Added %1% variables.", attrs.attrs->size()); } -void NixRepl::addVarToScope(const Symbol & name, Value * v) +void NixRepl::addVarToScope(const Symbol & name, Value & v) { if (displ >= envSize) throw Error("environment full; cannot add more variables"); @@ -709,7 +709,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value * v) staticEnv->vars.erase(oldVar); staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); - env->values[displ++] = v; + env->values[displ++] = &v; varNames.insert((string) name); notice("Added variable to scope: %1%", name); @@ -906,7 +906,7 @@ void runRepl( for (auto & [name, value] : extraEnv) { // names.insert(ANSI_BOLD + name + ANSI_NORMAL); names.insert(name); - repl->addVarToScope(repl->state->symbols.create(name), value); + repl->addVarToScope(repl->state->symbols.create(name), *value); } printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); -- cgit v1.2.3 From 6801a423fc9abdfd2cb7307f2970553bcfad089d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 16:28:45 -0700 Subject: :d env --- src/libcmd/repl.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 188bf75e4..3948ede02 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -402,7 +402,6 @@ StorePath NixRepl::getDerivationPath(Value & v) { return drvPath; } - bool NixRepl::processLine(string line) { if (line == "") return true; @@ -441,7 +440,8 @@ bool NixRepl::processLine(string line) << " :doc Show documentation of a builtin function\n" << " :d Debug mode commands\n" << " :d stack Show call stack\n" - << " :d stack Detail for step N\n" + // << " :d stack Detail for stack level N\n" + << " :d env Show env stack\n" << " :d error Show current error\n"; } @@ -466,17 +466,21 @@ bool NixRepl::processLine(string line) } } } - - + } else if (arg == "env") { + std::cout << "env stack:" << std::endl; + auto iter = this->state->debugTraces.begin(); + if (iter != this->state->debugTraces.end()) { + printStaticEnvBindings(iter->expr); + } } else if (arg == "error") { - if (this->debugError) { - showErrorInfo(std::cout, debugError->info(), true); - } - else - { - notice("error information not available"); - } + if (this->debugError) { + showErrorInfo(std::cout, debugError->info(), true); + } + else + { + notice("error information not available"); + } } } -- cgit v1.2.3 From 9760fa8661f7562e0b8979338200904053cc4631 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 17:35:27 -0700 Subject: add DebugTrace for the current error --- src/libcmd/repl.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 3948ede02..4a61d2be4 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -897,6 +897,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, const Error *debugError, + const Expr &expr, const std::map & extraEnv) { auto repl = std::make_unique(evalState); @@ -905,6 +906,15 @@ void runRepl( repl->initEnv(); + // tack on a final DebugTrace for the error position. + DebugTraceStacker ldts( + *evalState, + DebugTrace + {.pos = debugError->info().errPos, + .expr = expr, + .hint = debugError->info().msg + }); + // add 'extra' vars. std::set names; for (auto & [name, value] : extraEnv) { -- cgit v1.2.3 From 4610e02d04c9f41ac355d2ca6a27d3a631ffefc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 18:12:46 -0700 Subject: remove debug code --- src/libcmd/repl.cc | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 4a61d2be4..64547344a 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -202,9 +202,6 @@ namespace { void NixRepl::mainLoop(const std::vector & files) { - std::cout << "iinitial mainLoop; " << std::endl; - // printStaticEnvBindings(*staticEnv, 0); - string error = ANSI_RED "error:" ANSI_NORMAL " "; notice("Welcome to Nix " + nixVersion + ". Type :? for help.\n"); @@ -231,9 +228,6 @@ void NixRepl::mainLoop(const std::vector & files) std::string input; - std::cout << "pre MAINLOOP; " << std::endl; - // printStaticEnvBindings(*staticEnv, 0); - while (true) { // When continuing input from previous lines, don't print a prompt, just align to the same // number of chars as the prompt. @@ -446,7 +440,6 @@ bool NixRepl::processLine(string line) } else if (command == ":d" || command == ":debug") { - std::cout << "debug: '" << arg << "'" << std::endl; if (arg == "stack") { std::cout << "eval stack:" << std::endl; for (auto iter = this->state->debugTraces.begin(); @@ -613,13 +606,11 @@ bool NixRepl::processLine(string line) line[p + 1] != '=' && isVarName(name = removeWhitespace(string(line, 0, p)))) { - std::cout << "isvarname" << std::endl; Expr * e = parseString(string(line, p + 1)); Value *v = new Value(*state->allocValue()); v->mkThunk(env, e); addVarToScope(state->symbols.create(name), *v); } else { - std::cout << "evalstring" << std::endl; Value v; evalString(line, v); printValue(std::cout, v, 1) << std::endl; @@ -715,8 +706,6 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v) staticEnv->sort(); env->values[displ++] = &v; varNames.insert((string) name); - notice("Added variable to scope: %1%", name); - } // version from master. @@ -741,11 +730,8 @@ Expr * NixRepl::parseString(string s) void NixRepl::evalString(string s, Value & v) { - std::cout << "pre partstirns:l" << std::endl; Expr * e = parseString(s); - std::cout << "pre e->eval" << std::endl; e->eval(*state, *env, v); - std::cout << "prev fv" << std::endl; state->forceValue(v); } @@ -924,10 +910,6 @@ void runRepl( } printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); - // printError("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)); - - std::cout << " pre repl->mainLoop({});" << std::endl; - // printStaticEnvBindings(*repl->staticEnv, 0); repl->mainLoop({}); } -- cgit v1.2.3 From 5954cbf3e9dca0e3b84e4bf2def74abb3d6f80cd Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 18:29:55 -0700 Subject: more cleanup --- src/libcmd/repl.cc | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 64547344a..cf784db61 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -434,7 +434,6 @@ bool NixRepl::processLine(string line) << " :doc Show documentation of a builtin function\n" << " :d Debug mode commands\n" << " :d stack Show call stack\n" - // << " :d stack Detail for stack level N\n" << " :d env Show env stack\n" << " :d error Show current error\n"; } @@ -708,19 +707,6 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v) varNames.insert((string) name); } -// version from master. -// void NixRepl::addVarToScope(const Symbol & name, Value & v) -// { -// if (displ >= envSize) -// throw Error("environment full; cannot add more variables"); -// if (auto oldVar = staticEnv.find(name); oldVar != staticEnv.vars.end()) -// staticEnv.vars.erase(oldVar); -// staticEnv.vars.emplace_back(name, displ); -// staticEnv.sort(); -// env->values[displ++] = &v; -// varNames.insert((string) name); -// } - Expr * NixRepl::parseString(string s) { Expr * e = state->parseExprFromString(s, curDir, staticEnv); -- cgit v1.2.3 From c6691089814ac16eb02bab968a97ea2b0fe942f2 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 3 Jan 2022 18:13:16 -0700 Subject: merge cleanup --- src/libcmd/repl.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index e7628082a..4cf93c26e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -435,7 +435,7 @@ bool NixRepl::processLine(string line) << " :u Build derivation, then start nix-shell\n" << " :doc Show documentation of a builtin function\n" << " :log Show logs for a derivation\n" - << " :st [bool] Enable, disable or toggle showing traces for errors\n"; + << " :st [bool] Enable, disable or toggle showing traces for errors\n" << " :d Debug mode commands\n" << " :d stack Show call stack\n" << " :d env Show env stack\n" @@ -730,12 +730,12 @@ void NixRepl::addAttrsToScope(Value & attrs) throw Error("environment full; cannot add more variables"); for (auto & i : *attrs.attrs) { - staticEnv.vars.emplace_back(i.name, displ); + staticEnv->vars.emplace_back(i.name, displ); env->values[displ++] = i.value; varNames.insert((string) i.name); } - staticEnv.sort(); - staticEnv.deduplicate(); + staticEnv->sort(); + staticEnv->deduplicate(); notice("Added %1% variables.", attrs.attrs->size()); } -- cgit v1.2.3 From bf8a065be0d0cdccf5b6bc1034dc3e1709b21bd5 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 5 Jan 2022 12:28:31 -0700 Subject: add colors; remove headings --- src/libcmd/repl.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 4cf93c26e..4ecbf51b5 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -444,7 +444,6 @@ bool NixRepl::processLine(string line) else if (command == ":d" || command == ":debug") { if (arg == "stack") { - std::cout << "eval stack:" << std::endl; for (auto iter = this->state->debugTraces.begin(); iter != this->state->debugTraces.end(); ++iter) { std::cout << "\n" << "… " << iter->hint.str() << "\n"; @@ -463,7 +462,6 @@ bool NixRepl::processLine(string line) } } } else if (arg == "env") { - std::cout << "env stack:" << std::endl; auto iter = this->state->debugTraces.begin(); if (iter != this->state->debugTraces.end()) { printStaticEnvBindings(iter->expr); -- cgit v1.2.3 From 84aeb74377ce41408680256813870271999e8208 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 5 Jan 2022 14:25:45 -0700 Subject: revert value-add --- src/libcmd/repl.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 4ecbf51b5..57463bd79 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -641,9 +641,9 @@ bool NixRepl::processLine(string line) isVarName(name = removeWhitespace(string(line, 0, p)))) { Expr * e = parseString(string(line, p + 1)); - Value *v = new Value(*state->allocValue()); - v->mkThunk(env, e); - addVarToScope(state->symbols.create(name), *v); + Value & v(*state->allocValue()); + v.mkThunk(env, e); + addVarToScope(state->symbols.create(name), v); } else { Value v; evalString(line, v); -- cgit v1.2.3 From c51b527c280ee08b3ce3ca6d229139c4292b3176 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 7 Jan 2022 16:37:44 -0700 Subject: add env to DebugTrace --- src/libcmd/repl.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 57463bd79..fdd63621f 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -927,6 +927,7 @@ void runRepl( DebugTrace {.pos = debugError->info().errPos, .expr = expr, + .env = *repl->env, .hint = debugError->info().msg }); -- cgit v1.2.3 From a963674d88f2f1af6181f126ed4288ec65b61fc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 8 Jan 2022 11:03:48 -0700 Subject: optinoal error; compiles --- src/libcmd/repl.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index fdd63621f..e66cf4430 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -917,19 +917,23 @@ void runRepl( { auto repl = std::make_unique(evalState); - repl->debugError = debugError; + // repl->debugError = debugError; repl->initEnv(); - // tack on a final DebugTrace for the error position. - DebugTraceStacker ldts( - *evalState, - DebugTrace - {.pos = debugError->info().errPos, - .expr = expr, - .env = *repl->env, - .hint = debugError->info().msg - }); + // auto dts = debugError ? + // std::unique_ptr( + // // tack on a final DebugTrace for the error position. + // new DebugTraceStacker( + // *evalState, + // DebugTrace + // {.pos = debugError->info().errPos, + // .expr = expr, + // .env = *repl->env, + // .hint = debugError->info().msg + // }) + // ) + // : nullptr; // add 'extra' vars. std::set names; -- cgit v1.2.3 From 412d58f0bb65104b0065dbf721a92b9e5dcdcdbb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 3 Feb 2022 13:15:21 -0700 Subject: break() primop; step and go debug commands --- src/libcmd/repl.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index e66cf4430..5c14c7d3e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -439,7 +439,11 @@ bool NixRepl::processLine(string line) << " :d Debug mode commands\n" << " :d stack Show call 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") { @@ -476,6 +480,16 @@ bool NixRepl::processLine(string line) 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") { -- cgit v1.2.3 From e761bf0601a56db26c31891a3433c1319814fffa Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 14 Feb 2022 14:04:34 -0700 Subject: make an 'info' level error on break --- src/libcmd/repl.cc | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 51bbbbc57..db88aa9b6 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -931,24 +931,10 @@ void runRepl( { auto repl = std::make_unique(evalState); - // repl->debugError = debugError; + repl->debugError = debugError; repl->initEnv(); - // auto dts = debugError ? - // std::unique_ptr( - // // tack on a final DebugTrace for the error position. - // new DebugTraceStacker( - // *evalState, - // DebugTrace - // {.pos = debugError->info().errPos, - // .expr = expr, - // .env = *repl->env, - // .hint = debugError->info().msg - // }) - // ) - // : nullptr; - // add 'extra' vars. std::set names; for (auto & [name, value] : extraEnv) { -- cgit v1.2.3 From c9bc3735f639a4d022ab071feb5dabd451a0d016 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 15 Feb 2022 09:49:25 -0700 Subject: quit repl from step mode --- src/libcmd/repl.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index db88aa9b6..2b3dfcbd2 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -89,6 +89,7 @@ string removeWhitespace(string s) s = chomp(s); size_t n = s.find_first_not_of(" \n\r\t"); if (n != string::npos) s = string(s, n); + return s; } @@ -231,8 +232,12 @@ void NixRepl::mainLoop(const std::vector & files) // When continuing input from previous lines, don't print a prompt, just align to the same // number of chars as the prompt. if (!getLine(input, input.empty() ? "nix-repl> " : " ")) + { + // ctrl-D should exit the debugger. + state->debugStop = false; + state->debugQuit = true; break; - + } try { if (!removeWhitespace(input).empty() && !processLine(input)) return; } catch (ParseError & e) { @@ -464,12 +469,12 @@ bool NixRepl::processLine(string line) std::cout << "\n"; } } - } + } } else if (arg == "env") { auto iter = this->state->debugTraces.begin(); if (iter != this->state->debugTraces.end()) { printStaticEnvBindings(iter->expr); - } + } } else if (arg == "error") { if (this->debugError) { @@ -481,12 +486,12 @@ bool NixRepl::processLine(string line) } } else if (arg == "step") { - // set flag and exit repl. + // set flag to stop at next DebugTrace; exit repl. state->debugStop = true; return false; } 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; return false; } @@ -605,8 +610,11 @@ bool NixRepl::processLine(string line) 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; + } else if (command == ":doc") { Value v; @@ -944,7 +952,7 @@ void runRepl( } printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); - + repl->mainLoop({}); } -- cgit v1.2.3 From 14f515544bf7ea3c894fbc21d1393e69aa115784 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 28 Mar 2022 12:09:21 -0600 Subject: debugTraceIndex --- src/libcmd/repl.cc | 99 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 21 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 2b3dfcbd2..f0a8ef676 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -49,7 +49,8 @@ struct NixRepl ref state; Bindings * autoArgs; - const Error *debugError; + const Error *debugError; + int debugTraceIndex; Strings loadedFiles; @@ -96,6 +97,7 @@ string removeWhitespace(string s) NixRepl::NixRepl(ref state) : state(state) + , debugTraceIndex(0) , staticEnv(new StaticEnv(false, state->staticBaseEnv.get())) , historyFile(getDataDir() + "/nix/repl-history") { @@ -403,6 +405,28 @@ StorePath NixRepl::getDerivationPath(Value & v) { return drvPath; } +std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) +{ + if (dt.is_error) + out << ANSI_RED "error: " << ANSI_NORMAL; + out << dt.hint.str() << "\n"; + + if (dt.pos.has_value() && (*dt.pos)) { + auto pos = dt.pos.value(); + out << "\n"; + printAtPos(pos, out); + + auto loc = getCodeLines(pos); + if (loc.has_value()) { + out << "\n"; + printCodeLines(out, "", pos, *loc); + out << "\n"; + } + } + + return out; +} + bool NixRepl::processLine(string line) { if (line == "") return true; @@ -444,7 +468,7 @@ bool NixRepl::processLine(string line) << " :d Debug mode commands\n" << " :d stack Show call stack\n" << " :d env Show env stack\n" - << " :d error Show current error\n" + << " :d show Show current trace, or change to call stack index\n" << " :d go Go until end of program, exception, or builtins.break().\n" << " :d step Go one step\n" ; @@ -453,30 +477,63 @@ bool NixRepl::processLine(string line) else if (command == ":d" || command == ":debug") { if (arg == "stack") { + int idx = 0; for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); ++iter) { - std::cout << "\n" << "… " << iter->hint.str() << "\n"; - - if (iter->pos.has_value() && (*iter->pos)) { - auto pos = iter->pos.value(); - std::cout << "\n"; - printAtPos(pos, std::cout); - - auto loc = getCodeLines(pos); - if (loc.has_value()) { - std::cout << "\n"; - printCodeLines(std::cout, "", pos, *loc); - std::cout << "\n"; - } - } - } + iter != this->state->debugTraces.end(); + ++iter, ++idx) { + std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + showDebugTrace(std::cout, *iter); + } } else if (arg == "env") { - auto iter = this->state->debugTraces.begin(); - if (iter != this->state->debugTraces.end()) { - printStaticEnvBindings(iter->expr); + int idx = 0; + for (auto iter = this->state->debugTraces.begin(); + iter != this->state->debugTraces.end(); + ++iter, ++idx) { + if (idx == this->debugTraceIndex) + { + // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + printStaticEnvBindings(iter->expr); + break; + } + // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + // showDebugTrace(std::cout, *iter); + } + + // auto iter = this->state->debugTraces.begin(); + // if (iter != this->state->debugTraces.end()) { + // printStaticEnvBindings(iter->expr); + // } + } + else if (arg.compare(0,4,"show") == 0) { + try { + // change the DebugTrace index. + debugTraceIndex = stoi(arg.substr(4)); + + // std::cout << "idx: " << idx << std::endl; + // debugTraceIndex = idx; + + } + catch (...) + { + debugTraceIndex = 0; + } + + int idx = 0; + for (auto iter = this->state->debugTraces.begin(); + iter != this->state->debugTraces.end(); + ++iter, ++idx) { + if (idx == this->debugTraceIndex) + { + std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + showDebugTrace(std::cout, *iter); + break; + } + // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + // showDebugTrace(std::cout, *iter); } } else if (arg == "error") { + // TODO: remove, along with debugError. if (this->debugError) { showErrorInfo(std::cout, debugError->info(), true); } -- cgit v1.2.3 From 5ab7bdf0b14199da8423a8f2e433b2d6beef1e69 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 28 Mar 2022 15:28:59 -0600 Subject: load debug trace staticenv on 'show' --- src/libcmd/repl.cc | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index f0a8ef676..2e3a3b6df 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -78,6 +78,7 @@ struct NixRepl void addVarToScope(const Symbol & name, Value & v); Expr * parseString(string s); void evalString(string s, Value & v); + void loadDebugTraceEnv(DebugTrace &dt); typedef set ValuesSeen; std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth); @@ -427,6 +428,25 @@ std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) return out; } +void NixRepl::loadDebugTraceEnv(DebugTrace &dt) +{ + if (dt.expr.staticenv) + { + initEnv(); + + auto vm = std::make_unique(*(mapStaticEnvBindings(*dt.expr.staticenv.get(), dt.env))); + + // add staticenv vars. + for (auto & [name, value] : *(vm.get())) { + this->addVarToScope(this->state->symbols.create(name), *value); + } + } + else + { + initEnv(); + } +} + bool NixRepl::processLine(string line) { if (line == "") return true; @@ -491,31 +511,18 @@ bool NixRepl::processLine(string line) ++iter, ++idx) { if (idx == this->debugTraceIndex) { - // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; printStaticEnvBindings(iter->expr); break; } - // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - // showDebugTrace(std::cout, *iter); } - - // auto iter = this->state->debugTraces.begin(); - // if (iter != this->state->debugTraces.end()) { - // printStaticEnvBindings(iter->expr); - // } } else if (arg.compare(0,4,"show") == 0) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg.substr(4)); - - // std::cout << "idx: " << idx << std::endl; - // debugTraceIndex = idx; - } catch (...) { - debugTraceIndex = 0; } int idx = 0; @@ -526,6 +533,8 @@ bool NixRepl::processLine(string line) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, *iter); + printStaticEnvBindings(iter->expr); + loadDebugTraceEnv(*iter); break; } // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; -- cgit v1.2.3 From 1096d17b65834a7e1ff29d1afdf09536cc9d7a8d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 31 Mar 2022 09:37:36 -0600 Subject: show 'with' bindings as well as static --- src/libcmd/repl.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 2e3a3b6df..5de4cdf76 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -511,7 +511,7 @@ bool NixRepl::processLine(string line) ++iter, ++idx) { if (idx == this->debugTraceIndex) { - printStaticEnvBindings(iter->expr); + printEnvBindings(iter->expr, iter->env); break; } } @@ -533,7 +533,7 @@ bool NixRepl::processLine(string line) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, *iter); - printStaticEnvBindings(iter->expr); + printEnvBindings(iter->expr, iter->env); loadDebugTraceEnv(*iter); break; } @@ -1010,14 +1010,14 @@ void runRepl( repl->initEnv(); // add 'extra' vars. - std::set names; + // std::set names; for (auto & [name, value] : extraEnv) { // names.insert(ANSI_BOLD + name + ANSI_NORMAL); - names.insert(name); + // names.insert(name); repl->addVarToScope(repl->state->symbols.create(name), *value); } - printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); + // printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); repl->mainLoop({}); } -- cgit v1.2.3 From 5cfd038bd8bcd65c45f08f6c3665cd49e6643714 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 6 Apr 2022 19:08:29 -0600 Subject: show expr pos if DebugTrace one is noPos --- src/libcmd/repl.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 5de4cdf76..416635f16 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -412,9 +412,11 @@ std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) out << ANSI_RED "error: " << ANSI_NORMAL; out << dt.hint.str() << "\n"; - if (dt.pos.has_value() && (*dt.pos)) { - auto pos = dt.pos.value(); - out << "\n"; + // prefer direct pos, but if noPos then try the expr. + auto pos = (*dt.pos ? *dt.pos : + (dt.expr.getPos() ? *dt.expr.getPos() : noPos)); + + if (pos) { printAtPos(pos, out); auto loc = getCodeLines(pos); -- cgit v1.2.3 From d29af88d58283293d919066acd792fafd5e60689 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 7 Apr 2022 11:17:57 -0600 Subject: newline before env --- src/libcmd/repl.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 416635f16..376aa35cd 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -535,6 +535,7 @@ bool NixRepl::processLine(string line) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, *iter); + std::cout << std::endl; printEnvBindings(iter->expr, iter->env); loadDebugTraceEnv(*iter); break; -- cgit v1.2.3 From d2ec9b4e15718e42720787140d7825dcbfd73249 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 7 Apr 2022 12:09:47 -0600 Subject: in debugger mode, print the current error when another repl returns. --- src/libcmd/repl.cc | 56 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 24 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 376aa35cd..31d0019d4 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -203,6 +203,30 @@ namespace { } } +std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) +{ + if (dt.is_error) + out << ANSI_RED "error: " << ANSI_NORMAL; + out << dt.hint.str() << "\n"; + + // prefer direct pos, but if noPos then try the expr. + auto pos = (*dt.pos ? *dt.pos : + (dt.expr.getPos() ? *dt.expr.getPos() : noPos)); + + if (pos) { + printAtPos(pos, out); + + auto loc = getCodeLines(pos); + if (loc.has_value()) { + out << "\n"; + printCodeLines(out, "", pos, *loc); + out << "\n"; + } + } + + return out; +} + void NixRepl::mainLoop(const std::vector & files) { string error = ANSI_RED "error:" ANSI_NORMAL " "; @@ -251,6 +275,14 @@ void NixRepl::mainLoop(const std::vector & files) } else { printMsg(lvlError, e.msg()); } + } catch (EvalError & e) { + // in debugger mode, an EvalError should trigger another repl session. + // when that session returns the exception will land here. No need to show it again; + // show the error for this repl session instead. + if (debuggerHook && !this->state->debugTraces.empty()) + showDebugTrace(std::cout, this->state->debugTraces.front()); + else + printMsg(lvlError, e.msg()); } catch (Error & e) { printMsg(lvlError, e.msg()); } catch (Interrupted & e) { @@ -406,30 +438,6 @@ StorePath NixRepl::getDerivationPath(Value & v) { return drvPath; } -std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) -{ - if (dt.is_error) - out << ANSI_RED "error: " << ANSI_NORMAL; - out << dt.hint.str() << "\n"; - - // prefer direct pos, but if noPos then try the expr. - auto pos = (*dt.pos ? *dt.pos : - (dt.expr.getPos() ? *dt.expr.getPos() : noPos)); - - if (pos) { - printAtPos(pos, out); - - auto loc = getCodeLines(pos); - if (loc.has_value()) { - out << "\n"; - printCodeLines(out, "", pos, *loc); - out << "\n"; - } - } - - return out; -} - void NixRepl::loadDebugTraceEnv(DebugTrace &dt) { if (dt.expr.staticenv) -- cgit v1.2.3 From b8b8ec710160cfd343a8fce33ec8734e23c98444 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 12:34:27 -0600 Subject: move throw to preverve Error type; turn off debugger for tryEval --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 3dd55e104..2e7974b5d 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -50,7 +50,7 @@ struct NixRepl ref state; Bindings * autoArgs; - const Error *debugError; + const Error *debugError; int debugTraceIndex; Strings loadedFiles; -- cgit v1.2.3 From a86c2a8481c5bedb992d7126bc342a34b9c4902e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 13:30:18 -0600 Subject: remove 'debugError', dead code --- src/libcmd/repl.cc | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 2e7974b5d..22a6439b4 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -50,7 +50,6 @@ struct NixRepl ref state; Bindings * autoArgs; - const Error *debugError; int debugTraceIndex; Strings loadedFiles; @@ -552,16 +551,6 @@ bool NixRepl::processLine(std::string line) // showDebugTrace(std::cout, *iter); } } - else if (arg == "error") { - // TODO: remove, along with debugError. - if (this->debugError) { - showErrorInfo(std::cout, debugError->info(), true); - } - else - { - notice("error information not available"); - } - } else if (arg == "step") { // set flag to stop at next DebugTrace; exit repl. state->debugStop = true; @@ -1024,26 +1013,18 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, - const Error *debugError, const Expr &expr, const std::map & extraEnv) { auto repl = std::make_unique(evalState); - repl->debugError = debugError; - repl->initEnv(); // add 'extra' vars. - // std::set names; for (auto & [name, value] : extraEnv) { - // names.insert(ANSI_BOLD + name + ANSI_NORMAL); - // names.insert(name); repl->addVarToScope(repl->state->symbols.create(name), *value); } - // printError(hintfmt("The following extra variables are in scope: %s\n", concatStringsSep(", ", names)).str()); - repl->mainLoop({}); } -- cgit v1.2.3 From 27d45f9eb3c151afed8a20f1adc1d4dd1a200f09 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 15:46:12 -0600 Subject: minor cleanup --- src/libcmd/repl.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 22a6439b4..edd74c993 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -547,8 +547,6 @@ bool NixRepl::processLine(std::string line) loadDebugTraceEnv(*iter); break; } - // std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - // showDebugTrace(std::cout, *iter); } } else if (arg == "step") { -- cgit v1.2.3 From 3aaf02839f1491e6d766661209904f74efde8970 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 16:22:27 -0600 Subject: trace stack, not call stack --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index edd74c993..07e433293 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -495,7 +495,7 @@ bool NixRepl::processLine(std::string line) << " :log Show logs for a derivation\n" << " :st [bool] Enable, disable or toggle showing traces for errors\n" << " :d Debug mode commands\n" - << " :d stack Show call stack\n" + << " :d stack Show trace stack\n" << " :d env Show env stack\n" << " :d show Show current trace, or change to call stack index\n" << " :d go Go until end of program, exception, or builtins.break().\n" -- cgit v1.2.3 From f5757a0804e0278e1ad2ac7a46adeb3dc96ce034 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 16:34:20 -0600 Subject: revise command help --- src/libcmd/repl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 07e433293..5c25183cc 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -497,7 +497,8 @@ bool NixRepl::processLine(std::string line) << " :d Debug mode commands\n" << " :d stack Show trace stack\n" << " :d env Show env stack\n" - << " :d show Show current trace, or change to call stack index\n" + << " :d show Show current trace\n" + << " :d show Change to another trace in the stack\n" << " :d go Go until end of program, exception, or builtins.break().\n" << " :d step Go one step\n" ; -- cgit v1.2.3 From 2a5632c70dcb686a7764c23a5f330fcb9a33c8a1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 29 Apr 2022 10:02:17 -0600 Subject: incorporate PosIdx changes, symbol changes. --- src/libcmd/repl.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index d9ba7e7a4..40299e910 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -203,7 +203,7 @@ namespace { } } -std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) +std::ostream& showDebugTrace(std::ostream &out, const PosTable &positions, const DebugTrace &dt) { if (dt.is_error) out << ANSI_RED "error: " << ANSI_NORMAL; @@ -211,7 +211,7 @@ std::ostream& showDebugTrace(std::ostream &out, const DebugTrace &dt) // prefer direct pos, but if noPos then try the expr. auto pos = (*dt.pos ? *dt.pos : - (dt.expr.getPos() ? *dt.expr.getPos() : noPos)); + positions[(dt.expr.getPos() ? dt.expr.getPos() : noPos)]); if (pos) { printAtPos(pos, out); @@ -280,7 +280,7 @@ void NixRepl::mainLoop(const std::vector & files) // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. if (debuggerHook && !this->state->debugTraces.empty()) - showDebugTrace(std::cout, this->state->debugTraces.front()); + showDebugTrace(std::cout, this->state->positions, this->state->debugTraces.front()); else printMsg(lvlError, e.msg()); } catch (Error & e) { @@ -443,7 +443,7 @@ void NixRepl::loadDebugTraceEnv(DebugTrace &dt) { initEnv(); - auto vm = std::make_unique(*(mapStaticEnvBindings(*dt.expr.staticenv.get(), dt.env))); + auto vm = std::make_unique(*(mapStaticEnvBindings(this->state->symbols, *dt.expr.staticenv.get(), dt.env))); // add staticenv vars. for (auto & [name, value] : *(vm.get())) { @@ -514,7 +514,7 @@ bool NixRepl::processLine(std::string line) iter != this->state->debugTraces.end(); ++iter, ++idx) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, *iter); + showDebugTrace(std::cout, this->state->positions, *iter); } } else if (arg == "env") { int idx = 0; @@ -523,7 +523,7 @@ bool NixRepl::processLine(std::string line) ++iter, ++idx) { if (idx == this->debugTraceIndex) { - printEnvBindings(iter->expr, iter->env); + printEnvBindings(state->symbols,iter->expr, iter->env); break; } } @@ -544,9 +544,9 @@ bool NixRepl::processLine(std::string line) if (idx == this->debugTraceIndex) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, *iter); + showDebugTrace(std::cout, this->state->positions, *iter); std::cout << std::endl; - printEnvBindings(iter->expr, iter->env); + printEnvBindings(state->symbols,iter->expr, iter->env); loadDebugTraceEnv(*iter); break; } -- cgit v1.2.3 From 172a83d22a3c984b6b569b5528d2338059bb748b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 29 Apr 2022 11:24:54 -0600 Subject: line endings --- src/libcmd/repl.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 40299e910..b94831064 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -276,10 +276,10 @@ void NixRepl::mainLoop(const std::vector & files) printMsg(lvlError, e.msg()); } } catch (EvalError & e) { - // in debugger mode, an EvalError should trigger another repl session. + // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (debuggerHook && !this->state->debugTraces.empty()) + if (debuggerHook && !this->state->debugTraces.empty()) showDebugTrace(std::cout, this->state->positions, this->state->debugTraces.front()); else printMsg(lvlError, e.msg()); @@ -511,7 +511,7 @@ bool NixRepl::processLine(std::string line) if (arg == "stack") { int idx = 0; for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); + iter != this->state->debugTraces.end(); ++iter, ++idx) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, this->state->positions, *iter); @@ -519,7 +519,7 @@ bool NixRepl::processLine(std::string line) } else if (arg == "env") { int idx = 0; for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); + iter != this->state->debugTraces.end(); ++iter, ++idx) { if (idx == this->debugTraceIndex) { @@ -539,7 +539,7 @@ bool NixRepl::processLine(std::string line) int idx = 0; for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); + iter != this->state->debugTraces.end(); ++iter, ++idx) { if (idx == this->debugTraceIndex) { -- cgit v1.2.3 From dd8b91eebc0d31c9f8016609b36d89f58d8c4d19 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 5 May 2022 12:29:14 +0200 Subject: Style fixes In particular, use std::make_shared and enumerate(). Also renamed some fields to fit naming conventions. --- src/libcmd/repl.cc | 85 ++++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 53 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index b94831064..c35f29a2f 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -51,7 +51,7 @@ struct NixRepl ref state; Bindings * autoArgs; - int debugTraceIndex; + size_t debugTraceIndex; Strings loadedFiles; @@ -79,7 +79,7 @@ struct NixRepl void addVarToScope(const Symbol name, Value & v); Expr * parseString(std::string s); void evalString(std::string s, Value & v); - void loadDebugTraceEnv(DebugTrace &dt); + void loadDebugTraceEnv(DebugTrace & dt); typedef std::set ValuesSeen; std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth); @@ -203,15 +203,16 @@ namespace { } } -std::ostream& showDebugTrace(std::ostream &out, const PosTable &positions, const DebugTrace &dt) +static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positions, const DebugTrace & dt) { - if (dt.is_error) + if (dt.isError) out << ANSI_RED "error: " << ANSI_NORMAL; out << dt.hint.str() << "\n"; // prefer direct pos, but if noPos then try the expr. - auto pos = (*dt.pos ? *dt.pos : - positions[(dt.expr.getPos() ? dt.expr.getPos() : noPos)]); + auto pos = *dt.pos + ? *dt.pos + : positions[dt.expr.getPos() ? dt.expr.getPos() : noPos]; if (pos) { printAtPos(pos, out); @@ -258,8 +259,7 @@ void NixRepl::mainLoop(const std::vector & files) while (true) { // When continuing input from previous lines, don't print a prompt, just align to the same // 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; @@ -279,8 +279,8 @@ void NixRepl::mainLoop(const std::vector & files) // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (debuggerHook && !this->state->debugTraces.empty()) - showDebugTrace(std::cout, this->state->positions, this->state->debugTraces.front()); + if (debuggerHook && !state->debugTraces.empty()) + showDebugTrace(std::cout, state->positions, state->debugTraces.front()); else printMsg(lvlError, e.msg()); } catch (Error & e) { @@ -437,22 +437,16 @@ StorePath NixRepl::getDerivationPath(Value & v) { return *drvPath; } -void NixRepl::loadDebugTraceEnv(DebugTrace &dt) +void NixRepl::loadDebugTraceEnv(DebugTrace & dt) { - if (dt.expr.staticenv) - { - initEnv(); + initEnv(); - auto vm = std::make_unique(*(mapStaticEnvBindings(this->state->symbols, *dt.expr.staticenv.get(), dt.env))); + if (dt.expr.staticEnv) { + auto vm = mapStaticEnvBindings(state->symbols, *dt.expr.staticEnv.get(), dt.env); // add staticenv vars. - for (auto & [name, value] : *(vm.get())) { - this->addVarToScope(this->state->symbols.create(name), *value); - } - } - else - { - initEnv(); + for (auto & [name, value] : *(vm.get())) + addVarToScope(state->symbols.create(name), *value); } } @@ -509,45 +503,31 @@ bool NixRepl::processLine(std::string line) else if (command == ":d" || command == ":debug") { if (arg == "stack") { - int idx = 0; - for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); - ++iter, ++idx) { - std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, this->state->positions, *iter); + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + showDebugTrace(std::cout, state->positions, i); } } else if (arg == "env") { - int idx = 0; - for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); - ++iter, ++idx) { - if (idx == this->debugTraceIndex) - { - printEnvBindings(state->symbols,iter->expr, iter->env); - break; - } + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + if (idx == debugTraceIndex) { + printEnvBindings(state->symbols, i.expr, i.env); + break; + } } } - else if (arg.compare(0,4,"show") == 0) { + else if (arg.compare(0, 4, "show") == 0) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg.substr(4)); - } - catch (...) - { - } + } catch (...) { } - int idx = 0; - for (auto iter = this->state->debugTraces.begin(); - iter != this->state->debugTraces.end(); - ++iter, ++idx) { - if (idx == this->debugTraceIndex) - { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + if (idx == debugTraceIndex) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, this->state->positions, *iter); + showDebugTrace(std::cout, state->positions, i); std::cout << std::endl; - printEnvBindings(state->symbols,iter->expr, iter->env); - loadDebugTraceEnv(*iter); + printEnvBindings(state->symbols, i.expr, i.env); + loadDebugTraceEnv(i); break; } } @@ -1032,9 +1012,8 @@ void runRepl( repl->initEnv(); // add 'extra' vars. - for (auto & [name, value] : extraEnv) { + for (auto & [name, value] : extraEnv) repl->addVarToScope(repl->state->symbols.create(name), *value); - } repl->mainLoop({}); } -- cgit v1.2.3 From ce304d01544c799500bfffe48b7b0e85da888cd6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 5 May 2022 15:24:57 -0600 Subject: rename debug commands to be more gdb-like; hide them except in debug mode --- src/libcmd/repl.cc | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index c35f29a2f..37e454b21 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -484,30 +484,38 @@ bool NixRepl::processLine(std::string line) << " :p Evaluate and print expression recursively\n" << " :q Exit nix-repl\n" << " :r Reload all files\n" - << " :s Build dependencies of derivation, then start nix-shell\n" + << " :sh Build dependencies of derivation, then start nix-shell\n" << " :t Describe result of evaluation\n" << " :u Build derivation, then start nix-shell\n" << " :doc Show documentation of a builtin function\n" << " :log Show logs for a derivation\n" - << " :st [bool] Enable, disable or toggle showing traces for errors\n" - << " :d Debug mode commands\n" - << " :d stack Show trace stack\n" - << " :d env Show env stack\n" - << " :d show Show current trace\n" - << " :d show Change to another trace in the stack\n" - << " :d go Go until end of program, exception, or builtins.break().\n" - << " :d step Go one step\n" + << " :te [bool] Enable, disable or toggle showing traces for errors\n" ; + if (debuggerHook) { + std::cout + << "\n" + << " Debug mode commands\n" + << " :env Show env stack\n" + << " :bt Show trace stack\n" + << " :st Show current trace\n" + << " :st Change to another trace in the stack\n" + << " :c Go until end of program, exception, or builtins.break().\n" + << " :s Go one step\n" + ; + } } - else if (command == ":d" || command == ":debug") { - if (arg == "stack") { + else if (debuggerHook) { + + if (command == ":bt" || command == ":backtrace") { for (const auto & [idx, i] : enumerate(state->debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, state->positions, i); } - } else if (arg == "env") { + } + + else if (command == ":env") { for (const auto & [idx, i] : enumerate(state->debugTraces)) { if (idx == debugTraceIndex) { printEnvBindings(state->symbols, i.expr, i.env); @@ -515,10 +523,11 @@ bool NixRepl::processLine(std::string line) } } } - else if (arg.compare(0, 4, "show") == 0) { + + else if (command == ":st") { try { // change the DebugTrace index. - debugTraceIndex = stoi(arg.substr(4)); + debugTraceIndex = stoi(arg); } catch (...) { } for (const auto & [idx, i] : enumerate(state->debugTraces)) { @@ -532,12 +541,14 @@ bool NixRepl::processLine(std::string line) } } } - else if (arg == "step") { + + else if (command == ":s" || command == ":step") { // set flag to stop at next DebugTrace; exit repl. state->debugStop = true; return false; } - else if (arg == "go") { + + else if (command == ":c" || command == ":continue") { // set flag to run to next breakpoint or end of program; exit repl. state->debugStop = false; return false; @@ -613,7 +624,7 @@ bool NixRepl::processLine(std::string line) runNix("nix-shell", {state->store->printStorePath(drvPath)}); } - else if (command == ":b" || command == ":bl" || command == ":i" || command == ":s" || command == ":log") { + else if (command == ":b" || command == ":bl" || command == ":i" || command == ":sh" || command == ":log") { Value v; evalString(arg, v); StorePath drvPath = getDerivationPath(v); @@ -703,7 +714,7 @@ bool NixRepl::processLine(std::string line) throw Error("value does not have documentation"); } - else if (command == ":st" || command == ":show-trace") { + else if (command == ":te" || command == ":trace-enable") { if (arg == "false" || (arg == "" && loggerSettings.showTrace)) { std::cout << "not showing error traces\n"; loggerSettings.showTrace = false; -- cgit v1.2.3 From dea998b2f29eaad67b3003550fcfdf9d31045d4c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 5 May 2022 20:26:10 -0600 Subject: traceable_allocator --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 37e454b21..950195572 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1016,7 +1016,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, const Expr &expr, - const std::map & extraEnv) + const ValMap & extraEnv) { auto repl = std::make_unique(evalState); -- cgit v1.2.3 From 99d69ac23faf06598ca0aabd61d22a575db848df Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 5 May 2022 21:23:03 -0600 Subject: fix repl bug --- src/libcmd/repl.cc | 75 ++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 950195572..8f0b1bfc0 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -506,53 +506,50 @@ bool NixRepl::processLine(std::string line) } - else if (debuggerHook) { - - if (command == ":bt" || command == ":backtrace") { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { - std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); - } + else if (debuggerHook && (command == ":bt" || command == ":backtrace")) { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + showDebugTrace(std::cout, state->positions, i); } + } - else if (command == ":env") { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { - if (idx == debugTraceIndex) { - printEnvBindings(state->symbols, i.expr, i.env); - break; - } + else if (debuggerHook && (command == ":env")) { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + if (idx == debugTraceIndex) { + printEnvBindings(state->symbols, i.expr, i.env); + break; } } + } - else if (command == ":st") { - try { - // change the DebugTrace index. - debugTraceIndex = stoi(arg); - } catch (...) { } - - for (const auto & [idx, i] : enumerate(state->debugTraces)) { - if (idx == debugTraceIndex) { - std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); - std::cout << std::endl; - printEnvBindings(state->symbols, i.expr, i.env); - loadDebugTraceEnv(i); - break; - } - } + else if (debuggerHook && (command == ":st")) { + try { + // change the DebugTrace index. + debugTraceIndex = stoi(arg); + } catch (...) { } + + for (const auto & [idx, i] : enumerate(state->debugTraces)) { + if (idx == debugTraceIndex) { + std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; + showDebugTrace(std::cout, state->positions, i); + std::cout << std::endl; + printEnvBindings(state->symbols, i.expr, i.env); + loadDebugTraceEnv(i); + break; + } } + } - else if (command == ":s" || command == ":step") { - // set flag to stop at next DebugTrace; exit repl. - state->debugStop = true; - return false; - } + else if (debuggerHook && (command == ":s" || command == ":step")) { + // set flag to stop at next DebugTrace; exit repl. + state->debugStop = true; + return false; + } - else if (command == ":c" || command == ":continue") { - // set flag to run to next breakpoint or end of program; exit repl. - state->debugStop = false; - return false; - } + else if (debuggerHook && (command == ":c" || command == ":continue")) { + // set flag to run to next breakpoint or end of program; exit repl. + state->debugStop = false; + return false; } else if (command == ":a" || command == ":add") { -- cgit v1.2.3 From 6faa56ea1f7f8b708e8c931f41b627541a023c79 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 15 May 2022 12:05:34 -0600 Subject: remove extra argument --- src/libcmd/repl.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 8f0b1bfc0..deac3d408 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1012,7 +1012,6 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, - const Expr &expr, const ValMap & extraEnv) { auto repl = std::make_unique(evalState); -- cgit v1.2.3 From 667074b5867ffe40e3f1c59bd8e4ebf259f86aaa Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 16 May 2022 09:20:51 -0600 Subject: first whack at passing evalState as an arg to debuggerHook. --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index deac3d408..cb5d5bb34 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1011,7 +1011,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m } void runRepl( - ref evalState, + EvalState& evalState, const ValMap & extraEnv) { auto repl = std::make_unique(evalState); -- cgit v1.2.3 From 357fb84dbaad0b056704915c6a43764cda63ee7f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 10:48:10 -0600 Subject: use an expr->StaticEnv table in evalState --- src/libcmd/repl.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index deac3d408..43c2ce65e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -441,8 +441,9 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt) { initEnv(); - if (dt.expr.staticEnv) { - auto vm = mapStaticEnvBindings(state->symbols, *dt.expr.staticEnv.get(), dt.env); + auto se = state->getStaticEnv(dt.expr); + if (se) { + auto vm = mapStaticEnvBindings(state->symbols, *se.get(), dt.env); // add staticenv vars. for (auto & [name, value] : *(vm.get())) @@ -516,7 +517,7 @@ bool NixRepl::processLine(std::string line) else if (debuggerHook && (command == ":env")) { for (const auto & [idx, i] : enumerate(state->debugTraces)) { if (idx == debugTraceIndex) { - printEnvBindings(state->symbols, i.expr, i.env); + printEnvBindings(*state, i.expr, i.env); break; } } @@ -533,7 +534,7 @@ bool NixRepl::processLine(std::string line) std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, state->positions, i); std::cout << std::endl; - printEnvBindings(state->symbols, i.expr, i.env); + printEnvBindings(*state, i.expr, i.env); loadDebugTraceEnv(i); break; } -- cgit v1.2.3 From 7ddef73d026d79adc0c4f3fd1518d88d1331c38c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 12:44:40 -0600 Subject: de-const evalState exceptions --- src/libcmd/repl.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 5b17f2fb2..5aecf3ac3 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -96,6 +96,7 @@ std::string removeWhitespace(std::string s) } +// NixRepl::NixRepl(ref state) NixRepl::NixRepl(ref state) : state(state) , debugTraceIndex(0) @@ -1012,7 +1013,8 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m } void runRepl( - EvalState& evalState, + ref evalState, + // EvalState& evalState, const ValMap & extraEnv) { auto repl = std::make_unique(evalState); -- cgit v1.2.3 From 0600df86b8bc59633457f7ceb79e84c8ea3fed17 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 17:01:23 -0600 Subject: 'debugMode' --- src/libcmd/repl.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 5aecf3ac3..6bf23cc61 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -280,7 +280,7 @@ void NixRepl::mainLoop(const std::vector & files) // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (debuggerHook && !state->debugTraces.empty()) + if (state->debugMode && !state->debugTraces.empty()) showDebugTrace(std::cout, state->positions, state->debugTraces.front()); else printMsg(lvlError, e.msg()); @@ -493,7 +493,7 @@ bool NixRepl::processLine(std::string line) << " :log Show logs for a derivation\n" << " :te [bool] Enable, disable or toggle showing traces for errors\n" ; - if (debuggerHook) { + if (state->debugMode) { std::cout << "\n" << " Debug mode commands\n" @@ -508,14 +508,14 @@ bool NixRepl::processLine(std::string line) } - else if (debuggerHook && (command == ":bt" || command == ":backtrace")) { + else if (state->debugMode && (command == ":bt" || command == ":backtrace")) { for (const auto & [idx, i] : enumerate(state->debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, state->positions, i); } } - else if (debuggerHook && (command == ":env")) { + else if (state->debugMode && (command == ":env")) { for (const auto & [idx, i] : enumerate(state->debugTraces)) { if (idx == debugTraceIndex) { printEnvBindings(*state, i.expr, i.env); @@ -524,7 +524,7 @@ bool NixRepl::processLine(std::string line) } } - else if (debuggerHook && (command == ":st")) { + else if (state->debugMode && (command == ":st")) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg); @@ -542,13 +542,13 @@ bool NixRepl::processLine(std::string line) } } - else if (debuggerHook && (command == ":s" || command == ":step")) { + else if (state->debugMode && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. state->debugStop = true; return false; } - else if (debuggerHook && (command == ":c" || command == ":continue")) { + else if (state->debugMode && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. state->debugStop = false; return false; -- cgit v1.2.3 From 34ffaa9f5786fafa68c55bae99c5512506f7f0db Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 22 May 2022 18:57:45 -0600 Subject: changning repl to use EvalState& instead of ref --- src/libcmd/repl.cc | 145 +++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 72 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 43c2ce65e..7b9ad9d71 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -48,7 +48,8 @@ struct NixRepl #endif { std::string curDir; - ref state; + EvalState &state; + // ref state; Bindings * autoArgs; size_t debugTraceIndex; @@ -63,7 +64,7 @@ struct NixRepl const Path historyFile; - NixRepl(ref state); + NixRepl(EvalState &state); ~NixRepl(); void mainLoop(const std::vector & files); StringSet completePrefix(const std::string & prefix); @@ -96,10 +97,10 @@ std::string removeWhitespace(std::string s) } -NixRepl::NixRepl(ref state) +NixRepl::NixRepl(EvalState &state) : state(state) , debugTraceIndex(0) - , staticEnv(new StaticEnv(false, state->staticBaseEnv.get())) + , staticEnv(new StaticEnv(false, state.staticBaseEnv.get())) , historyFile(getDataDir() + "/nix/repl-history") { curDir = absPath("."); @@ -261,8 +262,8 @@ void NixRepl::mainLoop(const std::vector & files) // number of chars as the prompt. if (!getLine(input, input.empty() ? "nix-repl> " : " ")) { // ctrl-D should exit the debugger. - state->debugStop = false; - state->debugQuit = true; + state.debugStop = false; + state.debugQuit = true; break; } try { @@ -279,8 +280,8 @@ void NixRepl::mainLoop(const std::vector & files) // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (debuggerHook && !state->debugTraces.empty()) - showDebugTrace(std::cout, state->positions, state->debugTraces.front()); + if (debuggerHook && !state.debugTraces.empty()) + showDebugTrace(std::cout, state.positions, state.debugTraces.front()); else printMsg(lvlError, e.msg()); } catch (Error & e) { @@ -386,11 +387,11 @@ StringSet NixRepl::completePrefix(const std::string & prefix) Expr * e = parseString(expr); Value v; - e->eval(*state, *env, v); - state->forceAttrs(v, noPos); + e->eval(state, *env, v); + state.forceAttrs(v, noPos); for (auto & i : *v.attrs) { - std::string_view name = state->symbols[i.name]; + std::string_view name = state.symbols[i.name]; if (name.substr(0, cur2.size()) != cur2) continue; completions.insert(concatStrings(prev, expr, ".", name)); } @@ -426,14 +427,14 @@ static bool isVarName(std::string_view s) StorePath NixRepl::getDerivationPath(Value & v) { - auto drvInfo = getDerivation(*state, v, false); + auto drvInfo = getDerivation(state, v, false); if (!drvInfo) throw Error("expression does not evaluate to a derivation, so I can't build it"); auto drvPath = drvInfo->queryDrvPath(); if (!drvPath) throw Error("expression did not evaluate to a valid derivation (no 'drvPath' attribute)"); - if (!state->store->isValidPath(*drvPath)) - throw Error("expression evaluated to invalid derivation '%s'", state->store->printStorePath(*drvPath)); + if (!state.store->isValidPath(*drvPath)) + throw Error("expression evaluated to invalid derivation '%s'", state.store->printStorePath(*drvPath)); return *drvPath; } @@ -441,13 +442,13 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt) { initEnv(); - auto se = state->getStaticEnv(dt.expr); + auto se = state.getStaticEnv(dt.expr); if (se) { - auto vm = mapStaticEnvBindings(state->symbols, *se.get(), dt.env); + auto vm = mapStaticEnvBindings(state.symbols, *se.get(), dt.env); // add staticenv vars. for (auto & [name, value] : *(vm.get())) - addVarToScope(state->symbols.create(name), *value); + addVarToScope(state.symbols.create(name), *value); } } @@ -508,16 +509,16 @@ bool NixRepl::processLine(std::string line) } else if (debuggerHook && (command == ":bt" || command == ":backtrace")) { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); + showDebugTrace(std::cout, state.positions, i); } } else if (debuggerHook && (command == ":env")) { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { if (idx == debugTraceIndex) { - printEnvBindings(*state, i.expr, i.env); + printEnvBindings(state, i.expr, i.env); break; } } @@ -529,12 +530,12 @@ bool NixRepl::processLine(std::string line) debugTraceIndex = stoi(arg); } catch (...) { } - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { if (idx == debugTraceIndex) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); + showDebugTrace(std::cout, state.positions, i); std::cout << std::endl; - printEnvBindings(*state, i.expr, i.env); + printEnvBindings(state, i.expr, i.env); loadDebugTraceEnv(i); break; } @@ -543,13 +544,13 @@ bool NixRepl::processLine(std::string line) else if (debuggerHook && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. - state->debugStop = true; + state.debugStop = true; return false; } else if (debuggerHook && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. - state->debugStop = false; + state.debugStop = false; return false; } @@ -560,7 +561,7 @@ bool NixRepl::processLine(std::string line) } else if (command == ":l" || command == ":load") { - state->resetFileCache(); + state.resetFileCache(); loadFile(arg); } @@ -569,7 +570,7 @@ bool NixRepl::processLine(std::string line) } else if (command == ":r" || command == ":reload") { - state->resetFileCache(); + state.resetFileCache(); reloadFiles(); } @@ -580,15 +581,15 @@ bool NixRepl::processLine(std::string line) const auto [file, line] = [&] () -> std::pair { if (v.type() == nPath || v.type() == nString) { PathSet context; - auto filename = state->coerceToString(noPos, v, context).toOwned(); - state->symbols.create(filename); + auto filename = state.coerceToString(noPos, v, context).toOwned(); + state.symbols.create(filename); return {filename, 0}; } else if (v.isLambda()) { - auto pos = state->positions[v.lambda.fun->pos]; + auto pos = state.positions[v.lambda.fun->pos]; return {pos.file, pos.line}; } else { // assume it's a derivation - return findPackageFilename(*state, v, arg); + return findPackageFilename(state, v, arg); } }(); @@ -602,7 +603,7 @@ bool NixRepl::processLine(std::string line) runProgram2(RunOptions { .program = editor, .searchPath = true, .args = args }); // Reload right after exiting the editor - state->resetFileCache(); + state.resetFileCache(); reloadFiles(); } @@ -616,30 +617,30 @@ bool NixRepl::processLine(std::string line) Value v, f, result; evalString(arg, v); evalString("drv: (import {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); - state->callFunction(f, v, result, PosIdx()); + state.callFunction(f, v, result, PosIdx()); StorePath drvPath = getDerivationPath(result); - runNix("nix-shell", {state->store->printStorePath(drvPath)}); + runNix("nix-shell", {state.store->printStorePath(drvPath)}); } else if (command == ":b" || command == ":bl" || command == ":i" || command == ":sh" || command == ":log") { Value v; evalString(arg, v); StorePath drvPath = getDerivationPath(v); - Path drvPathRaw = state->store->printStorePath(drvPath); + Path drvPathRaw = state.store->printStorePath(drvPath); if (command == ":b" || command == ":bl") { - state->store->buildPaths({DerivedPath::Built{drvPath}}); - auto drv = state->store->readDerivation(drvPath); + state.store->buildPaths({DerivedPath::Built{drvPath}}); + auto drv = state.store->readDerivation(drvPath); logger->cout("\nThis derivation produced the following outputs:"); - for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) { - auto localStore = state->store.dynamic_pointer_cast(); + for (auto & [outputName, outputPath] : state.store->queryDerivationOutputMap(drvPath)) { + auto localStore = state.store.dynamic_pointer_cast(); if (localStore && command == ":bl") { std::string symlink = "repl-result-" + outputName; localStore->addPermRoot(outputPath, absPath(symlink)); - logger->cout(" ./%s -> %s", symlink, state->store->printStorePath(outputPath)); + logger->cout(" ./%s -> %s", symlink, state.store->printStorePath(outputPath)); } else { - logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath)); + logger->cout(" %s -> %s", outputName, state.store->printStorePath(outputPath)); } } } else if (command == ":i") { @@ -651,7 +652,7 @@ bool NixRepl::processLine(std::string line) }); auto subs = getDefaultSubstituters(); - subs.push_front(state->store); + subs.push_front(state.store); bool foundLog = false; RunPager pager; @@ -684,15 +685,15 @@ bool NixRepl::processLine(std::string line) } else if (command == ":q" || command == ":quit") { - state->debugStop = false; - state->debugQuit = true; + state.debugStop = false; + state.debugQuit = true; return false; } else if (command == ":doc") { Value v; evalString(arg, v); - if (auto doc = state->getDoc(v)) { + if (auto doc = state.getDoc(v)) { std::string markdown; if (!doc->args.empty() && doc->name) { @@ -736,9 +737,9 @@ bool NixRepl::processLine(std::string line) isVarName(name = removeWhitespace(line.substr(0, p)))) { Expr * e = parseString(line.substr(p + 1)); - Value & v(*state->allocValue()); + Value & v(*state.allocValue()); v.mkThunk(env, e); - addVarToScope(state->symbols.create(name), v); + addVarToScope(state.symbols.create(name), v); } else { Value v; evalString(line, v); @@ -755,8 +756,8 @@ void NixRepl::loadFile(const Path & path) loadedFiles.remove(path); loadedFiles.push_back(path); Value v, v2; - state->evalFile(lookupFileArg(*state, path), v); - state->autoCallFunction(*autoArgs, v, v2); + state.evalFile(lookupFileArg(state, path), v); + state.autoCallFunction(*autoArgs, v, v2); addAttrsToScope(v2); } @@ -771,8 +772,8 @@ void NixRepl::loadFlake(const std::string & flakeRefS) Value v; - flake::callFlake(*state, - flake::lockFlake(*state, flakeRef, + flake::callFlake(state, + flake::lockFlake(state, flakeRef, flake::LockFlags { .updateLockFile = false, .useRegistries = !evalSettings.pureEval, @@ -785,14 +786,14 @@ void NixRepl::loadFlake(const std::string & flakeRefS) void NixRepl::initEnv() { - env = &state->allocEnv(envSize); - env->up = &state->baseEnv; + env = &state.allocEnv(envSize); + env->up = &state.baseEnv; displ = 0; staticEnv->vars.clear(); varNames.clear(); - for (auto & i : state->staticBaseEnv->vars) - varNames.emplace(state->symbols[i.first]); + for (auto & i : state.staticBaseEnv->vars) + varNames.emplace(state.symbols[i.first]); } @@ -821,14 +822,14 @@ void NixRepl::loadFiles() void NixRepl::addAttrsToScope(Value & attrs) { - state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }); + state.forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }); if (displ + attrs.attrs->size() >= envSize) throw Error("environment full; cannot add more variables"); for (auto & i : *attrs.attrs) { staticEnv->vars.emplace_back(i.name, displ); env->values[displ++] = i.value; - varNames.emplace(state->symbols[i.name]); + varNames.emplace(state.symbols[i.name]); } staticEnv->sort(); staticEnv->deduplicate(); @@ -845,13 +846,13 @@ void NixRepl::addVarToScope(const Symbol name, Value & v) staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); env->values[displ++] = &v; - varNames.emplace(state->symbols[name]); + varNames.emplace(state.symbols[name]); } Expr * NixRepl::parseString(std::string s) { - Expr * e = state->parseExprFromString(std::move(s), curDir, staticEnv); + Expr * e = state.parseExprFromString(std::move(s), curDir, staticEnv); return e; } @@ -859,8 +860,8 @@ Expr * NixRepl::parseString(std::string s) void NixRepl::evalString(std::string s, Value & v) { Expr * e = parseString(s); - e->eval(*state, *env, v); - state->forceValue(v, [&]() { return v.determinePos(noPos); }); + e->eval(state, *env, v); + state.forceValue(v, [&]() { return v.determinePos(noPos); }); } @@ -890,7 +891,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m str.flush(); checkInterrupt(); - state->forceValue(v, [&]() { return v.determinePos(noPos); }); + state.forceValue(v, [&]() { return v.determinePos(noPos); }); switch (v.type()) { @@ -919,14 +920,14 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m case nAttrs: { seen.insert(&v); - bool isDrv = state->isDerivation(v); + bool isDrv = state.isDerivation(v); if (isDrv) { str << "«derivation "; - Bindings::iterator i = v.attrs->find(state->sDrvPath); + Bindings::iterator i = v.attrs->find(state.sDrvPath); PathSet context; if (i != v.attrs->end()) - str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context)); + str << state.store->printStorePath(state.coerceToStorePath(i->pos, *i->value, context)); else str << "???"; str << "»"; @@ -938,7 +939,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m typedef std::map Sorted; Sorted sorted; for (auto & i : *v.attrs) - sorted.emplace(state->symbols[i.name], i.value); + sorted.emplace(state.symbols[i.name], i.value); for (auto & i : sorted) { if (isVarName(i.first)) @@ -988,7 +989,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m case nFunction: if (v.isLambda()) { std::ostringstream s; - s << state->positions[v.lambda.fun->pos]; + s << state.positions[v.lambda.fun->pos]; str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL; } else if (v.isPrimOp()) { str << ANSI_MAGENTA "«primop»" ANSI_NORMAL; @@ -1012,7 +1013,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m } void runRepl( - ref evalState, + EvalState &evalState, const ValMap & extraEnv) { auto repl = std::make_unique(evalState); @@ -1021,7 +1022,7 @@ void runRepl( // add 'extra' vars. for (auto & [name, value] : extraEnv) - repl->addVarToScope(repl->state->symbols.create(name), *value); + repl->addVarToScope(repl->state.symbols.create(name), *value); repl->mainLoop({}); } @@ -1057,8 +1058,8 @@ struct CmdRepl : StoreCommand, MixEvalArgs auto evalState = make_ref(searchPath, store); - auto repl = std::make_unique(evalState); - repl->autoArgs = getAutoArgs(*repl->state); + auto repl = std::make_unique(*evalState); + repl->autoArgs = getAutoArgs(repl->state); repl->initEnv(); repl->mainLoop(files); } -- cgit v1.2.3 From 13d02af0799f5d2f7a53825936d587e22edcacb6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 22 May 2022 21:45:24 -0600 Subject: remove redundant 'debugMode' flag --- src/libcmd/repl.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index d335a56cd..940a287c7 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -280,7 +280,7 @@ void NixRepl::mainLoop(const std::vector & files) // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (state.debugMode && !state.debugTraces.empty()) + if (state.debugRepl && !state.debugTraces.empty()) showDebugTrace(std::cout, state.positions, state.debugTraces.front()); else printMsg(lvlError, e.msg()); @@ -493,7 +493,7 @@ bool NixRepl::processLine(std::string line) << " :log Show logs for a derivation\n" << " :te [bool] Enable, disable or toggle showing traces for errors\n" ; - if (state.debugMode) { + if (state.debugRepl) { std::cout << "\n" << " Debug mode commands\n" @@ -508,14 +508,14 @@ bool NixRepl::processLine(std::string line) } - else if (state.debugMode && (command == ":bt" || command == ":backtrace")) { + else if (state.debugRepl && (command == ":bt" || command == ":backtrace")) { for (const auto & [idx, i] : enumerate(state.debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, state.positions, i); } } - else if (state.debugMode && (command == ":env")) { + else if (state.debugRepl && (command == ":env")) { for (const auto & [idx, i] : enumerate(state.debugTraces)) { if (idx == debugTraceIndex) { printEnvBindings(state, i.expr, i.env); @@ -524,7 +524,7 @@ bool NixRepl::processLine(std::string line) } } - else if (state.debugMode && (command == ":st")) { + else if (state.debugRepl && (command == ":st")) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg); @@ -542,13 +542,13 @@ bool NixRepl::processLine(std::string line) } } - else if (state.debugMode && (command == ":s" || command == ":step")) { + else if (state.debugRepl && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. state.debugStop = true; return false; } - else if (state.debugMode && (command == ":c" || command == ":continue")) { + else if (state.debugRepl && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. state.debugStop = false; return false; -- cgit v1.2.3 From ba035f7dd03232d093a1265778b9587bab92cf1d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 23 May 2022 10:13:47 -0600 Subject: comment --- src/libcmd/repl.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 940a287c7..d7201b321 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -49,7 +49,6 @@ struct NixRepl { std::string curDir; EvalState &state; - // ref state; Bindings * autoArgs; size_t debugTraceIndex; -- cgit v1.2.3 From 91b7d5373acdc5d9b3f2c13d16b9850ab5fc9e9d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 25 May 2022 12:32:22 +0200 Subject: Style tweaks --- src/libcmd/repl.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index d7201b321..7d8bbdb7e 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -48,7 +48,7 @@ struct NixRepl #endif { std::string curDir; - EvalState &state; + EvalState & state; Bindings * autoArgs; size_t debugTraceIndex; @@ -63,11 +63,11 @@ struct NixRepl const Path historyFile; - NixRepl(EvalState &state); + NixRepl(EvalState & state); ~NixRepl(); void mainLoop(const std::vector & files); StringSet completePrefix(const std::string & prefix); - bool getLine(std::string & input, const std::string &prompt); + bool getLine(std::string & input, const std::string & prompt); StorePath getDerivationPath(Value & v); bool processLine(std::string line); void loadFile(const Path & path); @@ -96,7 +96,7 @@ std::string removeWhitespace(std::string s) } -NixRepl::NixRepl(EvalState &state) +NixRepl::NixRepl(EvalState & state) : state(state) , debugTraceIndex(0) , staticEnv(new StaticEnv(false, state.staticBaseEnv.get())) -- cgit v1.2.3 From b4c24a29c62259a068c8270be62cf5a412e1e35c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 May 2022 10:21:20 -0600 Subject: back to ref in NixRepl --- src/libcmd/repl.cc | 156 ++++++++++++++++++++++++++--------------------------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 7d8bbdb7e..993dcd634 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -48,7 +48,7 @@ struct NixRepl #endif { std::string curDir; - EvalState & state; + ref state; Bindings * autoArgs; size_t debugTraceIndex; @@ -63,7 +63,7 @@ struct NixRepl const Path historyFile; - NixRepl(EvalState & state); + NixRepl(ref state); ~NixRepl(); void mainLoop(const std::vector & files); StringSet completePrefix(const std::string & prefix); @@ -96,10 +96,10 @@ std::string removeWhitespace(std::string s) } -NixRepl::NixRepl(EvalState & state) +NixRepl::NixRepl(ref state) : state(state) , debugTraceIndex(0) - , staticEnv(new StaticEnv(false, state.staticBaseEnv.get())) + , staticEnv(new StaticEnv(false, state->staticBaseEnv.get())) , historyFile(getDataDir() + "/nix/repl-history") { curDir = absPath("."); @@ -261,8 +261,8 @@ void NixRepl::mainLoop(const std::vector & files) // number of chars as the prompt. if (!getLine(input, input.empty() ? "nix-repl> " : " ")) { // ctrl-D should exit the debugger. - state.debugStop = false; - state.debugQuit = true; + state->debugStop = false; + state->debugQuit = true; break; } try { @@ -279,8 +279,8 @@ void NixRepl::mainLoop(const std::vector & files) // in debugger mode, an EvalError should trigger another repl session. // when that session returns the exception will land here. No need to show it again; // show the error for this repl session instead. - if (state.debugRepl && !state.debugTraces.empty()) - showDebugTrace(std::cout, state.positions, state.debugTraces.front()); + if (state->debugRepl && !state->debugTraces.empty()) + showDebugTrace(std::cout, state->positions, state->debugTraces.front()); else printMsg(lvlError, e.msg()); } catch (Error & e) { @@ -386,11 +386,11 @@ StringSet NixRepl::completePrefix(const std::string & prefix) Expr * e = parseString(expr); Value v; - e->eval(state, *env, v); - state.forceAttrs(v, noPos); + e->eval(*state, *env, v); + state->forceAttrs(v, noPos); for (auto & i : *v.attrs) { - std::string_view name = state.symbols[i.name]; + std::string_view name = state->symbols[i.name]; if (name.substr(0, cur2.size()) != cur2) continue; completions.insert(concatStrings(prev, expr, ".", name)); } @@ -426,14 +426,14 @@ static bool isVarName(std::string_view s) StorePath NixRepl::getDerivationPath(Value & v) { - auto drvInfo = getDerivation(state, v, false); + auto drvInfo = getDerivation(*state, v, false); if (!drvInfo) throw Error("expression does not evaluate to a derivation, so I can't build it"); auto drvPath = drvInfo->queryDrvPath(); if (!drvPath) throw Error("expression did not evaluate to a valid derivation (no 'drvPath' attribute)"); - if (!state.store->isValidPath(*drvPath)) - throw Error("expression evaluated to invalid derivation '%s'", state.store->printStorePath(*drvPath)); + if (!state->store->isValidPath(*drvPath)) + throw Error("expression evaluated to invalid derivation '%s'", state->store->printStorePath(*drvPath)); return *drvPath; } @@ -441,13 +441,13 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt) { initEnv(); - auto se = state.getStaticEnv(dt.expr); + auto se = state->getStaticEnv(dt.expr); if (se) { - auto vm = mapStaticEnvBindings(state.symbols, *se.get(), dt.env); + auto vm = mapStaticEnvBindings(state->symbols, *se.get(), dt.env); // add staticenv vars. for (auto & [name, value] : *(vm.get())) - addVarToScope(state.symbols.create(name), *value); + addVarToScope(state->symbols.create(name), *value); } } @@ -492,7 +492,7 @@ bool NixRepl::processLine(std::string line) << " :log Show logs for a derivation\n" << " :te [bool] Enable, disable or toggle showing traces for errors\n" ; - if (state.debugRepl) { + if (state->debugRepl) { std::cout << "\n" << " Debug mode commands\n" @@ -507,49 +507,49 @@ bool NixRepl::processLine(std::string line) } - else if (state.debugRepl && (command == ":bt" || command == ":backtrace")) { - for (const auto & [idx, i] : enumerate(state.debugTraces)) { + else if (state->debugRepl && (command == ":bt" || command == ":backtrace")) { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state.positions, i); + showDebugTrace(std::cout, state->positions, i); } } - else if (state.debugRepl && (command == ":env")) { - for (const auto & [idx, i] : enumerate(state.debugTraces)) { + else if (state->debugRepl && (command == ":env")) { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { if (idx == debugTraceIndex) { - printEnvBindings(state, i.expr, i.env); + printEnvBindings(*state, i.expr, i.env); break; } } } - else if (state.debugRepl && (command == ":st")) { + else if (state->debugRepl && (command == ":st")) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg); } catch (...) { } - for (const auto & [idx, i] : enumerate(state.debugTraces)) { + for (const auto & [idx, i] : enumerate(state->debugTraces)) { if (idx == debugTraceIndex) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state.positions, i); + showDebugTrace(std::cout, state->positions, i); std::cout << std::endl; - printEnvBindings(state, i.expr, i.env); + printEnvBindings(*state, i.expr, i.env); loadDebugTraceEnv(i); break; } } } - else if (state.debugRepl && (command == ":s" || command == ":step")) { + else if (state->debugRepl && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. - state.debugStop = true; + state->debugStop = true; return false; } - else if (state.debugRepl && (command == ":c" || command == ":continue")) { + else if (state->debugRepl && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. - state.debugStop = false; + state->debugStop = false; return false; } @@ -560,7 +560,7 @@ bool NixRepl::processLine(std::string line) } else if (command == ":l" || command == ":load") { - state.resetFileCache(); + state->resetFileCache(); loadFile(arg); } @@ -569,7 +569,7 @@ bool NixRepl::processLine(std::string line) } else if (command == ":r" || command == ":reload") { - state.resetFileCache(); + state->resetFileCache(); reloadFiles(); } @@ -580,15 +580,15 @@ bool NixRepl::processLine(std::string line) const auto [file, line] = [&] () -> std::pair { if (v.type() == nPath || v.type() == nString) { PathSet context; - auto filename = state.coerceToString(noPos, v, context).toOwned(); - state.symbols.create(filename); + auto filename = state->coerceToString(noPos, v, context).toOwned(); + state->symbols.create(filename); return {filename, 0}; } else if (v.isLambda()) { - auto pos = state.positions[v.lambda.fun->pos]; + auto pos = state->positions[v.lambda.fun->pos]; return {pos.file, pos.line}; } else { // assume it's a derivation - return findPackageFilename(state, v, arg); + return findPackageFilename(*state, v, arg); } }(); @@ -602,7 +602,7 @@ bool NixRepl::processLine(std::string line) runProgram2(RunOptions { .program = editor, .searchPath = true, .args = args }); // Reload right after exiting the editor - state.resetFileCache(); + state->resetFileCache(); reloadFiles(); } @@ -616,30 +616,30 @@ bool NixRepl::processLine(std::string line) Value v, f, result; evalString(arg, v); evalString("drv: (import {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); - state.callFunction(f, v, result, PosIdx()); + state->callFunction(f, v, result, PosIdx()); StorePath drvPath = getDerivationPath(result); - runNix("nix-shell", {state.store->printStorePath(drvPath)}); + runNix("nix-shell", {state->store->printStorePath(drvPath)}); } else if (command == ":b" || command == ":bl" || command == ":i" || command == ":sh" || command == ":log") { Value v; evalString(arg, v); StorePath drvPath = getDerivationPath(v); - Path drvPathRaw = state.store->printStorePath(drvPath); + Path drvPathRaw = state->store->printStorePath(drvPath); if (command == ":b" || command == ":bl") { - state.store->buildPaths({DerivedPath::Built{drvPath}}); - auto drv = state.store->readDerivation(drvPath); + state->store->buildPaths({DerivedPath::Built{drvPath}}); + auto drv = state->store->readDerivation(drvPath); logger->cout("\nThis derivation produced the following outputs:"); - for (auto & [outputName, outputPath] : state.store->queryDerivationOutputMap(drvPath)) { - auto localStore = state.store.dynamic_pointer_cast(); + for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) { + auto localStore = state->store.dynamic_pointer_cast(); if (localStore && command == ":bl") { std::string symlink = "repl-result-" + outputName; localStore->addPermRoot(outputPath, absPath(symlink)); - logger->cout(" ./%s -> %s", symlink, state.store->printStorePath(outputPath)); + logger->cout(" ./%s -> %s", symlink, state->store->printStorePath(outputPath)); } else { - logger->cout(" %s -> %s", outputName, state.store->printStorePath(outputPath)); + logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath)); } } } else if (command == ":i") { @@ -651,7 +651,7 @@ bool NixRepl::processLine(std::string line) }); auto subs = getDefaultSubstituters(); - subs.push_front(state.store); + subs.push_front(state->store); bool foundLog = false; RunPager pager; @@ -684,15 +684,15 @@ bool NixRepl::processLine(std::string line) } else if (command == ":q" || command == ":quit") { - state.debugStop = false; - state.debugQuit = true; + state->debugStop = false; + state->debugQuit = true; return false; } else if (command == ":doc") { Value v; evalString(arg, v); - if (auto doc = state.getDoc(v)) { + if (auto doc = state->getDoc(v)) { std::string markdown; if (!doc->args.empty() && doc->name) { @@ -736,9 +736,9 @@ bool NixRepl::processLine(std::string line) isVarName(name = removeWhitespace(line.substr(0, p)))) { Expr * e = parseString(line.substr(p + 1)); - Value & v(*state.allocValue()); + Value & v(*state->allocValue()); v.mkThunk(env, e); - addVarToScope(state.symbols.create(name), v); + addVarToScope(state->symbols.create(name), v); } else { Value v; evalString(line, v); @@ -755,8 +755,8 @@ void NixRepl::loadFile(const Path & path) loadedFiles.remove(path); loadedFiles.push_back(path); Value v, v2; - state.evalFile(lookupFileArg(state, path), v); - state.autoCallFunction(*autoArgs, v, v2); + state->evalFile(lookupFileArg(*state, path), v); + state->autoCallFunction(*autoArgs, v, v2); addAttrsToScope(v2); } @@ -771,8 +771,8 @@ void NixRepl::loadFlake(const std::string & flakeRefS) Value v; - flake::callFlake(state, - flake::lockFlake(state, flakeRef, + flake::callFlake(*state, + flake::lockFlake(*state, flakeRef, flake::LockFlags { .updateLockFile = false, .useRegistries = !evalSettings.pureEval, @@ -785,14 +785,14 @@ void NixRepl::loadFlake(const std::string & flakeRefS) void NixRepl::initEnv() { - env = &state.allocEnv(envSize); - env->up = &state.baseEnv; + env = &state->allocEnv(envSize); + env->up = &state->baseEnv; displ = 0; staticEnv->vars.clear(); varNames.clear(); - for (auto & i : state.staticBaseEnv->vars) - varNames.emplace(state.symbols[i.first]); + for (auto & i : state->staticBaseEnv->vars) + varNames.emplace(state->symbols[i.first]); } @@ -821,14 +821,14 @@ void NixRepl::loadFiles() void NixRepl::addAttrsToScope(Value & attrs) { - state.forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }); + state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }); if (displ + attrs.attrs->size() >= envSize) throw Error("environment full; cannot add more variables"); for (auto & i : *attrs.attrs) { staticEnv->vars.emplace_back(i.name, displ); env->values[displ++] = i.value; - varNames.emplace(state.symbols[i.name]); + varNames.emplace(state->symbols[i.name]); } staticEnv->sort(); staticEnv->deduplicate(); @@ -845,13 +845,13 @@ void NixRepl::addVarToScope(const Symbol name, Value & v) staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); env->values[displ++] = &v; - varNames.emplace(state.symbols[name]); + varNames.emplace(state->symbols[name]); } Expr * NixRepl::parseString(std::string s) { - Expr * e = state.parseExprFromString(std::move(s), curDir, staticEnv); + Expr * e = state->parseExprFromString(std::move(s), curDir, staticEnv); return e; } @@ -859,8 +859,8 @@ Expr * NixRepl::parseString(std::string s) void NixRepl::evalString(std::string s, Value & v) { Expr * e = parseString(s); - e->eval(state, *env, v); - state.forceValue(v, [&]() { return v.determinePos(noPos); }); + e->eval(*state, *env, v); + state->forceValue(v, [&]() { return v.determinePos(noPos); }); } @@ -890,7 +890,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m str.flush(); checkInterrupt(); - state.forceValue(v, [&]() { return v.determinePos(noPos); }); + state->forceValue(v, [&]() { return v.determinePos(noPos); }); switch (v.type()) { @@ -919,14 +919,14 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m case nAttrs: { seen.insert(&v); - bool isDrv = state.isDerivation(v); + bool isDrv = state->isDerivation(v); if (isDrv) { str << "«derivation "; - Bindings::iterator i = v.attrs->find(state.sDrvPath); + Bindings::iterator i = v.attrs->find(state->sDrvPath); PathSet context; if (i != v.attrs->end()) - str << state.store->printStorePath(state.coerceToStorePath(i->pos, *i->value, context)); + str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context)); else str << "???"; str << "»"; @@ -938,7 +938,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m typedef std::map Sorted; Sorted sorted; for (auto & i : *v.attrs) - sorted.emplace(state.symbols[i.name], i.value); + sorted.emplace(state->symbols[i.name], i.value); for (auto & i : sorted) { if (isVarName(i.first)) @@ -988,7 +988,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m case nFunction: if (v.isLambda()) { std::ostringstream s; - s << state.positions[v.lambda.fun->pos]; + s << state->positions[v.lambda.fun->pos]; str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL; } else if (v.isPrimOp()) { str << ANSI_MAGENTA "«primop»" ANSI_NORMAL; @@ -1012,7 +1012,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m } void runRepl( - EvalState &evalState, + refevalState, const ValMap & extraEnv) { auto repl = std::make_unique(evalState); @@ -1021,7 +1021,7 @@ void runRepl( // add 'extra' vars. for (auto & [name, value] : extraEnv) - repl->addVarToScope(repl->state.symbols.create(name), *value); + repl->addVarToScope(repl->state->symbols.create(name), *value); repl->mainLoop({}); } @@ -1057,8 +1057,8 @@ struct CmdRepl : StoreCommand, MixEvalArgs auto evalState = make_ref(searchPath, store); - auto repl = std::make_unique(*evalState); - repl->autoArgs = getAutoArgs(repl->state); + auto repl = std::make_unique(evalState); + repl->autoArgs = getAutoArgs(*repl->state); repl->initEnv(); repl->mainLoop(files); } -- cgit v1.2.3 From 9068d32e12750542b59418501ce1bd3835e92400 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 May 2022 12:55:58 -0600 Subject: remove parens from repl help --- src/libcmd/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 993dcd634..458e824c5 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -500,7 +500,7 @@ bool NixRepl::processLine(std::string line) << " :bt Show trace stack\n" << " :st Show current trace\n" << " :st Change to another trace in the stack\n" - << " :c Go until end of program, exception, or builtins.break().\n" + << " :c Go until end of program, exception, or builtins.break\n" << " :s Go one step\n" ; } -- cgit v1.2.3 From 159b5815b527f466578a2d28fbf832617cc45b88 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 31 Jan 2022 18:03:24 +0100 Subject: repl: `--option pure-eval true` actually enables pure eval mode To quote Eelco in #5867: > Unfortunately we can't do > > evalSettings.pureEval.setDefault(false); > > because then we have to do the same in main.cc (where > pureEval is set to true), and that would allow pure-eval > to be disabled globally from nix.conf. Instead, a command should specify that it should be impure by default. Then, `evalSettings.pureEval` will be set to `false;` unless it's overridden by e.g. a CLI flag. In that case it's IMHO OK to be (theoretically) able to override `pure-eval` via `nix.conf` because it doesn't have an effect on commands where `forceImpureByDefault` returns `false` (i.e. everything where pure eval actually matters). Closes #5867 --- src/libcmd/repl.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 458e824c5..3c89a8ea3 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1039,6 +1039,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs }); } + bool forceImpureByDefault() override + { + return true; + } + std::string description() override { return "start an interactive environment for evaluating Nix expressions"; @@ -1053,8 +1058,6 @@ struct CmdRepl : StoreCommand, MixEvalArgs void run(ref store) override { - evalSettings.pureEval = false; - auto evalState = make_ref(searchPath, store); auto repl = std::make_unique(evalState); -- cgit v1.2.3 From c6f7726f48e83230246f9328115368547fe29f5f Mon Sep 17 00:00:00 2001 From: Dave Nicponski Date: Wed, 15 Jun 2022 12:49:12 -0400 Subject: Don't capture stdout when launching subshells in `nix repl` --- src/libcmd/repl.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 3c89a8ea3..588115a48 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -111,23 +111,20 @@ NixRepl::~NixRepl() write_history(historyFile.c_str()); } -std::string runNix(Path program, const Strings & args, +void runNix(Path program, const Strings & args, const std::optional & input = {}) { auto subprocessEnv = getEnv(); subprocessEnv["NIX_CONFIG"] = globalConfig.toKeyValue(); - auto res = runProgram(RunOptions { + runProgram2(RunOptions { .program = settings.nixBinDir+ "/" + program, .args = args, .environment = subprocessEnv, .input = input, }); - if (!statusOk(res.first)) - throw ExecError(res.first, "program '%1%' %2%", program, statusToString(res.first)); - - return res.second; + return; } static NixRepl * curRepl; // ugly -- cgit v1.2.3 From 0d2163c6dcf03463fa91ec6d0d96c928ad907366 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 22 Aug 2022 14:27:36 +0200 Subject: nix repl: Stop the progress bar The repl was broken since c3769c68465bae971ab6bb48cfcdea85b61ea83a. In general, the progress bar is incompatible with the repl. --- src/libcmd/repl.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/libcmd/repl.cc') diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 23df40337..150bd42ac 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -35,6 +35,7 @@ extern "C" { #include "finally.hh" #include "markdown.hh" #include "local-fs-store.hh" +#include "progress-bar.hh" #if HAVE_BOEHMGC #define GC_INCLUDE_NEW @@ -252,6 +253,10 @@ void NixRepl::mainLoop() rl_set_list_possib_func(listPossibleCallback); #endif + /* Stop the progress bar because it interferes with the display of + the repl. */ + stopProgressBar(); + std::string input; while (true) { @@ -1037,9 +1042,10 @@ void runRepl( struct CmdRepl : InstallablesCommand { - CmdRepl(){ + CmdRepl() { evalSettings.pureEval = false; } + void prepare() { if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && this->_installables.size() >= 1) { @@ -1053,12 +1059,15 @@ struct CmdRepl : InstallablesCommand } installables = InstallablesCommand::load(); } + std::vector files; + Strings getDefaultFlakeAttrPaths() override { return {""}; } - virtual bool useDefaultInstallables() override + + bool useDefaultInstallables() override { return file.has_value() or expr.has_value(); } -- cgit v1.2.3