compiler: support map literals

This commit is contained in:
Evgenii Stratonikov 2020-01-23 17:06:15 +03:00
parent 2d2a6463e8
commit 058958729d
2 changed files with 61 additions and 0 deletions

View file

@ -357,6 +357,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
typ = c.typeInfo.ObjectOf(t).Type().Underlying()
case *ast.SelectorExpr:
typ = c.typeInfo.ObjectOf(t.Sel).Type().Underlying()
case *ast.MapType:
typ = c.typeInfo.TypeOf(t)
default:
ln := len(n.Elts)
// ByteArrays needs a different approach than normal arrays.
@ -375,6 +377,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
switch typ.(type) {
case *types.Struct:
c.convertStruct(n)
case *types.Map:
c.convertMap(n)
}
return nil
@ -700,6 +704,17 @@ func (c *codegen) convertByteArray(lit *ast.CompositeLit) {
emitBytes(c.prog.BinWriter, buf)
}
func (c *codegen) convertMap(lit *ast.CompositeLit) {
emitOpcode(c.prog.BinWriter, opcode.NEWMAP)
for i := range lit.Elts {
elem := lit.Elts[i].(*ast.KeyValueExpr)
emitOpcode(c.prog.BinWriter, opcode.DUP)
ast.Walk(c, elem.Key)
ast.Walk(c, elem.Value)
emitOpcode(c.prog.BinWriter, opcode.SETITEM)
}
}
func (c *codegen) convertStruct(lit *ast.CompositeLit) {
// Create a new structScope to initialize and store
// the positions of its variables.

46
pkg/compiler/map_test.go Normal file
View file

@ -0,0 +1,46 @@
package compiler_test
import (
"math/big"
"testing"
)
var mapTestCases = []testCase{
{
"map composite literal",
`
package foo
func Main() int {
t := map[int]int{
1: 6,
2: 9,
}
age := t[2]
return age
}
`,
big.NewInt(9),
},
{
"nested map",
`
package foo
func Main() int {
t := map[int]map[int]int{
1: map[int]int{2: 5, 3: 1},
2: nil,
5: map[int]int{3: 4, 7: 2},
}
x := t[5][3]
return x
}
`,
big.NewInt(4),
},
}
func TestMaps(t *testing.T) {
runTestCases(t, mapTestCases)
}