From d0840759b3a54a8163b6f43bc9d980773ae8fe77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Tue, 31 Mar 2026 20:14:49 +0200 Subject: [PATCH] feat(core): Display for EvalError + ParserError --- lispers-core/src/lisp/eval.rs | 6 +++++- lispers-core/src/parser/parser.rs | 11 +++++++++++ lispers-core/src/parser/token.rs | 19 +++++++++++++++++++ lispers-core/src/parser/tokenizer.rs | 10 ++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lispers-core/src/lisp/eval.rs b/lispers-core/src/lisp/eval.rs index a122849..1d89f8e 100644 --- a/lispers-core/src/lisp/eval.rs +++ b/lispers-core/src/lisp/eval.rs @@ -1,10 +1,12 @@ use std::fmt::Display; +use crate::parser::ParserError; + use super::environment::Environment; use super::environment::EnvironmentLayer; use super::expression::Expression; -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq)] /// All possible evaluation errors pub enum EvalError { SymbolNotBound(String), @@ -14,6 +16,7 @@ pub enum EvalError { TypeError(String), NotASymbol(Expression), RuntimeError(String), + ParserError(ParserError), } impl Display for EvalError { @@ -26,6 +29,7 @@ impl Display for EvalError { EvalError::TypeError(s) => write!(f, "Type error: {}", s), EvalError::NotASymbol(e) => write!(f, "Expression {} is not a symbol", e), EvalError::RuntimeError(s) => write!(f, "Runtime error: {}", s), + EvalError::ParserError(s) => write!(f, "Parser error: {}", s), } } } diff --git a/lispers-core/src/parser/parser.rs b/lispers-core/src/parser/parser.rs index a5ed319..af28cf2 100644 --- a/lispers-core/src/parser/parser.rs +++ b/lispers-core/src/parser/parser.rs @@ -3,6 +3,7 @@ use super::tokenizer::tokenize; use super::tokenizer::TokenStream; use super::tokenizer::TokenizerError; use crate::lisp::Expression; +use std::fmt::Display; use std::iter::Peekable; #[derive(Debug, Clone, PartialEq)] @@ -18,6 +19,16 @@ impl From for ParserError { } } +impl Display for ParserError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + ParserError::TokenizerError(t) => write!(f, "Tokenizer Error: {}", t), + ParserError::UnexpectedToken(t) => write!(f, "Unexpecte Token: {}", t), + ParserError::UnexpectedEndOfInput => write!(f, "Unexpected end of input."), + } + } +} + fn parse_list(stream: &mut Peekable>) -> Result where I: Iterator, diff --git a/lispers-core/src/parser/token.rs b/lispers-core/src/parser/token.rs index 4d7643a..3209663 100644 --- a/lispers-core/src/parser/token.rs +++ b/lispers-core/src/parser/token.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + #[derive(Debug, PartialEq, Clone)] /// Sum type of different tokens pub enum Token { @@ -12,3 +14,20 @@ pub enum Token { Symbol(String), True, } + +impl Display for Token { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Token::FloatLiteral(x) => write!(f, "{}", x), + Token::IntLiteral(x) => write!(f, "{}", x), + Token::Dot => write!(f, "."), + Token::Nil => write!(f, "nil"), + Token::ParClose => write!(f, ")"), + Token::ParOpen => write!(f, "("), + Token::Quote => write!(f, "'"), + Token::StringLiteral(x) => write!(f, "\"{}\"", x), + Token::Symbol(x) => write!(f, "{}", x), + Token::True => write!(f, "true"), + } + } +} diff --git a/lispers-core/src/parser/tokenizer.rs b/lispers-core/src/parser/tokenizer.rs index 466c9be..cc46d26 100644 --- a/lispers-core/src/parser/tokenizer.rs +++ b/lispers-core/src/parser/tokenizer.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use super::token::Token; #[derive(Debug, Clone, PartialEq)] @@ -7,6 +9,14 @@ pub enum TokenizerError { UnmatchedSequence(String), } +impl Display for TokenizerError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TokenizerError::UnmatchedSequence(s) => write!(f, "Unmatched sequence: {}", s), + } + } +} + /// A reader used to wrap the `TokenStream`. /// When reading, it starts with the staging buffer of the stream, once /// it's end is reached, the input stream is copied character wise to