Skip to content

Commit

Permalink
refactor: implement Display trait for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed Jun 2, 2024
1 parent 65ab529 commit 339ad9e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 10 deletions.
49 changes: 49 additions & 0 deletions src/lexer/token.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

#[derive(Debug, PartialEq, Clone, Hash, Eq)]
pub enum Token {
Eof,
Expand Down Expand Up @@ -55,3 +57,50 @@ impl Token {
}
}
}

impl Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Token::*;

match self {
Eof => write!(f, "EOF"),
Ident(ident) => write!(f, "ident({})", ident),
Integer(integer) => write!(f, "int({})", integer),
String(string) => write!(f, "string({})", string),
Assign => write!(f, "="),
Plus => write!(f, "+"),
Minus => write!(f, "-"),
Bang => write!(f, "!"),
Asterisk => write!(f, "*"),
Slash => write!(f, "/"),
Arrow => write!(f, "->"),
Period => write!(f, "."),
Ampersand => write!(f, "&"),
Equal => write!(f, "=="),
NotEqual => write!(f, "!="),
LessThan => write!(f, "<"),
GreaterThan => write!(f, ">"),
LessEqual => write!(f, "<="),
GreaterEqual => write!(f, "=>"),
Comma => write!(f, ","),
Semicolon => write!(f, ";"),
Colon => write!(f, ":"),
LParen => write!(f, "("),
RParen => write!(f, ")"),
LBrace => write!(f, "{{"),
RBrace => write!(f, "}}"),
LBracket => write!(f, "["),
RBracket => write!(f, "]"),
Const => write!(f, "const"),
True => write!(f, "true"),
Enum => write!(f, "enum"),
Struct => write!(f, "struct"),
False => write!(f, "false"),
If => write!(f, "if"),
Else => write!(f, "else"),
Return => write!(f, "return"),
I8 => write!(f, "i8"),
U8 => write!(f, "u8"),
}
}
}
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ fn main() {
"
u8 bar;
bar = 5 * 6 + 69 - 45 / 8;
baz = 1;
"
.to_string(),
);

let parser = Parser::new(lexer);
let (stmts, symtable) = parser.into_parts();
let stmts = match stmts {
Ok(stmts) => stmts,
Err(e) => panic!("Achtung: {}", e),
};

dbg!(&stmts);
dbg!(&symtable);
Expand Down
15 changes: 15 additions & 0 deletions src/parser/expr/expr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use super::IntLitRepr;
use crate::{
lexer::Token,
Expand All @@ -11,6 +13,19 @@ pub enum OpParseError {
Un(Token),
}

impl Display for OpParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Un(token) => {
write!(f, "Failed to parse unary operator from {}", token)
}
Self::Bin(token) => {
write!(f, "Failed to parse binary operator from {}", token)
}
}
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum BinOp {
Add,
Expand Down
10 changes: 10 additions & 0 deletions src/parser/expr/int_repr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use crate::parser::Type;

const MAX_BITS_NUM_SUPPORTED: usize = 8;
Expand Down Expand Up @@ -126,6 +128,14 @@ pub enum IntLitReprError {
TooLarge(usize),
}

impl Display for IntLitReprError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::TooLarge(bits) => write!(f, "{} bits integers are not supported", bits),
}
}
}

impl TryFrom<&str> for IntLitRepr {
type Error = IntLitReprError;

Expand Down
29 changes: 24 additions & 5 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use super::{
expr::{BinOp, ExprBinary, ExprLit, ExprUnary, IntLitRepr, UnOp},
precedence::Precedence,
Expand All @@ -12,7 +14,7 @@ use crate::{
#[derive(Debug)]
pub enum ParserError {
UnexpectedPeek(Token, Token),
UnexpectedToken(Token),
ParseType(Token),
Prefix(Token),
Infix(Token),
Assignment(Type, Type),
Expand All @@ -21,6 +23,23 @@ pub enum ParserError {
Int(IntLitReprError),
}

impl Display for ParserError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::UnexpectedPeek(expected, actual) => {
write!(f, "Expected token {}, got {}", expected, actual)
}
Self::ParseType(token) => write!(f, "Failed to parse type, found {}", token),
Self::Prefix(token) => write!(f, "Failed to parse prefix token {}", token),
Self::Infix(token) => write!(f, "Failed to parse infix token {}", token),
Self::Assignment(lhs, rhs) => write!(f, "Can't assign {} to {}", lhs, rhs),
Self::Type(e) => write!(f, "{}", e),
Self::Operator(e) => write!(f, "{}", e),
Self::Int(e) => write!(f, "{}", e),
}
}
}

impl From<TypeError> for ParserError {
fn from(value: TypeError) -> Self {
ParserError::Type(value)
Expand Down Expand Up @@ -136,7 +155,7 @@ impl Parser {
match token {
Token::U8 => Ok(Type::U8),
Token::I8 => Ok(Type::I8),
token => Err(ParserError::UnexpectedToken(token)),
token => Err(ParserError::ParseType(token)),
}
}

Expand All @@ -148,7 +167,7 @@ impl Parser {
name = ident.to_string();
}
_ => {
return Err(ParserError::UnexpectedToken(self.cur_token.to_owned()));
return Err(ParserError::ParseType(self.cur_token.to_owned()));
}
}

Expand All @@ -164,7 +183,7 @@ impl Parser {
fn ident(&mut self) -> Result<Expr, ParserError> {
match &self.cur_token {
Token::Ident(ident) => Ok(Expr::Ident(ident.to_owned())),
_ => Err(ParserError::UnexpectedToken(self.cur_token.to_owned())),
_ => Err(ParserError::ParseType(self.cur_token.to_owned())),
}
}

Expand All @@ -173,7 +192,7 @@ impl Parser {
Token::Integer(num_str) => Ok(Expr::Lit(ExprLit::Int(
IntLitRepr::try_from(&num_str[..]).map_err(|e| ParserError::Int(e))?,
))),
_ => Err(ParserError::UnexpectedToken(self.cur_token.to_owned())),
_ => Err(ParserError::ParseType(self.cur_token.to_owned())),
}
}

Expand Down
30 changes: 26 additions & 4 deletions src/parser/type_.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
use std::fmt::Display;

#[derive(Debug)]
pub enum TypeError {
Promotion(Type, Type),
IdentNotFound(String),
}

impl Display for TypeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::IdentNotFound(ident) => write!(f, "Ident {} not found", ident),
Self::Promotion(lhs, rhs) => {
write!(f, "Operation between {} and {} are not allowed", lhs, rhs)
}
}
}
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Type {
U8,
I8,
}

#[derive(Debug)]
pub enum TypeError {
Promotion(Type, Type),
IdentNotFound(String),
impl Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::U8 => write!(f, "u8"),
Self::I8 => write!(f, "i8"),
}
}
}

impl Type {
Expand Down

0 comments on commit 339ad9e

Please sign in to comment.