forked from lix-project/lix
Style fixes
In particular, use std::make_shared and enumerate(). Also renamed some fields to fit naming conventions.
This commit is contained in:
parent
c98648bef0
commit
dd8b91eebc
|
@ -121,25 +121,23 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
if (startReplOnEvalErrors)
|
if (startReplOnEvalErrors)
|
||||||
debuggerHook = [evalState{ref<EvalState>(evalState)}](const Error * error, const Env & env, const Expr & expr) {
|
debuggerHook = [evalState{ref<EvalState>(evalState)}](const Error * error, const Env & env, const Expr & expr) {
|
||||||
auto dts =
|
auto dts =
|
||||||
error && expr.getPos() ?
|
error && expr.getPos()
|
||||||
std::unique_ptr<DebugTraceStacker>(
|
? std::make_unique<DebugTraceStacker>(
|
||||||
new DebugTraceStacker(
|
*evalState,
|
||||||
*evalState,
|
DebugTrace {
|
||||||
DebugTrace
|
.pos = error->info().errPos ? *error->info().errPos : evalState->positions[expr.getPos()],
|
||||||
{.pos = (error->info().errPos ? *error->info().errPos : evalState->positions[expr.getPos()]),
|
.expr = expr,
|
||||||
.expr = expr,
|
.env = env,
|
||||||
.env = env,
|
.hint = error->info().msg,
|
||||||
.hint = error->info().msg,
|
.isError = true
|
||||||
.is_error = true
|
})
|
||||||
}))
|
: nullptr;
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what());
|
printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what());
|
||||||
|
|
||||||
if (expr.staticenv)
|
if (expr.staticEnv) {
|
||||||
{
|
auto vm = mapStaticEnvBindings(evalState->symbols, *expr.staticEnv.get(), env);
|
||||||
std::unique_ptr<valmap> vm(mapStaticEnvBindings(evalState->symbols, *expr.staticenv.get(), env));
|
|
||||||
runRepl(evalState, expr, *vm);
|
runRepl(evalState, expr, *vm);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -275,6 +275,7 @@ void printClosureDiff(
|
||||||
|
|
||||||
void runRepl(
|
void runRepl(
|
||||||
ref<EvalState> evalState,
|
ref<EvalState> evalState,
|
||||||
const Expr &expr,
|
const Expr & expr,
|
||||||
const std::map<std::string, Value *> & extraEnv);
|
const std::map<std::string, Value *> & extraEnv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct NixRepl
|
||||||
ref<EvalState> state;
|
ref<EvalState> state;
|
||||||
Bindings * autoArgs;
|
Bindings * autoArgs;
|
||||||
|
|
||||||
int debugTraceIndex;
|
size_t debugTraceIndex;
|
||||||
|
|
||||||
Strings loadedFiles;
|
Strings loadedFiles;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ struct NixRepl
|
||||||
void addVarToScope(const Symbol name, Value & v);
|
void addVarToScope(const Symbol name, Value & v);
|
||||||
Expr * parseString(std::string s);
|
Expr * parseString(std::string s);
|
||||||
void evalString(std::string s, Value & v);
|
void evalString(std::string s, Value & v);
|
||||||
void loadDebugTraceEnv(DebugTrace &dt);
|
void loadDebugTraceEnv(DebugTrace & dt);
|
||||||
|
|
||||||
typedef std::set<Value *> ValuesSeen;
|
typedef std::set<Value *> ValuesSeen;
|
||||||
std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth);
|
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 << ANSI_RED "error: " << ANSI_NORMAL;
|
||||||
out << dt.hint.str() << "\n";
|
out << dt.hint.str() << "\n";
|
||||||
|
|
||||||
// prefer direct pos, but if noPos then try the expr.
|
// prefer direct pos, but if noPos then try the expr.
|
||||||
auto pos = (*dt.pos ? *dt.pos :
|
auto pos = *dt.pos
|
||||||
positions[(dt.expr.getPos() ? dt.expr.getPos() : noPos)]);
|
? *dt.pos
|
||||||
|
: positions[dt.expr.getPos() ? dt.expr.getPos() : noPos];
|
||||||
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
printAtPos(pos, out);
|
printAtPos(pos, out);
|
||||||
|
@ -258,8 +259,7 @@ void NixRepl::mainLoop(const std::vector<std::string> & files)
|
||||||
while (true) {
|
while (true) {
|
||||||
// When continuing input from previous lines, don't print a prompt, just align to the same
|
// When continuing input from previous lines, don't print a prompt, just align to the same
|
||||||
// number of chars as the prompt.
|
// number of chars as the prompt.
|
||||||
if (!getLine(input, input.empty() ? "nix-repl> " : " "))
|
if (!getLine(input, input.empty() ? "nix-repl> " : " ")) {
|
||||||
{
|
|
||||||
// ctrl-D should exit the debugger.
|
// ctrl-D should exit the debugger.
|
||||||
state->debugStop = false;
|
state->debugStop = false;
|
||||||
state->debugQuit = true;
|
state->debugQuit = true;
|
||||||
|
@ -279,8 +279,8 @@ void NixRepl::mainLoop(const std::vector<std::string> & files)
|
||||||
// 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;
|
// when that session returns the exception will land here. No need to show it again;
|
||||||
// show the error for this repl session instead.
|
// show the error for this repl session instead.
|
||||||
if (debuggerHook && !this->state->debugTraces.empty())
|
if (debuggerHook && !state->debugTraces.empty())
|
||||||
showDebugTrace(std::cout, this->state->positions, this->state->debugTraces.front());
|
showDebugTrace(std::cout, state->positions, state->debugTraces.front());
|
||||||
else
|
else
|
||||||
printMsg(lvlError, e.msg());
|
printMsg(lvlError, e.msg());
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
@ -437,22 +437,16 @@ StorePath NixRepl::getDerivationPath(Value & v) {
|
||||||
return *drvPath;
|
return *drvPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NixRepl::loadDebugTraceEnv(DebugTrace &dt)
|
void NixRepl::loadDebugTraceEnv(DebugTrace & dt)
|
||||||
{
|
{
|
||||||
if (dt.expr.staticenv)
|
initEnv();
|
||||||
{
|
|
||||||
initEnv();
|
|
||||||
|
|
||||||
auto vm = std::make_unique<valmap>(*(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.
|
// add staticenv vars.
|
||||||
for (auto & [name, value] : *(vm.get())) {
|
for (auto & [name, value] : *(vm.get()))
|
||||||
this->addVarToScope(this->state->symbols.create(name), *value);
|
addVarToScope(state->symbols.create(name), *value);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
initEnv();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,45 +503,31 @@ bool NixRepl::processLine(std::string line)
|
||||||
|
|
||||||
else if (command == ":d" || command == ":debug") {
|
else if (command == ":d" || command == ":debug") {
|
||||||
if (arg == "stack") {
|
if (arg == "stack") {
|
||||||
int idx = 0;
|
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
|
||||||
for (auto iter = this->state->debugTraces.begin();
|
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
||||||
iter != this->state->debugTraces.end();
|
showDebugTrace(std::cout, state->positions, i);
|
||||||
++iter, ++idx) {
|
|
||||||
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
|
||||||
showDebugTrace(std::cout, this->state->positions, *iter);
|
|
||||||
}
|
}
|
||||||
} else if (arg == "env") {
|
} else if (arg == "env") {
|
||||||
int idx = 0;
|
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
|
||||||
for (auto iter = this->state->debugTraces.begin();
|
if (idx == debugTraceIndex) {
|
||||||
iter != this->state->debugTraces.end();
|
printEnvBindings(state->symbols, i.expr, i.env);
|
||||||
++iter, ++idx) {
|
break;
|
||||||
if (idx == this->debugTraceIndex)
|
}
|
||||||
{
|
|
||||||
printEnvBindings(state->symbols,iter->expr, iter->env);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (arg.compare(0,4,"show") == 0) {
|
else if (arg.compare(0, 4, "show") == 0) {
|
||||||
try {
|
try {
|
||||||
// change the DebugTrace index.
|
// change the DebugTrace index.
|
||||||
debugTraceIndex = stoi(arg.substr(4));
|
debugTraceIndex = stoi(arg.substr(4));
|
||||||
}
|
} catch (...) { }
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = 0;
|
for (const auto & [idx, i] : enumerate(state->debugTraces)) {
|
||||||
for (auto iter = this->state->debugTraces.begin();
|
if (idx == debugTraceIndex) {
|
||||||
iter != this->state->debugTraces.end();
|
|
||||||
++iter, ++idx) {
|
|
||||||
if (idx == this->debugTraceIndex)
|
|
||||||
{
|
|
||||||
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
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;
|
std::cout << std::endl;
|
||||||
printEnvBindings(state->symbols,iter->expr, iter->env);
|
printEnvBindings(state->symbols, i.expr, i.env);
|
||||||
loadDebugTraceEnv(*iter);
|
loadDebugTraceEnv(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,9 +1012,8 @@ void runRepl(
|
||||||
repl->initEnv();
|
repl->initEnv();
|
||||||
|
|
||||||
// add 'extra' vars.
|
// add 'extra' vars.
|
||||||
for (auto & [name, value] : extraEnv) {
|
for (auto & [name, value] : extraEnv)
|
||||||
repl->addVarToScope(repl->state->symbols.create(name), *value);
|
repl->addVarToScope(repl->state->symbols.create(name), *value);
|
||||||
}
|
|
||||||
|
|
||||||
repl->mainLoop({});
|
repl->mainLoop({});
|
||||||
}
|
}
|
||||||
|
|
|
@ -466,7 +466,7 @@ EvalState::EvalState(
|
||||||
, env1AllocCache(std::make_shared<void *>(nullptr))
|
, env1AllocCache(std::make_shared<void *>(nullptr))
|
||||||
#endif
|
#endif
|
||||||
, baseEnv(allocEnv(128))
|
, baseEnv(allocEnv(128))
|
||||||
, staticBaseEnv(new StaticEnv(false, 0))
|
, staticBaseEnv{std::make_shared<StaticEnv>(false, nullptr)}
|
||||||
{
|
{
|
||||||
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ void EvalState::allowPath(const StorePath & storePath)
|
||||||
allowedPaths->insert(store->toRealPath(storePath));
|
allowedPaths->insert(store->toRealPath(storePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::allowAndSetStorePathString(const StorePath &storePath, Value & v)
|
void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v)
|
||||||
{
|
{
|
||||||
allowPath(storePath);
|
allowPath(storePath);
|
||||||
|
|
||||||
|
@ -714,22 +714,19 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
||||||
|
|
||||||
|
|
||||||
// just for the current level of StaticEnv, not the whole chain.
|
// just for the current level of StaticEnv, not the whole chain.
|
||||||
void printStaticEnvBindings(const SymbolTable &st, const StaticEnv &se)
|
void printStaticEnvBindings(const SymbolTable & st, const StaticEnv & se)
|
||||||
{
|
{
|
||||||
std::cout << ANSI_MAGENTA;
|
std::cout << ANSI_MAGENTA;
|
||||||
for (auto i = se.vars.begin(); i != se.vars.end(); ++i)
|
for (auto & i : se.vars)
|
||||||
{
|
std::cout << st[i.first] << " ";
|
||||||
std::cout << st[i->first] << " ";
|
|
||||||
}
|
|
||||||
std::cout << ANSI_NORMAL;
|
std::cout << ANSI_NORMAL;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// just for the current level of Env, not the whole chain.
|
// just for the current level of Env, not the whole chain.
|
||||||
void printWithBindings(const SymbolTable &st, const Env &env)
|
void printWithBindings(const SymbolTable & st, const Env & env)
|
||||||
{
|
{
|
||||||
if (env.type == Env::HasWithAttrs)
|
if (env.type == Env::HasWithAttrs) {
|
||||||
{
|
|
||||||
std::cout << "with: ";
|
std::cout << "with: ";
|
||||||
std::cout << ANSI_MAGENTA;
|
std::cout << ANSI_MAGENTA;
|
||||||
Bindings::iterator j = env.values[0]->attrs->begin();
|
Bindings::iterator j = env.values[0]->attrs->begin();
|
||||||
|
@ -742,7 +739,7 @@ void printWithBindings(const SymbolTable &st, const Env &env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, int lvl)
|
void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl)
|
||||||
{
|
{
|
||||||
std::cout << "Env level " << lvl << std::endl;
|
std::cout << "Env level " << lvl << std::endl;
|
||||||
|
|
||||||
|
@ -752,16 +749,13 @@ void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env
|
||||||
printWithBindings(st, env);
|
printWithBindings(st, env);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
printEnvBindings(st, *se.up, *env.up, ++lvl);
|
printEnvBindings(st, *se.up, *env.up, ++lvl);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << ANSI_MAGENTA;
|
std::cout << ANSI_MAGENTA;
|
||||||
// for the top level, don't print the double underscore ones; they are in builtins.
|
// for the top level, don't print the double underscore ones;
|
||||||
for (auto i = se.vars.begin(); i != se.vars.end(); ++i)
|
// they are in builtins.
|
||||||
{
|
for (auto & i : se.vars)
|
||||||
if (((std::string)st[i->first]).substr(0,2) != "__")
|
if (!hasPrefix(st[i.first], "__"))
|
||||||
std::cout << st[i->first] << " ";
|
std::cout << st[i.first] << " ";
|
||||||
}
|
|
||||||
std::cout << ANSI_NORMAL;
|
std::cout << ANSI_NORMAL;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
printWithBindings(st, env); // probably nothing there for the top level.
|
printWithBindings(st, env); // probably nothing there for the top level.
|
||||||
|
@ -771,56 +765,50 @@ void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add accompanying env for With stuff.
|
// TODO: add accompanying env for With stuff.
|
||||||
void printEnvBindings(const SymbolTable &st, const Expr &expr, const Env &env)
|
void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env)
|
||||||
{
|
{
|
||||||
// just print the names for now
|
// just print the names for now
|
||||||
if (expr.staticenv)
|
if (expr.staticEnv)
|
||||||
{
|
printEnvBindings(st, *expr.staticEnv.get(), env, 0);
|
||||||
printEnvBindings(st, *expr.staticenv.get(), env, 0);
|
}
|
||||||
|
|
||||||
|
void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, valmap & vm)
|
||||||
|
{
|
||||||
|
// add bindings for the next level up first, so that the bindings for this level
|
||||||
|
// override the higher levels.
|
||||||
|
// The top level bindings (builtins) are skipped since they are added for us by initEnv()
|
||||||
|
if (env.up && se.up) {
|
||||||
|
mapStaticEnvBindings(st, *se.up, *env.up, vm);
|
||||||
|
|
||||||
|
if (env.type == Env::HasWithAttrs) {
|
||||||
|
// add 'with' bindings.
|
||||||
|
Bindings::iterator j = env.values[0]->attrs->begin();
|
||||||
|
while (j != env.values[0]->attrs->end()) {
|
||||||
|
vm[st[j->name]] = j->value;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// iterate through staticenv bindings and add them.
|
||||||
|
for (auto & i : se.vars)
|
||||||
|
vm[st[i.first]] = env.values[i.second];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapStaticEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, valmap & vm)
|
std::unique_ptr<valmap> mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env)
|
||||||
{
|
{
|
||||||
// add bindings for the next level up first, so that the bindings for this level
|
auto vm = std::make_unique<valmap>();
|
||||||
// override the higher levels.
|
|
||||||
// The top level bindings (builtins) are skipped since they are added for us by initEnv()
|
|
||||||
if (env.up && se.up) {
|
|
||||||
mapStaticEnvBindings(st, *se.up, *env.up, vm);
|
|
||||||
|
|
||||||
if (env.type == Env::HasWithAttrs)
|
|
||||||
{
|
|
||||||
// add 'with' bindings.
|
|
||||||
Bindings::iterator j = env.values[0]->attrs->begin();
|
|
||||||
while (j != env.values[0]->attrs->end()) {
|
|
||||||
vm[st[j->name]] = j->value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// iterate through staticenv bindings and add them.
|
|
||||||
for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter)
|
|
||||||
{
|
|
||||||
vm[st[iter->first]] = env.values[iter->second];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
valmap * mapStaticEnvBindings(const SymbolTable &st,const StaticEnv &se, const Env &env)
|
|
||||||
{
|
|
||||||
auto vm = new valmap();
|
|
||||||
mapStaticEnvBindings(st, se, env, *vm);
|
mapStaticEnvBindings(st, se, env, *vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EvalState::debugLastTrace(Error & e) const
|
||||||
void EvalState::debugLastTrace(Error & e) const {
|
{
|
||||||
// call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context
|
// Call this in the situation where Expr and Env are inaccessible.
|
||||||
// that's in the DebugTrace stack.
|
// The debugger will start in the last context that's in the
|
||||||
|
// DebugTrace stack.
|
||||||
if (debuggerHook && !debugTraces.empty()) {
|
if (debuggerHook && !debugTraces.empty()) {
|
||||||
const DebugTrace &last = debugTraces.front();
|
const DebugTrace & last = debugTraces.front();
|
||||||
debuggerHook(&e, last.env, last.expr);
|
debuggerHook(&e, last.env, last.expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,7 +817,7 @@ void EvalState::debugLastTrace(Error & e) const {
|
||||||
of stack space, which is a real killer in the recursive
|
of stack space, which is a real killer in the recursive
|
||||||
evaluator. So here are some helper functions for throwing
|
evaluator. So here are some helper functions for throwing
|
||||||
exceptions. */
|
exceptions. */
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr &expr) const
|
void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
auto error = EvalError({
|
auto error = EvalError({
|
||||||
.msg = hintfmt(s),
|
.msg = hintfmt(s),
|
||||||
|
@ -864,7 +852,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
||||||
const std::string & s2, Env & env, Expr &expr) const
|
const std::string & s2, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
auto error = EvalError(ErrorInfo{
|
auto error = EvalError(ErrorInfo{
|
||||||
.msg = hintfmt(s, s2),
|
.msg = hintfmt(s, s2),
|
||||||
|
@ -890,7 +878,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr &expr) const
|
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
auto error = EvalError({
|
auto error = EvalError({
|
||||||
.msg = hintfmt(s, s2),
|
.msg = hintfmt(s, s2),
|
||||||
|
@ -900,7 +888,6 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
debuggerHook(&error, env, expr);
|
debuggerHook(&error, env, expr);
|
||||||
|
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +918,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
||||||
const std::string & s3, Env & env, Expr &expr) const
|
const std::string & s3, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
auto error = EvalError({
|
auto error = EvalError({
|
||||||
.msg = hintfmt(s, s2),
|
.msg = hintfmt(s, s2),
|
||||||
|
@ -944,7 +931,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr &expr) const
|
void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
||||||
auto error = EvalError({
|
auto error = EvalError({
|
||||||
|
@ -970,7 +957,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr &expr) const
|
void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) const
|
||||||
{
|
{
|
||||||
auto error = TypeError({
|
auto error = TypeError({
|
||||||
.msg = hintfmt(s, showType(v)),
|
.msg = hintfmt(s, showType(v)),
|
||||||
|
@ -1086,27 +1073,31 @@ void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const
|
||||||
e.addTrace(positions[pos], s, s2);
|
e.addTrace(positions[pos], s, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env,
|
static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
|
||||||
std::optional<ErrPos> pos, const char * s, const std::string & s2)
|
EvalState & state,
|
||||||
|
Expr & expr,
|
||||||
|
Env & env,
|
||||||
|
std::optional<ErrPos> pos,
|
||||||
|
const char * s,
|
||||||
|
const std::string & s2)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<DebugTraceStacker>(
|
return std::make_unique<DebugTraceStacker>(state,
|
||||||
new DebugTraceStacker(
|
DebugTrace {
|
||||||
state,
|
.pos = pos,
|
||||||
DebugTrace
|
.expr = expr,
|
||||||
{.pos = pos,
|
.env = env,
|
||||||
.expr = expr,
|
.hint = hintfmt(s, s2),
|
||||||
.env = env,
|
.isError = false
|
||||||
.hint = hintfmt(s, s2),
|
});
|
||||||
.is_error = false
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugTraceStacker::DebugTraceStacker(EvalState &evalState, DebugTrace t)
|
DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t)
|
||||||
:evalState(evalState), trace(t)
|
: evalState(evalState)
|
||||||
|
, trace(std::move(t))
|
||||||
{
|
{
|
||||||
evalState.debugTraces.push_front(t);
|
evalState.debugTraces.push_front(trace);
|
||||||
if (evalState.debugStop && debuggerHook)
|
if (evalState.debugStop && debuggerHook)
|
||||||
debuggerHook(0, t.env, t.expr);
|
debuggerHook(nullptr, trace.env, trace.expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::mkString(std::string_view s)
|
void Value::mkString(std::string_view s)
|
||||||
|
@ -1303,15 +1294,14 @@ void EvalState::cacheFile(
|
||||||
fileParseCache[resolvedPath] = e;
|
fileParseCache[resolvedPath] = e;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto dts =
|
auto dts = debuggerHook
|
||||||
debuggerHook ?
|
? makeDebugTraceStacker(
|
||||||
makeDebugTraceStacker(
|
*this,
|
||||||
*this,
|
*e,
|
||||||
*e,
|
this->baseEnv,
|
||||||
this->baseEnv,
|
e->getPos() ? std::optional(ErrPos(positions[e->getPos()])) : std::nullopt,
|
||||||
(e->getPos() ? std::optional(ErrPos(positions[e->getPos()])) : std::nullopt),
|
"while evaluating the file '%1%':", resolvedPath)
|
||||||
"while evaluating the file '%1%':", resolvedPath)
|
: nullptr;
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
// Enforce that 'flake.nix' is a direct attrset, not a
|
// Enforce that 'flake.nix' is a direct attrset, not a
|
||||||
// computation.
|
// computation.
|
||||||
|
@ -1538,15 +1528,14 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
e->eval(state, env, vTmp);
|
e->eval(state, env, vTmp);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto dts =
|
auto dts = debuggerHook
|
||||||
debuggerHook ?
|
? makeDebugTraceStacker(
|
||||||
makeDebugTraceStacker(
|
state,
|
||||||
state,
|
*this,
|
||||||
*this,
|
env,
|
||||||
env,
|
state.positions[pos2],
|
||||||
state.positions[pos2],
|
"while evaluating the attribute '%1%'",
|
||||||
"while evaluating the attribute '%1%'",
|
showAttrPath(state, env, attrPath))
|
||||||
showAttrPath(state, env, attrPath))
|
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
for (auto & i : attrPath) {
|
for (auto & i : attrPath) {
|
||||||
|
@ -1708,14 +1697,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
|
|
||||||
/* Evaluate the body. */
|
/* Evaluate the body. */
|
||||||
try {
|
try {
|
||||||
auto dts =
|
auto dts = debuggerHook
|
||||||
debuggerHook ?
|
? makeDebugTraceStacker(
|
||||||
makeDebugTraceStacker(*this, *lambda.body, env2, positions[lambda.pos],
|
*this, *lambda.body, env2, positions[lambda.pos],
|
||||||
"while evaluating %s",
|
"while evaluating %s",
|
||||||
(lambda.name
|
lambda.name
|
||||||
? concatStrings("'", symbols[lambda.name], "'")
|
? concatStrings("'", symbols[lambda.name], "'")
|
||||||
: "anonymous lambda"))
|
: "anonymous lambda")
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
lambda.body->eval(*this, env2, vCur);
|
lambda.body->eval(*this, env2, vCur);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
@ -2135,14 +2124,10 @@ void EvalState::forceValueDeep(Value & v)
|
||||||
if (v.type() == nAttrs) {
|
if (v.type() == nAttrs) {
|
||||||
for (auto & i : *v.attrs)
|
for (auto & i : *v.attrs)
|
||||||
try {
|
try {
|
||||||
|
// If the value is a thunk, we're evaling. Otherwise no trace necessary.
|
||||||
auto dts =
|
auto dts = debuggerHook && i.value->isThunk()
|
||||||
debuggerHook ?
|
? makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos],
|
||||||
// if the value is a thunk, we're evaling. otherwise no trace necessary.
|
"while evaluating the attribute '%1%'", symbols[i.name])
|
||||||
(i.value->isThunk() ?
|
|
||||||
makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos],
|
|
||||||
"while evaluating the attribute '%1%'", symbols[i.name])
|
|
||||||
: nullptr)
|
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
recurse(*i.value);
|
recurse(*i.value);
|
||||||
|
|
|
@ -25,8 +25,8 @@ enum RepairFlag : bool;
|
||||||
|
|
||||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||||
|
|
||||||
void printEnvBindings(const SymbolTable &st, const Expr &expr, const Env &env);
|
void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env);
|
||||||
void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, int lvl = 0);
|
void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl = 0);
|
||||||
|
|
||||||
struct PrimOp
|
struct PrimOp
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ struct Env
|
||||||
Value * values[0];
|
Value * values[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
valmap * mapStaticEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env);
|
std::unique_ptr<valmap> mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env);
|
||||||
|
|
||||||
void copyContext(const Value & v, PathSet & context);
|
void copyContext(const Value & v, PathSet & context);
|
||||||
|
|
||||||
|
@ -75,10 +75,10 @@ std::shared_ptr<RegexCache> makeRegexCache();
|
||||||
|
|
||||||
struct DebugTrace {
|
struct DebugTrace {
|
||||||
std::optional<ErrPos> pos;
|
std::optional<ErrPos> pos;
|
||||||
const Expr &expr;
|
const Expr & expr;
|
||||||
const Env &env;
|
const Env & env;
|
||||||
hintformat hint;
|
hintformat hint;
|
||||||
bool is_error;
|
bool isError;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EvalState
|
class EvalState
|
||||||
|
@ -297,7 +297,7 @@ public:
|
||||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3) const;
|
void throwEvalError(const char * s, const std::string & s2, const std::string & s3) const;
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2,
|
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2,
|
||||||
Env & env, Expr &expr) const;
|
Env & env, Expr & expr) const;
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2,
|
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2,
|
||||||
Env & env, Expr & expr) const;
|
Env & env, Expr & expr) const;
|
||||||
|
@ -508,16 +508,15 @@ private:
|
||||||
friend struct Value;
|
friend struct Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebugTraceStacker {
|
struct DebugTraceStacker {
|
||||||
public:
|
DebugTraceStacker(EvalState & evalState, DebugTrace t);
|
||||||
DebugTraceStacker(EvalState &evalState, DebugTrace t);
|
~DebugTraceStacker()
|
||||||
~DebugTraceStacker()
|
{
|
||||||
{
|
// assert(evalState.debugTraces.front() == trace);
|
||||||
// assert(evalState.debugTraces.front() == trace);
|
evalState.debugTraces.pop_front();
|
||||||
evalState.debugTraces.pop_front();
|
}
|
||||||
}
|
EvalState & evalState;
|
||||||
EvalState &evalState;
|
DebugTrace trace;
|
||||||
DebugTrace trace;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return a string representing the type of the value `v'. */
|
/* Return a string representing the type of the value `v'. */
|
||||||
|
|
|
@ -296,39 +296,38 @@ std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
|
||||||
|
|
||||||
/* Computing levels/displacements for variables. */
|
/* Computing levels/displacements for variables. */
|
||||||
|
|
||||||
void Expr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void Expr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprInt::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprInt::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;}
|
||||||
|
|
||||||
|
void ExprFloat::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
|
{
|
||||||
|
if (debuggerHook)
|
||||||
|
staticEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprFloat::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprString::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprString::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprPath::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprPath::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprVar::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
}
|
|
||||||
|
|
||||||
void ExprVar::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
|
||||||
{
|
|
||||||
if (debuggerHook)
|
|
||||||
staticenv = env;
|
|
||||||
|
|
||||||
/* Check whether the variable appears in the environment. If so,
|
/* Check whether the variable appears in the environment. If so,
|
||||||
set its level and displacement. */
|
set its level and displacement. */
|
||||||
|
@ -353,20 +352,18 @@ void ExprVar::bindVars(const EvalState & es, const std::shared_ptr<const StaticE
|
||||||
enclosing `with'. If there is no `with', then we can issue an
|
enclosing `with'. If there is no `with', then we can issue an
|
||||||
"undefined variable" error now. */
|
"undefined variable" error now. */
|
||||||
if (withLevel == -1)
|
if (withLevel == -1)
|
||||||
{
|
|
||||||
throw UndefinedVarError({
|
throw UndefinedVarError({
|
||||||
.msg = hintfmt("undefined variable '%1%'", es.symbols[name]),
|
.msg = hintfmt("undefined variable '%1%'", es.symbols[name]),
|
||||||
.errPos = es.positions[pos]
|
.errPos = es.positions[pos]
|
||||||
});
|
});
|
||||||
}
|
|
||||||
fromWith = true;
|
fromWith = true;
|
||||||
this->level = withLevel;
|
this->level = withLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprSelect::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprSelect::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
if (def) def->bindVars(es, env);
|
if (def) def->bindVars(es, env);
|
||||||
|
@ -375,10 +372,10 @@ void ExprSelect::bindVars(const EvalState & es, const std::shared_ptr<const Stat
|
||||||
i.expr->bindVars(es, env);
|
i.expr->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprOpHasAttr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprOpHasAttr::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
for (auto & i : attrPath)
|
for (auto & i : attrPath)
|
||||||
|
@ -386,13 +383,13 @@ void ExprOpHasAttr::bindVars(const EvalState & es, const std::shared_ptr<const S
|
||||||
i.expr->bindVars(es, env);
|
i.expr->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprAttrs::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprAttrs::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
auto newEnv = std::shared_ptr<StaticEnv>(new StaticEnv(false, env.get(), recursive ? attrs.size() : 0));
|
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), recursive ? attrs.size() : 0);
|
||||||
|
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
|
@ -419,25 +416,24 @@ void ExprAttrs::bindVars(const EvalState & es, const std::shared_ptr<const Stati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprList::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprList::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
for (auto & i : elems)
|
for (auto & i : elems)
|
||||||
i->bindVars(es, env);
|
i->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprLambda::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprLambda::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
auto newEnv = std::shared_ptr<StaticEnv>(
|
auto newEnv = std::make_shared<StaticEnv>(
|
||||||
new StaticEnv(
|
false, env.get(),
|
||||||
false, env.get(),
|
(hasFormals() ? formals->formals.size() : 0) +
|
||||||
(hasFormals() ? formals->formals.size() : 0) +
|
(!arg ? 0 : 1));
|
||||||
(!arg ? 0 : 1)));
|
|
||||||
|
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
|
|
||||||
|
@ -456,22 +452,22 @@ void ExprLambda::bindVars(const EvalState & es, const std::shared_ptr<const Stat
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprCall::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprCall::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
fun->bindVars(es, env);
|
fun->bindVars(es, env);
|
||||||
for (auto e : args)
|
for (auto e : args)
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprLet::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprLet::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
auto newEnv = std::shared_ptr<StaticEnv>(new StaticEnv(false, env.get(), attrs->attrs.size()));
|
auto newEnv = std::make_shared<StaticEnv>(false, env.get(), attrs->attrs.size());
|
||||||
|
|
||||||
Displacement displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
|
@ -485,10 +481,10 @@ void ExprLet::bindVars(const EvalState & es, const std::shared_ptr<const StaticE
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprWith::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprWith::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
/* Does this `with' have an enclosing `with'? If so, record its
|
/* Does this `with' have an enclosing `with'? If so, record its
|
||||||
level so that `lookupVar' can look up variables in the previous
|
level so that `lookupVar' can look up variables in the previous
|
||||||
|
@ -503,54 +499,53 @@ void ExprWith::bindVars(const EvalState & es, const std::shared_ptr<const Static
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
attrs->bindVars(es, env);
|
attrs->bindVars(es, env);
|
||||||
auto newEnv = std::shared_ptr<StaticEnv>(new StaticEnv(true, env.get()));
|
auto newEnv = std::make_shared<StaticEnv>(true, env.get());
|
||||||
body->bindVars(es, newEnv);
|
body->bindVars(es, newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprIf::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprIf::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
cond->bindVars(es, env);
|
cond->bindVars(es, env);
|
||||||
then->bindVars(es, env);
|
then->bindVars(es, env);
|
||||||
else_->bindVars(es, env);
|
else_->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprAssert::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprAssert::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
cond->bindVars(es, env);
|
cond->bindVars(es, env);
|
||||||
body->bindVars(es, env);
|
body->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprOpNot::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprOpNot::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
e->bindVars(es, env);
|
e->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprConcatStrings::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprConcatStrings::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
for (auto & i : *this->es)
|
for (auto & i : *this->es)
|
||||||
i.second->bindVars(es, env);
|
i.second->bindVars(es, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprPos::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> &env)
|
void ExprPos::bindVars(const EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||||
{
|
{
|
||||||
if (debuggerHook)
|
if (debuggerHook)
|
||||||
staticenv = env;
|
staticEnv = env;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -148,8 +148,8 @@ struct Expr
|
||||||
virtual void eval(EvalState & state, Env & env, Value & v);
|
virtual void eval(EvalState & state, Env & env, Value & v);
|
||||||
virtual Value * maybeThunk(EvalState & state, Env & env);
|
virtual Value * maybeThunk(EvalState & state, Env & env);
|
||||||
virtual void setName(Symbol name);
|
virtual void setName(Symbol name);
|
||||||
std::shared_ptr<const StaticEnv> staticenv;
|
std::shared_ptr<const StaticEnv> staticEnv;
|
||||||
virtual const PosIdx getPos() const = 0;
|
virtual PosIdx getPos() const { return noPos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMON_METHODS \
|
#define COMMON_METHODS \
|
||||||
|
@ -163,7 +163,6 @@ struct ExprInt : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprInt(NixInt n) : n(n) { v.mkInt(n); };
|
ExprInt(NixInt n) : n(n) { v.mkInt(n); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,7 +172,6 @@ struct ExprFloat : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprFloat(NixFloat nf) : nf(nf) { v.mkFloat(nf); };
|
ExprFloat(NixFloat nf) : nf(nf) { v.mkFloat(nf); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,7 +181,6 @@ struct ExprString : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprString(std::string s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
ExprString(std::string s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,7 +190,6 @@ struct ExprPath : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprPath(std::string s) : s(std::move(s)) { v.mkPath(this->s.c_str()); };
|
ExprPath(std::string s) : s(std::move(s)) { v.mkPath(this->s.c_str()); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,7 +217,7 @@ struct ExprVar : Expr
|
||||||
ExprVar(Symbol name) : name(name) { };
|
ExprVar(Symbol name) : name(name) { };
|
||||||
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,7 +228,7 @@ struct ExprSelect : Expr
|
||||||
AttrPath attrPath;
|
AttrPath attrPath;
|
||||||
ExprSelect(const PosIdx & pos, Expr * e, const AttrPath & attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(attrPath) { };
|
ExprSelect(const PosIdx & pos, Expr * e, const AttrPath & attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(attrPath) { };
|
||||||
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -241,7 +237,7 @@ struct ExprOpHasAttr : Expr
|
||||||
Expr * e;
|
Expr * e;
|
||||||
AttrPath attrPath;
|
AttrPath attrPath;
|
||||||
ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
|
ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
|
||||||
const PosIdx getPos() const { return e->getPos(); }
|
PosIdx getPos() const override { return e->getPos(); }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,7 +266,7 @@ struct ExprAttrs : Expr
|
||||||
DynamicAttrDefs dynamicAttrs;
|
DynamicAttrDefs dynamicAttrs;
|
||||||
ExprAttrs(const PosIdx &pos) : recursive(false), pos(pos) { };
|
ExprAttrs(const PosIdx &pos) : recursive(false), pos(pos) { };
|
||||||
ExprAttrs() : recursive(false) { };
|
ExprAttrs() : recursive(false) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,13 +274,12 @@ struct ExprList : Expr
|
||||||
{
|
{
|
||||||
std::vector<Expr *> elems;
|
std::vector<Expr *> elems;
|
||||||
ExprList() { };
|
ExprList() { };
|
||||||
const PosIdx getPos() const
|
|
||||||
{ if (elems.empty())
|
|
||||||
return noPos;
|
|
||||||
else
|
|
||||||
return elems.front()->getPos();
|
|
||||||
}
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
|
||||||
|
PosIdx getPos() const override
|
||||||
|
{
|
||||||
|
return elems.empty() ? noPos : elems.front()->getPos();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Formal
|
struct Formal
|
||||||
|
@ -337,7 +332,7 @@ struct ExprLambda : Expr
|
||||||
void setName(Symbol name);
|
void setName(Symbol name);
|
||||||
std::string showNamePos(const EvalState & state) const;
|
std::string showNamePos(const EvalState & state) const;
|
||||||
inline bool hasFormals() const { return formals != nullptr; }
|
inline bool hasFormals() const { return formals != nullptr; }
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -349,7 +344,7 @@ struct ExprCall : Expr
|
||||||
ExprCall(const PosIdx & pos, Expr * fun, std::vector<Expr *> && args)
|
ExprCall(const PosIdx & pos, Expr * fun, std::vector<Expr *> && args)
|
||||||
: fun(fun), args(args), pos(pos)
|
: fun(fun), args(args), pos(pos)
|
||||||
{ }
|
{ }
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,7 +353,6 @@ struct ExprLet : Expr
|
||||||
ExprAttrs * attrs;
|
ExprAttrs * attrs;
|
||||||
Expr * body;
|
Expr * body;
|
||||||
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -368,7 +362,7 @@ struct ExprWith : Expr
|
||||||
Expr * attrs, * body;
|
Expr * attrs, * body;
|
||||||
size_t prevWith;
|
size_t prevWith;
|
||||||
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,7 +371,7 @@ struct ExprIf : Expr
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
Expr * cond, * then, * else_;
|
Expr * cond, * then, * else_;
|
||||||
ExprIf(const PosIdx & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
ExprIf(const PosIdx & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -386,7 +380,7 @@ struct ExprAssert : Expr
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
Expr * cond, * body;
|
Expr * cond, * body;
|
||||||
ExprAssert(const PosIdx & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
ExprAssert(const PosIdx & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -394,7 +388,6 @@ struct ExprOpNot : Expr
|
||||||
{
|
{
|
||||||
Expr * e;
|
Expr * e;
|
||||||
ExprOpNot(Expr * e) : e(e) { };
|
ExprOpNot(Expr * e) : e(e) { };
|
||||||
const PosIdx getPos() const { return noPos; }
|
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -414,7 +407,7 @@ struct ExprOpNot : Expr
|
||||||
e1->bindVars(es, env); e2->bindVars(es, env); \
|
e1->bindVars(es, env); e2->bindVars(es, env); \
|
||||||
} \
|
} \
|
||||||
void eval(EvalState & state, Env & env, Value & v); \
|
void eval(EvalState & state, Env & env, Value & v); \
|
||||||
const PosIdx getPos() const { return pos; } \
|
PosIdx getPos() const override { return pos; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeBinOp(ExprOpEq, "==")
|
MakeBinOp(ExprOpEq, "==")
|
||||||
|
@ -432,7 +425,7 @@ struct ExprConcatStrings : Expr
|
||||||
std::vector<std::pair<PosIdx, Expr *> > * es;
|
std::vector<std::pair<PosIdx, Expr *> > * es;
|
||||||
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *> > * es)
|
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *> > * es)
|
||||||
: pos(pos), forceString(forceString), es(es) { };
|
: pos(pos), forceString(forceString), es(es) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -440,7 +433,7 @@ struct ExprPos : Expr
|
||||||
{
|
{
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
ExprPos(const PosIdx & pos) : pos(pos) { };
|
ExprPos(const PosIdx & pos) : pos(pos) { };
|
||||||
const PosIdx getPos() const { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
|
||||||
Env * env = &state.allocEnv(vScope->attrs->size());
|
Env * env = &state.allocEnv(vScope->attrs->size());
|
||||||
env->up = &state.baseEnv;
|
env->up = &state.baseEnv;
|
||||||
|
|
||||||
auto staticEnv = std::shared_ptr<StaticEnv>(new StaticEnv(false, state.staticBaseEnv.get(), vScope->attrs->size()));
|
auto staticEnv = std::make_shared<StaticEnv>(false, state.staticBaseEnv.get(), vScope->attrs->size());
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
for (auto & attr : *vScope->attrs) {
|
for (auto & attr : *vScope->attrs) {
|
||||||
|
@ -329,8 +329,7 @@ void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Valu
|
||||||
std::string sym(state.forceStringNoCtx(*args[1], pos));
|
std::string sym(state.forceStringNoCtx(*args[1], pos));
|
||||||
|
|
||||||
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
if (!handle)
|
if (!handle) {
|
||||||
{
|
|
||||||
auto e = EvalError("could not open '%1%': %2%", path, dlerror());
|
auto e = EvalError("could not open '%1%': %2%", path, dlerror());
|
||||||
state.debugLastTrace(e);
|
state.debugLastTrace(e);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -340,14 +339,11 @@ void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Valu
|
||||||
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
||||||
if(!func) {
|
if(!func) {
|
||||||
char *message = dlerror();
|
char *message = dlerror();
|
||||||
if (message)
|
if (message) {
|
||||||
{
|
|
||||||
auto e = EvalError("could not load symbol '%1%' from '%2%': %3%", sym, path, message);
|
auto e = EvalError("could not load symbol '%1%' from '%2%': %3%", sym, path, message);
|
||||||
state.debugLastTrace(e);
|
state.debugLastTrace(e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
auto e = EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected",
|
auto e = EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected",
|
||||||
sym, path);
|
sym, path);
|
||||||
state.debugLastTrace(e);
|
state.debugLastTrace(e);
|
||||||
|
@ -573,8 +569,7 @@ struct CompareValues
|
||||||
return v1->fpoint < v2->integer;
|
return v1->fpoint < v2->integer;
|
||||||
if (v1->type() == nInt && v2->type() == nFloat)
|
if (v1->type() == nInt && v2->type() == nFloat)
|
||||||
return v1->integer < v2->fpoint;
|
return v1->integer < v2->fpoint;
|
||||||
if (v1->type() != v2->type())
|
if (v1->type() != v2->type()) {
|
||||||
{
|
|
||||||
auto e = EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
auto e = EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
state.debugLastTrace(e);
|
state.debugLastTrace(e);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -599,12 +594,11 @@ struct CompareValues
|
||||||
return (*this)(v1->listElems()[i], v2->listElems()[i]);
|
return (*this)(v1->listElems()[i], v2->listElems()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
{
|
auto e = EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
auto e = EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
state.debugLastTrace(e);
|
||||||
state.debugLastTrace(e);
|
throw e;
|
||||||
throw e;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -703,8 +697,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
|
||||||
|
|
||||||
Bindings::iterator key =
|
Bindings::iterator key =
|
||||||
e->attrs->find(state.sKey);
|
e->attrs->find(state.sKey);
|
||||||
if (key == e->attrs->end())
|
if (key == e->attrs->end()) {
|
||||||
{
|
|
||||||
auto e = EvalError({
|
auto e = EvalError({
|
||||||
.msg = hintfmt("attribute 'key' required"),
|
.msg = hintfmt("attribute 'key' required"),
|
||||||
.errPos = state.positions[pos]
|
.errPos = state.positions[pos]
|
||||||
|
@ -772,7 +765,7 @@ static RegisterPrimOp primop_break({
|
||||||
.name = "break",
|
.name = "break",
|
||||||
.args = {"v"},
|
.args = {"v"},
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
In debug mode, pause Nix expression evaluation and enter the repl.
|
In debug mode (enabled using `--debugger`), pause Nix expression evaluation and enter the REPL.
|
||||||
)",
|
)",
|
||||||
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
@ -783,16 +776,15 @@ static RegisterPrimOp primop_break({
|
||||||
.msg = hintfmt("breakpoint reached; value was %1%", s),
|
.msg = hintfmt("breakpoint reached; value was %1%", s),
|
||||||
.errPos = state.positions[pos],
|
.errPos = state.positions[pos],
|
||||||
});
|
});
|
||||||
if (debuggerHook && !state.debugTraces.empty())
|
if (debuggerHook && !state.debugTraces.empty()) {
|
||||||
{
|
auto & dt = state.debugTraces.front();
|
||||||
auto &dt = state.debugTraces.front();
|
|
||||||
debuggerHook(&error, dt.env, dt.expr);
|
debuggerHook(&error, dt.env, dt.expr);
|
||||||
|
|
||||||
if (state.debugQuit) {
|
if (state.debugQuit) {
|
||||||
// if the user elects to quit the repl, throw an exception.
|
// if the user elects to quit the repl, throw an exception.
|
||||||
throw Error(ErrorInfo{
|
throw Error(ErrorInfo{
|
||||||
.level = lvlInfo,
|
.level = lvlInfo,
|
||||||
.msg = hintfmt("quit from debugger"),
|
.msg = hintfmt("quit the debugger"),
|
||||||
.errPos = state.positions[noPos],
|
.errPos = state.positions[noPos],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -903,7 +895,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
||||||
{
|
{
|
||||||
auto attrs = state.buildBindings(2);
|
auto attrs = state.buildBindings(2);
|
||||||
auto saveDebuggerHook = debuggerHook;
|
auto saveDebuggerHook = debuggerHook;
|
||||||
debuggerHook = 0;
|
debuggerHook = nullptr;
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
attrs.insert(state.sValue, args[0]);
|
attrs.insert(state.sValue, args[0]);
|
||||||
|
|
Loading…
Reference in a new issue