Skip to content

Commit

Permalink
refactor: return Result instead of panic
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed Jun 2, 2024
1 parent f7fdf8d commit fd3cbc4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 23 deletions.
5 changes: 4 additions & 1 deletion src/parser/expr/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
17 changes: 8 additions & 9 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
31 changes: 18 additions & 13 deletions src/parser/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ pub enum Type {
I8,
}

#[derive(Debug)]
pub enum TypeError {
PromotionError(Type, Type),
}

impl Type {
fn int(&self) -> bool {
match self {
Expand All @@ -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<Self, TypeError> {
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<Self, TypeError> {
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 {
Expand Down

0 comments on commit fd3cbc4

Please sign in to comment.