pub mod ast; pub mod error; pub mod interpreter; pub mod lexer; use interpreter::ast_walker::Interpret; use interpreter::types::Value; use lexer::Lexer; pub fn run(code: &str) -> Result { let mut lexer = Lexer::new(code, None); let tokens = lexer.scan_tokens()?; let mut parser = crate::ast::parser::Parser::new(tokens.into_iter()); let expressions = parser.scan_expressions()?; Ok(expressions[0].interpret()?) } mod run { use std::fmt::Display; use super::ast; use super::interpreter::ast_walker::RuntimeError; use super::lexer; use from_variants::FromVariants; #[derive(Debug, FromVariants)] pub enum Error { Lexing(Vec), ASTParsing(Vec), Runtime(RuntimeError), } impl Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let error_kind = match *self { Error::Lexing(_) => "lexing", Error::ASTParsing(_) => "ast generation", Error::Runtime(_) => "runtime", }; write!(f, "Errors occured during {error_kind}\n")?; match *self { Error::Lexing(ref errors) => { for error in errors { write!(f, "{error} \n")?; } } Error::ASTParsing(ref errors) => { for error in errors { write!(f, "{error} \n")?; } } Error::Runtime(ref error) => write!(f, "{error} \n")?, }; Ok(()) } } impl std::error::Error for Error {} }