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:
+23
-14
@@ -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)
|
||||
}))
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user