Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

- 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
- Add `Dict.assignMany`, `Dict.concat`, `Dict.concatMany`, `Dict.concatAll`, `Array.concatAll` to the stdlib. https://github.com/rescript-lang/rescript/pull/8364
- Implement `for...of` and `for await...of` loops. https://github.com/rescript-lang/rescript/pull/7887

#### :bug: Bug fix

Expand Down
12 changes: 9 additions & 3 deletions analysis/reanalyze/src/Arnold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -982,9 +982,15 @@ module Compile = struct
| Texp_while _ ->
notImplemented "Texp_while";
assert false
| Texp_for _ ->
notImplemented "Texp_for";
assert false
| Texp_for (_id, _pat, e1, e2, _dir, e3) ->
let open Command in
expression ~ctx e1 +++ expression ~ctx e2 +++ expression ~ctx e3
| Texp_for_of (_id, _pat, e1, e2) ->
let open Command in
expression ~ctx e1 +++ expression ~ctx e2
| Texp_for_await_of (_id, _pat, e1, e2) ->
let open Command in
expression ~ctx e1 +++ expression ~ctx e2
| Texp_send _ ->
notImplemented "Texp_send";
assert false
Expand Down
1 change: 1 addition & 0 deletions analysis/reanalyze/src/SideEffects.ml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ let rec exprNoSideEffects (expr : Typedtree.expression) =
| Texp_for (_id, _pat, e1, e2, _dir, e3) ->
e1 |> exprNoSideEffects && e2 |> exprNoSideEffects
&& e3 |> exprNoSideEffects
| Texp_for_of _ | Texp_for_await_of _ -> false
| Texp_send _ -> false
| Texp_letexception (_ec, e) -> e |> exprNoSideEffects
| Texp_pack _ -> false
Expand Down
2 changes: 2 additions & 0 deletions analysis/src/Utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ let identifyPexp pexp =
| Pexp_continue -> "Pexp_continue"
| Pexp_while _ -> "Pexp_while"
| Pexp_for _ -> "Pexp_for"
| Pexp_for_of _ -> "Pexp_for_of"
| Pexp_for_await_of _ -> "Pexp_for_await_of"
| Pexp_constraint _ -> "Pexp_constraint"
| Pexp_coerce _ -> "Pexp_coerce"
| Pexp_send _ -> "Pexp_send"
Expand Down
2 changes: 2 additions & 0 deletions compiler/core/j.ml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ and statement_desc =
* for_ident
* for_direction
* block
| ForOf of label option * for_ident * expression * block
| ForAwaitOf of label option * for_ident * expression * block
| Continue of label option
| Break of label option (* only used when inline a fucntion *)
| Return of expression
Expand Down
5 changes: 3 additions & 2 deletions compiler/core/js_analyzer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ let no_side_effect_obj =
| Throw _ | Debugger | Break _ | Variable _ | Continue _ ->
raise_notrace Not_found
| Exp e -> self.expression self e
| ForOf _ | ForAwaitOf _ -> raise_notrace Not_found
| Int_switch _ | String_switch _ | ForRange _ | If _ | While _ | Block _
| Return _ | Try _ ->
super.statement self s);
Expand Down Expand Up @@ -255,8 +256,8 @@ and eq_statement ({statement_desc = x0} : J.statement)
match y0 with
| Block ys0 -> eq_block xs0 ys0
| _ -> false)
| Variable _ | If _ | While _ | ForRange _ | Continue _ | Int_switch _
| String_switch _ | Throw _ | Try _ ->
| Variable _ | If _ | While _ | ForRange _ | ForOf _ | ForAwaitOf _
| Continue _ | Int_switch _ | String_switch _ | Throw _ | Try _ ->
false

