Introduce Value::Cell for mutable upvalues, allowing closures to

modify captured variables.
Implement `capture_upvalue` and `get_value`/`set_value` methods in the
`VM` to handle these mutable upvalues.

Refactor number parsing to support integers and floats

Separate the `TokenKind::Number` into `TokenKind::Integer` and
`TokenKind::Float`.
Update the lexer to distinguish between integer and float literals.
Update the parser to correctly map these new token kinds to their
respective `Value` types.

Add integration tests for parsing integers and floats, and for closure
modification of captured variables.
This commit is contained in:
Michael Schimmel
2026-02-17 12:35:39 +01:00
parent 12791a7f8f
commit ce166f39e3
6 changed files with 289 additions and 16 deletions
+4
View File
@@ -68,6 +68,7 @@ pub enum Value {
Record(Arc<HashMap<Keyword, Value>>),
Function(Arc<dyn Fn(Vec<Value>) -> Value + Send + Sync>),
Object(Arc<dyn Object>), // For compiled Closures and other opaque types
Cell(Arc<Mutex<Value>>), // Boxed value for captures
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -93,6 +94,7 @@ impl Value {
match self {
Value::Void => false,
Value::Bool(b) => *b,
Value::Cell(c) => c.lock().unwrap().is_truthy(),
_ => true,
}
}
@@ -109,6 +111,7 @@ impl Value {
Value::Record(_) => StaticType::Record(Arc::new(BTreeMap::new())), // Empty for now
Value::Function { .. } => StaticType::Any, // Dynamic function
Value::Object(o) => StaticType::Object(o.type_name()),
Value::Cell(c) => c.lock().unwrap().static_type(),
}
}
}
@@ -126,6 +129,7 @@ impl fmt::Display for Value {
Value::Record(r) => write!(f, "<record[{}]>", r.len()),
Value::Function(_) => write!(f, "<native fn>"),
Value::Object(o) => write!(f, "<{}>", o.type_name()),
Value::Cell(c) => write!(f, "{}", c.lock().unwrap()),
}
}
}