Refactor UsageInfo and SubstitutionMap

This commit refactors the `UsageInfo` struct to use a single
`HashSet<Address>` for both used and assigned addresses, simplifying the
logic. It also updates the `SubstitutionMap` to use a similar approach
for tracking assigned values.

Key changes include:
- `UsageInfo` now has `used` and `assigned` fields of type
  `HashSet<Address>`.
- `SubstitutionMap`'s `add_local`, `add_global`, `add_upvalue`,
  `remove_local`, `remove_global`, and `remove_upvalue` methods have
  been replaced with a generic `add_value` and `remove_value` that
  operate on `Address`.
- The `Optimizer`'s `collect_pattern_usage` and `visit_node` methods
  have been updated to use the new `UsageInfo` and `SubstitutionMap`
  APIs.
- `Get` and `Set` nodes now use `sub.map_address` to transform addresses
  based on the current substitution.
This commit is contained in:
Michael Schimmel
2026-02-25 10:57:58 +01:00
parent c256a8a992
commit 283cdf61a4
4 changed files with 234 additions and 299 deletions
+12 -3
View File
@@ -118,7 +118,10 @@ impl Binder {
if self.functions.len() == 1 {
let mut globals = self.globals.borrow_mut();
if globals.contains_key(name) {
return Err(format!("Global variable '{}' is already defined.", name.name));
return Err(format!(
"Global variable '{}' is already defined.",
name.name
));
}
let idx = globals.len() as u32;
globals.insert(name.clone(), idx);
@@ -512,7 +515,10 @@ mod tests {
if let BoundKind::Lambda { body, .. } = &bound.kind {
if let BoundKind::Block { exprs } = &body.kind {
let x_decl = &exprs[0];
if let BoundKind::Define { captured_by, addr, .. } = &x_decl.kind {
if let BoundKind::Define {
captured_by, addr, ..
} = &x_decl.kind
{
assert!(matches!(addr, Address::Local(_)));
assert!(
!captured_by.is_empty(),
@@ -544,7 +550,10 @@ mod tests {
if let BoundKind::Lambda { body, .. } = &bound.kind {
if let BoundKind::Block { exprs } = &body.kind {
let x_decl = &exprs[0];
if let BoundKind::Define { captured_by, addr, .. } = &x_decl.kind {
if let BoundKind::Define {
captured_by, addr, ..
} = &x_decl.kind
{
assert!(matches!(addr, Address::Local(_)));
assert!(
captured_by.is_empty(),