diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go index 3e6994a7..91a16492 100644 --- a/compiler/compiler_test.go +++ b/compiler/compiler_test.go @@ -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 { diff --git a/compiler/parser/parser.go b/compiler/parser/parser.go index 469f333b..1f609ab5 100644 --- a/compiler/parser/parser.go +++ b/compiler/parser/parser.go @@ -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, } diff --git a/compiler/parser/parser_map_test.go b/compiler/parser/parser_map_test.go index f39ba174..ae0a3c1d 100644 --- a/compiler/parser/parser_map_test.go +++ b/compiler/parser/parser_map_test.go @@ -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( @@ -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( diff --git a/runtime/vm_map_test.go b/runtime/vm_map_test.go index 35090b3c..d3914078 100644 --- a/runtime/vm_map_test.go +++ b/runtime/vm_map_test.go @@ -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)