feat: add record spread syntax { ...base, field: val }
Adds spread operator for records, allowing concise record updates:
let p2 = { ...p, x: 5.0 }
Changes across the full pipeline:
- Lexer: new DotDotDot (...) token
- AST: optional spread field on Record variant
- Parser: detect ... at start of record expression
- Typechecker: merge spread record fields with explicit overrides
- Interpreter: evaluate spread, overlay explicit fields
- JS backend: emit native JS spread syntax
- C backend: copy spread into temp, assign overrides
- Formatter, linter, LSP, symbol table: propagate spread
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
19
src/lexer.rs
19
src/lexer.rs
@@ -90,6 +90,7 @@ pub enum TokenKind {
|
||||
Arrow, // =>
|
||||
ThinArrow, // ->
|
||||
Dot, // .
|
||||
DotDotDot, // ...
|
||||
Colon, // :
|
||||
ColonColon, // ::
|
||||
Comma, // ,
|
||||
@@ -181,6 +182,7 @@ impl fmt::Display for TokenKind {
|
||||
TokenKind::Arrow => write!(f, "=>"),
|
||||
TokenKind::ThinArrow => write!(f, "->"),
|
||||
TokenKind::Dot => write!(f, "."),
|
||||
TokenKind::DotDotDot => write!(f, "..."),
|
||||
TokenKind::Colon => write!(f, ":"),
|
||||
TokenKind::ColonColon => write!(f, "::"),
|
||||
TokenKind::Comma => write!(f, ","),
|
||||
@@ -373,7 +375,22 @@ impl<'a> Lexer<'a> {
|
||||
TokenKind::Pipe
|
||||
}
|
||||
}
|
||||
'.' => TokenKind::Dot,
|
||||
'.' => {
|
||||
if self.peek() == Some('.') {
|
||||
// Check for ... (need to peek past second dot)
|
||||
// We look at source directly since we can only peek one ahead
|
||||
let next_next = self.source[self.pos..].chars().nth(1);
|
||||
if next_next == Some('.') {
|
||||
self.advance(); // consume second '.'
|
||||
self.advance(); // consume third '.'
|
||||
TokenKind::DotDotDot
|
||||
} else {
|
||||
TokenKind::Dot
|
||||
}
|
||||
} else {
|
||||
TokenKind::Dot
|
||||
}
|
||||
}
|
||||
':' => {
|
||||
if self.peek() == Some(':') {
|
||||
self.advance();
|
||||
|
||||
Reference in New Issue
Block a user