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:
+46
-49
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user