From b7f6705d62ede093a2a1e20dd279e2c7886678de Mon Sep 17 00:00:00 2001 From: bad Date: Sun, 3 Apr 2022 21:54:26 +0200 Subject: [PATCH] More refactoring --- src/ast/parser.rs | 6 ++-- src/error.rs | 34 +++++++++++++++++++ src/interpreter/ast_walker.rs | 9 +++++ src/lexer/error.rs | 24 +------------- src/lexer/mod.rs | 18 ++++------ src/lib.rs | 62 +++++++++++++++++++++++++++++++++++ src/main.rs | 25 +++----------- 7 files changed, 122 insertions(+), 56 deletions(-) create mode 100644 src/lib.rs diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 343462e..4c33829 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -12,8 +12,10 @@ pub enum ASTParsingError { } impl std::fmt::Display for ASTParsingError { - fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!() + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::UnmatchedBrace => write!(f, "Unmatched brace"), + } } } impl std::error::Error for ASTParsingError {} diff --git a/src/error.rs b/src/error.rs index c3bdd71..6feb602 100644 --- a/src/error.rs +++ b/src/error.rs @@ -37,3 +37,37 @@ impl<'a> From<&'a OwnedLocation> for Location<'a> { pub trait ErrorWithLocation: Error { fn get_location(&self) -> Location; } + +#[derive(Debug)] +pub struct ErrorLocationWrapper { + inner: T, + location: OwnedLocation, +} + +impl ErrorLocationWrapper { + pub fn new(inner: T, location: OwnedLocation) -> Self { + Self { inner, location } + } +} + +impl ErrorWithLocation for ErrorLocationWrapper { + fn get_location(&self) -> Location { + (&self.location).into() + } +} + +impl std::fmt::Display for ErrorLocationWrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "An error occured: {} \n On line: {}, col: {}", + self.inner, self.location.line, self.location.col + ) + } +} + +impl Error for ErrorLocationWrapper { + fn cause(&self) -> Option<&dyn Error> { + Some(&self.inner) + } +} diff --git a/src/interpreter/ast_walker.rs b/src/interpreter/ast_walker.rs index f8d93ed..f8c8539 100644 --- a/src/interpreter/ast_walker.rs +++ b/src/interpreter/ast_walker.rs @@ -1,9 +1,18 @@ +use std::fmt::Display; + use super::types; use crate::ast::astnode::{self, UnaryOperator}; #[derive(Debug)] pub struct RuntimeError; +impl Display for RuntimeError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "A runtime error occured") + } +} +impl std::error::Error for RuntimeError {} + pub trait Interpret { fn interpret(&self) -> Result; } diff --git a/src/lexer/error.rs b/src/lexer/error.rs index 2a44866..9ad8a57 100644 --- a/src/lexer/error.rs +++ b/src/lexer/error.rs @@ -2,29 +2,7 @@ use crate::error::{ErrorWithLocation, Location, OwnedLocation}; use core::fmt; use std::error::Error; -#[derive(Debug)] -pub struct LexingError { - pub location: OwnedLocation, - pub kind: LexingErrorKind, -} - -impl fmt::Display for LexingError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Error: {}", self.kind) - } -} - -impl ErrorWithLocation for LexingError { - fn get_location<'a>(&'a self) -> Location<'a> { - (&self.location).into() - } -} - -impl Error for LexingError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.kind) - } -} +pub type LexingError = crate::error::ErrorLocationWrapper; #[derive(Debug)] pub enum LexingErrorKind { diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index 97237bf..ea354d2 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -68,6 +68,10 @@ impl<'a, 'b> Lexer<'a, 'b> { self.get_token(token_type) } + fn get_error(&self, error: LexingErrorKind) -> LexingError { + LexingError::new(error, self.source_iter.get_location(self.file).into()) + } + fn scan_token(&mut self) -> Option, LexingError>> { Some(Ok(match self.source_iter.next()? { '(' => self.get_token(token::TokenType::LeftParen), @@ -103,11 +107,8 @@ impl<'a, 'b> Lexer<'a, 'b> { ), '"' => { let mut string = String::new(); - let unmatched_char_error = Some(Err(LexingError { - kind: LexingErrorKind::UnmatchedQuote, - location: self.source_iter.get_location(self.file).into(), - })); - + let unmatched_char_error = + Some(Err(self.get_error(LexingErrorKind::UnmatchedQuote))); loop { let next_char = self.source_iter.next(); match next_char { @@ -156,12 +157,7 @@ impl<'a, 'b> Lexer<'a, 'b> { } // Ignore whitespace ' ' | '\r' | '\t' | '\n' => return None, - c => { - return Some(Err(LexingError { - location: self.source_iter.get_location(self.file).into(), - kind: LexingErrorKind::UnexpectedCharacter(c), - })) - } + c => return Some(Err(self.get_error(LexingErrorKind::UnexpectedCharacter(c)))), })) } } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e1e9225 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,62 @@ +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 {} +} diff --git a/src/main.rs b/src/main.rs index 1b25094..9323805 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,4 @@ -mod ast; -mod error; -mod interpreter; -mod lexer; - -use interpreter::ast_walker::Interpret; -use lexer::Lexer; +use crftng_intrprtrs::run; use std::{fs, io, path}; use tracing::Level; use tracing_subscriber::{EnvFilter, FmtSubscriber}; @@ -27,7 +21,10 @@ fn run_repl() { let line = line_buf.trim(); if !line.is_empty() { - run(line).unwrap(); + match run(line) { + Ok(v) => println!("{:?}", v), + Err(e) => println!("{}", e), + } line_buf.clear(); } } @@ -36,18 +33,6 @@ fn run_repl() { } } -fn run(code: &str) -> Result<(), Vec> { - let mut lexer = Lexer::new(code, None); - let tokens = lexer.scan_tokens()?; - println!("{:?}", tokens); - let mut parser = crate::ast::parser::Parser::new(tokens.into_iter()); - let expressions = parser.scan_expressions().unwrap(); - println!("{:?}", expressions); - println!("{:?}", expressions[0].interpret()); - - Ok(()) -} - fn main() { dotenv::dotenv().ok(); color_eyre::install().expect("Failed to install color-eyre");