/
log_or.go
80 lines (68 loc) · 1.55 KB
/
log_or.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package dynaml
import (
"fmt"
"github.com/mandelsoft/spiff/debug"
)
const (
OpOr = "-or"
)
type LogOrExpr struct {
A Expression
B Expression
}
func (e LogOrExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) {
a, b, info, resolved, first_ok, all_ok := resolveLOperands(e.A, e.B, binding)
if !first_ok {
debug.Debug("OR: failed %#v, %#v\n", e.A, e.B)
return nil, info, false
}
if !resolved {
return e, info, true
}
debug.Debug("OR: %#v, %#v\n", a, b)
inta, ok := a.(int64)
if ok {
if !all_ok {
return nil, info, false
}
return inta | b.(int64), info, true
}
if toBool(a) {
return true, info, true
}
if !all_ok {
return nil, info, false
}
return toBool(b), info, true
}
func (e LogOrExpr) String() string {
return fmt.Sprintf("%s %s %s", e.A, OpOr, e.B)
}
func resolveLOperands(a, b Expression, binding Binding) (eff_a, eff_b interface{}, info EvaluationInfo, resolved bool, first_ok bool, ok bool) {
var va, vb interface{}
var infoa, infob EvaluationInfo
va, infoa, first_ok = a.Evaluate(binding, false)
if first_ok {
if isExpression(va) {
return nil, nil, infoa, false, true, true
}
vb, infob, ok = b.Evaluate(binding, false)
info = infoa.Join(infob)
if !ok {
return va, nil, info, true, true, false
}
if isExpression(vb) {
return nil, nil, info, false, true, true
}
resolved = true
eff_a, ok = va.(int64)
if ok {
eff_b, ok = vb.(int64)
if ok {
return
}
}
return toBool(va), toBool(vb), info, true, true, true
}
return nil, nil, info, false, false, false
}