Refactor compile pipeline into helper function

This commit is contained in:
Michael Schimmel
2026-03-06 23:28:22 +01:00
parent f797ac37bf
commit 00ce13b17e
+27 -67
View File
@@ -405,17 +405,27 @@ impl Environment {
}
}
pub fn compile_untyped(&self, untyped_ast: Node<UntypedKind>) -> Result<TypedNode, String> {
let mut diagnostics = Diagnostics::new();
let expanded_ast = self.get_expander().expand(untyped_ast)?;
fn compile_pipeline(&self, untyped_ast: Node<UntypedKind>, diagnostics: &mut Diagnostics) -> Option<TypedNode> {
let expanded_ast = match self.get_expander().expand(untyped_ast) {
Ok(ast) => ast,
Err(e) => {
diagnostics.push_error(e, None);
return None;
}
};
let (bound_ast, captures) =
Binder::bind_root(self.global_names.clone(), &expanded_ast, &mut diagnostics)?;
match Binder::bind_root(self.global_names.clone(), &expanded_ast, diagnostics) {
Ok(res) => res,
Err(e) => {
diagnostics.push_error(e, None);
return None;
}
};
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
// Pre-allocate global slots
// Pre-allocate global slots to prevent out-of-bounds during specialization/optimization
{
let mut values = self.global_values.borrow_mut();
let names = self.global_names.borrow();
@@ -446,9 +456,15 @@ impl Environment {
ty: (),
}
};
let typed_ast = checker.check(&wrapped_ast, &[], &mut diagnostics);
Some(checker.check(&wrapped_ast, &[], diagnostics))
}
if diagnostics.has_errors() {
pub fn compile_untyped(&self, untyped_ast: Node<UntypedKind>) -> Result<TypedNode, String> {
let mut diagnostics = Diagnostics::new();
let typed_ast_opt = self.compile_pipeline(untyped_ast, &mut diagnostics);
if diagnostics.has_errors() || typed_ast_opt.is_none() {
return Err(diagnostics
.items
.into_iter()
@@ -457,7 +473,7 @@ impl Environment {
.join("\n"));
}
Ok(typed_ast)
Ok(typed_ast_opt.unwrap())
}
pub fn register_native(
@@ -536,66 +552,10 @@ impl Environment {
}
let mut diagnostics = parser.diagnostics;
let expanded_ast = match self.get_expander().expand(untyped_ast) {
Ok(ast) => ast,
Err(e) => {
diagnostics.push_error(e, None);
return CompilationResult {
ast: None,
diagnostics,
};
}
};
let (bound_ast, captures) =
match Binder::bind_root(self.global_names.clone(), &expanded_ast, &mut diagnostics) {
Ok(res) => res,
Err(e) => {
diagnostics.push_error(e, None);
return CompilationResult {
ast: None,
diagnostics,
};
}
};
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
// Pre-allocate global slots to prevent out-of-bounds during specialization/optimization
{
let mut values = self.global_values.borrow_mut();
let names = self.global_names.borrow();
let max_idx = names.values().map(|(idx, _)| idx.0).max().unwrap_or(0);
if (max_idx as usize) >= values.len() {
values.resize((max_idx + 1) as usize, Value::Void);
}
}
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
let checker = TypeChecker::new(self.global_types.clone());
let wrapped_ast = if let crate::ast::compiler::bound_nodes::BoundKind::Lambda { .. } = bound_ast.kind {
bound_ast
} else {
crate::ast::compiler::bound_nodes::BoundNode {
identity: bound_ast.identity.clone(),
kind: crate::ast::compiler::bound_nodes::BoundKind::Lambda {
params: std::rc::Rc::new(crate::ast::nodes::Node {
identity: bound_ast.identity.clone(),
kind: crate::ast::compiler::bound_nodes::BoundKind::Tuple { elements: vec![] },
ty: (),
}),
upvalues: vec![],
body: std::rc::Rc::new(bound_ast),
positional_count: Some(0),
},
ty: (),
}
};
let typed_ast = checker.check(&wrapped_ast, &[], &mut diagnostics);
let typed_ast = self.compile_pipeline(untyped_ast, &mut diagnostics);
CompilationResult {
ast: Some(typed_ast),
ast: typed_ast,
diagnostics,
}
}