proc: Short circuit evaluation of && and || like go does
Change evaluation of binary operators so that both && and || only evaluate their second argument conditionally, like go does.
This commit is contained in:
parent
e1f2626b56
commit
b9c4a1d68c
@ -244,6 +244,8 @@ func main() {
|
||||
|
||||
longstr := "very long string 0123456789a0123456789b0123456789c0123456789d0123456789e0123456789f0123456789g012345678h90123456789i0123456789j0123456789"
|
||||
|
||||
var nilstruct *astruct = nil
|
||||
|
||||
var amb1 = 1
|
||||
runtime.Breakpoint()
|
||||
for amb1 := 0; amb1 < 10; amb1++ {
|
||||
@ -251,5 +253,5 @@ func main() {
|
||||
}
|
||||
|
||||
runtime.Breakpoint()
|
||||
fmt.Println(i1, i2, i3, p1, amb1, s1, s3, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, errtypednil, emptyslice, emptymap, byteslice, runeslice, longstr)
|
||||
fmt.Println(i1, i2, i3, p1, amb1, s1, s3, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, errtypednil, emptyslice, emptymap, byteslice, runeslice, longstr, nilstruct)
|
||||
}
|
||||
|
||||
@ -931,19 +931,28 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
xv.loadValue(loadFullValue)
|
||||
if xv.Unreadable != nil {
|
||||
return nil, xv.Unreadable
|
||||
}
|
||||
|
||||
// short circuits logical operators
|
||||
switch node.Op {
|
||||
case token.LAND:
|
||||
if !constant.BoolVal(xv.Value) {
|
||||
return newConstant(xv.Value, xv.mem), nil
|
||||
}
|
||||
case token.LOR:
|
||||
if constant.BoolVal(xv.Value) {
|
||||
return newConstant(xv.Value, xv.mem), nil
|
||||
}
|
||||
}
|
||||
|
||||
yv, err := scope.evalAST(node.Y)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
xv.loadValue(loadFullValue)
|
||||
yv.loadValue(loadFullValue)
|
||||
|
||||
if xv.Unreadable != nil {
|
||||
return nil, xv.Unreadable
|
||||
}
|
||||
|
||||
if yv.Unreadable != nil {
|
||||
return nil, yv.Unreadable
|
||||
}
|
||||
|
||||
@ -735,6 +735,10 @@ func TestEvalExpression(t *testing.T) {
|
||||
{"ch1.dataqsiz", false, "10", "10", "uint", nil},
|
||||
{"ch1.buf", false, `*[10]int [1,4,3,2,0,0,0,0,0,0]`, `(*[10]int)(…`, "*[10]int", nil},
|
||||
{"ch1.buf[0]", false, "1", "1", "int", nil},
|
||||
|
||||
// shortcircuited logical operators
|
||||
{"nilstruct != nil && nilstruct.A == 1", false, "false", "false", "", nil},
|
||||
{"nilstruct == nil || nilstruct.A == 1", false, "true", "true", "", nil},
|
||||
}
|
||||
|
||||
ver, _ := goversion.Parse(runtime.Version())
|
||||
|
||||
Loading…
Reference in New Issue
Block a user