Refactor: Use root_purity instead of global_purity
This commit refactors the purity analysis from using a `HashMap<GlobalIdx, Purity>` to a `Vec<Purity>` indexed by `GlobalIdx.0`. This change simplifies the data structure and makes purity lookups more efficient. The `Binder`'s `globals` field has also been removed as it was not being used.
This commit is contained in:
@@ -4,7 +4,6 @@ use crate::ast::compiler::bound_nodes::{
|
||||
use crate::ast::diagnostics::Diagnostics;
|
||||
use crate::ast::nodes::{Node, Symbol, UntypedKind};
|
||||
use crate::ast::types::{Identity, StaticType, Purity};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -123,7 +122,6 @@ pub type BindingResult = (
|
||||
|
||||
pub struct Binder {
|
||||
functions: Vec<FunctionCompiler>,
|
||||
globals: Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
|
||||
capture_map: HashMap<Identity, std::collections::HashSet<Identity>>,
|
||||
fixed_scope_idx: i32,
|
||||
}
|
||||
@@ -133,11 +131,9 @@ impl Binder {
|
||||
initial_scopes: Vec<CompilerScope>,
|
||||
initial_slot_count: u32,
|
||||
fixed_scope_idx: i32,
|
||||
globals: Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
|
||||
) -> Self {
|
||||
let mut binder = Self {
|
||||
functions: Vec::new(),
|
||||
globals,
|
||||
capture_map: HashMap::new(),
|
||||
fixed_scope_idx,
|
||||
};
|
||||
@@ -156,11 +152,10 @@ impl Binder {
|
||||
initial_scopes: Vec<CompilerScope>,
|
||||
initial_slot_count: u32,
|
||||
fixed_scope_idx: i32,
|
||||
globals: Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
|
||||
node: &Node<UntypedKind>,
|
||||
diagnostics: &mut Diagnostics,
|
||||
) -> Result<BindingResult, String> {
|
||||
let mut binder = Self::new(initial_scopes, initial_slot_count, fixed_scope_idx, globals);
|
||||
let mut binder = Self::new(initial_scopes, initial_slot_count, fixed_scope_idx);
|
||||
let bound = binder.bind(node, ExprContext::Expression, diagnostics);
|
||||
|
||||
let final_captures = binder
|
||||
@@ -580,13 +575,7 @@ impl Binder {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Global Fallback
|
||||
let globals = self.globals.borrow();
|
||||
if let Some((idx, _)) = globals.get(sym) {
|
||||
return Some(Address::Global(*idx));
|
||||
}
|
||||
|
||||
// 4. Global Fallback (search in root level with context removed)
|
||||
// 3. Global Fallback (search in root level with context removed)
|
||||
if sym.context.is_some() {
|
||||
let fallback_sym = Symbol {
|
||||
name: sym.name.clone(),
|
||||
@@ -600,9 +589,6 @@ impl Binder {
|
||||
return Some(info.addr);
|
||||
}
|
||||
}
|
||||
if let Some((idx, _)) = globals.get(&fallback_sym) {
|
||||
return Some(Address::Global(*idx));
|
||||
}
|
||||
}
|
||||
|
||||
diag.push_error(
|
||||
@@ -719,9 +705,8 @@ mod tests {
|
||||
let mut parser = Parser::new(source);
|
||||
let untyped = parser.parse_expression();
|
||||
|
||||
let globals = Rc::new(RefCell::new(HashMap::new()));
|
||||
let mut diagnostics = Diagnostics::new();
|
||||
let (bound, captures, _scopes, _slots) = Binder::bind_root(vec![], 0, 0, globals, &untyped, &mut diagnostics).unwrap();
|
||||
let (bound, captures, _scopes, _slots) = Binder::bind_root(vec![], 0, 0, &untyped, &mut diagnostics).unwrap();
|
||||
|
||||
if let BoundKind::Lambda { body, .. } = &bound.kind {
|
||||
if let BoundKind::Block { exprs } = &body.kind {
|
||||
@@ -749,9 +734,8 @@ mod tests {
|
||||
let mut parser = Parser::new(source);
|
||||
let untyped = parser.parse_expression();
|
||||
|
||||
let globals = Rc::new(RefCell::new(HashMap::new()));
|
||||
let mut diagnostics = Diagnostics::new();
|
||||
let (bound, captures, _scopes, _slots) = Binder::bind_root(vec![], 0, 0, globals, &untyped, &mut diagnostics).unwrap();
|
||||
let (bound, captures, _scopes, _slots) = Binder::bind_root(vec![], 0, 0, &untyped, &mut diagnostics).unwrap();
|
||||
|
||||
if let BoundKind::Lambda { body, .. } = &bound.kind {
|
||||
if let BoundKind::Block { exprs } = &body.kind {
|
||||
@@ -779,9 +763,8 @@ mod tests {
|
||||
let mut parser = Parser::new(source);
|
||||
let untyped = parser.parse_expression();
|
||||
|
||||
let globals = Rc::new(RefCell::new(HashMap::new()));
|
||||
let mut diagnostics = Diagnostics::new();
|
||||
let _ = Binder::bind_root(vec![], 0, 0, globals, &untyped, &mut diagnostics);
|
||||
let _ = Binder::bind_root(vec![], 0, 0, &untyped, &mut diagnostics);
|
||||
|
||||
assert!(diagnostics.has_errors());
|
||||
assert!(diagnostics.items.iter().any(|i| i.message.contains("already defined")));
|
||||
@@ -789,18 +772,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_repro_global_redefinition() {
|
||||
let globals = Rc::new(RefCell::new(HashMap::new()));
|
||||
|
||||
let source1 = "(def x 1) 1";
|
||||
let untyped1 = Parser::new(source1).parse_expression();
|
||||
let mut diagnostics = Diagnostics::new();
|
||||
let (_, _, scopes1, slots1) = Binder::bind_root(vec![], 0, -1, globals.clone(), &untyped1, &mut diagnostics).unwrap();
|
||||
let (_, _, scopes1, slots1) = Binder::bind_root(vec![], 0, -1, &untyped1, &mut diagnostics).unwrap();
|
||||
|
||||
let source2 = "(def x 2) 2";
|
||||
let untyped2 = Parser::new(source2).parse_expression();
|
||||
let mut diagnostics2 = Diagnostics::new();
|
||||
// Here we simulate frozen scope by passing fixed_scope_idx = 0
|
||||
let _ = Binder::bind_root(scopes1, slots1, 0, globals.clone(), &untyped2, &mut diagnostics2);
|
||||
let _ = Binder::bind_root(scopes1, slots1, 0, &untyped2, &mut diagnostics2);
|
||||
|
||||
assert!(diagnostics2.has_errors());
|
||||
assert!(diagnostics2.items.iter().any(|i| i.message.contains("frozen/immutable")));
|
||||
|
||||
Reference in New Issue
Block a user