crftng-intrprtrs/src/lib.rs

83 lines
1.9 KiB
Rust

#![feature(char_indices_offset)]
pub mod ast;
pub mod error;
pub mod interpreter;
pub mod lexer;
use ast::parser::ParseAllResult;
use ast::statement::statement_node::Statement;
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<Token<'b>>, Vec<LexingError>> {
let mut lexer = Lexer::new(code, file);
lexer.scan_tokens()
}
pub fn parse(tokens: Vec<Token>) -> ParseAllResult {
let mut parser = crate::ast::parser::Parser::new(tokens.into_iter());
parser.parse_all()
}
pub fn exec(nodes: Vec<Statement>) -> Result<Value, RuntimeError> {
let mut last_res = Value::Nil;
for statement in nodes {
last_res = statement.interpret()?;
}
Ok(last_res)
}
pub fn run(code: &str) -> Result<Value, run::Error> {
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<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",
};
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 {}
}