diff --git a/kalk/src/inverter.rs b/kalk/src/inverter.rs index 11d0b2d..b474c34 100644 --- a/kalk/src/inverter.rs +++ b/kalk/src/inverter.rs @@ -1,9 +1,10 @@ use crate::ast::{Expr, Stmt}; use crate::lexer::TokenKind; +use crate::parser::CalcError; use crate::symbol_table::SymbolTable; impl Expr { - pub fn invert(&self, symbol_table: &mut SymbolTable) -> Self { + pub fn invert(&self, symbol_table: &mut SymbolTable) -> Result { match self { Expr::Binary(left, op, right) => invert_binary(symbol_table, &left, op, &right), Expr::Unary(op, expr) => invert_unary(op, &expr), @@ -23,7 +24,7 @@ fn invert_binary( left: &Expr, op: &TokenKind, right: &Expr, -) -> Expr { +) -> Result { let op_inv = match op { TokenKind::Plus => TokenKind::Minus, TokenKind::Minus => TokenKind::Plus, @@ -32,38 +33,50 @@ fn invert_binary( _ => unreachable!(), }; - Expr::Binary( - Box::new(right.invert(symbol_table)), + Ok(Expr::Binary( + Box::new(right.invert(symbol_table)?), op_inv, - Box::new(left.invert(symbol_table)), - ) + Box::new(left.invert(symbol_table)?), + )) } -fn invert_unary(op: &TokenKind, expr: &Expr) -> Expr { - match op { +fn invert_unary(op: &TokenKind, expr: &Expr) -> Result { + Ok(match op { TokenKind::Minus => expr.clone(), TokenKind::Exclamation => unimplemented!(), _ => unreachable!(), - } + }) } // Not necessary yet -fn invert_unit(_identifier: &str, _expr: &Expr) -> Expr { +fn invert_unit(_identifier: &str, _expr: &Expr) -> Result { unimplemented!() } -fn invert_group(expr: &Expr) -> Expr { +fn invert_group(expr: &Expr) -> Result { invert_value(expr) } -fn invert_fn_call(symbol_table: &mut SymbolTable, identifier: &str, arguments: &Vec) -> Expr { +fn invert_fn_call( + symbol_table: &mut SymbolTable, + identifier: &str, + arguments: &Vec, +) -> Result { let (parameters, body) = if let Some(Stmt::FnDecl(_, parameters, body)) = symbol_table.get_fn(identifier).cloned() { (parameters, body) } else { - panic!(); // TODO: Error checking + return Err(CalcError::UndefinedFn(identifier.into())); }; + if parameters.len() != arguments.len() { + return Err(CalcError::IncorrectAmountOfArguments( + parameters.len(), + identifier.into(), + arguments.len(), + )); + } + let mut parameters_iter = parameters.iter(); for argument in arguments { symbol_table.insert(Stmt::VarDecl( @@ -75,6 +88,6 @@ fn invert_fn_call(symbol_table: &mut SymbolTable, identifier: &str, arguments: & body.invert(symbol_table) } -fn invert_value(expr: &Expr) -> Expr { - Expr::Unary(TokenKind::Minus, Box::new(expr.clone())) +fn invert_value(expr: &Expr) -> Result { + Ok(Expr::Unary(TokenKind::Minus, Box::new(expr.clone()))) } diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index a998799..be474be 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -187,7 +187,7 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result { let stmt_inv = Stmt::UnitDecl( base_unit.clone(), identifier.value.clone(), - Box::new(def.invert(&mut context.symbol_table)), + Box::new(def.invert(&mut context.symbol_table)?), ); let stmt = Stmt::UnitDecl(identifier.value, base_unit, Box::new(def));