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:
+16
-3
@@ -11,7 +11,8 @@ pub enum TokenKind {
|
||||
Quote, Backtick, Tilde, At,
|
||||
Identifier(Arc<str>),
|
||||
Keyword(Arc<str>),
|
||||
Number(f64),
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
String(Arc<str>),
|
||||
EOF,
|
||||
}
|
||||
@@ -69,8 +70,20 @@ impl<'a> Lexer<'a> {
|
||||
'"' => TokenKind::String(Arc::from(self.read_string()?)),
|
||||
c if c.is_ascii_digit() || (c == '-' && self.input.peek().is_some_and(|p| p.is_ascii_digit())) => {
|
||||
let mut num_str = String::from(c);
|
||||
num_str.push_str(&self.read_while(|c| c.is_ascii_digit() || c == '.'));
|
||||
TokenKind::Number(num_str.parse().map_err(|_| "Invalid number format")?)
|
||||
while let Some(&next) = self.peek() {
|
||||
if next.is_ascii_digit() || next == '.' {
|
||||
num_str.push(self.input.next().unwrap());
|
||||
self.col += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if num_str.contains('.') {
|
||||
TokenKind::Float(num_str.parse().map_err(|_| "Invalid float format")?)
|
||||
} else {
|
||||
TokenKind::Integer(num_str.parse().map_err(|_| "Invalid integer format")?)
|
||||
}
|
||||
}
|
||||
c if is_ident_start(c) => {
|
||||
let mut id = String::from(c);
|
||||
|
||||
Reference in New Issue
Block a user