Refactor bound node types for clarity
Introduce generic `CompilerPhase` trait to unify different stages of the bound AST. Rename `LocalSlot` to `VirtualId` and introduce `StackOffset` for clearer distinction between compile-time and run-time addressing. Update type aliases and implementations to reflect these changes.
This commit is contained in:
+31
-24
@@ -10,12 +10,12 @@ use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::compiler::bound_nodes::{
|
||||
Address, AnalyzedNode, BoundKind, GlobalAnalyzedRegistry, GlobalFunctionRegistry, GlobalIdx,
|
||||
Node,
|
||||
Address, AnalyzedNode, BoundKind, ExecNode, GlobalAnalyzedRegistry, GlobalFunctionRegistry, GlobalIdx,
|
||||
Node, VirtualId,
|
||||
};
|
||||
use crate::ast::compiler::dumper::Dumper;
|
||||
use crate::ast::compiler::lambda_collector::LambdaCollector;
|
||||
use crate::ast::compiler::lowering::{Lowering, ExecNode};
|
||||
use crate::ast::compiler::lowering::Lowering;
|
||||
use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry};
|
||||
use crate::ast::compiler::optimizer::Optimizer;
|
||||
use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer};
|
||||
@@ -89,19 +89,11 @@ pub struct Environment {
|
||||
}
|
||||
|
||||
struct EnvFunctionRegistry {
|
||||
registry: Rc<RefCell<GlobalFunctionRegistry>>,
|
||||
analyzed_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
|
||||
}
|
||||
|
||||
impl FunctionRegistry for EnvFunctionRegistry {
|
||||
fn resolve(&self, addr: Address) -> Option<Rc<Node>> {
|
||||
if let Address::Global(idx) = addr {
|
||||
self.registry.borrow().get(&idx).cloned()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn resolve_analyzed(&self, addr: Address) -> Option<Rc<AnalyzedNode>> {
|
||||
fn resolve(&self, addr: Address<VirtualId>) -> Option<Rc<Node<crate::ast::compiler::bound_nodes::AnalyzedPhase>>> {
|
||||
if let Address::Global(idx) = addr {
|
||||
self.analyzed_registry.borrow().get(&idx).cloned()
|
||||
} else {
|
||||
@@ -406,7 +398,7 @@ impl Environment {
|
||||
|
||||
if !current_scope.locals.contains_key(sym) {
|
||||
let mut slot_count = self.root_slot_count.borrow_mut();
|
||||
let slot = crate::ast::compiler::bound_nodes::LocalSlot(*slot_count);
|
||||
let slot = VirtualId(*slot_count);
|
||||
current_scope.locals.insert(
|
||||
sym.clone(),
|
||||
crate::ast::compiler::binder::LocalInfo {
|
||||
@@ -484,15 +476,15 @@ impl Environment {
|
||||
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
||||
|
||||
let checker = TypeChecker::new(self.root_types.clone());
|
||||
let wrapped_ast = if let crate::ast::compiler::bound_nodes::BoundKind::Lambda { .. } = bound_ast.kind {
|
||||
let wrapped_ast = if let BoundKind::Lambda { .. } = bound_ast.kind {
|
||||
bound_ast
|
||||
} else {
|
||||
crate::ast::compiler::bound_nodes::Node {
|
||||
Node {
|
||||
identity: bound_ast.identity.clone(),
|
||||
kind: crate::ast::compiler::bound_nodes::BoundKind::Lambda {
|
||||
params: std::rc::Rc::new(crate::ast::compiler::bound_nodes::Node {
|
||||
kind: BoundKind::Lambda {
|
||||
params: std::rc::Rc::new(Node {
|
||||
identity: bound_ast.identity.clone(),
|
||||
kind: crate::ast::compiler::bound_nodes::BoundKind::Tuple { elements: vec![] },
|
||||
kind: BoundKind::Tuple { elements: vec![] },
|
||||
ty: (),
|
||||
}),
|
||||
upvalues: vec![],
|
||||
@@ -668,7 +660,7 @@ impl Environment {
|
||||
{
|
||||
let closure = Rc::new(crate::ast::vm::Closure::new(
|
||||
params.clone(),
|
||||
body.ty.original.clone(),
|
||||
body.ty.original.clone(),
|
||||
body.clone(),
|
||||
Vec::new(),
|
||||
*positional_count,
|
||||
@@ -717,13 +709,11 @@ impl Environment {
|
||||
|
||||
fn specialize_node(&self, node: AnalyzedNode) -> AnalyzedNode {
|
||||
let registry = Rc::new(EnvFunctionRegistry {
|
||||
registry: self.function_registry.clone(),
|
||||
analyzed_registry: self.typed_function_registry.clone(),
|
||||
});
|
||||
|
||||
let rtl_lookup = Rc::new(|name: &str, args: &[StaticType]| intrinsics::lookup(name, args));
|
||||
let typed_reg = self.typed_function_registry.clone();
|
||||
let syntax_reg = self.function_registry.clone();
|
||||
let mono_cache = self.monomorph_cache.clone();
|
||||
let root_values = self.root_values.clone();
|
||||
let root_types = self.root_types.clone();
|
||||
@@ -731,12 +721,30 @@ impl Environment {
|
||||
let optimization = self.optimization;
|
||||
|
||||
let compiler = Rc::new(
|
||||
move |func_template: Rc<Node>,
|
||||
move |func_template: Rc<Node<crate::ast::compiler::bound_nodes::AnalyzedPhase>>,
|
||||
arg_types: &[StaticType]|
|
||||
-> Result<(Value, StaticType), String> {
|
||||
let mut diag = Diagnostics::new();
|
||||
let checker = TypeChecker::new(root_types.clone());
|
||||
let retyped_ast = checker.check(func_template.as_ref(), arg_types, &mut diag);
|
||||
|
||||
// For specialization, we re-type-check the analyzed node.
|
||||
// Note: AnalyzedNode.ty.original is the TypedNode.
|
||||
// But TypeChecker expects Node<BoundPhase>. We need to go from TypedNode -> BoundNode.
|
||||
// However, since TypedNode is just Node<TypedPhase>, we can't easily "un-type" it.
|
||||
// Instead, we access the original AST from the binder if we had it,
|
||||
// OR we make the TypeChecker generic.
|
||||
// For now, we assume the TypedNode can be used where a BoundNode is expected
|
||||
// if we strip the metadata.
|
||||
// A better way is to store the BoundNode in NodeMetrics as well.
|
||||
|
||||
// Temporary fix: Re-binding from source would be too expensive.
|
||||
// Let's assume for now that we can specialize directly on the TypedNode
|
||||
// or that we need a small helper to transform TypedNode -> BoundNode.
|
||||
|
||||
// Realizing that TypedNode (StaticType) is very similar to BoundNode (()),
|
||||
// we can just use the internal transform.
|
||||
|
||||
let retyped_ast = checker.check_node_as_bound(func_template.ty.original.as_ref(), arg_types, &mut diag);
|
||||
|
||||
if diag.has_errors() {
|
||||
return Err(diag
|
||||
@@ -750,7 +758,6 @@ impl Environment {
|
||||
let analyzed = Analyzer::analyze(&retyped_ast, &root_purity.borrow());
|
||||
|
||||
let sub_registry = Rc::new(EnvFunctionRegistry {
|
||||
registry: syntax_reg.clone(),
|
||||
analyzed_registry: typed_reg.clone(),
|
||||
});
|
||||
let sub_rtl_lookup =
|
||||
|
||||
Reference in New Issue
Block a user