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)) } }