Refactor: Use generic Define bound kind
This commit consolidates `DefLocal` and `DefGlobal` into a single `Define` bound kind. This simplifies the AST and makes it more consistent. It also introduces `DeclarationKind` to differentiate between variable and parameter definitions.
This commit is contained in:
+13
-56
@@ -103,7 +103,7 @@ impl VMObserver for TracingObserver {
|
||||
self.indent = self.indent.saturating_sub(1);
|
||||
let pad = self.pad();
|
||||
match &node.kind {
|
||||
BoundKind::DefLocal { .. } | BoundKind::Set { .. } | BoundKind::DefGlobal { .. } => {
|
||||
BoundKind::Define { .. } | BoundKind::Set { .. } => {
|
||||
let s_pad = format!("{}| ", pad);
|
||||
self.logs.push(format!("{}--- Scope Status ---", s_pad));
|
||||
self.logs.push(format!(
|
||||
@@ -266,20 +266,20 @@ impl VM {
|
||||
match &node.kind {
|
||||
BoundKind::Nop => Ok(Value::Void),
|
||||
BoundKind::Constant(v) => Ok(v.clone()),
|
||||
BoundKind::Parameter { .. } => Ok(Value::Void),
|
||||
BoundKind::DefGlobal {
|
||||
global_index,
|
||||
BoundKind::Define {
|
||||
addr,
|
||||
value,
|
||||
captured_by,
|
||||
..
|
||||
} => {
|
||||
let val = self.eval_internal(obs, value)?;
|
||||
let idx = *global_index as usize;
|
||||
let mut globals = self.globals.borrow_mut();
|
||||
if idx >= globals.len() {
|
||||
globals.resize(idx + 1, Value::Void);
|
||||
}
|
||||
globals[idx] = val.clone();
|
||||
Ok(val)
|
||||
let final_val = if !captured_by.is_empty() && matches!(addr, Address::Local(_)) {
|
||||
Value::Cell(Rc::new(RefCell::new(val)))
|
||||
} else {
|
||||
val
|
||||
};
|
||||
self.set_value(*addr, final_val.clone())?;
|
||||
Ok(final_val)
|
||||
}
|
||||
BoundKind::Destructure { pattern, value } => {
|
||||
let val = self.eval_internal(obs, value)?;
|
||||
@@ -299,29 +299,6 @@ impl VM {
|
||||
self.set_value(*addr, val.clone())?;
|
||||
Ok(val)
|
||||
}
|
||||
BoundKind::DefLocal {
|
||||
slot,
|
||||
value,
|
||||
captured_by,
|
||||
..
|
||||
} => {
|
||||
let val = self.eval_internal(obs, value)?;
|
||||
let final_val = if !captured_by.is_empty() {
|
||||
Value::Cell(Rc::new(RefCell::new(val)))
|
||||
} else {
|
||||
val
|
||||
};
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
let abs_index = frame.stack_base + (*slot as usize);
|
||||
if abs_index == self.stack.len() {
|
||||
self.stack.push(final_val.clone());
|
||||
} else if abs_index < self.stack.len() {
|
||||
self.stack[abs_index] = final_val.clone();
|
||||
} else {
|
||||
return Err(format!("Stack gap at local {}", slot));
|
||||
}
|
||||
Ok(final_val)
|
||||
}
|
||||
BoundKind::If {
|
||||
cond,
|
||||
then_br,
|
||||
@@ -689,30 +666,10 @@ impl VM {
|
||||
offset: &mut usize,
|
||||
) -> Result<(), String> {
|
||||
match &pattern.kind {
|
||||
BoundKind::Parameter { slot, .. } => {
|
||||
BoundKind::Define { addr, .. } => {
|
||||
let val = values.get(*offset).cloned().unwrap_or(Value::Void);
|
||||
*offset += 1;
|
||||
let frame = self.frames.last().ok_or("No call frame")?;
|
||||
let abs_index = frame.stack_base + (*slot as usize);
|
||||
if abs_index == self.stack.len() {
|
||||
self.stack.push(val);
|
||||
} else if abs_index < self.stack.len() {
|
||||
self.stack[abs_index] = val;
|
||||
} else {
|
||||
return Err(format!("Stack gap during unpack at slot {}", slot));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
BoundKind::DefGlobal { global_index, .. } => {
|
||||
let val = values.get(*offset).cloned().unwrap_or(Value::Void);
|
||||
*offset += 1;
|
||||
let idx = *global_index as usize;
|
||||
let mut globals = self.globals.borrow_mut();
|
||||
if idx >= globals.len() {
|
||||
globals.resize(idx + 1, Value::Void);
|
||||
}
|
||||
globals[idx] = val;
|
||||
Ok(())
|
||||
self.set_value(*addr, val)
|
||||
}
|
||||
BoundKind::Set { addr, .. } => {
|
||||
let val = values.get(*offset).cloned().unwrap_or(Value::Void);
|
||||
|
||||
Reference in New Issue
Block a user