monkeyinterpreter 0.2.0

An interpreter written in Rust for the monkey programming language described in the book 'Writing An Interpreter In Go' (https://interpreterbook.com/).
Documentation
mod ast;
mod evaluator;
mod lexer;
mod object;
mod parser;
mod token;

use std::error::Error;

use ast::Program;
use evaluator::Evaluator;
use lexer::Lexer;
use object::{Environment, MutableEnvironment};
use parser::Parser;

const MONKEY_FACE: &str = r#"
            __,__
   .--.  .-"     "-.  .--.
  / .. \/  .-. .-.  \/ .. \
 | |  '|  /   Y   \  |'  | |
 | \   \  \ 0 | 0 /  /   / |
  \ '- ,\.-"""""""-./, -' /
   ''-' /_   ^ ^   _\ '-''
       |  \._   _./  |
       \   \ '~' /   /
        '._ '-=-' _.'
           '-----'
"#;

pub struct Interpreter {
    environment: MutableEnvironment,
    evaluator: Evaluator,
}

impl Interpreter {
    pub fn new() -> Interpreter {
        Interpreter {
            environment: Environment::new(),
            evaluator: Evaluator::new(),
        }
    }

    pub fn interpret(&mut self, input: String) -> String {
        let lex = Lexer::new(&input);
        let mut parser = Parser::new(lex);
        match parser.parse_program() {
            Err(e) => Self::format_error(Box::new(e)),
            Ok(p) => self.evaluate_program(p),
        }
    }

    fn format_error(error: Box<dyn Error>) -> String {
        format!(
            "{}\nWhoops! We ran into some monkey business here!\n  errors:\n{}",
            MONKEY_FACE, error
        )
    }

    fn evaluate_program(&self, program: Program) -> String {
        match self.evaluator.eval_program(&program, &self.environment) {
            Ok(evaluated) => format!("{}", evaluated.inspect()),
            Err(e) => Self::format_error(Box::new(e)),
        }
    }
}