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
+47 -28
View File
@@ -78,7 +78,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
fn expand_recursive(&mut self, node: Node<UntypedKind>) -> Result<Node<UntypedKind>, String> {
match node.kind {
UntypedKind::MacroDecl { name, params, body } => {
let p_names: Vec<Rc<str>> = params.into_iter().map(|s| s.name).collect();
let p_names = self.extract_param_names(&params)?;
self.registry.define(name.name, p_names, *body);
Ok(Node {
identity: node.identity,
@@ -90,25 +90,27 @@ impl<E: MacroEvaluator> MacroExpander<E> {
UntypedKind::Call { callee, args } => {
if let UntypedKind::Identifier(ref sym) = callee.kind
&& let Some((params, body)) = self.registry.lookup(&sym.name) {
let mut expanded_args = Vec::new();
for arg in args {
expanded_args.push(self.expand_recursive(arg)?);
}
let expanded = self.expand_call(node.identity.clone(), &sym.name, params, expanded_args, body)?;
let expanded_args = self.expand_recursive(*args)?;
// Extract argument nodes from the expanded tuple
let arg_elements = if let UntypedKind::Tuple { elements } = expanded_args.kind {
elements
} else {
vec![expanded_args]
};
let expanded = self.expand_call(node.identity.clone(), &sym.name, params, arg_elements, body)?;
return self.expand_recursive(expanded);
}
let expanded_callee = self.expand_recursive(*callee)?;
let mut expanded_args = Vec::new();
for arg in args {
expanded_args.push(self.expand_recursive(arg)?);
}
let expanded_args = self.expand_recursive(*args)?;
Ok(Node {
identity: node.identity,
kind: UntypedKind::Call {
callee: Box::new(expanded_callee),
args: expanded_args,
args: Box::new(expanded_args),
},
ty: (),
})
@@ -131,12 +133,16 @@ impl<E: MacroEvaluator> MacroExpander<E> {
UntypedKind::Lambda { params, body } => {
self.registry.push();
let expanded_params = self.expand_recursive(*params)?;
let expanded_body = self.expand_recursive(Node::clone(&body))?;
self.registry.pop();
Ok(Node {
identity: node.identity,
kind: UntypedKind::Lambda { params, body: Rc::new(expanded_body) },
kind: UntypedKind::Lambda {
params: Box::new(expanded_params),
body: Rc::new(expanded_body)
},
ty: (),
})
}
@@ -242,7 +248,11 @@ impl<E: MacroEvaluator> MacroExpander<E> {
kind: UntypedKind::Identifier(Symbol::from(name)),
ty: (),
}),
args: bindings.into_values().collect(),
args: Box::new(Node {
identity: identity.clone(),
kind: UntypedKind::Tuple { elements: bindings.into_values().collect() },
ty: (),
}),
},
ty: (),
};
@@ -257,6 +267,20 @@ impl<E: MacroEvaluator> MacroExpander<E> {
})
}
fn extract_param_names(&self, node: &Node<UntypedKind>) -> Result<Vec<Rc<str>>, String> {
match &node.kind {
UntypedKind::Parameter(sym) => Ok(vec![sym.name.clone()]),
UntypedKind::Tuple { elements } => {
let mut names = Vec::new();
for el in elements {
names.extend(self.extract_param_names(el)?);
}
Ok(names)
}
_ => Err("Invalid parameter pattern in macro declaration".to_string()),
}
}
fn expand_template(&self, node: Node<UntypedKind>, state: &mut ExpansionState) -> Result<Node<UntypedKind>, String> {
match node.kind {
UntypedKind::Identifier(mut sym) => {
@@ -265,6 +289,11 @@ impl<E: MacroEvaluator> MacroExpander<E> {
Ok(Node { identity: node.identity, kind: UntypedKind::Identifier(sym), ty: () })
}
UntypedKind::Parameter(mut sym) => {
sym.context = Some(state.expansion_id.clone());
Ok(Node { identity: node.identity, kind: UntypedKind::Parameter(sym), ty: () })
}
UntypedKind::Placeholder(inner) => {
// Break out of template for substitution/evaluation
if let UntypedKind::Identifier(ref sym) = inner.kind
@@ -353,18 +382,10 @@ impl<E: MacroEvaluator> MacroExpander<E> {
UntypedKind::Call { callee, args } => {
let expanded_callee = self.expand_template(*callee, state)?;
let mut expanded_args = Vec::new();
for arg in args {
if let UntypedKind::Splice(ref inner) = arg.kind {
let val = self.evaluator.evaluate(inner, state.bindings)?;
self.handle_splice_value(val, node.identity.clone(), &mut expanded_args)?;
} else {
expanded_args.push(self.expand_template(arg, state)?);
}
}
let expanded_args = self.expand_template(*args, state)?;
Ok(Node {
identity: node.identity,
kind: UntypedKind::Call { callee: Box::new(expanded_callee), args: expanded_args },
kind: UntypedKind::Call { callee: Box::new(expanded_callee), args: Box::new(expanded_args) },
ty: (),
})
}
@@ -384,14 +405,12 @@ impl<E: MacroEvaluator> MacroExpander<E> {
})
}
UntypedKind::Lambda { mut params, body } => {
for p in &mut params {
p.context = Some(state.expansion_id.clone());
}
UntypedKind::Lambda { params, body } => {
let expanded_params = self.expand_template(*params, state)?;
let body = self.expand_template(Node::clone(&body), state)?;
Ok(Node {
identity: node.identity,
kind: UntypedKind::Lambda { params, body: Rc::new(body) },
kind: UntypedKind::Lambda { params: Box::new(expanded_params), body: Rc::new(body) },
ty: (),
})
}