Skip to content

Commit 254693a

Browse files
add {:} syntax for empty map literals
1 parent cc65a5f commit 254693a

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

pkg/parser/parser.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,22 @@ func (p *Parser) parseNilValue() Expression {
28822882
func (p *Parser) parseArrayValue() Expression {
28832883
startToken := p.currentToken
28842884

2885+
// Check if this is an empty map literal {:}
2886+
if p.peekTokenMatches(COLON) {
2887+
// Save lexer state for speculative lookahead
2888+
savedState := p.l.SaveState()
2889+
// Get the token after : (peekToken is currently :)
2890+
afterColon := p.l.NextToken()
2891+
// Restore lexer state
2892+
p.l.RestoreState(savedState)
2893+
// If colon is followed by }, this is {:}
2894+
if afterColon.Type == RBRACE {
2895+
p.nextToken() // consume :
2896+
p.nextToken() // consume }
2897+
return &MapValue{Token: startToken, Pairs: []*MapPair{}}
2898+
}
2899+
}
2900+
28852901
// Check if this is an empty literal {} - treat as empty array
28862902
if p.peekTokenMatches(RBRACE) {
28872903
p.nextToken()

pkg/parser/parser_test.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,28 @@ func TestArrayLiterals(t *testing.T) {
315315
}
316316

317317
func TestMapLiterals(t *testing.T) {
318-
input := `temp m map[string:int] = {"a": 1, "b": 2}`
319-
program := parseProgram(t, input)
320-
stmt := program.Statements[0].(*VariableDeclaration)
321-
322-
mapVal, ok := stmt.Value.(*MapValue)
323-
if !ok {
324-
t.Fatalf("not MapValue, got %T", stmt.Value)
318+
tests := []struct {
319+
name string
320+
input string
321+
expectedPairs int
322+
}{
323+
{"non-empty map", `temp m map[string:int] = {"a": 1, "b": 2}`, 2},
324+
{"empty map", `temp m map[string:int] = {:}`, 0},
325325
}
326-
if len(mapVal.Pairs) != 2 {
327-
t.Errorf("expected 2 pairs, got %d", len(mapVal.Pairs))
326+
327+
for _, tt := range tests {
328+
t.Run(tt.name, func(t *testing.T) {
329+
program := parseProgram(t, tt.input)
330+
stmt := program.Statements[0].(*VariableDeclaration)
331+
332+
mapVal, ok := stmt.Value.(*MapValue)
333+
if !ok {
334+
t.Fatalf("not MapValue, got %T", stmt.Value)
335+
}
336+
if len(mapVal.Pairs) != tt.expectedPairs {
337+
t.Errorf("expected %d pairs, got %d", tt.expectedPairs, len(mapVal.Pairs))
338+
}
339+
})
328340
}
329341
}
330342

0 commit comments

Comments
 (0)