2022-04-03 21:54:26 +02:00
|
|
|
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",
|
|
|
|
};
|
2022-04-03 22:07:19 +02:00
|
|
|
writeln!(f, "Errors occured during {error_kind}")?;
|
2022-04-03 21:54:26 +02:00
|
|
|
match *self {
|
|
|
|
Error::Lexing(ref errors) => {
|
|
|
|
for error in errors {
|
2022-04-03 22:07:19 +02:00
|
|
|
writeln!(f, "{error} ")?;
|
2022-04-03 21:54:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Error::ASTParsing(ref errors) => {
|
|
|
|
for error in errors {
|
2022-04-03 22:07:19 +02:00
|
|
|
writeln!(f, "{error} ")?;
|
2022-04-03 21:54:26 +02:00
|
|
|
}
|
|
|
|
}
|
2022-04-03 22:07:19 +02:00
|
|
|
Error::Runtime(ref error) => writeln!(f, "{error} ")?,
|
2022-04-03 21:54:26 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
}
|