@@ -42,6 +42,10 @@ func (fold *fold) Visit(node *Node) {
42
42
if i , ok := n .Node .(* FloatNode ); ok {
43
43
patchWithType (& FloatNode {Value : i .Value }, n .Node .Type ())
44
44
}
45
+ case "!" , "not" :
46
+ if a := toBool (n .Node ); a != nil {
47
+ patch (& BoolNode {Value : ! a .Value })
48
+ }
45
49
}
46
50
47
51
case * BinaryNode :
@@ -211,6 +215,50 @@ func (fold *fold) Visit(node *Node) {
211
215
patchWithType (& FloatNode {Value : math .Pow (a .Value , b .Value )}, a .Type ())
212
216
}
213
217
}
218
+ case "and" , "&&" :
219
+ a := toBool (n .Left )
220
+ b := toBool (n .Right )
221
+
222
+ if a != nil && a .Value { // true and x
223
+ patch (n .Right )
224
+ } else if b != nil && b .Value { // x and true
225
+ patch (n .Left )
226
+ } else if (a != nil && ! a .Value ) || (b != nil && ! b .Value ) { // "x and false" or "false and x"
227
+ patch (& BoolNode {Value : false })
228
+ }
229
+ case "or" , "||" :
230
+ a := toBool (n .Left )
231
+ b := toBool (n .Right )
232
+
233
+ if a != nil && ! a .Value { // false or x
234
+ patch (n .Right )
235
+ } else if b != nil && ! b .Value { // x or false
236
+ patch (n .Left )
237
+ } else if (a != nil && a .Value ) || (b != nil && b .Value ) { // "x or true" or "true or x"
238
+ patch (& BoolNode {Value : true })
239
+ }
240
+ case "==" :
241
+ {
242
+ a := toInteger (n .Left )
243
+ b := toInteger (n .Right )
244
+ if a != nil && b != nil {
245
+ patch (& BoolNode {Value : a .Value == b .Value })
246
+ }
247
+ }
248
+ {
249
+ a := toString (n .Left )
250
+ b := toString (n .Right )
251
+ if a != nil && b != nil {
252
+ patch (& BoolNode {Value : a .Value == b .Value })
253
+ }
254
+ }
255
+ {
256
+ a := toBool (n .Left )
257
+ b := toBool (n .Right )
258
+ if a != nil && b != nil {
259
+ patch (& BoolNode {Value : a .Value == b .Value })
260
+ }
261
+ }
214
262
}
215
263
216
264
case * ArrayNode :
@@ -285,3 +333,11 @@ func toFloat(n Node) *FloatNode {
285
333
}
286
334
return nil
287
335
}
336
+
337
+ func toBool (n Node ) * BoolNode {
338
+ switch a := n .(type ) {
339
+ case * BoolNode :
340
+ return a
341
+ }
342
+ return nil
343
+ }
0 commit comments