Refactor Binder initialization and root binding
The `Binder` and `FunctionCompiler` initialization has been refactored to accept initial scopes and slot counts. This allows for more flexible management of the compiler's state, particularly for the root scope. The `bind_root` function now returns the final scopes and slot count of the root function compiler, enabling the `Environment` to update its state with these new bindings. The global variable handling has been integrated into the scope management, removing the direct reliance on a shared `HashMap` for globals. This promotes a more consistent approach to symbol resolution.
This commit is contained in:
+19
-7
@@ -112,7 +112,8 @@ impl FunctionRegistry for EnvFunctionRegistry {
|
||||
}
|
||||
|
||||
struct RuntimeMacroEvaluator {
|
||||
global_names: Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
|
||||
root_scopes: Rc<RefCell<Vec<crate::ast::compiler::binder::CompilerScope>>>,
|
||||
root_slot_count: Rc<RefCell<u32>>,
|
||||
global_types: Rc<RefCell<HashMap<GlobalIdx, StaticType>>>,
|
||||
global_values: Rc<RefCell<Vec<Value>>>,
|
||||
fixed_scope_idx: i32,
|
||||
@@ -131,7 +132,10 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
}
|
||||
|
||||
let mut diag = Diagnostics::new();
|
||||
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), self.fixed_scope_idx, node, &mut diag)?;
|
||||
let initial_scopes = self.root_scopes.borrow().clone();
|
||||
let initial_slot_count = *self.root_slot_count.borrow();
|
||||
|
||||
let (bound_ast, captures, _, _) = Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, node, &mut diag)?;
|
||||
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, &[], &mut diag);
|
||||
@@ -219,7 +223,8 @@ impl Environment {
|
||||
|
||||
fn get_expander(&self) -> MacroExpander<RuntimeMacroEvaluator> {
|
||||
let evaluator = RuntimeMacroEvaluator {
|
||||
global_names: self.global_names.clone(),
|
||||
root_scopes: self.root_scopes.clone(),
|
||||
root_slot_count: self.root_slot_count.clone(),
|
||||
global_types: self.global_types.clone(),
|
||||
global_values: self.global_values.clone(),
|
||||
fixed_scope_idx: self.fixed_scope_idx,
|
||||
@@ -433,8 +438,11 @@ impl Environment {
|
||||
}
|
||||
};
|
||||
|
||||
let (bound_ast, captures) =
|
||||
match Binder::bind_root(self.global_names.clone(), self.fixed_scope_idx, &expanded_ast, diagnostics) {
|
||||
let initial_scopes = self.root_scopes.borrow().clone();
|
||||
let initial_slot_count = *self.root_slot_count.borrow();
|
||||
|
||||
let (bound_ast, captures, final_scopes, final_slot_count) =
|
||||
match Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, &expanded_ast, diagnostics) {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
diagnostics.push_error(e, None);
|
||||
@@ -442,6 +450,10 @@ impl Environment {
|
||||
}
|
||||
};
|
||||
|
||||
// Update environment state with new bindings from this script
|
||||
*self.root_scopes.borrow_mut() = final_scopes;
|
||||
*self.root_slot_count.borrow_mut() = final_slot_count;
|
||||
|
||||
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
|
||||
|
||||
// Pre-allocate global slots to prevent out-of-bounds during specialization/optimization
|
||||
@@ -520,7 +532,7 @@ impl Environment {
|
||||
root_scopes[0].locals.insert(
|
||||
Symbol::from(name),
|
||||
crate::ast::compiler::binder::LocalInfo {
|
||||
addr: Address::Local(slot),
|
||||
addr: Address::Global(GlobalIdx(slot.0)),
|
||||
identity,
|
||||
_ty: ty,
|
||||
purity: func.purity,
|
||||
@@ -566,7 +578,7 @@ impl Environment {
|
||||
root_scopes[0].locals.insert(
|
||||
Symbol::from(name),
|
||||
crate::ast::compiler::binder::LocalInfo {
|
||||
addr: Address::Local(slot),
|
||||
addr: Address::Global(GlobalIdx(slot.0)),
|
||||
identity,
|
||||
_ty: ty,
|
||||
purity: Purity::Pure,
|
||||
|
||||
Reference in New Issue
Block a user