Skip to content

Commit f976093

Browse files
authored
Implement for...of and for await...of loops (#7887)
* Implement for..of and for await..of loops * fixes * CHANGELOG # Conflicts: # CHANGELOG.md
1 parent 1ec0a25 commit f976093

110 files changed

Lines changed: 1863 additions & 64 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

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

2424
- Rewatch: add `--prod` flag to `build`, `watch`, and `clean` to skip dev-dependencies and dev sources (`"type": "dev"`), enabling builds in environments where dev packages aren't installed (e.g. after `pnpm install --prod`). https://github.com/rescript-lang/rescript/pull/8347
2525
- Add `Dict.assignMany`, `Dict.concat`, `Dict.concatMany`, `Dict.concatAll`, `Array.concatAll` to the stdlib. https://github.com/rescript-lang/rescript/pull/8364
26+
- Implement `for...of` and `for await...of` loops. https://github.com/rescript-lang/rescript/pull/7887
2627

2728
#### :bug: Bug fix
2829

analysis/reanalyze/src/Arnold.ml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -982,9 +982,15 @@ module Compile = struct
982982
| Texp_while _ ->
983983
notImplemented "Texp_while";
984984
assert false
985-
| Texp_for _ ->
986-
notImplemented "Texp_for";
987-
assert false
985+
| Texp_for (_id, _pat, e1, e2, _dir, e3) ->
986+
let open Command in
987+
expression ~ctx e1 +++ expression ~ctx e2 +++ expression ~ctx e3
988+
| Texp_for_of (_id, _pat, e1, e2) ->
989+
let open Command in
990+
expression ~ctx e1 +++ expression ~ctx e2
991+
| Texp_for_await_of (_id, _pat, e1, e2) ->
992+
let open Command in
993+
expression ~ctx e1 +++ expression ~ctx e2
988994
| Texp_send _ ->
989995
notImplemented "Texp_send";
990996
assert false

analysis/reanalyze/src/SideEffects.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ let rec exprNoSideEffects (expr : Typedtree.expression) =
6262
| Texp_for (_id, _pat, e1, e2, _dir, e3) ->
6363
e1 |> exprNoSideEffects && e2 |> exprNoSideEffects
6464
&& e3 |> exprNoSideEffects
65+
| Texp_for_of _ | Texp_for_await_of _ -> false
6566
| Texp_send _ -> false
6667
| Texp_letexception (_ec, e) -> e |> exprNoSideEffects
6768
| Texp_pack _ -> false

analysis/src/Utils.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ let identifyPexp pexp =
102102
| Pexp_continue -> "Pexp_continue"
103103
| Pexp_while _ -> "Pexp_while"
104104
| Pexp_for _ -> "Pexp_for"
105+
| Pexp_for_of _ -> "Pexp_for_of"
106+
| Pexp_for_await_of _ -> "Pexp_for_await_of"
105107
| Pexp_constraint _ -> "Pexp_constraint"
106108
| Pexp_coerce _ -> "Pexp_coerce"
107109
| Pexp_send _ -> "Pexp_send"

compiler/core/j.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ and statement_desc =
266266
* for_ident
267267
* for_direction
268268
* block
269+
| ForOf of label option * for_ident * expression * block
270+
| ForAwaitOf of label option * for_ident * expression * block
269271
| Continue of label option
270272
| Break of label option (* only used when inline a fucntion *)
271273
| Return of expression

compiler/core/js_analyzer.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ let no_side_effect_obj =
135135
| Throw _ | Debugger | Break _ | Variable _ | Continue _ ->
136136
raise_notrace Not_found
137137
| Exp e -> self.expression self e
138+
| ForOf _ | ForAwaitOf _ -> raise_notrace Not_found
138139
| Int_switch _ | String_switch _ | ForRange _ | If _ | While _ | Block _
139140
| Return _ | Try _ ->
140141
super.statement self s);
@@ -255,8 +256,8 @@ and eq_statement ({statement_desc = x0} : J.statement)
255256
match y0 with
256257
| Block ys0 -> eq_block xs0 ys0
257258
| _ -> false)
258-
| Variable _ | If _ | While _ | ForRange _ | Continue _ | Int_switch _
259-
| String_switch _ | Throw _ | Try _ ->
259+
| Variable _ | If _ | While _ | ForRange _ | ForOf _ | ForAwaitOf _
260+
| Continue _ | Int_switch _ | String_switch _ | Throw _ | Try _ ->
260261
false
261262

