From 05bfabb1d4a8c2a4dd95208eb3e5fbf5fb08e588 Mon Sep 17 00:00:00 2001 From: PaddiM8 Date: Sat, 13 Jun 2020 20:06:21 +0200 Subject: [PATCH] Made it possible for the inverter to invert expressions with function calls. --- kalk/src/inverter.rs | 50 ++++++++++++++++++++++++++++++++++---------- kalk/src/parser.rs | 2 +- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/kalk/src/inverter.rs b/kalk/src/inverter.rs index d79486c..11d0b2d 100644 --- a/kalk/src/inverter.rs +++ b/kalk/src/inverter.rs @@ -1,21 +1,29 @@ -use crate::ast::Expr; +use crate::ast::{Expr, Stmt}; use crate::lexer::TokenKind; +use crate::symbol_table::SymbolTable; impl Expr { - pub fn invert(&self) -> Self { + pub fn invert(&self, symbol_table: &mut SymbolTable) -> Self { match self { - Expr::Binary(left, op, right) => invert_binary(&left, op, &right), + Expr::Binary(left, op, right) => invert_binary(symbol_table, &left, op, &right), Expr::Unary(op, expr) => invert_unary(op, &expr), Expr::Unit(identifier, expr) => invert_unit(&identifier, &expr), - Expr::Var(identifier) => invert_value(self), + Expr::Var(_) => invert_value(self), Expr::Group(expr) => invert_group(&expr), - Expr::FnCall(identifier, expressions) => invert_fn_call(&identifier, expressions), - Expr::Literal(value) => invert_value(self), + Expr::FnCall(identifier, arguments) => { + invert_fn_call(symbol_table, &identifier, arguments) + } + Expr::Literal(_) => invert_value(self), } } } -fn invert_binary(left: &Expr, op: &TokenKind, right: &Expr) -> Expr { +fn invert_binary( + symbol_table: &mut SymbolTable, + left: &Expr, + op: &TokenKind, + right: &Expr, +) -> Expr { let op_inv = match op { TokenKind::Plus => TokenKind::Minus, TokenKind::Minus => TokenKind::Plus, @@ -24,7 +32,11 @@ fn invert_binary(left: &Expr, op: &TokenKind, right: &Expr) -> Expr { _ => unreachable!(), }; - Expr::Binary(Box::new(right.invert()), op_inv, Box::new(left.invert())) + Expr::Binary( + Box::new(right.invert(symbol_table)), + op_inv, + Box::new(left.invert(symbol_table)), + ) } fn invert_unary(op: &TokenKind, expr: &Expr) -> Expr { @@ -35,7 +47,8 @@ fn invert_unary(op: &TokenKind, expr: &Expr) -> Expr { } } -fn invert_unit(identifier: &str, expr: &Expr) -> Expr { +// Not necessary yet +fn invert_unit(_identifier: &str, _expr: &Expr) -> Expr { unimplemented!() } @@ -43,8 +56,23 @@ fn invert_group(expr: &Expr) -> Expr { invert_value(expr) } -fn invert_fn_call(identifier: &str, expressions: &Vec) -> Expr { - unimplemented!() +fn invert_fn_call(symbol_table: &mut SymbolTable, identifier: &str, arguments: &Vec) -> Expr { + let (parameters, body) = + if let Some(Stmt::FnDecl(_, parameters, body)) = symbol_table.get_fn(identifier).cloned() { + (parameters, body) + } else { + panic!(); // TODO: Error checking + }; + + let mut parameters_iter = parameters.iter(); + for argument in arguments { + symbol_table.insert(Stmt::VarDecl( + parameters_iter.next().unwrap().to_string(), + Box::new(argument.clone()), + )); + } + + body.invert(symbol_table) } fn invert_value(expr: &Expr) -> Expr { diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index bdf37db..a998799 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()), + Box::new(def.invert(&mut context.symbol_table)), ); let stmt = Stmt::UnitDecl(identifier.value, base_unit, Box::new(def));