From 90f9afa0fd2410d08e5064190c2c7f8718831c2c Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 31 Mar 2026 16:42:13 +0200 Subject: [PATCH] Fix: Simplify type checker and optimizer Removes unnecessary lambda wrapping in the type checking pipeline. Adds optimization logic for `NodeKind::Program` to handle sequences of expressions. Removes debug print statements from the type checker. --- src/ast/compiler/optimizer/engine.rs | 29 +++++++++++++++++ src/ast/compiler/type_checker/check.rs | 13 -------- src/ast/compiler/type_checker/mod.rs | 2 -- src/ast/environment.rs | 45 +++----------------------- 4 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/ast/compiler/optimizer/engine.rs b/src/ast/compiler/optimizer/engine.rs index 7eb05b6..7079a61 100644 --- a/src/ast/compiler/optimizer/engine.rs +++ b/src/ast/compiler/optimizer/engine.rs @@ -792,6 +792,35 @@ impl Optimizer { node.ty.clone(), ) } + NodeKind::Program { exprs } => { + let mut new_exprs = Vec::with_capacity(exprs.len()); + let mut changed = false; + + for e in exprs { + let opt = self.visit_node(e.clone(), sub, path); + if !Rc::ptr_eq(&opt, e) { + changed = true; + } + new_exprs.push(opt); + } + + if new_exprs.len() == 1 { + return new_exprs.pop().unwrap(); + } + + if !changed { + return node_rc; + } + + let last_ty = new_exprs + .last() + .map(|e| e.ty.original.ty.clone()) + .unwrap_or(StaticType::Void); + ( + NodeKind::Program { exprs: new_exprs }, + refreshed_metrics(&node.ty, last_ty), + ) + } k => (k.clone(), node.ty.clone()), }; diff --git a/src/ast/compiler/type_checker/check.rs b/src/ast/compiler/type_checker/check.rs index 55a064a..a8bdbfa 100644 --- a/src/ast/compiler/type_checker/check.rs +++ b/src/ast/compiler/type_checker/check.rs @@ -529,20 +529,17 @@ impl TypeChecker { let param_hint_ty = StaticType::Tuple( (0..positional_count.unwrap_or(0)).map(|_| self.fresh_var()).collect(), ); - eprintln!("[TC] Lambda check_node: positional_count={:?} param_hint={}", positional_count, param_hint_ty.display_compact()); let params_typed = self.check_params( params.as_ref(), ¶m_hint_ty, &mut lambda_ctx, diag, ); - eprintln!("[TC] Lambda params_typed.ty={}", params_typed.ty.display_compact()); lambda_ctx.current_params_ty = Some(params_typed.ty.clone()); let body_typed = self.check_node(body, &mut lambda_ctx, diag); let ret_ty = body_typed.ty.clone(); - eprintln!("[TC] Lambda body ret_ty={}", ret_ty.display_compact()); let fn_ty = StaticType::Function(Box::new(Signature { params: params_typed.ty.clone(), @@ -563,9 +560,7 @@ impl TypeChecker { } NodeKind::Call { callee, args } => { - eprintln!("[TC] Call: checking callee..."); let callee_typed = self.check_node(callee, ctx, diag); - eprintln!("[TC] Call: callee_typed.ty={}", callee_typed.ty.display_compact()); let args_typed = if let NodeKind::Tuple { elements } = &args.kind { let arg_count = elements.len(); @@ -624,7 +619,6 @@ impl TypeChecker { self.check_node(args, ctx, diag) }; - eprintln!("[TC] Call: args_typed.ty={}", args_typed.ty.display_compact()); let mut ret_ty = match callee_typed.ty.resolve_call(&args_typed.ty) { Some(ty) => ty, None => { @@ -688,16 +682,9 @@ impl TypeChecker { if let StaticType::Function(sig) = &callee_typed.ty && Self::has_typevar_component(&sig.params) { - eprintln!("[TC] HM10: unify params={} with args={}", sig.params.display_compact(), args_typed.ty.display_compact()); let params = sig.params.clone(); self.unify(params, args_typed.ty.clone(), diag); ret_ty = Self::apply_subst(ret_ty, &self.subst.borrow()); - eprintln!("[TC] HM10: after unify ret_ty={}", ret_ty.display_compact()); - } else { - eprintln!("[TC] HM10: SKIPPED (callee_ty={}, has_typevar={})", - callee_typed.ty.display_compact(), - if let StaticType::Function(sig) = &callee_typed.ty { Self::has_typevar_component(&sig.params) } else { false } - ); } // Dispatch compiler hooks registered by the RTL (keyed by global slot index). diff --git a/src/ast/compiler/type_checker/mod.rs b/src/ast/compiler/type_checker/mod.rs index 52e3e76..a29536b 100644 --- a/src/ast/compiler/type_checker/mod.rs +++ b/src/ast/compiler/type_checker/mod.rs @@ -70,7 +70,6 @@ impl TypeChecker { ) -> TypedNode { match &node.kind { NodeKind::Lambda { params, body, info } => { - eprintln!("[TC] check_node_as_bound: Lambda entry"); let upvalues = &info.upvalues; let positional_count = info.positional_count; @@ -116,7 +115,6 @@ impl TypeChecker { } } NodeKind::Block { .. } | NodeKind::Program { .. } => { - eprintln!("[TC] check_node_as_bound: Block/Program entry"); let mut ctx = TypeContext::new(64, vec![], &self.root_types, None); self.check_node(node, &mut ctx, diag) } diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 135e800..8ea961f 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -12,7 +12,7 @@ use std::rc::Rc; use crate::ast::nodes::{ Address, AnalyzedNode, ExecNode, GlobalAnalyzedRegistry, GlobalFunctionRegistry, GlobalIdx, - LambdaBinding, Node, NodeKind, VirtualId, + Node, NodeKind, VirtualId, }; use crate::ast::compiler::dumper::Dumper; use crate::ast::compiler::lambda_collector::LambdaCollector; @@ -447,38 +447,11 @@ impl Environment { typed } - /// Wraps a bound AST in a parameterless lambda (unless it already is one). - fn wrap_as_lambda(&self, bound_ast: Node) -> Node { - if let NodeKind::Lambda { .. } = bound_ast.kind { - bound_ast - } else { - Node { - identity: bound_ast.identity.clone(), - kind: NodeKind::Lambda { - params: Rc::new(Node { - identity: bound_ast.identity.clone(), - kind: NodeKind::Tuple { elements: vec![] }, - ty: (), - comments: Rc::from([]), - }), - body: Rc::new(bound_ast), - info: LambdaBinding { - upvalues: vec![], - positional_count: Some(0), - }, - }, - ty: (), - comments: Rc::from([]), - } - } - } - - /// Full compilation pipeline: expand → bind → wrap → type-check. + /// Full compilation pipeline: expand → bind → type-check. fn compile_pipeline(&self, syntax_ast: SyntaxNode, diagnostics: &mut Diagnostics) -> Option { let expanded = self.expand(syntax_ast, diagnostics)?; let bound = self.bind_and_update(&expanded, diagnostics)?; - let wrapped = self.wrap_as_lambda(bound); - let typed = self.type_check(&wrapped, diagnostics); + let typed = self.type_check(&bound, diagnostics); Some(typed) } @@ -737,17 +710,7 @@ impl Environment { } let mut parser = Parser::new(source); - let syntax_ast = parser.parse_expression(); - - if !parser.at_eof() { - parser - .diagnostics - .push_error("Unexpected trailing expressions in script.", None); - return CompilationResult { - ast: None, - diagnostics: parser.diagnostics, - }; - } + let syntax_ast = parser.parse_program(); let mut diagnostics = parser.diagnostics; let typed_ast = self.compile_pipeline(syntax_ast, &mut diagnostics);