let rev_flatten_seq (x : J.expression) =
Expand Down
54 changes: 54 additions & 0 deletions compiler/core/js_dump.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,60 @@ and statement_desc top cxt f (s : J.statement_desc) : cxt =
brace_block cxt f s)
in
action cxt
| ForOf (label, id, iterable, s) ->
P.vgroup f 0 (fun _ ->
let cxt =
P.group f 0 (fun _ ->
let cxt =
match label with
| None -> cxt
| Some label ->
P.string f label;
P.string f L.colon;
P.space f;
cxt
in
P.string f L.for_;
P.space f;
P.paren_group f 1 (fun _ ->
P.string f L.let_;
P.space f;
let cxt = Ext_pp_scope.ident cxt f id in
P.space f;
P.string f L.of_;
P.space f;
expression ~level:0 cxt f iterable))
in
P.space f;
brace_block cxt f s)
| ForAwaitOf (label, id, iterable, s) ->
P.vgroup f 0 (fun _ ->
let cxt =
P.group f 0 (fun _ ->
let cxt =
match label with
| None -> cxt
| Some label ->
P.string f label;
P.string f L.colon;
P.space f;
cxt
in
P.string f L.for_;
P.space f;
P.string f L.await;
P.space f;
P.paren_group f 1 (fun _ ->
P.string f L.let_;
P.space f;
let cxt = Ext_pp_scope.ident cxt f id in
P.space f;
P.string f L.of_;
P.space f;
expression ~level:0 cxt f iterable))
in
P.space f;
brace_block cxt f s)
| Continue label ->
P.string f L.continue;
(match label with
Expand Down
2 changes: 2 additions & 0 deletions compiler/core/js_dump_lit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ let if_ = "if"

let for_ = "for"

let of_ = "of"

let try_ = "try"

let finally = "finally"
Expand Down
10 changes: 10 additions & 0 deletions compiler/core/js_fold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ class fold =
let _self = _self#for_direction _x3 in
let _self = _self#block _x4 in
_self
| ForOf (_label, _x0, _x1, _x2) ->
let _self = _self#for_ident _x0 in
let _self = _self#expression _x1 in
let _self = _self#block _x2 in
_self
| ForAwaitOf (_label, _x0, _x1, _x2) ->
let _self = _self#for_ident _x0 in
let _self = _self#expression _x1 in
let _self = _self#block _x2 in
_self
| Continue _ -> _self
| Break _ -> _self
| Return _x0 ->
Expand Down
4 changes: 3 additions & 1 deletion compiler/core/js_pass_scope.ml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ let record_scope_pass =
statement =
(fun self state x ->
match x.statement_desc with
| ForRange (_, _, _, loop_id, _, _) ->
| ForRange (_, _, _, loop_id, _, _)
| ForOf (_, loop_id, _, _)
| ForAwaitOf (_, loop_id, _, _) ->
(* TODO: simplify definition of For *)
let {
defined_idents = defined_idents';
Expand Down
10 changes: 10 additions & 0 deletions compiler/core/js_record_fold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ let statement_desc : 'a. ('a, statement_desc) fn =
let st = for_direction _self st _x3 in
let st = _self.block _self st _x4 in
st
| ForOf (_label, _x0, _x1, _x2) ->
let st = _self.for_ident _self st _x0 in
let st = _self.expression _self st _x1 in
let st = _self.block _self st _x2 in
st
| ForAwaitOf (_label, _x0, _x1, _x2) ->
let st = _self.for_ident _self st _x0 in
let st = _self.expression _self st _x1 in
let st = _self.block _self st _x2 in
st
| Continue _ -> st
| Break _ -> st
| Return _x0 ->
Expand Down
8 changes: 8 additions & 0 deletions compiler/core/js_record_iter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ let statement_desc : statement_desc fn =
_self.for_ident _self _x2;
for_direction _self _x3;
_self.block _self _x4
| ForOf (_label, _x0, _x1, _x2) ->
_self.for_ident _self _x0;
_self.expression _self _x1;
_self.block _self _x2
| ForAwaitOf (_label, _x0, _x1, _x2) ->
_self.for_ident _self _x0;
_self.expression _self _x1;
_self.block _self _x2
| Continue _ -> ()
| Break _ -> ()
| Return _x0 -> _self.expression _self _x0
Expand Down
10 changes: 10 additions & 0 deletions compiler/core/js_record_map.ml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ let statement_desc : statement_desc fn =
let _x3 = for_direction _self _x3 in
let _x4 = _self.block _self _x4 in
ForRange (_label, _x0, _x1, _x2, _x3, _x4)
| ForOf (_label, _x0, _x1, _x2) ->
let _x0 = _self.for_ident _self _x0 in
let _x1 = _self.expression _self _x1 in
let _x2 = _self.block _self _x2 in
ForOf (_label, _x0, _x1, _x2)
| ForAwaitOf (_label, _x0, _x1, _x2) ->
let _x0 = _self.for_ident _self _x0 in
let _x1 = _self.expression _self _x1 in
let _x2 = _self.block _self _x2 in
ForAwaitOf (_label, _x0, _x1, _x2)
| Continue _ as v -> v
| Break _ as v -> v
| Return _x0 ->
Expand Down
6 changes: 6 additions & 0 deletions compiler/core/js_stmt_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ let for_ ?comment ?label for_ident_expression finish_ident_expression id
comment;
}

let for_of ?comment ?label iterable_expression id (b : J.block) : t =
{statement_desc = ForOf (label, id, iterable_expression, b); comment}

let for_await_of ?comment ?label iterable_expression id (b : J.block) : t =
{statement_desc = ForAwaitOf (label, id, iterable_expression, b); comment}

let try_ ?comment ?with_ ?finally body : t =
{statement_desc = Try (body, with_, finally); comment}

Expand Down
6 changes: 6 additions & 0 deletions compiler/core/js_stmt_make.mli
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ val for_ :
J.block ->
t

val for_of :
?comment:string -> ?label:J.label -> J.expression -> J.ident -> J.block -> t

val for_await_of :
?comment:string -> ?label:J.label -> J.expression -> J.ident -> J.block -> t

val try_ :
?comment:string ->
?with_:J.ident * J.block ->
Expand Down
18 changes: 17 additions & 1 deletion compiler/core/lam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ module Types = struct
| Lcontinue
| Lwhile of t * t
| Lfor of ident * t * t * Asttypes.direction_flag * t
| Lfor_of of ident * t * t
| Lfor_await_of of ident * t * t
| Lassign of ident * t
(* | Lsend of Lam_compat.meth_kind * t * t * t list * Location.t *)
end
Expand Down Expand Up @@ -162,6 +164,8 @@ module X = struct
| Lcontinue
| Lwhile of t * t
| Lfor of ident * t * t * Asttypes.direction_flag * t
| Lfor_of of ident * t * t
| Lfor_await_of of ident * t * t
| Lassign of ident * t
(* | Lsend of Lam_compat.meth_kind * t * t * t list * Location.t *)
end
Expand Down Expand Up @@ -252,6 +256,14 @@ let inner_map (l : t) (f : t -> X.t) : X.t =
let e2 = f e2 in
let e3 = f e3 in
Lfor (v, e1, e2, dir, e3)
| Lfor_of (v, e1, e2) ->
let e1 = f e1 in
let e2 = f e2 in
Lfor_of (v, e1, e2)
| Lfor_await_of (v, e1, e2) ->
let e1 = f e1 in
let e2 = f e2 in
Lfor_await_of (v, e1, e2)
| Lassign (id, e) ->
let e = f e in
Lassign (id, e)
Expand Down Expand Up @@ -409,7 +421,9 @@ let rec eq_approx (l1 : t) (l2 : t) =
| Lfunction _
| Llet (_, _, _, _)
| Lletrec _ | Lswitch _ | Lstaticcatch _ | Ltrywith _
| Lfor (_, _, _, _, _) ->
| Lfor (_, _, _, _, _)
| Lfor_of (_, _, _)
| Lfor_await_of (_, _, _) ->
false

and eq_option l1 l2 =
Expand Down Expand Up @@ -469,6 +483,8 @@ let letrec bindings body : t = Lletrec (bindings, body)
let while_ a b : t = Lwhile (a, b)
let try_ body id handler : t = Ltrywith (body, id, handler)
let for_ v e1 e2 dir e3 : t = Lfor (v, e1, e2, dir, e3)
let for_of v e1 e2 : t = Lfor_of (v, e1, e2)
let for_await_of v e1 e2 : t = Lfor_await_of (v, e1, e2)
let assign v l : t = Lassign (v, l)
let staticcatch a b c : t = Lstaticcatch (a, b, c)
let staticraise a b : t = Lstaticraise (a, b)
Expand Down
6 changes: 6 additions & 0 deletions compiler/core/lam.mli
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ and t = private
| Lcontinue
| Lwhile of t * t
| Lfor of ident * t * t * Asttypes.direction_flag * t
| Lfor_of of ident * t * t
| Lfor_await_of of ident * t * t
| Lassign of ident * t

(* | Lsend of Lambda.meth_kind * t * t * t list * Location.t *)
Expand Down Expand Up @@ -170,6 +172,10 @@ val staticraise : int -> t list -> t

val for_ : ident -> t -> t -> Asttypes.direction_flag -> t -> t

val for_of : ident -> t -> t -> t

val for_await_of : ident -> t -> t -> t

(**************************************************************)

val eq_approx : t -> t -> bool
2 changes: 2 additions & 0 deletions compiler/core/lam_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
| Lwhile _ ->
false (* conservative here, non-terminating loop does have side effect *)
| Lfor _ -> false
| Lfor_of _ | Lfor_await_of _ -> false
| Lassign _ -> false (* actually it depends ... *)
(* | Lsend _ -> false *)
| Lapply
Expand Down Expand Up @@ -181,6 +182,7 @@ let rec size (lam : Lam.t) =
| Lbreak | Lcontinue -> 1
| Lwhile _ -> really_big ()
| Lfor _ -> really_big ()
| Lfor_of _ | Lfor_await_of _ -> really_big ()
| Lassign (_, v) -> 1 + size v
(* This is side effectful, be careful *)
(* | Lsend _ -> really_big () *)
Expand Down
3 changes: 2 additions & 1 deletion compiler/core/lam_arity_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ let rec get_arity (meta : Lam_stats.t) (lam : Lam.t) : Lam_arity.t =
| Lsequence (_, l2) -> get_arity meta l2
| Lstaticraise _ (* since it will not be in tail position *) -> Lam_arity.na
| Lbreak | Lcontinue -> Lam_arity.non_function_arity_info
| Lwhile _ | Lfor _ | Lassign _ -> Lam_arity.non_function_arity_info
| Lwhile _ | Lfor _ | Lfor_of _ | Lfor_await_of _ | Lassign _ ->
Lam_arity.non_function_arity_info

and all_lambdas meta (xs : Lam.t list) =
match xs with
Expand Down
10 changes: 10 additions & 0 deletions compiler/core/lam_bounded_vars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ let rewrite (map : _ Hash_ident.t) (lam : Lam.t) : Lam.t =
let l2 = aux l2 in
let l3 = aux l3 in
Lam.for_ ident (aux l1) l2 dir l3
| Lfor_of (ident, l1, l2) ->
let ident = rebind ident in
let l1 = aux l1 in
let l2 = aux l2 in
Lam.for_of ident l1 l2
| Lfor_await_of (ident, l1, l2) ->
let ident = rebind ident in
let l1 = aux l1 in
let l2 = aux l2 in
Lam.for_await_of ident l1 l2
| Lconst _ -> lam
| Lprim {primitive; args; loc} ->
(* here it makes sure that global vars are not rebound *)
Expand Down
14 changes: 14 additions & 0 deletions compiler/core/lam_check.ml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ let check file lam =
check_staticfails e1 cxt;
check_staticfails e2 cxt;
check_staticfails e3 Set_int.empty
| Lfor_of (_v, e1, e2) ->
check_staticfails e1 cxt;
check_staticfails e2 Set_int.empty
| Lfor_await_of (_v, e1, e2) ->
check_staticfails e1 cxt;
check_staticfails e2 Set_int.empty
| Lbreak | Lcontinue -> ()
| Llet (_str, _id, arg, body) -> check_list [arg; body] cxt
| Lletrec (decl, body) ->
Expand Down Expand Up @@ -148,6 +154,14 @@ let check file lam =
iter e2;
def v;
iter e3
| Lfor_of (v, e1, e2) ->
iter e1;
def v;
iter e2
| Lfor_await_of (v, e1, e2) ->
iter e1;
def v;
iter e2
| Lassign (id, e) ->
use id;
iter e
Expand Down
Loading
Loading