compiler: allow to append multiple elements

This commit is contained in:
Roman Khimov 2020-07-09 13:51:49 +03:00
parent 76925fe3e0
commit bc1d6791b9
2 changed files with 43 additions and 12 deletions

View file

@ -1176,25 +1176,29 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
case "append": case "append":
arg := expr.Args[0] arg := expr.Args[0]
typ := c.typeInfo.Types[arg].Type typ := c.typeInfo.Types[arg].Type
emit.Opcode(c.prog.BinWriter, opcode.OVER) c.emitReverse(len(expr.Args))
emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Opcode(c.prog.BinWriter, opcode.ISNULL) emit.Opcode(c.prog.BinWriter, opcode.ISNULL)
emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 4}) emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 3})
if isByteSlice(typ) { if isByteSlice(typ) {
emit.Opcode(c.prog.BinWriter, opcode.NIP) emit.Opcode(c.prog.BinWriter, opcode.DROP)
emit.Opcode(c.prog.BinWriter, opcode.PUSH0) emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
emit.Opcode(c.prog.BinWriter, opcode.NEWBUFFER) emit.Opcode(c.prog.BinWriter, opcode.NEWBUFFER)
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
// Jump target.
emit.Opcode(c.prog.BinWriter, opcode.CAT)
} else { } else {
emit.Opcode(c.prog.BinWriter, opcode.NIP) emit.Opcode(c.prog.BinWriter, opcode.DROP)
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY0) emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY0)
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
emit.Opcode(c.prog.BinWriter, opcode.NOP) emit.Opcode(c.prog.BinWriter, opcode.NOP)
// Jump target. }
emit.Opcode(c.prog.BinWriter, opcode.OVER) // Jump target.
emit.Opcode(c.prog.BinWriter, opcode.SWAP) for range expr.Args[1:] {
emit.Opcode(c.prog.BinWriter, opcode.APPEND) if isByteSlice(typ) {
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
emit.Opcode(c.prog.BinWriter, opcode.CAT)
} else {
emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Opcode(c.prog.BinWriter, opcode.ROT)
emit.Opcode(c.prog.BinWriter, opcode.APPEND)
}
} }
case "panic": case "panic":
arg := expr.Args[0] arg := expr.Args[0]

View file

@ -151,6 +151,33 @@ var sliceTestCases = []testCase{
}`, }`,
[]byte{1, 2}, []byte{1, 2},
}, },
{
"append multiple bytes to a slice",
`package foo
func Main() []byte {
var a []byte
a = append(a, 1, 2)
return a
}`,
[]byte{1, 2},
},
{
"append multiple ints to a slice",
`package foo
func Main() []int {
var a []int
a = append(a, 1, 2, 3)
a = append(a, 4, 5)
return a
}`,
[]stackitem.Item{
stackitem.NewBigInteger(big.NewInt(1)),
stackitem.NewBigInteger(big.NewInt(2)),
stackitem.NewBigInteger(big.NewInt(3)),
stackitem.NewBigInteger(big.NewInt(4)),
stackitem.NewBigInteger(big.NewInt(5)),
},
},
{ {
"declare compound slice", "declare compound slice",
`package foo `package foo