use std::error::Error;
use rustyline::DefaultEditor;
use wartcl::{empty, Env, FlowChange, Token, Tokenizer};
fn main() -> Result<(), Box<dyn Error>> {
let mut editor = DefaultEditor::new()?;
let mut tcl = Env::default();
tcl.register(b"exit", 0, |_, _| {
println!("so long!");
Err(FlowChange::Return(empty()))
});
'outerloop:
loop {
let mut prompt = "> ";
let mut read = String::new();
'readloop:
loop {
let line = editor.readline(prompt)?;
read.push_str(&line);
read.push('\n');
editor.add_history_entry(line)?;
let mut t = Tokenizer::new(read.as_bytes());
while let Some(tok) = t.next() {
if tok == Token::Error && !t.at_end() {
println!("ERROR");
continue 'outerloop;
}
if matches!(tok, Token::CmdSep(b'\r' | b'\n')) {
break 'readloop;
}
}
prompt = "… ";
}
match tcl.eval(read.as_bytes()) {
Err(FlowChange::Error) => println!("ERROR"),
Err(FlowChange::Return(_)) => {
break;
}
Err(fc) => {
println!("Unexpected flow change outside loop: {fc:?}");
}
Ok(result) => {
if !result.is_empty() {
println!("{}", String::from_utf8_lossy(&result));
}
}
}
}
Ok(())
}