private static bool DebuggerLoop(VirtualMachine vm, Debugger debugger, VMDebugger vmDebugger) { Console.Write("(moncdbg) "); string line = Console.ReadLine(); string[] args; if (line != null) { args = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); } else { args = Array.Empty <string>(); } string command = ""; if (args.Length > 0) { command = args[0]; } switch (command) { case "reg": { StackFrameInfo frame = vm.GetStackFrame(0); Console.WriteLine($"Function: {frame.Function}, PC: {frame.PC}"); string?sourcePath; int lineNumber; if (debugger.GetSourceLocation(frame, out sourcePath, out lineNumber)) { Console.WriteLine($"File: {sourcePath}, Line: {lineNumber + 1}"); } } break; case "read": StackFrameMemory memory = vm.GetStackFrameMemory(0); for (int i = 0, ilen = memory.Size; i < ilen; ++i) { if (i % 4 == 0 && i != 0) { Console.WriteLine(); } Console.Write(memory.Read(i) + "\t"); } Console.WriteLine(); break; case "bp": { if (args.Length < 2) { Console.WriteLine("Not enough args"); break; } int breakpointLineNumber; int.TryParse(args[1], out breakpointLineNumber); StackFrameInfo frame = vm.GetStackFrame(0); string? sourcePath; if (!debugger.GetSourceLocation(frame, out sourcePath, out _)) { sourcePath = ""; } Console.WriteLine($"Assuming source file is {sourcePath}"); debugger.SetBreakpoint(sourcePath !, breakpointLineNumber - 1); } break; case "over": return(vmDebugger.StepOver()); case "into": return(vmDebugger.StepInto()); case "out": return(vmDebugger.StepOut()); case "step": return(vmDebugger.Step()); case "continue": case null: return(vmDebugger.Continue()); case "": break; default: Console.Error.WriteLine($"moncdbg: unknown command {line}"); break; } return(true); }