@@ -188,6 +188,9 @@ let index ?comment (e0 : t) (e1 : int) : t =
188
188
match e0.expression_desc with
189
189
| Array (l ,_mutable_flag ) when no_side_effect e0 ->
190
190
List. nth l e1 (* Float i -- should not appear here *)
191
+ | Caml_block (l ,_mutable_flag , _ , _ ) when no_side_effect e0 ->
192
+ List. nth l e1 (* Float i -- should not appear here *)
193
+
191
194
| _ -> { expression_desc = Access (e0, int e1); comment}
192
195
193
196
let call ?comment ?info e0 args : t =
@@ -237,7 +240,7 @@ let is_caml_block ?comment (e : t) : t =
237
240
let array_length ?comment (e : t ) : t =
238
241
match e.expression_desc with
239
242
(* TODO: use array instead? * )
240
- | Array (l , _ ) -> int ?comment (List. length l)
243
+ | ( Array (l , _ ) | Caml_block ( l , _ , _ , _ )) when no_side_effect e -> int ?comment (List. length l)
241
244
| _ -> { expression_desc = Length (e, Array ) ; comment }
242
245
243
246
let string_length ?comment (e : t ) : t =
@@ -330,6 +333,18 @@ let tag_ml_obj ?comment e : t =
330
333
let var_dot ?comment (x : Ident.t ) (e1 : string ) : t =
331
334
{expression_desc = Dot (var x, e1, true ); comment}
332
335
336
+ let bind_call ?comment obj (e1 : string ) args : t =
337
+ call {expression_desc =
338
+ Bind ({expression_desc = Dot (obj, e1, true ); comment} , obj);
339
+ comment = None } args
340
+
341
+ let bind_var_call ?comment (x : Ident.t ) (e1 : string ) args : t =
342
+ let obj = var x in
343
+ call {expression_desc =
344
+ Bind ({expression_desc = Dot (obj, e1, true ); comment} , obj);
345
+ comment = None } args
346
+
347
+
333
348
(* Dot .....................**)
334
349
335
350
let float ?comment f : t =
@@ -466,7 +481,7 @@ let rec econd ?comment (b : t) (t : t) (f : t) : t =
466
481
467
482
| Number ((Int { i = 0 ; _}) ), _, _
468
483
-> f (* TODO: constant folding: could be refined *)
469
- | (Number _ | Array _), _, _
484
+ | (Number _ | Array _ | Caml_block _ ), _, _ when no_side_effect b && no_side_effect f
470
485
-> t (* a block can not be false in OCAML, CF - relies on flow inference*)
471
486
| (Bin (Bor , v , {expression_desc = Number (Int {i = 0 ; _})})), _, _
472
487
-> econd v t f
@@ -687,6 +702,9 @@ let tag ?comment e : t =
687
702
Bin (Bor , {expression_desc = Caml_block_tag e; comment }, int 0 );
688
703
comment = None }
689
704
705
+ let bind ?comment fn obj : t =
706
+ {expression_desc = Bind (fn, obj) ; comment }
707
+
690
708
let public_method_call meth_name obj label cache args =
691
709
let len = List. length args in
692
710
(* * FIXME: not caml object *)
@@ -714,13 +732,26 @@ let public_method_call meth_name obj label cache args =
714
732
how about x#|getElementById|2|
715
733
*)
716
734
(
717
- if len < = 8 then
735
+ let fn = bind (dot obj meth_name) obj in
736
+ if len = 0 then
737
+ dot obj meth_name
738
+ (* Note that when no args supplied,
739
+ it is not necessarily a function, [bind]
740
+ is dangerous
741
+ so if user write such code
742
+ {[
743
+ let u = x # say in
744
+ u 3
745
+ ]}
746
+ It's reasonable to drop [this] support
747
+ *)
748
+ else if len < = 8 then
718
749
let len_str = string_of_int len in
719
750
runtime_call Js_config. curry (" app" ^ len_str)
720
- (dot obj meth_name :: args)
751
+ (fn :: args)
721
752
else
722
753
runtime_call Js_config. curry " app"
723
- [dot obj meth_name ; arr NA args ]
754
+ [fn ; arr NA args ]
724
755
)
725
756
726
757
let set_tag ?comment e tag : t =
0 commit comments