main.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. use matzo::grammar::StmtsParser;
  2. use matzo::interp::State;
  3. use matzo::lexer::tokens;
  4. fn matzo_version() -> String {
  5. format!("matzo (git {})", env!("VERGEN_GIT_SHA"))
  6. }
  7. fn run(src: &str) {
  8. let lexed = tokens(src);
  9. let stmts = StmtsParser::new().parse(lexed).unwrap();
  10. let mut state = State::new();
  11. for stmt in stmts {
  12. if let Err(err) = state.execute(&stmt) {
  13. eprintln!("error: {}", err);
  14. }
  15. }
  16. }
  17. fn run_repl() -> Result<(), Box<dyn std::error::Error>> {
  18. let mut rl = rustyline::Editor::<matzo::repl::Repl>::new();
  19. let state = std::rc::Rc::new(std::cell::RefCell::new(State::new()));
  20. rl.set_helper(Some(matzo::repl::Repl::new(state.clone())));
  21. let parser = StmtsParser::new();
  22. println!(
  23. "{}",
  24. ansi_term::Colour::Blue.bold().paint(matzo_version()),
  25. );
  26. println!("{}", ansi_term::Colour::Blue.paint("(work-in-progress)"),);
  27. loop {
  28. let line = match rl.readline(">>> ") {
  29. Ok(ln) => ln,
  30. Err(rustyline::error::ReadlineError::Eof)
  31. | Err(rustyline::error::ReadlineError::Interrupted) => return Ok(()),
  32. err => err?,
  33. };
  34. let lexed = tokens(&line);
  35. let stmts = match parser.parse(lexed) {
  36. Ok(stmts) => stmts,
  37. Err(err) => {
  38. // for the REPL specifically, let's try adding a
  39. // `puts` to see if that works
  40. let added_puts = format!("puts {}", line);
  41. let lexed = tokens(&added_puts);
  42. match parser.parse(lexed) {
  43. Ok(stmts) => stmts,
  44. Err(_) => {
  45. // that didn't fix it, so report the
  46. // _original_ parse error, not the new one
  47. eprintln!("{}", ansi_term::Colour::Red.paint(format!("{:?}", err)),);
  48. continue;
  49. }
  50. }
  51. }
  52. };
  53. for stmt in stmts {
  54. if let Err(err) = state.borrow_mut().execute(&stmt) {
  55. eprintln!(
  56. "{} {}",
  57. ansi_term::Colour::Red.bold().paint("error:"),
  58. ansi_term::Colour::Red.paint(format!("{}", err)),
  59. );
  60. }
  61. }
  62. }
  63. }
  64. fn main() {
  65. let args = std::env::args().skip(1).collect::<Vec<String>>();
  66. if args.is_empty() {
  67. run_repl().unwrap();
  68. return;
  69. }
  70. for arg in args {
  71. let buf = std::fs::read_to_string(arg).unwrap();
  72. run(&buf);
  73. }
  74. }