From cb4d3525c21a862d45476c49d78da09fa95c5246 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Tue, 10 Mar 2026 17:25:27 +0100 Subject: [PATCH] Refactor binder to simplify root scope logic The previous implementation of the binder had a slightly complex way of handling the root scope. This commit simplifies that logic by directly checking if the current scope is the root scope and the scope stack has only one element. This makes the code more readable and maintainable. --- src/ast/compiler/binder.rs | 95 ++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/src/ast/compiler/binder.rs b/src/ast/compiler/binder.rs index 3771c44..5c74153 100644 --- a/src/ast/compiler/binder.rs +++ b/src/ast/compiler/binder.rs @@ -70,58 +70,55 @@ impl FunctionCompiler { identity: Identity, globals: &Rc>>, ) -> Result { - match self.kind { - ScopeKind::Root => { - let current_scope = self.scopes.last_mut().unwrap(); - if current_scope.locals.contains_key(name) { - return Err(format!( - "Variable '{}' is already defined in this scope level.", - name.name - )); - } - - let mut globals_map = globals.borrow_mut(); - let addr = if let Some((idx, existing_id)) = globals_map.get(name) { - if *existing_id != identity { - return Err(format!("Variable '{}' is already defined in global scope.", name.name)); - } - Address::Global(*idx) - } else { - let idx = GlobalIdx(globals_map.len() as u32); - globals_map.insert(name.clone(), (idx, identity.clone())); - Address::Global(idx) - }; - - current_scope.locals.insert( - name.clone(), - LocalInfo { - addr, - identity, - _ty: StaticType::Any, - }, - ); - Ok(addr) + if self.kind == ScopeKind::Root && self.scopes.len() == 1 { + let current_scope = self.scopes.last_mut().unwrap(); + if current_scope.locals.contains_key(name) { + return Err(format!( + "Variable '{}' is already defined in this scope level.", + name.name + )); } - ScopeKind::Local => { - let current_scope = self.scopes.last_mut().unwrap(); - if current_scope.locals.contains_key(name) { - return Err(format!( - "Variable '{}' is already defined in this scope level.", - name.name - )); + + let mut globals_map = globals.borrow_mut(); + let addr = if let Some((idx, existing_id)) = globals_map.get(name) { + if *existing_id != identity { + return Err(format!("Variable '{}' is already defined in global scope.", name.name)); } - let slot = LocalSlot(self.slot_count); - current_scope.locals.insert( - name.clone(), - LocalInfo { - addr: Address::Local(slot), - identity, - _ty: StaticType::Any, - }, - ); - self.slot_count += 1; - Ok(Address::Local(slot)) + Address::Global(*idx) + } else { + let idx = GlobalIdx(globals_map.len() as u32); + globals_map.insert(name.clone(), (idx, identity.clone())); + Address::Global(idx) + }; + + current_scope.locals.insert( + name.clone(), + LocalInfo { + addr, + identity, + _ty: StaticType::Any, + }, + ); + Ok(addr) + } else { + let current_scope = self.scopes.last_mut().unwrap(); + if current_scope.locals.contains_key(name) { + return Err(format!( + "Variable '{}' is already defined in this scope level.", + name.name + )); } + let slot = LocalSlot(self.slot_count); + current_scope.locals.insert( + name.clone(), + LocalInfo { + addr: Address::Local(slot), + identity, + _ty: StaticType::Any, + }, + ); + self.slot_count += 1; + Ok(Address::Local(slot)) } }