1mod ast;
2mod evaluator;
3mod lexer;
4mod object;
5mod parser;
6mod token;
7
8use std::error::Error;
9
10use ast::Program;
11use evaluator::Evaluator;
12use lexer::Lexer;
13use object::{Environment, MutableEnvironment};
14use parser::Parser;
15
16const MONKEY_FACE: &str = r#"
17 __,__
18 .--. .-" "-. .--.
19 / .. \/ .-. .-. \/ .. \
20 | | '| / Y \ |' | |
21 | \ \ \ 0 | 0 / / / |
22 \ '- ,\.-"""""""-./, -' /
23 ''-' /_ ^ ^ _\ '-''
24 | \._ _./ |
25 \ \ '~' / /
26 '._ '-=-' _.'
27 '-----'
28"#;
29
30pub struct Interpreter {
31 environment: MutableEnvironment,
32 evaluator: Evaluator,
33}
34
35impl Interpreter {
36 pub fn new() -> Interpreter {
37 Interpreter {
38 environment: Environment::new(),
39 evaluator: Evaluator::new(),
40 }
41 }
42
43 pub fn interpret(&mut self, input: String) -> String {
44 let lex = Lexer::new(&input);
45 let mut parser = Parser::new(lex);
46 match parser.parse_program() {
47 Err(e) => Self::format_error(Box::new(e)),
48 Ok(p) => self.evaluate_program(p),
49 }
50 }
51
52 fn format_error(error: Box<dyn Error>) -> String {
53 format!(
54 "{}\nWhoops! We ran into some monkey business here!\n errors:\n{}",
55 MONKEY_FACE, error
56 )
57 }
58
59 fn evaluate_program(&self, program: Program) -> String {
60 match self.evaluator.eval_program(&program, &self.environment) {
61 Ok(evaluated) => format!("{}", evaluated.inspect()),
62 Err(e) => Self::format_error(Box::new(e)),
63 }
64 }
65}