Refactor lambda binding and parameter handling

Introduce `BoundKind::Parameter` to represent function parameters.
Modify `Binder` to correctly handle parameters within lambda
definitions, ensuring they are only defined within function scopes.
Update `LambdaCollector` to register the body of lambdas as templates
for global definitions.
Adjust `Dumper` to accurately represent lambda parameters.
Update `Specializer` and `TCO` to handle the new `BoundKind::Parameter`.
Refactor `Call` and `TailCall` to use a single `args` node, often a
tuple.
Adjust type signatures in RTL to use `StaticType::Tuple` for function
parameters.
This commit is contained in:
Michael Schimmel
2026-02-20 12:14:22 +01:00
parent 8d6d3be5c2
commit e2279f214b
17 changed files with 497 additions and 247 deletions
+23 -14
View File
@@ -110,6 +110,19 @@ impl Binder {
}))
},
UntypedKind::Parameter(sym) => {
// Parameters are ONLY allowed if we are inside a function (Binder stack > 1)
if self.functions.len() <= 1 {
return Err(format!("Parameter '{}' is not allowed in root scope.", sym.name));
}
let current_fn = self.functions.last_mut().unwrap();
let slot = current_fn.scope.define(sym)?;
Ok(self.make_node(node.identity.clone(), BoundKind::Parameter {
name: sym.clone(),
slot
}))
},
UntypedKind::If { cond, then_br, else_br } => {
let cond = self.bind(cond)?;
let then_br = self.bind(then_br)?;
@@ -176,20 +189,19 @@ impl Binder {
},
UntypedKind::Lambda { params, body } => {
let identity = node.identity.clone();
self.functions.push(FunctionCompiler::new());
{
let current_fn = self.functions.last_mut().unwrap();
for param in params {
current_fn.scope.define(param)?;
}
}
// 1. Bind the parameter pattern/tuple
let params_bound = self.bind(params)?;
// 2. Bind the body
let body_bound = self.bind(body)?;
let compiled_fn = self.functions.pop().unwrap();
Ok(self.make_node(node.identity.clone(), BoundKind::Lambda {
param_count: params.len() as u32,
Ok(self.make_node(identity, BoundKind::Lambda {
params: Box::new(params_bound),
upvalues: compiled_fn.upvalues,
body: Rc::new(body_bound),
}))
@@ -197,14 +209,11 @@ impl Binder {
UntypedKind::Call { callee, args } => {
let callee = self.bind(callee)?;
let mut bound_args = Vec::new();
for arg in args {
bound_args.push(self.bind(arg)?);
}
let args = self.bind(args)?;
Ok(self.make_node(node.identity.clone(), BoundKind::Call {
callee: Box::new(callee),
args: bound_args
args: Box::new(args)
}))
},