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:
Michael Schimmel
2026-03-12 14:40:13 +01:00
parent 08b5bba2c4
commit a220815bd6
3 changed files with 79 additions and 91 deletions
+15 -12
View File
@@ -623,6 +623,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::compiler::bound_nodes::Address;
use crate::ast::compiler::Binder;
use crate::ast::parser::Parser;
use crate::ast::types::{Object, Value};
@@ -764,21 +765,25 @@ mod tests {
let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator);
let expanded = expander.expand(untyped).unwrap();
let mut global_names = HashMap::new();
global_names.insert(
// Convert test globals into a CompilerScope
let mut locals = HashMap::new();
locals.insert(
Symbol::from("*"),
(
crate::ast::compiler::bound_nodes::GlobalIdx(0),
crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation {
crate::ast::compiler::binder::LocalInfo {
addr: Address::Local(crate::ast::compiler::bound_nodes::LocalSlot(0)),
identity: crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation {
line: 0,
col: 0,
}),
),
_ty: crate::ast::types::StaticType::Any,
purity: crate::ast::types::Purity::Pure,
},
);
let globals = Rc::new(RefCell::new(global_names));
let initial_scopes = vec![crate::ast::compiler::binder::CompilerScope { locals }];
let mut diag = crate::ast::diagnostics::Diagnostics::new();
let result = Binder::bind_root(globals, 0, &expanded, &mut diag);
// fixed_scope_idx = 0 means scope 0 is frozen (Global)
let result = Binder::bind_root(initial_scopes, 1, 0, &expanded, &mut diag);
assert!(
result.is_ok(),
"Should find global '*' Error: {:?}",
@@ -801,9 +806,8 @@ mod tests {
let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator);
let expanded = expander.expand(untyped).unwrap();
let globals = Rc::new(RefCell::new(HashMap::new()));
let mut diag = crate::ast::diagnostics::Diagnostics::new();
let result = Binder::bind_root(globals, 0, &expanded, &mut diag);
let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag);
assert!(result.is_ok(), "Hygiene failed: {:?}", result.err());
}
@@ -822,9 +826,8 @@ mod tests {
let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator);
let expanded = expander.expand(untyped).unwrap();
let globals = Rc::new(RefCell::new(HashMap::new()));
let mut diag = crate::ast::diagnostics::Diagnostics::new();
let result = Binder::bind_root(globals, 0, &expanded, &mut diag);
let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag);
assert!(
result.is_ok(),
"Explicit Hygiene with Backticks failed: {:?}",