63 lines
1.4 KiB
Rust
63 lines
1.4 KiB
Rust
|
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<Value, run::Error> {
|
||
|
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<lexer::LexingError>),
|
||
|
ASTParsing(Vec<ast::parser::ASTParsingError>),
|
||
|
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 {}
|
||
|
}
|