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:
+47
-28
@@ -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(¶ms)?;
|
||||
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: (),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user