From e62a53fd2826bc9ca5ec657b89f4af93a4049fca Mon Sep 17 00:00:00 2001 From: bakk Date: Sun, 23 Jan 2022 02:19:38 +0100 Subject: [PATCH] Allow re-definition of functions --- kalk/src/analysis.rs | 43 +++++++++++++++++++++++++++++++-- kalk/src/integration_testing.rs | 1 + tests/redefining.kalker | 6 +++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/redefining.kalker diff --git a/kalk/src/analysis.rs b/kalk/src/analysis.rs index db88851..92e4681 100644 --- a/kalk/src/analysis.rs +++ b/kalk/src/analysis.rs @@ -82,7 +82,46 @@ fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result { - build_fn_decl(context, *identifier_expr, *parameter_expr, *right)? + build_fn_decl_from_scratch(context, *identifier_expr, *parameter_expr, *right)? + } + Expr::FnCall(identifier, arguments) => { + // First loop through with a reference + // to arguments, to be able to back-track if + // one of the arguments can't be made into a parameter. + if identifier.prime_count != 0 + || arguments + .iter() + .any(|argument| !matches!(argument, Expr::Var(_))) + { + // Analyse as 0f64 + fn_call = right so that + // it won't come here again. + return analyse_stmt_expr( + context, + Expr::Binary( + Box::new(Expr::Binary( + Box::new(Expr::Literal(0f64)), + TokenKind::Plus, + Box::new(Expr::FnCall(identifier, arguments)), + )), + TokenKind::Equals, + right, + ), + ); + } + + let mut parameters = Vec::new(); + for argument in arguments { + if let Expr::Var(parameter_identifier) = argument { + parameters.push(parameter_identifier.full_name); + } else { + unreachable!() + } + } + + let fn_decl = Stmt::FnDecl(identifier, parameters, right); + context.symbol_table.insert(fn_decl.clone()); + + fn_decl } Expr::Var(identifier) if !context.in_conditional => { if inverter::contains_var(context.symbol_table, &right, &identifier.full_name) { @@ -111,7 +150,7 @@ fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result