Refactor address types to use newtype wrappers
This commit introduces newtype wrappers for `LocalSlot`, `UpvalueIdx`, and `GlobalIdx` to improve type safety and clarity. These wrappers replace direct use of `u32` for indices, making the code more robust and easier to understand. The changes include: - Defining `LocalSlot`, `UpvalueIdx`, and `GlobalIdx` structs. - Implementing `Display` for these new types to provide user-friendly output. - Updating the `Address` enum to use these new types. - Modifying various compiler components (analyzer, binder, optimizer, type checker, environment, VM) to use the new types. - Adjusting tests to accommodate the changes.
This commit is contained in:
+25
-25
@@ -506,9 +506,9 @@ impl VM {
|
||||
|
||||
fn capture_upvalue(&mut self, addr: Address) -> Result<Rc<RefCell<Value>>, String> {
|
||||
match addr {
|
||||
Address::Local(idx) => {
|
||||
Address::Local(slot) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
let abs_index = frame.stack_base + (idx as usize);
|
||||
let abs_index = frame.stack_base + (slot.0 as usize);
|
||||
if abs_index < self.stack.len() {
|
||||
if let Value::Cell(cell) = &self.stack[abs_index] {
|
||||
Ok(cell.clone())
|
||||
@@ -519,15 +519,15 @@ impl VM {
|
||||
Ok(cell)
|
||||
}
|
||||
} else {
|
||||
Err(format!("Stack underflow capture local {}", idx))
|
||||
Err(format!("Stack underflow capture local {}", slot))
|
||||
}
|
||||
}
|
||||
Address::Upvalue(idx) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
if let Some(closure) = &frame.closure {
|
||||
let idx = idx as usize;
|
||||
if idx < closure.upvalues.len() {
|
||||
Ok(closure.upvalues[idx].clone())
|
||||
let u_idx = idx.0 as usize;
|
||||
if u_idx < closure.upvalues.len() {
|
||||
Ok(closure.upvalues[u_idx].clone())
|
||||
} else {
|
||||
Err(format!("Upvalue access out of bounds capture {}", idx))
|
||||
}
|
||||
@@ -541,23 +541,23 @@ impl VM {
|
||||
|
||||
fn get_value(&self, addr: Address) -> Result<Value, String> {
|
||||
match addr {
|
||||
Address::Local(idx) => {
|
||||
Address::Local(slot) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
let abs_index = frame.stack_base + (idx as usize);
|
||||
let abs_index = frame.stack_base + (slot.0 as usize);
|
||||
if abs_index < self.stack.len() {
|
||||
match &self.stack[abs_index] {
|
||||
Value::Cell(cell) => Ok(cell.borrow().clone()),
|
||||
val => Ok(val.clone()),
|
||||
}
|
||||
} else {
|
||||
Err(format!("Stack underflow access local {}", idx))
|
||||
Err(format!("Stack underflow access local {}", slot))
|
||||
}
|
||||
}
|
||||
Address::Global(idx) => {
|
||||
let idx = idx as usize;
|
||||
let g_idx = idx.0 as usize;
|
||||
let globals = self.globals.borrow();
|
||||
if idx < globals.len() {
|
||||
Ok(globals[idx].clone())
|
||||
if g_idx < globals.len() {
|
||||
Ok(globals[g_idx].clone())
|
||||
} else {
|
||||
Err(format!("Global access out of bounds {}", idx))
|
||||
}
|
||||
@@ -565,9 +565,9 @@ impl VM {
|
||||
Address::Upvalue(idx) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
if let Some(closure) = &frame.closure {
|
||||
let idx = idx as usize;
|
||||
if idx < closure.upvalues.len() {
|
||||
Ok(closure.upvalues[idx].borrow().clone())
|
||||
let u_idx = idx.0 as usize;
|
||||
if u_idx < closure.upvalues.len() {
|
||||
Ok(closure.upvalues[u_idx].borrow().clone())
|
||||
} else {
|
||||
Err(format!("Upvalue access out of bounds {}", idx))
|
||||
}
|
||||
@@ -580,9 +580,9 @@ impl VM {
|
||||
|
||||
fn set_value(&mut self, addr: Address, value: Value) -> Result<(), String> {
|
||||
match addr {
|
||||
Address::Local(idx) => {
|
||||
Address::Local(slot) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
let abs_index = frame.stack_base + (idx as usize);
|
||||
let abs_index = frame.stack_base + (slot.0 as usize);
|
||||
if abs_index < self.stack.len() {
|
||||
if let Value::Cell(cell) = &self.stack[abs_index] {
|
||||
*cell.borrow_mut() = value;
|
||||
@@ -592,25 +592,25 @@ impl VM {
|
||||
} else if abs_index == self.stack.len() {
|
||||
self.stack.push(value);
|
||||
} else {
|
||||
return Err(format!("Stack gap write local {}", idx));
|
||||
return Err(format!("Stack gap write local {}", slot));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Address::Global(idx) => {
|
||||
let idx = idx as usize;
|
||||
let g_idx = idx.0 as usize;
|
||||
let mut globals = self.globals.borrow_mut();
|
||||
if idx >= globals.len() {
|
||||
globals.resize(idx + 1, Value::Void);
|
||||
if g_idx >= globals.len() {
|
||||
globals.resize(g_idx + 1, Value::Void);
|
||||
}
|
||||
globals[idx] = value;
|
||||
globals[g_idx] = value;
|
||||
Ok(())
|
||||
}
|
||||
Address::Upvalue(idx) => {
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
if let Some(closure) = &frame.closure {
|
||||
let idx = idx as usize;
|
||||
if idx < closure.upvalues.len() {
|
||||
*closure.upvalues[idx].borrow_mut() = value;
|
||||
let u_idx = idx.0 as usize;
|
||||
if u_idx < closure.upvalues.len() {
|
||||
*closure.upvalues[u_idx].borrow_mut() = value;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Upvalue assignment out of bounds {}", idx))
|
||||
|
||||
Reference in New Issue
Block a user