mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-06-25 20:21:44 +02:00
Made it possible for the inverter to invert expressions with function calls.
This commit is contained in:
parent
71df9f5454
commit
05bfabb1d4
@ -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>) -> Expr {
|
||||
unimplemented!()
|
||||
fn invert_fn_call(symbol_table: &mut SymbolTable, identifier: &str, arguments: &Vec<Expr>) -> 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 {
|
||||
|
@ -187,7 +187,7 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
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));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user