@@ -662,57 +662,126 @@ let bin ?comment (op : J.binop) (e0 : t) (e1 : t) : t =
662662 be careful for side effect
663663*)
664664
665- type filter_const = Ctrue | Cnull | Cundefined
666- let string_of_filter_const = function
667- | Ctrue -> " Ctrue"
668- | Cnull -> " Cnull"
669- | Cundefined -> " Cundefined"
670-
671665let string_of_expression = ref (fun _ -> " " )
672666let debug = false
673667
674- let rec filter_const ( e : t ) ~ j ~ eq ~ const =
668+ let rec simplify_and ( e1 : t ) ( e2 : t ) : t option =
675669 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
716785
717786let and_ ?comment (e1 : t ) (e2 : t ) : t =
718787 match (e1.expression_desc, e2.expression_desc) with
@@ -729,45 +798,10 @@ let and_ ?comment (e1 : t) (e2 : t) : t =
729798 )
730799 when Js_op_util. same_vident i j ->
731800 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})
771805
772806let or_ ?comment (e1 : t ) (e2 : t ) =
773807 match (e1.expression_desc, e2.expression_desc) with
@@ -778,25 +812,10 @@ let or_ ?comment (e1 : t) (e2 : t) =
778812 | Var i, Bin (Or , l, ({expression_desc = Var j; _} as r))
779813 when Js_op_util. same_vident i j ->
780814 {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})
800819
801820(* return a value of type boolean *)
802821(* TODO:
0 commit comments