From b10b837d18f14cbcd38d75680d0410dee3a66064 Mon Sep 17 00:00:00 2001 From: Joe Strout Date: Sat, 22 Oct 2022 17:12:39 -0700 Subject: [PATCH] Added `stackTrace` which was somehow missing. --- Farmtronics/M1/M1API.cs | 16 ++++++++++++++++ Farmtronics/M1/Shell.cs | 23 ++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Farmtronics/M1/M1API.cs b/Farmtronics/M1/M1API.cs index a29e04e..5f830bd 100644 --- a/Farmtronics/M1/M1API.cs +++ b/Farmtronics/M1/M1API.cs @@ -301,6 +301,22 @@ public static void Init(Shell shell) { f.code = (context, partialResult) => { return new Intrinsic.Result(WorldInfo()); }; + + // stackTrace: get a list describing the call stack. + f = Intrinsic.Create("stackTrace"); + f.code = (context, partialResult) => { + TAC.Machine vm = context.vm; + if (vm.globalContext.variables.ContainsKey(_stackAtBreak)) { + // We have a stored stack from a break or exit. + // So, display that. This gets cleared by 'run' so should never interfere with + // showing a more up-to-date stack during a run. + return new Intrinsic.Result(vm.globalContext.variables.map[_stackAtBreak]); + } + // Otherwise, build a stack now from the state of the VM. + ValList result = StackList(context.vm); + return new Intrinsic.Result(result); + }; + } static bool DisallowAllAssignment(Value key, Value value) { diff --git a/Farmtronics/M1/Shell.cs b/Farmtronics/M1/Shell.cs index 9a9f541..67d34e9 100644 --- a/Farmtronics/M1/Shell.cs +++ b/Farmtronics/M1/Shell.cs @@ -52,12 +52,14 @@ public bool allowControlCBreak { ValString curScreenColor; public TextDisplay textDisplay { get { return console.display; } } - + + ValList stackAtLastErr; + public Shell() { console = new Console(this); // prepare the interpreter - interpreter = new Interpreter(null, PrintLineWithTaskCheck, PrintLine); + interpreter = new Interpreter(null, PrintLineWithTaskCheck, PrintErrLine); interpreter.implicitOutput = PrintLine; interpreter.hostData = this; } @@ -275,7 +277,8 @@ public void Break(bool silent=false) { if (!silent && !allowControlCBreak) return; // grab the full stack and tuck it away for future reference - ValList stack = M1API.StackList(interpreter.vm); + ValList stack = stackAtLastErr; + if (stack == null) stack = M1API.StackList(interpreter.vm); // also find the first non-null entry, to display right away SourceLoc loc = null; @@ -349,8 +352,8 @@ void Clear() { public void Exit() { if (interpreter.Running()) { - //interpreter.vm.globalContext.variables.SetElem(MiniMicroAPI._stackAtBreak, - // MiniMicroAPI.StackList(interpreter.vm)); + interpreter.vm.globalContext.variables.SetElem(M1API._stackAtBreak, + M1API.StackList(interpreter.vm)); interpreter.Stop(); } } @@ -361,6 +364,16 @@ public void PrintLine(string line) { disp.Print(disp.delimiter); } + public void PrintErrLine(string line) { + if (interpreter.vm != null) { + stackAtLastErr = M1API.StackList(interpreter.vm); + interpreter.vm.globalContext.variables.SetElem(M1API._stackAtBreak, stackAtLastErr); + } else { + stackAtLastErr = new ValList(); // empty list signifies error without a VM, e.g. at compile time. + } + PrintLine(line); + } + void PrintLineWithTaskCheck(string line) { PrintLine(line); ToDoManager.NotePrintOutput(line);