Refactor: Pass global names to Binder
The `Binder` struct now accepts a `Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>` for global names. This allows the binder to directly access and manage global symbols during the binding process, simplifying the logic and improving efficiency. Additionally, `CompilerScope` now implements `Default`, and a type alias `BindingResult` has been introduced for clarity. The `bind_root` function signature has been updated to accept the `globals` argument.
This commit is contained in:
+26
-10
@@ -112,6 +112,7 @@ 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>>>,
|
||||
@@ -135,7 +136,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
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, captures, _, _) = Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, self.global_names.clone(), 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);
|
||||
@@ -186,6 +187,8 @@ impl Environment {
|
||||
|
||||
let mut env = env;
|
||||
env.fixed_scope_idx = 0;
|
||||
// Push the first mutable user scope (Level 1)
|
||||
env.root_scopes.borrow_mut().push(crate::ast::compiler::binder::CompilerScope::new());
|
||||
|
||||
// Automatically add standard search paths (CWD and CWD/rtl)
|
||||
if let Ok(cwd) = std::env::current_dir() {
|
||||
@@ -223,6 +226,7 @@ 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(),
|
||||
@@ -398,10 +402,23 @@ impl Environment {
|
||||
match &node.kind {
|
||||
UntypedKind::Def { target, .. } => {
|
||||
if let UntypedKind::Identifier(sym) = &target.kind {
|
||||
let mut names = self.global_names.borrow_mut();
|
||||
if !names.contains_key(sym) {
|
||||
let idx = GlobalIdx(names.len() as u32);
|
||||
names.insert(sym.clone(), (idx, node.identity.clone()));
|
||||
let mut root_scopes = self.root_scopes.borrow_mut();
|
||||
let last_idx = root_scopes.len() - 1;
|
||||
let current_scope = &mut root_scopes[last_idx];
|
||||
|
||||
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);
|
||||
current_scope.locals.insert(
|
||||
sym.clone(),
|
||||
crate::ast::compiler::binder::LocalInfo {
|
||||
addr: Address::Local(slot),
|
||||
identity: node.identity.clone(),
|
||||
_ty: StaticType::Any,
|
||||
purity: Purity::Impure,
|
||||
},
|
||||
);
|
||||
*slot_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,7 +459,7 @@ impl Environment {
|
||||
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) {
|
||||
match Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, self.global_names.clone(), &expanded_ast, diagnostics) {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
diagnostics.push_error(e, None);
|
||||
@@ -459,10 +476,9 @@ impl Environment {
|
||||
// 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);
|
||||
let count = *self.root_slot_count.borrow();
|
||||
if (count as usize) > values.len() {
|
||||
values.resize(count as usize, Value::Void);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user