main.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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::<()>::new();
  16. let mut state = State::new();
  17. let parser = StmtsParser::new();
  18. println!(
  19. "{}",
  20. ansi_term::Colour::Blue.bold().paint("matzo interpreter"),
  21. );
  22. println!(
  23. "{}",
  24. ansi_term::Colour::Blue.paint("(work-in-progress)"),
  25. );
  26. loop {
  27. let line = match rl.readline(">>> ") {
  28. Ok(ln) => ln,
  29. Err(rustyline::error::ReadlineError::Eof) |
  30. Err(rustyline::error::ReadlineError::Interrupted) =>
  31. 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!(
  48. "{}",
  49. ansi_term::Colour::Red.paint(
  50. format!("{:?}", err)
  51. ),
  52. );
  53. continue;
  54. }
  55. }
  56. }
  57. };
  58. for stmt in stmts {
  59. if let Err(err) = state.execute(&stmt) {
  60. eprintln!(
  61. "{} {}",
  62. ansi_term::Colour::Red.bold().paint("error:"),
  63. ansi_term::Colour::Red.paint(format!("{}", err)),
  64. );
  65. }
  66. }
  67. }
  68. }
  69. fn main() {
  70. let args = std::env::args().skip(1).collect::<Vec<String>>();
  71. if args.is_empty() {
  72. run_repl().unwrap();
  73. return;
  74. }
  75. for arg in args {
  76. let buf = std::fs::read_to_string(arg).unwrap();
  77. run(&buf);
  78. }
  79. }