262263
let rev_flatten_seq (x : J.expression) =

compiler/core/js_dump.ml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,60 @@ and statement_desc top cxt f (s : J.statement_desc) : cxt =
14981498
brace_block cxt f s)
14991499
in
15001500
action cxt
1501+
| ForOf (label, id, iterable, s) ->
1502+
P.vgroup f 0 (fun _ ->
1503+
let cxt =
1504+
P.group f 0 (fun _ ->
1505+
let cxt =
1506+
match label with
1507+
| None -> cxt
1508+
| Some label ->
1509+
P.string f label;
1510+
P.string f L.colon;
1511+
P.space f;
1512+
cxt
1513+
in
1514+
P.string f L.for_;
1515+
P.space f;
1516+
P.paren_group f 1 (fun _ ->
1517+
P.string f L.let_;
1518+
P.space f;
1519+
let cxt = Ext_pp_scope.ident cxt f id in
1520+
P.space f;
1521+
P.string f L.of_;
1522+
P.space f;
1523+
expression ~level:0 cxt f iterable))
1524+
in
1525+
P.space f;
1526+
brace_block cxt f s)
1527+
| ForAwaitOf (label, id, iterable, s) ->
1528+
P.vgroup f 0 (fun _ ->
1529+
let cxt =
1530+
P.group f 0 (fun _ ->
1531+
let cxt =
1532+
match label with
1533+
| None -> cxt
1534+
| Some label ->
1535+
P.string f label;
1536+
P.string f L.colon;
1537+
P.space f;
1538+
cxt
1539+
in
1540+
P.string f L.for_;
1541+
P.space f;
1542+
P.string f L.await;
1543+
P.space f;
1544+
P.paren_group f 1 (fun _ ->
1545+
P.string f L.let_;
1546+
P.space f;
1547+
let cxt = Ext_pp_scope.ident cxt f id in
1548+
P.space f;
1549+
P.string f L.of_;
1550+
P.space f;
1551+
expression ~level:0 cxt f iterable))
1552+
in
1553+
P.space f;
1554+
brace_block cxt f s)
15011555
| Continue label ->
15021556
P.string f L.continue;
15031557
(match label with

compiler/core/js_dump_lit.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ let if_ = "if"
9090

9191
let for_ = "for"
9292

93+
let of_ = "of"
94+
9395
let try_ = "try"
9496

9597
let finally = "finally"

compiler/core/js_fold.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,16 @@ class fold =
241241
let _self = _self#for_direction _x3 in
242242
let _self = _self#block _x4 in
243243
_self
244+
| ForOf (_label, _x0, _x1, _x2) ->
245+
let _self = _self#for_ident _x0 in
246+
let _self = _self#expression _x1 in
247+
let _self = _self#block _x2 in
248+
_self
249+
| ForAwaitOf (_label, _x0, _x1, _x2) ->
250+
let _self = _self#for_ident _x0 in
251+
let _self = _self#expression _x1 in
252+
let _self = _self#block _x2 in
253+
_self
244254
| Continue _ -> _self
245255
| Break _ -> _self
246256
| Return _x0 ->

compiler/core/js_pass_scope.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,9 @@ let record_scope_pass =
238238
statement =
239239
(fun self state x ->
240240
match x.statement_desc with
241-
| ForRange (_, _, _, loop_id, _, _) ->
241+
| ForRange (_, _, _, loop_id, _, _)
242+
| ForOf (_, loop_id, _, _)
243+
| ForAwaitOf (_, loop_id, _, _) ->
242244
(* TODO: simplify definition of For *)
243245
let {
244246
defined_idents = defined_idents';

0 commit comments

Comments
 (0)