summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 01:27:25 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 13:18:32 +0200
commit1ddda7de7458ac4bfc67936ffb129eb52f0bed72 (patch)
treee30ab890d5487c3394469eabde2c864686f9a810 /crates
parentdecbf0f8318d0918d9455c2524bfc40a89cbc76c (diff)
downloadrebel-1ddda7de7458ac4bfc67936ffb129eb52f0bed72.tar
rebel-1ddda7de7458ac4bfc67936ffb129eb52f0bed72.zip
rebel-lang: repl: add support for multiline input
Only multiline strings are supported, as the validator only checks if the token stream is valid, not if it is a valid expression.
Diffstat (limited to 'crates')
-rw-r--r--crates/rebel-lang/Cargo.toml2
-rw-r--r--crates/rebel-lang/examples/repl.rs35
2 files changed, 32 insertions, 5 deletions
diff --git a/crates/rebel-lang/Cargo.toml b/crates/rebel-lang/Cargo.toml
index 0c2f684..957d31d 100644
--- a/crates/rebel-lang/Cargo.toml
+++ b/crates/rebel-lang/Cargo.toml
@@ -15,4 +15,4 @@ enum-kinds = "0.5.1"
[dev-dependencies]
clap = { version = "4.0.0", features = ["derive"] }
-rustyline = "14.0.0"
+rustyline = { version = "14.0.0", features = ["derive"] }
diff --git a/crates/rebel-lang/examples/repl.rs b/crates/rebel-lang/examples/repl.rs
index 07c906f..e4c2550 100644
--- a/crates/rebel-lang/examples/repl.rs
+++ b/crates/rebel-lang/examples/repl.rs
@@ -5,6 +5,7 @@ use rebel_lang::{
value::{EvalError, Result, Value},
};
use rebel_parse::{recipe, tokenize};
+use rustyline::{error::ReadlineError, validate::ValidationResult};
fn intrinsic_array_len(params: &[Value]) -> Result<Value> {
assert!(params.len() == 1);
@@ -23,6 +24,24 @@ fn intrinsic_string_len(params: &[Value]) -> Result<Value> {
))
}
+#[derive(rustyline::Completer, rustyline::Hinter, rustyline::Highlighter, rustyline::Helper)]
+struct Helper;
+
+impl rustyline::validate::Validator for Helper {
+ fn validate(
+ &self,
+ ctx: &mut rustyline::validate::ValidationContext,
+ ) -> rustyline::Result<rustyline::validate::ValidationResult> {
+ let input = ctx.input();
+ let result = match tokenize::token_stream(input) {
+ Ok(_) => ValidationResult::Valid(None),
+ Err(_) => ValidationResult::Incomplete,
+ };
+
+ Ok(result)
+ }
+}
+
fn main() -> rustyline::Result<()> {
let mut ctx = Context::default();
@@ -47,12 +66,20 @@ fn main() -> rustyline::Result<()> {
},
);
- let mut rl = rustyline::DefaultEditor::new()?;
+ let mut rl = rustyline::Editor::<Helper, rustyline::history::DefaultHistory>::new()?;
+ rl.set_helper(Some(Helper));
- while let Ok(line) = rl.readline("> ") {
- rl.add_history_entry(line.as_str())?;
+ loop {
+ let input = match rl.readline("> ") {
+ Ok(input) => input,
+ Err(ReadlineError::Interrupted) => continue,
+ Err(ReadlineError::WindowResized) => continue,
+ Err(ReadlineError::Eof) => break,
+ Err(err) => panic!("{err}"),
+ };
+ rl.add_history_entry(input.as_str())?;
- let tokens = match tokenize::token_stream(&line) {
+ let tokens = match tokenize::token_stream(&input) {
Ok(value) => value,
Err(err) => {
println!("Tokenize error: {err}");