forked from TrueCloudLab/neoneo-go
compiler: allow usage of string literals in index expressions
This commit is contained in:
parent
058958729d
commit
4fd766fe09
2 changed files with 48 additions and 21 deletions
|
@ -61,30 +61,34 @@ func (c *codegen) emitLoadConst(t types.TypeAndValue) {
|
|||
}
|
||||
switch typ := t.Type.Underlying().(type) {
|
||||
case *types.Basic:
|
||||
switch typ.Kind() {
|
||||
case types.Int, types.UntypedInt, types.Uint:
|
||||
val, _ := constant.Int64Val(t.Value)
|
||||
emitInt(c.prog.BinWriter, val)
|
||||
case types.String, types.UntypedString:
|
||||
val := constant.StringVal(t.Value)
|
||||
emitString(c.prog.BinWriter, val)
|
||||
case types.Bool, types.UntypedBool:
|
||||
val := constant.BoolVal(t.Value)
|
||||
emitBool(c.prog.BinWriter, val)
|
||||
case types.Byte:
|
||||
val, _ := constant.Int64Val(t.Value)
|
||||
b := byte(val)
|
||||
emitBytes(c.prog.BinWriter, []byte{b})
|
||||
default:
|
||||
c.prog.Err = fmt.Errorf("compiler doesn't know how to convert this basic type: %v", t)
|
||||
return
|
||||
}
|
||||
c.convertBasicType(t, typ)
|
||||
default:
|
||||
c.prog.Err = fmt.Errorf("compiler doesn't know how to convert this constant: %v", t)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *codegen) convertBasicType(t types.TypeAndValue, typ *types.Basic) {
|
||||
switch typ.Kind() {
|
||||
case types.Int, types.UntypedInt, types.Uint:
|
||||
val, _ := constant.Int64Val(t.Value)
|
||||
emitInt(c.prog.BinWriter, val)
|
||||
case types.String, types.UntypedString:
|
||||
val := constant.StringVal(t.Value)
|
||||
emitString(c.prog.BinWriter, val)
|
||||
case types.Bool, types.UntypedBool:
|
||||
val := constant.BoolVal(t.Value)
|
||||
emitBool(c.prog.BinWriter, val)
|
||||
case types.Byte:
|
||||
val, _ := constant.Int64Val(t.Value)
|
||||
b := byte(val)
|
||||
emitBytes(c.prog.BinWriter, []byte{b})
|
||||
default:
|
||||
c.prog.Err = fmt.Errorf("compiler doesn't know how to convert this basic type: %v", t)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *codegen) emitLoadLocal(name string) {
|
||||
pos := c.scope.loadLocal(name)
|
||||
if pos < 0 {
|
||||
|
@ -574,12 +578,19 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
switch n.Index.(type) {
|
||||
case *ast.BasicLit:
|
||||
t := c.typeInfo.Types[n.Index]
|
||||
val, _ := constant.Int64Val(t.Value)
|
||||
c.emitLoadField(int(val))
|
||||
switch typ := t.Type.Underlying().(type) {
|
||||
case *types.Basic:
|
||||
c.convertBasicType(t, typ)
|
||||
default:
|
||||
c.prog.Err = fmt.Errorf("compiler can't use following type as an index: %T", typ)
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
ast.Walk(c, n.Index)
|
||||
emitOpcode(c.prog.BinWriter, opcode.PICKITEM) // just pickitem here
|
||||
}
|
||||
|
||||
emitOpcode(c.prog.BinWriter, opcode.PICKITEM) // just pickitem here
|
||||
|
||||
return nil
|
||||
|
||||
case *ast.ForStmt:
|
||||
|
|
|
@ -39,6 +39,22 @@ var mapTestCases = []testCase{
|
|||
`,
|
||||
big.NewInt(4),
|
||||
},
|
||||
{
|
||||
"map with string index",
|
||||
`
|
||||
package foo
|
||||
func Main() string {
|
||||
t := map[string]string{
|
||||
"name": "Valera",
|
||||
"age": "33",
|
||||
}
|
||||
|
||||
name := t["name"]
|
||||
return name
|
||||
}
|
||||
`,
|
||||
[]byte("Valera"),
|
||||
},
|
||||
}
|
||||
|
||||
func TestMaps(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue