From fd3cbc4c2c1bfcf9b9ecc744da2e8733912ede48 Mon Sep 17 00:00:00 2001 From: MilkeeyCat Date: Sun, 2 Jun 2024 15:54:37 +0300 Subject: [PATCH] refactor: return `Result` instead of panic --- src/parser/expr/expr.rs | 5 ++++- src/parser/parser.rs | 17 ++++++++--------- src/parser/type_.rs | 31 ++++++++++++++++++------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/parser/expr/expr.rs b/src/parser/expr/expr.rs index 246fc9f..95b1a10 100644 --- a/src/parser/expr/expr.rs +++ b/src/parser/expr/expr.rs @@ -54,7 +54,10 @@ impl Expr { let left_type = expr.left.as_ref().type_(symtable); let right_type = expr.right.as_ref().type_(symtable); - Type::resolve(left_type, right_type) + match Type::promote(left_type, right_type) { + Ok(type_) => type_, + Err(e) => panic!("{:?}", e), + } } Self::Unary(expr) => expr.type_(symtable), Self::Lit(literal) => match literal { diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 50c6edd..b733195 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -157,17 +157,16 @@ impl Parser { let right = Box::new(self.expr(token.precedence())); let op = BinOp::from(&token); - if op == BinOp::Assign { - if !left + if op == BinOp::Assign + && !left .type_(&self.symtable) .assignable(&right.type_(&self.symtable)) - { - panic!( - "Cant assign {:?} to {:?}", - right.type_(&self.symtable), - left.type_(&self.symtable) - ); - } + { + panic!( + "Cant assign {:?} to {:?}", + right.type_(&self.symtable), + left.type_(&self.symtable) + ); } Expr::Binary(ExprBinary::new(op, left, right)) diff --git a/src/parser/type_.rs b/src/parser/type_.rs index 692c9c9..87e5509 100644 --- a/src/parser/type_.rs +++ b/src/parser/type_.rs @@ -4,6 +4,11 @@ pub enum Type { I8, } +#[derive(Debug)] +pub enum TypeError { + PromotionError(Type, Type), +} + impl Type { fn int(&self) -> bool { match self { @@ -28,29 +33,29 @@ impl Type { } } - pub fn resolve(left: Self, right: Self) -> Self { - if left == right { - return left; + pub fn promote(self, type_: Self) -> Result { + if self == type_ { + return Ok(self); } - if left.int() && right.int() { - return Self::resolve_ints(left, right); + if self.int() && type_.int() { + return self.promote_ints(type_); } - todo!(); + Err(TypeError::PromotionError(self, type_)) } - fn resolve_ints(mut left: Self, mut right: Self) -> Self { - if left.signed() || left.signed() { - left.to_signed(); - right.to_signed(); + fn promote_ints(mut self, mut type_: Self) -> Result { + if self.signed() || type_.signed() { + self.to_signed(); + type_.to_signed(); } - if left > right { - return left; + if self > type_ { + return Ok(self); } - right + Ok(type_) } pub fn assignable(&self, type_: &Self) -> bool {