Skip to content

Commit eca611d

Browse files
committed
rewrite more directly
1 parent 2386f6e commit eca611d

File tree

5 files changed

+130
-113
lines changed

5 files changed

+130
-113
lines changed

compiler/core/js_exp_make.ml

Lines changed: 124 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
671665
let string_of_expression = ref (fun _ -> "")
672666
let 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

717786
let 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

772806
let 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:

tests/tests/src/UntaggedVariants.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ function check$1(s) {
386386
return;
387387
}
388388
let match = s[0];
389-
if (match === true) {
389+
if (match === undefined || match === null || match === true) {
390390
let match$1 = s[1];
391-
if (match$1 === false) {
391+
if (match$1 === undefined || match$1 === null || match$1 === false) {
392392
let match$2 = s[2];
393393
if (match$2 === undefined || match$2 === null || match$2 === false || match$2 === true) {
394394
console.log("Nope...");

tests/tests/src/and_or_simplify.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33

44
function check_null_typeof(x) {
5-
if (x !== null) {
5+
if (typeof x !== "boolean" || x !== null) {
66
return 4;
77
} else {
88
return 3;
99
}
1010
}
1111

1212
function check_undefined_typeof(x) {
13-
if (x !== undefined) {
13+
if (typeof x !== "boolean" || x !== undefined) {
1414
return 4;
1515
} else {
1616
return 3;

tests/tests/src/and_or_simplify.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@unboxed
2-
type t = | @as(null) Null | @as(undefined) Undefined | B(bool)
2+
type t = | @as(null) Null | @as(undefined) Undefined | B(bool) //| S(string)
33

44
let check_null_typeof = x =>
55
switch x {

tests/tests/src/option_repr_test.mjs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,6 @@ let xs$1 = {
218218

219219
b("File \"option_repr_test.res\", line 127, characters 3-10", Belt_List.every(xs$1, x => x));
220220

221-
let xs_0$2 = true && true;
222-
223221
let xs_1$1 = {
224222
hd: neqx(undefined, null),
225223
tl: {
@@ -235,7 +233,7 @@ let xs_1$1 = {
235233
};
236234

237235
let xs$2 = {
238-
hd: xs_0$2,
236+
hd: true,
239237
tl: xs_1$1
240238
};
241239

0 commit comments

Comments
 (0)