Skip to content

Commit 0ccd292

Browse files
committed
Fuse const and block cases when the defaults are equal.
1 parent d7aaa37 commit 0ccd292

File tree

7 files changed

+171
-76
lines changed

7 files changed

+171
-76
lines changed

compiler/core/lam_compile.ml

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,8 @@ let compile output_prefix =
673673
also if last statement is throw -- should we drop remaining
674674
statement?
675675
*)
676-
Printf.eprintf "XXX switch_arg: %s\n\n"
677-
(Lam_print.lambda_to_string switch_arg);
676+
(* Printf.eprintf "XXX switch_arg: %s\n\n"
677+
(Lam_print.lambda_to_string switch_arg); *)
678678
let ({
679679
sw_consts_full;
680680
sw_consts;
@@ -715,28 +715,28 @@ let compile output_prefix =
715715
block
716716
@
717717
if sw_consts_full && sw_consts = [] then
718-
let _ = Printf.eprintf "QQQ sw_consts_full\n\n" in
718+
(* let _ = Printf.eprintf "QQQ sw_consts_full\n\n" in *)
719719
compile_cases ~block_cases ~untagged ~cxt
720720
~switch_exp:(if untagged then e else E.tag ~name:tag_name e)
721721
~default:sw_blocks_default ~get_tag:get_block_tag sw_blocks
722722
else if sw_blocks_full && sw_blocks = [] then
723-
let _ = Printf.eprintf "QQQ sw_blocks_full\n\n" in
723+
(* let _ = Printf.eprintf "QQQ sw_blocks_full\n\n" in *)
724724
compile_cases ~cxt ~switch_exp:e ~block_cases ~default:sw_num_default
725725
~get_tag:get_const_tag sw_consts
726726
else
727-
let _ = Printf.eprintf "QQQ else\n\n" in
727+
(* let _ = Printf.eprintf "QQQ else\n\n" in *)
728728
(* [e] will be used twice *)
729729
let dispatch e =
730730
let is_a_literal_case =
731-
if untagged then (
731+
if untagged then
732732
let literal_case =
733733
E.is_a_literal_case
734734
~literal_cases:(get_literal_cases sw_names)
735735
~block_cases e
736736
in
737-
Printf.eprintf "LLL literal_case: %s\n\n"
738-
(Js_dump.string_of_expression literal_case);
739-
literal_case)
737+
(* Printf.eprintf "LLL literal_case: %s\n\n"
738+
(Js_dump.string_of_expression literal_case); *)
739+
literal_case
740740
else
741741
E.is_int_tag
742742
~has_null_undefined_other:(has_null_undefined_other sw_names)
@@ -748,14 +748,21 @@ let compile output_prefix =
748748
let qblocks =
749749
use_compile_literal_cases sw_blocks ~get_tag:get_block_tag
750750
in
751+
let eq_default d1 d2 =
752+
match (d1, d2) with
753+
| Default lam1, Default lam2 -> Lam.eq_approx lam1 lam2
754+
| Complete, Complete -> true
755+
| NonComplete, NonComplete -> true
756+
| _ -> false
757+
in
751758
match (qconsts, qblocks) with
752-
| Some consts_cases, Some blocks_cases when untagged ->
753-
let untagged_cases = consts_cases @ blocks_cases in
754-
let z =
755-
compile_untagged_cases ~cxt ~switch_exp:e ~block_cases
756-
~default:sw_num_default untagged_cases
757-
in
758-
z
759+
| Some consts_cases, Some blocks_cases
760+
when untagged
761+
&& List.length blocks_cases >= 1
762+
&& List.length consts_cases = 0
763+
&& eq_default sw_num_default sw_blocks_default ->
764+
compile_cases ~untagged ~cxt ~switch_exp:e ~block_cases
765+
~default:sw_blocks_default ~get_tag:get_block_tag sw_blocks
759766
| _ ->
760767
[
761768
S.if_ is_a_literal_case
@@ -785,17 +792,17 @@ let compile output_prefix =
785792
*)
786793
let v = Ext_ident.create_tmp () in
787794
let res = compile_whole {lambda_cxt with continuation = Assign v} in
788-
Printf.eprintf "XXX res 1: %s\n\n" (Js_dump.string_of_block res);
795+
(* Printf.eprintf "XXX res 1: %s\n\n" (Js_dump.string_of_block res); *)
789796
Js_output.make
790797
(S.declare_variable ~kind:Variable v :: res)
791798
~value:(E.var v)
792799
| Declare (kind, id) ->
793800
let res = compile_whole {lambda_cxt with continuation = Assign id} in
794-
Printf.eprintf "XXX res 2: %s\n\n" (Js_dump.string_of_block res);
801+
(* Printf.eprintf "XXX res 2: %s\n\n" (Js_dump.string_of_block res); *)
795802
Js_output.make (S.declare_variable ~kind id :: res) ~value:(E.var id)
796803
| EffectCall _ | Assign _ ->
797804
let res = compile_whole lambda_cxt in
798-
Printf.eprintf "XXX res 3: %s\n\n" (Js_dump.string_of_block res);
805+
(* Printf.eprintf "XXX res 3: %s\n\n" (Js_dump.string_of_block res); *)
799806
Js_output.make res
800807
and compile_string_cases ~cxt ~switch_exp ~default cases : initialization =
801808
cases

tests/tests/src/UntaggedVariants.mjs

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,6 @@ let TestFunctionCase = {
376376
let someJson = '[{"name": "Haan"}, {"name": "Mr"}, false]';
377377

378378
function check$1(s) {
379-
if (s === undefined || s === null || s === false || s === true) {
380-
console.log("Nope...");
381-
return;
382-
}
383379
if (Array.isArray(s)) {
384380
if (s.length !== 3) {
385381
console.log("Nope...");
@@ -388,46 +384,40 @@ function check$1(s) {
388384
let match = s[0];
389385
if (match === true) {
390386
let match$1 = s[1];
391-
if (match$1 === false) {
392-
let match$2 = s[2];
393-
if (match$2 === undefined || match$2 === null || match$2 === false || match$2 === true) {
394-
console.log("Nope...");
395-
return;
396-
}
397-
if (Array.isArray(match$2)) {
398-
if (match$2.length !== 2) {
399-
console.log("Nope...");
400-
return;
401-
}
402-
let match$3 = match$2[0];
403-
if (match$3 === undefined || match$3 === null || match$3 === false || match$3 === true) {
404-
console.log("Nope...");
405-
return;
406-
}
407-
if (match$3 === "My name is") {
408-
let match$4 = match$2[1];
409-
if (match$4 === undefined || match$4 === null || match$4 === false || match$4 === true) {
387+
if (match$1 === undefined || match$1 === null || match$1 === false || match$1 === true) {
388+
if (match$1 === false) {
389+
let match$2 = s[2];
390+
if (Array.isArray(match$2)) {
391+
if (match$2.length !== 2) {
410392
console.log("Nope...");
411393
return;
412394
}
413-
if (typeof match$4 === "number") {
414-
if (match$4 !== 10) {
395+
let match$3 = match$2[0];
396+
if (typeof match$3 === "string") {
397+
if (match$3 === "My name is") {
398+
let match$4 = match$2[1];
399+
if (typeof match$4 === "number") {
400+
if (match$4 !== 10) {
401+
console.log("Nope...");
402+
} else {
403+
console.log("yup");
404+
}
405+
return;
406+
}
415407
console.log("Nope...");
416-
} else {
417-
console.log("yup");
408+
return;
418409
}
410+
console.log("Nope...");
419411
return;
420412
}
421413
console.log("Nope...");
422414
return;
423-
} else {
424-
console.log("Nope...");
425-
return;
426415
}
427-
} else {
428416
console.log("Nope...");
429417
return;
430418
}
419+
console.log("Nope...");
420+
return;
431421
} else {
432422
console.log("Nope...");
433423
return;

tests/tests/src/and_or_simplify.mjs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ function check_null_eq_typeof(x) {
66
}
77

88
function check_null_neq_typeof(x) {
9-
if (typeof x !== "boolean") {
10-
return 4;
11-
} else {
9+
if (typeof x === "boolean") {
1210
return 3;
11+
} else {
12+
return 4;
1313
}
1414
}
1515

@@ -18,10 +18,10 @@ function check_undefined_eq_typeof(x) {
1818
}
1919

2020
function check_undefined_neq_typeof(x) {
21-
if (typeof x !== "boolean") {
22-
return 4;
23-
} else {
21+
if (typeof x === "boolean") {
2422
return 3;
23+
} else {
24+
return 4;
2525
}
2626
}
2727

tests/tests/src/core/Core_JsonTests.mjs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ import * as Test from "./Test.mjs";
55
function decodeJsonTest() {
66
let json = {"someProp":{"otherProp": null, "thirdProp": [true, false]}};
77
let decodedCorrectly;
8-
if (json === null || !(typeof json === "object" && !Array.isArray(json))) {
9-
decodedCorrectly = false;
10-
} else {
8+
if (typeof json === "object" && !Array.isArray(json)) {
119
let match = json["someProp"];
12-
if (match !== undefined && !(match === null || !(typeof match === "object" && !Array.isArray(match)))) {
10+
if (match !== undefined && typeof match === "object" && !Array.isArray(match)) {
1311
let match$1 = match["thirdProp"];
14-
if (match$1 !== undefined && !(match$1 === null || !(Array.isArray(match$1) && match$1.length === 2))) {
12+
if (match$1 !== undefined && Array.isArray(match$1) && match$1.length === 2) {
1513
let match$2 = match$1[0];
16-
if (match$2 === null || !(typeof match$2 === "boolean" && match$2)) {
17-
decodedCorrectly = false;
18-
} else {
14+
if (typeof match$2 === "boolean" && match$2) {
1915
let match$3 = match$1[1];
20-
decodedCorrectly = match$3 === null ? false : typeof match$3 === "boolean" && !match$3;
16+
decodedCorrectly = typeof match$3 === "boolean" && !match$3;
17+
} else {
18+
decodedCorrectly = false;
2119
}
2220
} else {
2321
decodedCorrectly = false;
2422
}
2523
} else {
2624
decodedCorrectly = false;
2725
}
26+
} else {
27+
decodedCorrectly = false;
2828
}
2929
Test.run([
3030
[

tests/tests/src/json_decorders.mjs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Generated by ReScript, PLEASE EDIT WITH CARE
2+
3+
import * as $$Array from "rescript/lib/es6/Array.js";
4+
5+
function decodeUser(json) {
6+
if (!(typeof json === "object" && !Array.isArray(json))) {
7+
return;
8+
}
9+
let id = json.id;
10+
if (typeof id !== "string") {
11+
return;
12+
}
13+
let name = json.name;
14+
if (typeof name !== "string") {
15+
return;
16+
}
17+
let age = json.age;
18+
if (typeof age !== "number") {
19+
return;
20+
}
21+
let email = json.email;
22+
let tmp;
23+
tmp = typeof email === "string" ? email : undefined;
24+
return {
25+
id: id,
26+
name: name,
27+
age: age | 0,
28+
email: tmp
29+
};
30+
}
31+
32+
function decodeGroup(json) {
33+
if (!(typeof json === "object" && !Array.isArray(json))) {
34+
return;
35+
}
36+
let id = json.id;
37+
if (typeof id !== "string") {
38+
return;
39+
}
40+
let name = json.name;
41+
if (typeof name !== "string") {
42+
return;
43+
}
44+
let users = json.users;
45+
if (Array.isArray(users)) {
46+
return {
47+
id: id,
48+
name: name,
49+
users: $$Array.filterMap(users, decodeUser)
50+
};
51+
}
52+
53+
}
54+
55+
export {
56+
decodeUser,
57+
decodeGroup,
58+
}
59+
/* No side effect */

tests/tests/src/json_decorders.res

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
type user = {
2+
id: string,
3+
name: string,
4+
age: int,
5+
email: option<string>,
6+
}
7+
8+
type group = {
9+
id: string,
10+
name: string,
11+
users: array<user>,
12+
}
13+
14+
let decodeUser = json => {
15+
switch json {
16+
| JSON.Object(dict{
17+
"id": JSON.String(id),
18+
"name": String(name),
19+
"age": Number(age),
20+
"email": ?email,
21+
}) =>
22+
Some({
23+
id,
24+
name,
25+
age: age->Float.toInt,
26+
email: switch email {
27+
| Some(String(email)) => Some(email)
28+
| _ => None
29+
},
30+
})
31+
| _ => None
32+
}
33+
}
34+
35+
let decodeGroup = json => {
36+
switch json {
37+
| JSON.Object(dict{"id": JSON.String(id), "name": String(name), "users": Array(users)}) =>
38+
Some({
39+
id,
40+
name,
41+
users: users->Array.filterMap(decodeUser),
42+
})
43+
| _ => None
44+
}
45+
}

tests/tests/src/pattern_match_json.mjs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,22 @@ import * as Primitive_option from "rescript/lib/es6/Primitive_option.js";
44

55
function decodeGroup(group) {
66
let id = group.id;
7-
if (id == null) {
8-
return [
9-
"e",
10-
"f"
11-
];
12-
}
137
if (typeof id !== "string") {
148
return [
159
"e",
1610
"f"
1711
];
1812
}
1913
let name = group.name;
20-
if (typeof name !== "string") {
14+
if (typeof name === "string") {
2115
return [
22-
"e",
23-
"f"
16+
id,
17+
name
2418
];
2519
} else {
2620
return [
27-
id,
28-
name
21+
"e",
22+
"f"
2923
];
3024
}
3125
}

0 commit comments

Comments
 (0)