Skip to content

Commit 3af3f3b

Browse files
authored
Example of complex pattern for untagged variant. (#6240)
* Example of complex pattern for untagged variant. From #6108 * Some simplification. * More optimization * Optimize "or". * Update CHANGELOG.md
1 parent ce43416 commit 3af3f3b

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#### :rocket: New Feature
1616
- Untagged variants: consider regexp as an object type. https://github.com/rescript-lang/rescript-compiler/pull/6296
17+
- Semantic-based optimization of code generated for untagged variants https://github.com/rescript-lang/rescript-compiler/issues/6108
1718

1819
# 11.0.0-beta.2
1920

jscomp/core/js_exp_make.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,33 @@ let bin ?comment (op : J.binop) (e0 : t) (e1 : t) : t =
618618
be careful for side effect
619619
*)
620620

621+
let rec filter_bool (e: t) ~j ~b = match e.expression_desc with
622+
| Bin (And, e1, e2) ->
623+
(match (filter_bool e1 ~j ~b, filter_bool e2 ~j ~b) with
624+
| None, None -> None
625+
| Some e, None
626+
| None, Some e -> Some e
627+
| Some e1, Some e2 ->
628+
Some {e with expression_desc = Bin (And, e1, e2)} )
629+
| Bin (Or, e1, e2) ->
630+
(match (filter_bool e1 ~j ~b, filter_bool e2 ~j ~b) with
631+
| None, _ | _, None ->
632+
None
633+
| Some e1, Some e2 ->
634+
Some {e with expression_desc = Bin (Or, e1, e2)} )
635+
| Bin
636+
( NotEqEq,
637+
{expression_desc = Typeof {expression_desc = Var i}},
638+
{expression_desc = Str {txt}}) when Js_op_util.same_vident i j ->
639+
if txt <> "bool"
640+
then None
641+
else assert false
642+
| Js_not {expression_desc =
643+
Call ({expression_desc = Str {txt = "Array.isArray"}},
644+
[{expression_desc = Var i}], _)} when Js_op_util.same_vident i j ->
645+
None
646+
| _ -> Some e
647+
621648
let and_ ?comment (e1 : t) (e2 : t) : t =
622649
match (e1.expression_desc, e2.expression_desc) with
623650
| Var i, Var j when Js_op_util.same_vident i j -> e1
@@ -634,6 +661,15 @@ let and_ ?comment (e1 : t) (e2 : t) : t =
634661
{ expression_desc = Str _ | Number _ } ) )
635662
when Js_op_util.same_vident i j ->
636663
e2
664+
| ( _,
665+
Bin
666+
( EqEqEq,
667+
{ expression_desc = Var j },
668+
{ expression_desc = Bool b } )
669+
) ->
670+
(match filter_bool e1 ~j ~b with
671+
| None -> e2
672+
| Some e1 -> { expression_desc = Bin (And, e1, e2); comment })
637673
| _, _ -> { expression_desc = Bin (And, e1, e2); comment }
638674

639675
let or_ ?comment (e1 : t) (e2 : t) =

jscomp/test/UntaggedVariants.js

Lines changed: 75 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/UntaggedVariants.res

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,34 @@ module TestFunctionCase = {
306306
}
307307

308308
let ff = Function((. x) => x+1)
309+
}
310+
311+
module ComplexPattern = {
312+
@unboxed
313+
type rec t =
314+
| @as(undefined) Missing
315+
| @as(false) False
316+
| @as(true) True
317+
| @as(null) Null
318+
| String(string)
319+
| Number(float)
320+
| Object(Js.Dict.t<t>)
321+
| Array(array<t>)
322+
323+
type tagged_t =
324+
| JSONFalse
325+
| JSONTrue
326+
| JSONNull
327+
| JSONString(string)
328+
| JSONNumber(float)
329+
| JSONObject(Js.Dict.t<t>)
330+
| JSONArray(array<t>)
331+
332+
let someJson: t = %raw(`'[{"name": "Haan"}, {"name": "Mr"}, false]'`)->Obj.magic
333+
334+
let check = s =>
335+
switch s {
336+
| Array([True, False, Array([String("My name is"), Number(10.)])]) => Js.log("yup")
337+
| _ => Js.log("Nope...")
338+
}
309339
}

0 commit comments

Comments
 (0)