compiler: support sub-slicing
This commit is contained in:
parent
bcff9faac4
commit
32bce30777
2 changed files with 82 additions and 0 deletions
|
@ -309,6 +309,29 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
}
|
||||
return nil
|
||||
|
||||
case *ast.SliceExpr:
|
||||
name := n.X.(*ast.Ident).Name
|
||||
c.emitLoadLocal(name)
|
||||
|
||||
if n.Low != nil {
|
||||
ast.Walk(c, n.Low)
|
||||
} else {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
|
||||
}
|
||||
|
||||
if n.High != nil {
|
||||
ast.Walk(c, n.High)
|
||||
} else {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.OVER)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.ARRAYSIZE)
|
||||
}
|
||||
|
||||
emit.Opcode(c.prog.BinWriter, opcode.OVER)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.SUB)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.SUBSTR)
|
||||
|
||||
return nil
|
||||
|
||||
case *ast.ReturnStmt:
|
||||
l := c.newLabel()
|
||||
c.setLabel(l)
|
||||
|
|
|
@ -69,6 +69,65 @@ var sliceTestCases = []testCase{
|
|||
`,
|
||||
big.NewInt(15),
|
||||
},
|
||||
{
|
||||
"sub-slice with literal bounds",
|
||||
`
|
||||
package foo
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
b := a[1:3]
|
||||
return b
|
||||
}`,
|
||||
[]byte{1, 2},
|
||||
},
|
||||
{
|
||||
"sub-slice with constant bounds",
|
||||
`
|
||||
package foo
|
||||
const x = 1
|
||||
const y = 3
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
b := a[x:y]
|
||||
return b
|
||||
}`,
|
||||
[]byte{1, 2},
|
||||
},
|
||||
{
|
||||
"sub-slice with variable bounds",
|
||||
`
|
||||
package foo
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
x := 1
|
||||
y := 3
|
||||
b := a[x:y]
|
||||
return b
|
||||
}`,
|
||||
[]byte{1, 2},
|
||||
},
|
||||
{
|
||||
"sub-slice with no lower bound",
|
||||
`
|
||||
package foo
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
b := a[:3]
|
||||
return b
|
||||
}`,
|
||||
[]byte{0, 1, 2},
|
||||
},
|
||||
{
|
||||
"sub-slice with no upper bound",
|
||||
`
|
||||
package foo
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
b := a[2:]
|
||||
return b
|
||||
}`,
|
||||
[]byte{2, 3},
|
||||
},
|
||||
}
|
||||
|
||||
func TestSliceOperations(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue