ternary conditional expression implementation
This commit is contained in:
parent
69eb7da51e
commit
cae7b24770
2 changed files with 71 additions and 0 deletions
|
@ -480,6 +480,33 @@ func (c *Compiler) Compile(node ast.Node) error {
|
|||
}
|
||||
|
||||
c.emit(OpImmutable)
|
||||
|
||||
case *ast.CondExpr:
|
||||
if err := c.Compile(node.Cond); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// first jump placeholder
|
||||
jumpPos1 := c.emit(OpJumpFalsy, 0)
|
||||
|
||||
if err := c.Compile(node.True); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// second jump placeholder
|
||||
jumpPos2 := c.emit(OpJump, 0)
|
||||
|
||||
// update first jump offset
|
||||
curPos := len(c.currentInstructions())
|
||||
c.changeOperand(jumpPos1, curPos)
|
||||
|
||||
if err := c.Compile(node.False); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update second jump offset
|
||||
curPos = len(c.currentInstructions())
|
||||
c.changeOperand(jumpPos2, curPos)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
44
runtime/vm_cond_test.go
Normal file
44
runtime/vm_cond_test.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package runtime_test
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCondExpr(t *testing.T) {
|
||||
expect(t, `out = true ? 5 : 10`, 5)
|
||||
expect(t, `out = false ? 5 : 10`, 10)
|
||||
expect(t, `out = (1 == 1) ? 2 + 3 : 12 - 2`, 5)
|
||||
expect(t, `out = (1 != 1) ? 2 + 3 : 12 - 2`, 10)
|
||||
expect(t, `out = (1 == 1) ? true ? 10 - 8 : 1 + 3 : 12 - 2`, 2)
|
||||
expect(t, `out = (1 == 1) ? false ? 10 - 8 : 1 + 3 : 12 - 2`, 4)
|
||||
|
||||
expect(t, `
|
||||
f1 := func() { out += 10 }
|
||||
f2 := func() { out = -out }
|
||||
true ? f1() : f2()
|
||||
`, 10)
|
||||
expect(t, `
|
||||
out = 5
|
||||
f1 := func() { out += 10 }
|
||||
f2 := func() { out = -out }
|
||||
false ? f1() : f2()
|
||||
`, -5)
|
||||
expect(t, `
|
||||
f1 := func(a) { return a + 2 }
|
||||
f2 := func(a) { return a - 2 }
|
||||
f3 := func(a) { return a + 10 }
|
||||
f4 := func(a) { return -a }
|
||||
|
||||
f := func(c) {
|
||||
return c == 0 ? f1(c) : f2(c) ? f3(c) : f4(c)
|
||||
}
|
||||
|
||||
out = [f(0), f(1), f(2)]
|
||||
`, ARR{2, 11, -2})
|
||||
|
||||
expect(t, `f := func(a) { return -a }; out = f(true ? 5 : 3)`, -5)
|
||||
expect(t, `out = [false?5:10, true?1:2]`, ARR{10, 1})
|
||||
|
||||
expect(t, `
|
||||
out = 1 > 2 ?
|
||||
1 + 2 + 3 :
|
||||
10 - 5`, 5)
|
||||
}
|
Loading…
Reference in a new issue