Refactor: Remove explicit upvalue analysis pass
The `UpvalueAnalyzer` pass is no longer necessary as the binder now directly tracks captures. This commit removes the `UpvalueAnalyzer` struct and associated logic from `src/ast/compiler/upvalues.rs`. The `Binder::bind_root` function now returns the `captures` map, which is then processed by a new `CapturePass` in `src/ast/environment.rs` before type checking. This consolidates capture logic within the binder and its subsequent processing steps.
This commit is contained in:
+18
-7
@@ -17,10 +17,12 @@ use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer
|
||||
use crate::ast::compiler::tco::{ExecNode, TCO};
|
||||
use crate::ast::rtl;
|
||||
use crate::ast::rtl::intrinsics;
|
||||
use crate::ast::types::{Object, Purity, StaticType, Value};
|
||||
use crate::ast::types::{
|
||||
Identity, NodeIdentity, Object, Purity, SourceLocation, StaticType, Value,
|
||||
};
|
||||
|
||||
pub struct Environment {
|
||||
pub global_names: Rc<RefCell<HashMap<Symbol, u32>>>,
|
||||
pub global_names: Rc<RefCell<HashMap<Symbol, (u32, Identity)>>>,
|
||||
pub global_types: Rc<RefCell<HashMap<u32, StaticType>>>,
|
||||
pub global_purity: Rc<RefCell<HashMap<u32, Purity>>>,
|
||||
pub global_values: Rc<RefCell<Vec<Value>>>,
|
||||
@@ -55,7 +57,7 @@ impl FunctionRegistry for EnvFunctionRegistry {
|
||||
}
|
||||
|
||||
struct RuntimeMacroEvaluator {
|
||||
global_names: Rc<RefCell<HashMap<Symbol, u32>>>,
|
||||
global_names: Rc<RefCell<HashMap<Symbol, (u32, Identity)>>>,
|
||||
global_types: Rc<RefCell<HashMap<u32, StaticType>>>,
|
||||
global_values: Rc<RefCell<Vec<Value>>>,
|
||||
}
|
||||
@@ -72,7 +74,8 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
return Ok(Value::Object(Rc::new(arg_node.clone()) as Rc<dyn Object>));
|
||||
}
|
||||
|
||||
let bound_ast = Binder::bind_root(self.global_names.clone(), node)?;
|
||||
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), node)?;
|
||||
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
|
||||
let checker = TypeChecker::new(self.global_types.clone());
|
||||
let typed_ast = checker.check(bound_ast, &[])?;
|
||||
let exec_ast = TCO::optimize(Analyzer::analyze(&typed_ast, &HashMap::new())); // Minimal analysis for macro eval
|
||||
@@ -131,7 +134,10 @@ impl Environment {
|
||||
let mut purity = self.global_purity.borrow_mut();
|
||||
|
||||
let idx = values.len() as u32;
|
||||
names.insert(Symbol::from(name), idx);
|
||||
let identity = Rc::new(NodeIdentity {
|
||||
location: SourceLocation { line: 0, col: 0 },
|
||||
});
|
||||
names.insert(Symbol::from(name), (idx, identity));
|
||||
types.insert(idx, ty);
|
||||
purity.insert(idx, func.purity);
|
||||
values.push(Value::Function(func));
|
||||
@@ -161,7 +167,10 @@ impl Environment {
|
||||
let mut purity = self.global_purity.borrow_mut();
|
||||
|
||||
let idx = values.len() as u32;
|
||||
names.insert(Symbol::from(name), idx);
|
||||
let identity = Rc::new(NodeIdentity {
|
||||
location: SourceLocation { line: 0, col: 0 },
|
||||
});
|
||||
names.insert(Symbol::from(name), (idx, identity));
|
||||
types.insert(idx, ty);
|
||||
purity.insert(idx, Purity::Pure);
|
||||
values.push(val);
|
||||
@@ -186,7 +195,9 @@ impl Environment {
|
||||
}
|
||||
|
||||
let expanded_ast = self.get_expander().expand(untyped_ast)?;
|
||||
let bound_ast = Binder::bind_root(self.global_names.clone(), &expanded_ast)?;
|
||||
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), &expanded_ast)?;
|
||||
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
|
||||
|
||||
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
||||
|
||||
let checker = TypeChecker::new(self.global_types.clone());
|
||||
|
||||
Reference in New Issue
Block a user