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.
This commit is contained in:
Michael Schimmel
2026-03-10 17:25:27 +01:00
parent a78e72d074
commit cb4d3525c2
+46 -49
View File
@@ -70,58 +70,55 @@ impl FunctionCompiler {
identity: Identity,
globals: &Rc<RefCell<HashMap<Symbol, (GlobalIdx, Identity)>>>,
) -> Result<Address, String> {
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))
}
}