@@ -177,41 +177,6 @@ module Exp = struct
177
177
| _ ->
178
178
{expression_desc = Seq (e0,e1); comment}
179
179
180
- let rec econd ?comment (b : t ) (t : t ) (f : t ) : t =
181
- match b.expression_desc , t.expression_desc, f.expression_desc with
182
- | Number ((Int { i = 0 ; _}) ), _, _
183
- -> f (* TODO: constant folding: could be refined *)
184
- | (Number _ | Array _), _, _
185
- -> t (* a block can not be false in OCAML, CF - relies on flow inference*)
186
-
187
- | ((Bin ((EqEqEq , {expression_desc = Number (Int { i = 0 ; _}); _},x))
188
- | Bin (EqEqEq , x,{expression_desc = Number (Int { i = 0 ; _});_}))), _, _
189
- ->
190
- econd ?comment x f t
191
-
192
- | (Bin (Ge ,
193
- ({expression_desc =
194
- (String_length _
195
- | Array_length _ | Bytes_length _ | Function_length _ );
196
- _}), {expression_desc = Number (Int { i = 0 ; _})})), _, _
197
- -> f
198
-
199
- | (Bin (Gt ,
200
- ({expression_desc =
201
- (String_length _
202
- | Array_length _ | Bytes_length _ | Function_length _ );
203
- _} as pred ), {expression_desc = Number (Int {i = 0 ; })})), _, _
204
- ->
205
- (* * Add comment when simplified *)
206
- econd ?comment pred t f
207
- | Not e , _ , _ -> econd ?comment e f t
208
- | Int_of_boolean b , _ , _ -> econd ?comment b t f
209
-
210
- | _ ->
211
- if Js_analyzer. eq_expression t f then
212
- if no_side_effect b then t else seq ?comment b t
213
- else
214
- {expression_desc = Cond (b,t,f); comment}
215
180
216
181
let int ?comment ?c i : t =
217
182
{expression_desc = Number (Int {i; c}) ; comment}
@@ -378,6 +343,7 @@ module Exp = struct
378
343
379
344
let assign ?comment e0 e1 : t = {expression_desc = Bin (Eq , e0,e1); comment}
380
345
346
+
381
347
(* * Convert a javascript boolean to ocaml boolean
382
348
It's necessary for return value
383
349
this should be optmized away for [if] ,[cond] to produce
@@ -411,6 +377,158 @@ module Exp = struct
411
377
triple_equal ?comment a b
412
378
| _ ->
413
379
to_ocaml_boolean {expression_desc = Bin (EqEqEq , e0,e1); comment}
380
+ let bin ?comment (op : J.binop ) e0 e1 : t =
381
+ match op with
382
+ | EqEqEq -> triple_equal ?comment e0 e1
383
+ | _ -> {expression_desc = Bin (op,e0,e1); comment}
384
+
385
+ (* TODO: Constant folding, Google Closure will do that?,
386
+ Even if Google Clsoure can do that, we will see how it interact with other
387
+ optimizations
388
+ We wrap all boolean functions here, since OCaml boolean is a
389
+ bit different from Javascript, so that we can change it in the future
390
+ *)
391
+ let rec and_ ?comment (e1 : t ) (e2 : t ) =
392
+ match e1.expression_desc, e2.expression_desc with
393
+ | Int_of_boolean e1 , Int_of_boolean e2 ->
394
+ and_ ?comment e1 e2
395
+ | Int_of_boolean e1 , _ -> and_ ?comment e1 e2
396
+ | _, Int_of_boolean e2
397
+ -> and_ ?comment e1 e2
398
+ (* optimization if [e1 = e2], then and_ e1 e2 -> e2
399
+ be careful for side effect
400
+ *)
401
+ | Var i, Var j when Js_op_util. same_vident i j
402
+ ->
403
+ to_ocaml_boolean e1
404
+ | Var i,
405
+ (Bin (And , {expression_desc = Var j ; _}, _)
406
+ | Bin (And , _, {expression_desc = Var j ; _}))
407
+ when Js_op_util. same_vident i j
408
+ ->
409
+ to_ocaml_boolean e2
410
+ | _ , _ ->
411
+ to_ocaml_boolean @@ bin ?comment And e1 e2
412
+
413
+ let rec or_ ?comment (e1 : t ) (e2 : t ) =
414
+ match e1.expression_desc, e2.expression_desc with
415
+ | Int_of_boolean e1 , Int_of_boolean e2
416
+ ->
417
+ or_ ?comment e1 e2
418
+ | Int_of_boolean e1 , _ -> or_ ?comment e1 e2
419
+ | _, Int_of_boolean e2
420
+ -> or_ ?comment e1 e2
421
+ | Var i, Var j when Js_op_util. same_vident i j
422
+ ->
423
+ to_ocaml_boolean e1
424
+ | Var i,
425
+ (Bin (Or , {expression_desc = Var j ; _}, _)
426
+ | Bin (Or , _, {expression_desc = Var j ; _}))
427
+ when Js_op_util. same_vident i j
428
+ -> to_ocaml_boolean e2
429
+ | _ , _ ->
430
+ to_ocaml_boolean @@ bin ?comment Or e1 e2
431
+
432
+ (* return a value of type boolean *)
433
+ (* TODO:
434
+ when comparison with Int
435
+ it is right that !(x > 3 ) -> x <= 3 *)
436
+ let rec not ({expression_desc; comment} as e : t ) : t =
437
+ match expression_desc with
438
+ | Bin (EqEqEq , e0,e1)
439
+ -> {expression_desc = Bin (NotEqEq , e0,e1); comment}
440
+ | Bin (NotEqEq , e0 ,e1 ) -> {expression_desc = Bin (EqEqEq , e0,e1); comment}
441
+
442
+ (* Note here the compiled js use primtive comparison only
443
+ for *primitive types*, so it is safe to do such optimization,
444
+ for generic comparison, this does not hold
445
+ *)
446
+ | Bin (Lt, a , b ) -> {e with expression_desc = Bin (Ge ,a,b)}
447
+ | Bin (Ge,a ,b ) -> {e with expression_desc = Bin (Lt ,a,b)}
448
+ | Bin (Le,a ,b ) -> {e with expression_desc = Bin (Gt ,a,b)}
449
+ | Bin (Gt,a ,b ) -> {e with expression_desc = Bin (Le ,a,b)}
450
+
451
+ | Number (Int {i; _} ) ->
452
+ if i != 0 then false_ else true_
453
+ | Int_of_boolean e -> not e
454
+ | Not e -> e
455
+ | x -> {expression_desc = Not e ; comment = None }
456
+
457
+ let rec econd ?comment (b : t ) (t : t ) (f : t ) : t =
458
+ match b.expression_desc , t.expression_desc, f.expression_desc with
459
+ | Number ((Int { i = 0 ; _}) ), _, _
460
+ -> f (* TODO: constant folding: could be refined *)
461
+ | (Number _ | Array _), _, _
462
+ -> t (* a block can not be false in OCAML, CF - relies on flow inference*)
463
+
464
+ | ((Bin ((EqEqEq , {expression_desc = Number (Int { i = 0 ; _}); _},x))
465
+ | Bin (EqEqEq , x,{expression_desc = Number (Int { i = 0 ; _});_}))), _, _
466
+ ->
467
+ econd ?comment x f t
468
+
469
+ | (Bin (Ge ,
470
+ ({expression_desc =
471
+ (String_length _
472
+ | Array_length _ | Bytes_length _ | Function_length _ );
473
+ _}), {expression_desc = Number (Int { i = 0 ; _})})), _, _
474
+ -> f
475
+
476
+ | (Bin (Gt ,
477
+ ({expression_desc =
478
+ (String_length _
479
+ | Array_length _ | Bytes_length _ | Function_length _ );
480
+ _} as pred ), {expression_desc = Number (Int {i = 0 ; })})), _, _
481
+ ->
482
+ (* * Add comment when simplified *)
483
+ econd ?comment pred t f
484
+
485
+ | _, (Cond (p1, branch_code0, branch_code1)), _
486
+ when Js_analyzer. eq_expression branch_code1 f
487
+ ->
488
+ (* {[
489
+ if b then (if p1 then branch_code0 else branch_code1)
490
+ else branch_code1
491
+ ]}
492
+ is equivalent to
493
+ {[
494
+ if b && p1 then branch_code0 else branch_code1
495
+ ]}
496
+ *)
497
+ econd (and_ b p1) branch_code0 f
498
+ | _, (Cond (p1, branch_code0, branch_code1)), _
499
+ when Js_analyzer. eq_expression branch_code0 f
500
+ ->
501
+ (* the same as above except we revert the [cond] expression *)
502
+ econd (and_ b (not p1)) branch_code1 f
503
+
504
+ | _, _, (Cond (p1', branch_code0, branch_code1))
505
+ when Js_analyzer. eq_expression t branch_code0
506
+ (*
507
+ {[
508
+ if b then branch_code0 else (if p1' then branch_code0 else branch_code1)
509
+ ]}
510
+ is equivalent to
511
+ {[
512
+ if b or p1' then branch_code0 else branch_code1
513
+ ]}
514
+ *)
515
+ ->
516
+ econd (or_ b p1') t branch_code1
517
+ | _, _, (Cond (p1', branch_code0, branch_code1))
518
+ when Js_analyzer. eq_expression t branch_code1
519
+ ->
520
+ (* the same as above except we revert the [cond] expression *)
521
+ econd (or_ b (not p1')) t branch_code0
522
+
523
+ | Not e , _ , _ -> econd ?comment e f t
524
+ | Int_of_boolean b , _ , _ -> econd ?comment b t f
525
+
526
+ | _ ->
527
+ if Js_analyzer. eq_expression t f then
528
+ if no_side_effect b then t else seq ?comment b t
529
+ else
530
+ {expression_desc = Cond (b,t,f); comment}
531
+
414
532
415
533
let rec float_equal ?comment (e0 : t ) (e1 : t ) : t =
416
534
match e0.expression_desc, e1.expression_desc with
@@ -429,10 +547,6 @@ module Exp = struct
429
547
->
430
548
to_ocaml_boolean {expression_desc = Bin (EqEqEq , e0,e1); comment}
431
549
432
- let bin ?comment (op : J.binop ) e0 e1 : t =
433
- match op with
434
- | EqEqEq -> triple_equal ?comment e0 e1
435
- | _ -> {expression_desc = Bin (op,e0,e1); comment}
436
550
437
551
let arr ?comment mt es : t =
438
552
{expression_desc = Array (es,mt) ; comment}
@@ -462,33 +576,7 @@ module Exp = struct
462
576
let is_type_number ?comment (e : t ) : t =
463
577
string_equal ?comment (typeof e) (str " number" )
464
578
465
- (* TODO remove this comment ? *)
466
- (* let un ?comment op e : t = {expression_desc = Un(op,e); comment} *)
467
-
468
- (* return a value of type boolean *)
469
- (* TODO:
470
- when comparison with Int
471
- it is right that !(x > 3 ) -> x <= 3 *)
472
- let rec not ({expression_desc; comment} as e : t ) : t =
473
- match expression_desc with
474
- | Bin (EqEqEq , e0,e1)
475
- -> {expression_desc = Bin (NotEqEq , e0,e1); comment}
476
- | Bin (NotEqEq , e0 ,e1 ) -> {expression_desc = Bin (EqEqEq , e0,e1); comment}
477
-
478
- (* Note here the compiled js use primtive comparison only
479
- for *primitive types*, so it is safe to do such optimization,
480
- for generic comparison, this does not hold
481
- *)
482
- | Bin (Lt, a , b ) -> {e with expression_desc = Bin (Ge ,a,b)}
483
- | Bin (Ge,a ,b ) -> {e with expression_desc = Bin (Lt ,a,b)}
484
- | Bin (Le,a ,b ) -> {e with expression_desc = Bin (Gt ,a,b)}
485
- | Bin (Gt,a ,b ) -> {e with expression_desc = Bin (Le ,a,b)}
486
579
487
- | Number (Int {i; _} ) ->
488
- if i != 0 then false_ else true_
489
- | Int_of_boolean e -> not e
490
- | Not e -> e
491
- | x -> {expression_desc = Not e ; comment = None }
492
580
493
581
let new_ ?comment e0 args : t =
494
582
{ expression_desc = New (e0, Some args ); comment}
@@ -516,52 +604,6 @@ module Exp = struct
516
604
| _ -> bin ?comment Plus e (int 1 )
517
605
518
606
519
- (* TODO: Constant folding, Google Closure will do that?,
520
- Even if Google Clsoure can do that, we will see how it interact with other
521
- optimizations
522
- We wrap all boolean functions here, since OCaml boolean is a
523
- bit different from Javascript, so that we can change it in the future
524
- *)
525
- let rec and_ ?comment (e1 : t ) (e2 : t ) =
526
- match e1.expression_desc, e2.expression_desc with
527
- | Int_of_boolean e1 , Int_of_boolean e2 ->
528
- and_ ?comment e1 e2
529
- | Int_of_boolean e1 , _ -> and_ ?comment e1 e2
530
- | _, Int_of_boolean e2
531
- -> and_ ?comment e1 e2
532
- (* optimization if [e1 = e2], then and_ e1 e2 -> e2
533
- be careful for side effect
534
- *)
535
- | Var i, Var j when Js_op_util. same_vident i j
536
- ->
537
- to_ocaml_boolean e1
538
- | Var i,
539
- (Bin (And , {expression_desc = Var j ; _}, _)
540
- | Bin (And , _, {expression_desc = Var j ; _}))
541
- when Js_op_util. same_vident i j
542
- ->
543
- to_ocaml_boolean e2
544
- | _ , _ ->
545
- to_ocaml_boolean @@ bin ?comment And e1 e2
546
-
547
- let rec or_ ?comment (e1 : t ) (e2 : t ) =
548
- match e1.expression_desc, e2.expression_desc with
549
- | Int_of_boolean e1 , Int_of_boolean e2
550
- ->
551
- or_ ?comment e1 e2
552
- | Int_of_boolean e1 , _ -> or_ ?comment e1 e2
553
- | _, Int_of_boolean e2
554
- -> or_ ?comment e1 e2
555
- | Var i, Var j when Js_op_util. same_vident i j
556
- ->
557
- to_ocaml_boolean e1
558
- | Var i,
559
- (Bin (Or , {expression_desc = Var j ; _}, _)
560
- | Bin (Or , _, {expression_desc = Var j ; _}))
561
- when Js_op_util. same_vident i j
562
- -> to_ocaml_boolean e2
563
- | _ , _ ->
564
- to_ocaml_boolean @@ bin ?comment Or e1 e2
565
607
566
608
let string_of_small_int_array ?comment xs : t =
567
609
{expression_desc = String_of_small_int_array xs; comment}
0 commit comments