Refactor compile pipeline into helper function
This commit is contained in:
+27
-67
@@ -405,17 +405,27 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_untyped(&self, untyped_ast: Node<UntypedKind>) -> Result<TypedNode, String> {
|
fn compile_pipeline(&self, untyped_ast: Node<UntypedKind>, diagnostics: &mut Diagnostics) -> Option<TypedNode> {
|
||||||
let mut diagnostics = Diagnostics::new();
|
let expanded_ast = match self.get_expander().expand(untyped_ast) {
|
||||||
|
Ok(ast) => ast,
|
||||||
let expanded_ast = self.get_expander().expand(untyped_ast)?;
|
Err(e) => {
|
||||||
|
diagnostics.push_error(e, None);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let (bound_ast, captures) =
|
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);
|
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 mut values = self.global_values.borrow_mut();
|
||||||
let names = self.global_names.borrow();
|
let names = self.global_names.borrow();
|
||||||
@@ -446,9 +456,15 @@ impl Environment {
|
|||||||
ty: (),
|
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
|
return Err(diagnostics
|
||||||
.items
|
.items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -457,7 +473,7 @@ impl Environment {
|
|||||||
.join("\n"));
|
.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(typed_ast)
|
Ok(typed_ast_opt.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_native(
|
pub fn register_native(
|
||||||
@@ -536,66 +552,10 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
let mut diagnostics = parser.diagnostics;
|
let mut diagnostics = parser.diagnostics;
|
||||||
|
|
||||||
let expanded_ast = match self.get_expander().expand(untyped_ast) {
|
let typed_ast = self.compile_pipeline(untyped_ast, &mut diagnostics);
|
||||||
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);
|
|
||||||
|
|
||||||
CompilationResult {
|
CompilationResult {
|
||||||
ast: Some(typed_ast),
|
ast: typed_ast,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user