compiler: use iterators in range loops

It is simpler than having some counters on stack and will help us to
support maps in future.
This commit is contained in:
Evgenii Stratonikov 2020-05-19 18:01:41 +03:00
parent 34a4c15932
commit b126056f04

View file

@ -900,20 +900,18 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
c.currentSwitch = label c.currentSwitch = label
ast.Walk(c, n.X) ast.Walk(c, n.X)
emit.Syscall(c.prog.BinWriter, "Neo.Iterator.Create")
emit.Opcode(c.prog.BinWriter, opcode.SIZE) c.pushStackLabel(label, 1)
emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
c.pushStackLabel(label, 2)
c.setLabel(start) c.setLabel(start)
emit.Opcode(c.prog.BinWriter, opcode.OVER) emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Opcode(c.prog.BinWriter, opcode.OVER) emit.Syscall(c.prog.BinWriter, "Neo.Enumerator.Next")
emit.Opcode(c.prog.BinWriter, opcode.LTE) // finish if len <= i emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOTL, end)
emit.Jmp(c.prog.BinWriter, opcode.JMPIFL, end)
if n.Key != nil { if n.Key != nil {
emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Syscall(c.prog.BinWriter, "Neo.Iterator.Key")
c.emitStoreVar(n.Key.(*ast.Ident).Name) c.emitStoreVar(n.Key.(*ast.Ident).Name)
} }
@ -921,7 +919,6 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
c.setLabel(post) c.setLabel(post)
emit.Opcode(c.prog.BinWriter, opcode.INC)
emit.Jmp(c.prog.BinWriter, opcode.JMPL, start) emit.Jmp(c.prog.BinWriter, opcode.JMPL, start)
c.setLabel(end) c.setLabel(end)