diff --git a/interpreter/src/interpreter.rs b/interpreter/src/interpreter.rs index 826793ec18..1c31736588 100644 --- a/interpreter/src/interpreter.rs +++ b/interpreter/src/interpreter.rs @@ -28,6 +28,7 @@ pub struct Interpreter { node_builder: NodeBuilder, breakpoints: Vec, pub watchpoints: Vec, + saved_cursors: Vec>, filename_to_program: HashMap, parsed_inputs: u32, } @@ -175,11 +176,26 @@ impl Interpreter { actions: Vec::new(), breakpoints: Vec::new(), watchpoints: Vec::new(), + saved_cursors: Vec::new(), filename_to_program, parsed_inputs: 0, }) } + pub fn save_cursor(&mut self) { + self.saved_cursors.push(self.cursor.clone()); + } + + /// Returns false if there was no saved cursor to restore. + pub fn restore_cursor(&mut self) -> bool { + if let Some(old_cursor) = self.saved_cursors.pop() { + self.cursor = old_cursor; + true + } else { + false + } + } + fn get_aleo_program(path: &Path) -> Result> { let text = fs::read_to_string(path).map_err(|e| CompilerError::file_read_error(path, e))?; let program = text.parse()?; diff --git a/interpreter/src/lib.rs b/interpreter/src/lib.rs index 3eaa7470cc..8444c19d50 100644 --- a/interpreter/src/lib.rs +++ b/interpreter/src/lib.rs @@ -90,6 +90,14 @@ the current program with This allows you to refer to structs and other items in the indicated program. +The interpreter may enter an invalid state, often due to Leo code entered at the +REPL. In this case, you may use the command + +#restore + +Which will restore to the last saved state of the interpreter. Any time you +enter Leo code at the prompt, interpreter state is saved. + Input history is available - use the up and down arrow keys. "; @@ -161,10 +169,16 @@ pub fn interpret( } InterpreterAction::RunFuture(num) } else { - println!("Failed to parse future"); + println!("Failed to parse future."); continue; } } + ("#restore", "") => { + if !interpreter.restore_cursor() { + println!("No saved state to restore."); + } + continue; + } ("#b" | "#break", rest) => { let Some(breakpoint) = parse_breakpoint(rest) else { println!("Failed to parse breakpoint"); @@ -193,6 +207,10 @@ pub fn interpret( } }; + if matches!(action, InterpreterAction::LeoInterpretInto(..) | InterpreterAction::LeoInterpretOver(..)) { + interpreter.save_cursor(); + } + match interpreter.action(action) { Ok(Some(value)) => { println!("{}: {}\n", "Result".bold(), format!("{value}").bright_cyan());