From b2b0513e4495d0b28d00c8f35bcfb72f1e1cd50c Mon Sep 17 00:00:00 2001 From: Michael Benfield Date: Fri, 22 Nov 2024 09:55:48 -0800 Subject: [PATCH] Use dialoguer for prompts with history. Modify intro and help text. --- Cargo.lock | 3 ++- interpreter/Cargo.toml | 6 +++++- interpreter/src/lib.rs | 38 +++++++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99229123a8..30d89bdb0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1563,9 +1563,10 @@ dependencies = [ [[package]] name = "leo-interpreter" -version = "2.3.0" +version = "2.3.1" dependencies = [ "colored", + "dialoguer", "indexmap 2.6.0", "leo-ast", "leo-errors", diff --git a/interpreter/Cargo.toml b/interpreter/Cargo.toml index ad56279674..5757c6439b 100644 --- a/interpreter/Cargo.toml +++ b/interpreter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leo-interpreter" -version = "2.3.0" +version = "2.3.1" authors = [ "The Leo Team " ] description = "Interpreter for the Leo programming language" homepage = "https://leo-lang.org" @@ -48,6 +48,10 @@ workspace = true [dependencies.indexmap] workspace = true +[dependencies.dialoguer] +version = "0.11.0" +features = [ "history" ] + [dependencies.rand] workspace = true diff --git a/interpreter/src/lib.rs b/interpreter/src/lib.rs index 0d150d71e3..de188c29d5 100644 --- a/interpreter/src/lib.rs +++ b/interpreter/src/lib.rs @@ -242,7 +242,11 @@ impl Interpreter { }); }; - if matches!(act, LeoInterpretOver(..)) { self.cursor.over()? } else { self.cursor.step()? } + if matches!(act, LeoInterpretOver(..)) { + self.cursor.over()? + } else { + StepResult { finished: false, value: None } + } } Step => self.cursor.whole_step()?, @@ -390,8 +394,10 @@ impl Interpreter { } } -const INSTRUCTIONS: &str = " -This is the Leo Interpreter. You probably want to start by running a function or transition. +const INTRO: &str = "This is the Leo Interpreter. Try the command `#help`."; + +const HELP: &str = " +You probably want to start by running a function or transition. For instance #into program.aleo/main() Once a function is running, commands include @@ -409,12 +415,19 @@ When executing Aleo VM code, you can print the value of a register like this: You may also use one letter abbreviations for these commands, such as #i. -You may simply enter expressions or statements on the command line +Note that this interpreter is not line oriented as in many common debuggers; +rather it is oriented around expressions and statements. +As you step into code, individual expressions or statements will +be evaluated one by one, including arguments of function calls. + +You may simply enter Leo expressions or statements on the command line to evaluate. For instance, if you want to see the value of a variable w: w If you want to set w to a new value: w = z + 2u8; +Note that statements (like the assignment above) must end with a semicolon. + If there are futures available to be executed, they will be listed by numerical index, and you may run them using `#future` (or `#f`); for instance #future 0 @@ -530,10 +543,10 @@ pub fn interpret( block_height: u32, ) -> Result<()> { let mut interpreter = Interpreter::new(leo_filenames.iter(), aleo_filenames.iter(), signer, block_height)?; - let mut buffer = String::new(); - println!("{}", INSTRUCTIONS); + println!("{}", INTRO); + + let mut history = dialoguer::BasicHistory::new(); loop { - buffer.clear(); if let Some(v) = interpreter.view_current_in_context() { println!("{v}"); } else if let Some(v) = interpreter.view_current() { @@ -542,9 +555,16 @@ pub fn interpret( for (i, future) in interpreter.cursor.futures.iter().enumerate() { println!("{i}: {future}"); } - std::io::stdin().read_line(&mut buffer).expect("read_line"); - let action = match buffer.trim() { + + let user_input: String = + dialoguer::Input::new().with_prompt("Command?").history_with(&mut history).interact_text().unwrap(); + + let action = match user_input.trim() { "" => continue, + "#h" | "#help" => { + println!("{}", HELP); + continue; + } "#i" | "#into" => InterpreterAction::Into, "#s" | "#step" => InterpreterAction::Step, "#o" | "#over" => InterpreterAction::Over,