compiler: do not short-circuit in complex conditions
Current implementation of short-circuting is just plain wrong as it uses `last` or `before-last` labels which meaning depend on context. It doesn't even handle simple assignements like `a := x == 1 && y == 2`. This commit makes all jumps in such conditions local and adds tests. Closes #699, #700.
This commit is contained in:
parent
26c4e83ddf
commit
b461a6ab63
2 changed files with 64 additions and 2 deletions
|
@ -505,15 +505,27 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
case *ast.BinaryExpr:
|
||||
switch n.Op {
|
||||
case token.LAND:
|
||||
next := c.newLabel()
|
||||
end := c.newLabel()
|
||||
ast.Walk(c, n.X)
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOT, uint16(len(c.l)-1))
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMPIF, next)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.PUSHF)
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMP, end)
|
||||
c.setLabel(next)
|
||||
ast.Walk(c, n.Y)
|
||||
c.setLabel(end)
|
||||
return nil
|
||||
|
||||
case token.LOR:
|
||||
next := c.newLabel()
|
||||
end := c.newLabel()
|
||||
ast.Walk(c, n.X)
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMPIF, uint16(len(c.l)-3))
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOT, next)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.PUSHT)
|
||||
emit.Jmp(c.prog.BinWriter, opcode.JMP, end)
|
||||
c.setLabel(next)
|
||||
ast.Walk(c, n.Y)
|
||||
c.setLabel(end)
|
||||
return nil
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue