use crate::WRIGHT_VERSION;
use derive_more::Display;
use std::io::{self, BufRead, Write};
const HELP_MESSAGE: &str = "
Wright REPL Help:
Built-in commands:
- :?/:h/:help -- Print this help menu.
- :m/:mode -- Print the current mode.
- :e/:eval -- Switch to eval mode.
- :t/:token -- Switch to token mode.
- :a/:ast -- Switch to AST mode.
- :c/:clear -- Clear the terminal window.
- :v/:version -- Print the current Wright version information.
- :q/:quit/:exit -- Quit/Exit the REPL.
Modes:
- eval mode: Evaluate each line of input
- token mode: Print the tokens generated for each line of input.
- AST mode: Print the AST tree/node generated for each line of input.
";
#[derive(Clone, Copy, PartialEq, Debug, Default, Display)]
enum ReplMode {
#[default]
Eval,
Tokens,
Ast,
}
pub fn start() -> anyhow::Result<()> {
println!("Wright REPL interpreter (wright version {})", WRIGHT_VERSION);
let stdin = io::stdin();
let mut input = stdin.lock();
let stdout = io::stdout();
let mut output = stdout.lock();
let mut input_number = 0usize;
let mut repl_mode = ReplMode::Tokens;
loop {
input_number += 1;
write!(&mut output, "[{}]: >> ", input_number)?;
output.flush()?;
let mut line = String::new();
input.read_line(&mut line)?;
match line.trim() {
":?" | ":h" | ":help" => {
writeln!(&mut output, "{}", HELP_MESSAGE)?;
continue;
}
":v" | ":version" => {
writeln!(&mut output, "Wright programming language version {}", WRIGHT_VERSION)?;
continue;
}
":m" | ":mode" => {
writeln!(&mut output, "{}", repl_mode)?;
continue;
}
":q" | ":exit" | ":quit" => return Ok(()),
":c" | ":clear" => {
writeln!(&mut output, "{esc}[2J{esc}[1;1H", esc = 27 as char)?;
continue;
}
":e" | ":eval" => unimplemented!("Eval mode is not yet implemented."),
"t" | ":token" => {
repl_mode = ReplMode::Tokens;
writeln!(&mut output, "switched to token mode")?;
continue;
}
":a" | ":ast" => {
repl_mode = ReplMode::Ast;
writeln!(&mut output, "switched to AST mode")?;
continue;
}
_ => {}
}
write!(&mut output, "[{}]: << ", input_number)?;
output.flush()?;
unimplemented!("REPL needs to be re-worked a bit.");
}
}