Skip to content

Commit

Permalink
String keys allowed for map definitions. (#118)
Browse files Browse the repository at this point in the history
* String keys allowed for map definitions.

* parse error for map key
  • Loading branch information
geseq authored and d5 committed Feb 26, 2019
1 parent 5816186 commit 39112d2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 19 deletions.
24 changes: 12 additions & 12 deletions compiler/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,19 +878,19 @@ func() {

expectError(t, `
r["x"] = {
"a":1,
"b":1,
"c":1,
"d":1,
"e":1,
"f":1,
"g":1,
"h":1,
"i":1,
"j":1,
"k":1,
@a:1,
@b:1,
@c:1,
@d:1,
@e:1,
@f:1,
@g:1,
@h:1,
@i:1,
@j:1,
@k:1
}
`, "Parse Error: expected 'IDENT', found \"a\"\n\tat test:3:5 (and 10 more errors)") // too many errors
`, "Parse Error: illegal character U+0040 '@'\n\tat test:3:5 (and 10 more errors)") // too many errors
}

func concat(instructions ...[]byte) []byte {
Expand Down
20 changes: 15 additions & 5 deletions compiler/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,16 +1015,26 @@ func (p *Parser) parseMapElementLit() *ast.MapElementLit {
defer un(trace(p, "MapElementLit"))
}

// key: read identifier token but it's not actually an identifier
ident := p.parseIdent()
pos := p.pos
name := "_"

colonPos := p.expect(token.Colon)
if p.token == token.Ident {
name = p.tokenLit
} else if p.token == token.String {
v, _ := strconv.Unquote(p.tokenLit)
name = v
} else {
p.errorExpected(pos, "map key")
}

p.next()

colonPos := p.expect(token.Colon)
valueExpr := p.parseExpr()

return &ast.MapElementLit{
Key: ident.Name,
KeyPos: ident.NamePos,
Key: name,
KeyPos: pos,
ColonPos: colonPos,
Value: valueExpr,
}
Expand Down
11 changes: 9 additions & 2 deletions compiler/parser/parser_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ func TestMap(t *testing.T) {
mapElementLit("key3", p(1, 23), p(1, 27), boolLit(true, p(1, 29))))))
})

expect(t, "{ \"key1\": 1 }", func(p pfn) []ast.Stmt {
return stmts(
exprStmt(
mapLit(p(1, 1), p(1, 13),
mapElementLit("key1", p(1, 3), p(1, 9), intLit(1, p(1, 11))))))
})

expect(t, "a = { key1: 1, key2: \"2\", key3: true }", func(p pfn) []ast.Stmt {
return stmts(
assignStmt(
Expand Down Expand Up @@ -46,8 +53,8 @@ func TestMap(t *testing.T) {

expect(t, `
{
key1: 1,
key2: "2",
key1: 1,
key2: "2",
key3: true
}`, func(p pfn) []ast.Stmt {
return stmts(
Expand Down
11 changes: 11 additions & 0 deletions runtime/vm_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ out = {
"three": 3,
})

expect(t, `
out = {
"one": 10 - 9,
"two": 1 + 1,
"three": 6 / 2
}`, MAP{
"one": 1,
"two": 2,
"three": 3,
})

expect(t, `out = {foo: 5}["foo"]`, 5)
expect(t, `out = {foo: 5}["bar"]`, objects.UndefinedValue)
expect(t, `key := "foo"; out = {foo: 5}[key]`, 5)
Expand Down

0 comments on commit 39112d2

Please sign in to comment.