Refactor scope handling and immutability
Introduces `fixed_scope_idx` to `Binder` and `Environment` to track immutable scopes. This allows enforcing that definitions (`def`) cannot occur in scopes that are considered fixed or immutable, such as the global scope or the initial bootstrap scope. The `FunctionCompiler` is updated to use `fixed_scope_idx` and `is_root` to determine scope immutability.
This commit is contained in:
@@ -75,6 +75,7 @@ pub struct Environment {
|
||||
pub global_types: Rc<RefCell<HashMap<GlobalIdx, StaticType>>>,
|
||||
pub global_purity: Rc<RefCell<HashMap<GlobalIdx, Purity>>>,
|
||||
pub global_values: Rc<RefCell<Vec<Value>>>,
|
||||
pub fixed_scope_idx: i32,
|
||||
pub function_registry: Rc<RefCell<GlobalFunctionRegistry>>,
|
||||
pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
|
||||
pub monomorph_cache: Rc<RefCell<MonoCache>>,
|
||||
@@ -112,6 +113,7 @@ struct RuntimeMacroEvaluator {
|
||||
global_names: Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
|
||||
global_types: Rc<RefCell<HashMap<GlobalIdx, StaticType>>>,
|
||||
global_values: Rc<RefCell<Vec<Value>>>,
|
||||
fixed_scope_idx: i32,
|
||||
}
|
||||
|
||||
impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
@@ -127,7 +129,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
}
|
||||
|
||||
let mut diag = Diagnostics::new();
|
||||
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), node, &mut diag)?;
|
||||
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), 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);
|
||||
@@ -161,6 +163,7 @@ impl Environment {
|
||||
global_types: Rc::new(RefCell::new(HashMap::new())),
|
||||
global_purity: Rc::new(RefCell::new(HashMap::new())),
|
||||
global_values: Rc::new(RefCell::new(Vec::new())),
|
||||
fixed_scope_idx: -1,
|
||||
function_registry: Rc::new(RefCell::new(HashMap::new())),
|
||||
typed_function_registry: Rc::new(RefCell::new(HashMap::new())),
|
||||
monomorph_cache: Rc::new(RefCell::new(HashMap::new())),
|
||||
@@ -172,6 +175,9 @@ impl Environment {
|
||||
loaded_modules: Rc::new(RefCell::new(HashSet::new())),
|
||||
};
|
||||
crate::ast::rtl::register(&env);
|
||||
|
||||
let mut env = env;
|
||||
env.fixed_scope_idx = 0;
|
||||
|
||||
// Automatically add standard search paths (CWD and CWD/rtl)
|
||||
if let Ok(cwd) = std::env::current_dir() {
|
||||
@@ -212,6 +218,7 @@ impl Environment {
|
||||
global_names: self.global_names.clone(),
|
||||
global_types: self.global_types.clone(),
|
||||
global_values: self.global_values.clone(),
|
||||
fixed_scope_idx: self.fixed_scope_idx,
|
||||
};
|
||||
MacroExpander::new(self.macro_registry.borrow().clone(), evaluator)
|
||||
}
|
||||
@@ -423,7 +430,7 @@ impl Environment {
|
||||
};
|
||||
|
||||
let (bound_ast, captures) =
|
||||
match Binder::bind_root(self.global_names.clone(), &expanded_ast, diagnostics) {
|
||||
match Binder::bind_root(self.global_names.clone(), self.fixed_scope_idx, &expanded_ast, diagnostics) {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
diagnostics.push_error(e, None);
|
||||
|
||||
Reference in New Issue
Block a user