@@ -662,57 +662,126 @@ let bin ?comment (op : J.binop) (e0 : t) (e1 : t) : t =
662
662
be careful for side effect
663
663
*)
664
664
665
- type filter_const = Ctrue | Cnull | Cundefined
666
- let string_of_filter_const = function
667
- | Ctrue -> " Ctrue"
668
- | Cnull -> " Cnull"
669
- | Cundefined -> " Cundefined"
670
-
671
665
let string_of_expression = ref (fun _ -> " " )
672
666
let debug = false
673
667
674
- let rec filter_const ( e : t ) ~ j ~ eq ~ const =
668
+ let rec simplify_and ( e1 : t ) ( e2 : t ) : t option =
675
669
if debug then
676
- Printf. eprintf " filter_const e:%s eq:%b const:%s\n "
677
- (! string_of_expression e) eq
678
- (string_of_filter_const const);
679
- match e.expression_desc with
680
- | Bin (And, e1 , e2 ) -> (
681
- match (filter_const e1 ~j ~eq ~const , filter_const e2 ~j ~eq ~const ) with
682
- | None , None -> None
683
- | Some e , None | None , Some e -> Some e
684
- | Some e1 , Some e2 -> Some {e with expression_desc = Bin (And , e1, e2)})
685
- | Bin (Or, e1 , e2 ) -> (
686
- match (filter_const e1 ~j ~eq ~const , filter_const e2 ~j ~eq ~const ) with
687
- | None , _ | _ , None -> None
688
- | Some e1 , Some e2 -> Some {e with expression_desc = Bin (Or , e1, e2)})
689
- | Bin (EqEqEq , {expression_desc = Var i}, {expression_desc = Bool b1})
690
- | Bin (EqEqEq , {expression_desc = Bool b1}, {expression_desc = Var i})
691
- when Js_op_util. same_vident i j && const = Ctrue ->
692
- if b1 = eq then None else Some e
693
- | Bin (NotEqEq , {expression_desc = Var i}, {expression_desc = Bool b1})
694
- | Bin (NotEqEq , {expression_desc = Bool b1}, {expression_desc = Var i})
695
- when Js_op_util. same_vident i j && const = Ctrue ->
696
- if b1 <> eq then None else Some e
697
- | Bin
698
- ( NotEqEq ,
699
- {expression_desc = Typeof {expression_desc = Var i}},
700
- {expression_desc = Str {txt = " boolean" | " string" }} )
701
- when Js_op_util. same_vident i j
702
- && (const = Ctrue || const = Cnull || const = Cundefined ) ->
703
- None
704
- | Js_not
705
- {
706
- expression_desc =
707
- Call
708
- ( {expression_desc = Str {txt = " Array.isArray" }},
709
- [{expression_desc = Var i}],
710
- _ );
711
- }
712
- when Js_op_util. same_vident i j
713
- && (const = Ctrue || const = Cnull || const = Cundefined ) ->
714
- None
715
- | _ -> Some e
670
+ Printf. eprintf " simplify_and %s %s\n " (! string_of_expression e1)
671
+ (! string_of_expression e2);
672
+
673
+ match (e1.expression_desc, e2.expression_desc) with
674
+ | Bool false , _ -> Some false_
675
+ | _ , Bool false -> Some false_
676
+ | Bool true , _ -> Some e2
677
+ | _ , Bool true -> Some e1
678
+ | Bin (And, a , b ), _ -> (
679
+ let ao = simplify_and a e2 in
680
+ let bo = simplify_and b e2 in
681
+ if ao = None && bo = None then None
682
+ else
683
+ let a_ =
684
+ match ao with
685
+ | None -> a
686
+ | Some a_ -> a_
687
+ in
688
+ let b_ =
689
+ match bo with
690
+ | None -> b
691
+ | Some b_ -> b_
692
+ in
693
+ match simplify_and a_ b_ with
694
+ | None -> Some {expression_desc = Bin (And , a_, b_); comment = None }
695
+ | Some e -> Some e)
696
+ | Bin (Or, a , b ), _ -> (
697
+ let ao = simplify_and a e2 in
698
+ let bo = simplify_and b e2 in
699
+ if ao = None && bo = None then None
700
+ else
701
+ let a_ =
702
+ match ao with
703
+ | None -> a
704
+ | Some a_ -> a_
705
+ in
706
+ let b_ =
707
+ match bo with
708
+ | None -> b
709
+ | Some b_ -> b_
710
+ in
711
+ match simplify_or a_ b_ with
712
+ | None -> Some {expression_desc = Bin (Or , a_, b_); comment = None }
713
+ | Some e -> Some e)
714
+ | ( Bin
715
+ ( ((EqEqEq | NotEqEq ) as op1),
716
+ {expression_desc = Var i1},
717
+ {expression_desc = Bool b1} ),
718
+ Bin
719
+ ( ((EqEqEq | NotEqEq ) as op2),
720
+ {expression_desc = Var i2},
721
+ {expression_desc = Bool b2} ) )
722
+ when Js_op_util. same_vident i1 i2 ->
723
+ let op_eq = op1 = op2 in
724
+ let consistent = if op_eq then b1 = b2 else b1 <> b2 in
725
+ if consistent then Some e1 else Some false_
726
+ | ( Bin
727
+ ( EqEqEq ,
728
+ {expression_desc = Typeof {expression_desc = Var ia}},
729
+ {expression_desc = Str {txt = " boolean" }} ),
730
+ (Bin (EqEqEq , {expression_desc = Var ib}, {expression_desc = Bool _}) as b)
731
+ )
732
+ | ( (Bin (EqEqEq , {expression_desc = Var ib}, {expression_desc = Bool _}) as b),
733
+ Bin
734
+ ( EqEqEq ,
735
+ {expression_desc = Typeof {expression_desc = Var ia}},
736
+ {expression_desc = Str {txt = " boolean" }} ) )
737
+ when Js_op_util. same_vident ia ib ->
738
+ Some {expression_desc = b; comment = None }
739
+ | ( Bin
740
+ ( EqEqEq ,
741
+ {
742
+ expression_desc =
743
+ ( Typeof {expression_desc = Var ia}
744
+ | Call
745
+ ( {expression_desc = Str {txt = " Array.isArray" }},
746
+ [{expression_desc = Var ia}],
747
+ _ ) );
748
+ },
749
+ {expression_desc = Str {txt = " boolean" | " string" }} ),
750
+ Bin
751
+ ( EqEqEq ,
752
+ {expression_desc = Var ib},
753
+ {expression_desc = Bool _ | Null | Undefined _} ) )
754
+ | ( Bin
755
+ ( EqEqEq ,
756
+ {expression_desc = Var ib},
757
+ {expression_desc = Bool _ | Null | Undefined _} ),
758
+ Bin
759
+ ( EqEqEq ,
760
+ {
761
+ expression_desc =
762
+ ( Typeof {expression_desc = Var ia}
763
+ | Call
764
+ ( {expression_desc = Str {txt = " Array.isArray" }},
765
+ [{expression_desc = Var ia}],
766
+ _ ) );
767
+ },
768
+ {expression_desc = Str {txt = " boolean" | " string" }} ) )
769
+ when Js_op_util. same_vident ia ib ->
770
+ (* Note: case boolean / Bool _ is handled above *)
771
+ Some false_
772
+ | _ -> None
773
+
774
+ and simplify_or (e1 : t ) (e2 : t ) : t option =
775
+ if debug then
776
+ Printf. eprintf " simplify_or %s %s\n " (! string_of_expression e1)
777
+ (! string_of_expression e2);
778
+
779
+ match (e1.expression_desc, e2.expression_desc) with
780
+ | Bool true , _ -> Some true_
781
+ | _ , Bool true -> Some true_
782
+ | Bool false , _ -> Some e2
783
+ | _ , Bool false -> Some e1
784
+ | _ -> None
716
785
717
786
let and_ ?comment (e1 : t ) (e2 : t ) : t =
718
787
match (e1.expression_desc, e2.expression_desc) with
@@ -729,45 +798,10 @@ let and_ ?comment (e1 : t) (e2 : t) : t =
729
798
)
730
799
when Js_op_util. same_vident i j ->
731
800
e2
732
- | ( _,
733
- Bin
734
- ( ((EqEqEq | NotEqEq ) as op),
735
- {expression_desc = Var j},
736
- {expression_desc = Bool b} ) ) -> (
737
- match
738
- filter_const e1 ~j ~eq: (if op = EqEqEq then b else not b) ~const: Ctrue
739
- with
740
- | None -> e2
741
- | Some e1 -> {expression_desc = Bin (And , e1, e2); comment})
742
- | ( Bin
743
- ( ((EqEqEq | NotEqEq ) as op),
744
- {expression_desc = Var j},
745
- {expression_desc = Bool b} ),
746
- _ ) -> (
747
- match
748
- filter_const e2 ~j ~eq: (if op = EqEqEq then b else not b) ~const: Ctrue
749
- with
750
- | None -> e1
751
- | Some e2 -> {expression_desc = Bin (And , e1, e2); comment})
752
- | ( _,
753
- Bin
754
- ( ((EqEqEq | NotEqEq ) as op),
755
- {expression_desc = Var j},
756
- {expression_desc = (Null | Undefined _ ) as c } ) ) -> (
757
- let const = if c == Null then Cnull else Cundefined in
758
- match filter_const e1 ~j ~eq: (op = EqEqEq ) ~const with
759
- | None -> e2
760
- | Some e1 -> {expression_desc = Bin (And , e1, e2); comment})
761
- | ( Bin
762
- ( ((EqEqEq | NotEqEq ) as op),
763
- {expression_desc = Var j},
764
- {expression_desc = (Null | Undefined _) as c} ),
765
- _ ) -> (
766
- let const = if c == Null then Cnull else Cundefined in
767
- match filter_const e2 ~j ~eq: (op = EqEqEq ) ~const with
768
- | None -> e1
769
- | Some e2 -> {expression_desc = Bin (And , e1, e2); comment})
770
- | _ , _ -> {expression_desc = Bin (And , e1, e2); comment}
801
+ | _ , _ -> (
802
+ match simplify_and e1 e2 with
803
+ | Some e -> e
804
+ | None -> {expression_desc = Bin (And , e1, e2); comment})
771
805
772
806
let or_ ?comment (e1 : t ) (e2 : t ) =
773
807
match (e1.expression_desc, e2.expression_desc) with
@@ -778,25 +812,10 @@ let or_ ?comment (e1 : t) (e2 : t) =
778
812
| Var i, Bin (Or , l, ({expression_desc = Var j; _} as r))
779
813
when Js_op_util. same_vident i j ->
780
814
{e2 with expression_desc = Bin (Or , r, l)}
781
- | ( _,
782
- Bin
783
- ( ((EqEqEq | NotEqEq ) as op),
784
- {expression_desc = Var j},
785
- {expression_desc = (Null | Undefined _ ) as c } ) ) -> (
786
- let const = if c == Null then Cnull else Cundefined in
787
- match filter_const e1 ~j ~eq: (op <> EqEqEq ) ~const with
788
- | None -> e2
789
- | Some e1 -> {expression_desc = Bin (Or , e1, e2); comment})
790
- | ( Bin
791
- ( ((EqEqEq | NotEqEq ) as op),
792
- {expression_desc = Var j},
793
- {expression_desc = (Null | Undefined _) as c} ),
794
- _ ) -> (
795
- let const = if c == Null then Cnull else Cundefined in
796
- match filter_const e2 ~j ~eq: (op <> EqEqEq ) ~const with
797
- | None -> e1
798
- | Some e2 -> {expression_desc = Bin (Or , e1, e2); comment})
799
- | _ , _ -> {expression_desc = Bin (Or , e1, e2); comment}
815
+ | _ , _ -> (
816
+ match simplify_or e1 e2 with
817
+ | Some e -> e
818
+ | None -> {expression_desc = Bin (Or , e1, e2); comment})
800
819
801
820
(* return a value of type boolean *)
802
821
(* TODO:
0 commit comments