pub mod ast; pub mod error; pub mod interpreter; pub mod lexer; use ast::expression::expression_node::ExpressionNode; use ast::parser::ASTParsingError; use interpreter::ast_walker::{Interpret, RuntimeError}; use interpreter::types::Value; use lexer::{token::Token, Lexer, LexingError}; pub fn lex<'a, 'b>( code: &'a str, file: Option<&'b str>, ) -> Result>, Vec> { let mut lexer = Lexer::new(code, file); lexer.scan_tokens() } pub fn parse(tokens: Vec) -> Result, Vec> { let mut parser = crate::ast::parser::Parser::new(tokens.into_iter()); parser.parse_all() } pub fn exec(nodes: Vec) -> Result { nodes[0].interpret() } pub fn run(code: &str) -> Result { let tokens = lex(code, None)?; let nodes = parse(tokens)?; Ok(exec(nodes)?) } 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", }; writeln!(f, "Errors occured during {error_kind}")?; match *self { Error::Lexing(ref errors) => { for error in errors { writeln!(f, "{error} ")?; } } Error::ASTParsing(ref errors) => { for error in errors { writeln!(f, "{error} ")?; } } Error::Runtime(ref error) => writeln!(f, "{error} ")?, }; Ok(()) } } impl std::error::Error for Error {} }