main.rs 2.4 KB

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