diff --git a/compiler/lib/js_traverse.ml b/compiler/lib/js_traverse.ml index 6df0f8b314..d7714ab2fd 100644 --- a/compiler/lib/js_traverse.ml +++ b/compiler/lib/js_traverse.ml @@ -1220,7 +1220,6 @@ class simpl = inherit map as super method expression e = - let e = super#expression e in let is_zero x = match Num.to_string x with | "0" | "0." -> true @@ -1228,6 +1227,7 @@ class simpl = in match e with | EBin (Plus, e1, e2) -> ( + let e = super#expression e in match e2, e1 with | ENum n, _ when Num.is_neg n -> EBin (Minus, e1, ENum (Num.neg n)) | _, ENum n when Num.is_neg n -> EBin (Minus, e2, ENum (Num.neg n)) @@ -1235,12 +1235,13 @@ class simpl = | (ENum _ as x), ENum zero when is_zero zero -> x | _ -> e) | EBin (Minus, e1, e2) -> ( + let e = super#expression e in match e2, e1 with | ENum n, _ when Num.is_neg n -> EBin (Plus, e1, ENum (Num.neg n)) | (ENum _ as x), ENum zero when is_zero zero -> x | _ -> e) | EFun (i, k, p, b, l) -> EFun (i, k, p, m#statements_top b, l) - | _ -> e + | _ -> super#expression e method statement s = let s = super#statement s in @@ -1248,9 +1249,7 @@ class simpl = | Block [ x ] -> fst x | _ -> s - method program p = - let p = super#statements p in - m#statements_top p + method program p = m#statements_top p method private statements_top l = (* In strict mode, functions inside blocks are scoped to that @@ -1266,35 +1265,41 @@ class simpl = | s -> s, loc)) method statements s = - let s = super#statements s in List.fold_right s ~init:[] ~f:(fun (st, loc) rem -> match st with | Function_declaration (i, k, p, b, l) -> (Function_declaration (i, k, p, m#statements_top b, l), loc) :: rem - | If_statement (ENum n, iftrue, _) when Num.is_one n -> iftrue :: rem - | If_statement (ENum n, _, iffalse) when Num.is_zero n -> opt_cons iffalse rem - | If_statement - (cond, (Return_statement (Some e1), _), Some (Return_statement (Some e2), _)) - -> (Return_statement (Some (ECond (cond, e1, e2))), loc) :: rem - | If_statement - ( cond - , (Expression_statement (EBin (Eq, v1, e1)), _) - , Some (Expression_statement (EBin (Eq, v2, e2)), _) ) - when Poly.(v1 = v2) -> - (Expression_statement (EBin (Eq, v1, ECond (cond, e1, e2))), loc) :: rem - | Variable_statement ((Var as k), l1) -> - let x = - List.map l1 ~f:(function - | DPattern (p, e) -> Variable_statement (k, [ DPattern (p, e) ]), loc - | DIdent (ident, None) -> - Variable_statement (k, [ DIdent (ident, None) ]), loc - | DIdent (ident, Some (exp, pc)) -> ( - match assign_op (EVar ident, exp) with - | Some e -> Expression_statement e, loc - | None -> - ( Variable_statement (k, [ DIdent (ident, Some (exp, pc)) ]) - , loc ))) - in - x @ rem - | _ -> (st, loc) :: rem) + | s -> ( + match super#statement s with + | If_statement (ENum n, iftrue, _) when Num.is_one n -> iftrue :: rem + | If_statement (ENum n, _, iffalse) when Num.is_zero n -> + opt_cons iffalse rem + | If_statement + ( cond + , (Return_statement (Some e1), _) + , Some (Return_statement (Some e2), _) ) -> + (Return_statement (Some (ECond (cond, e1, e2))), loc) :: rem + | If_statement + ( cond + , (Expression_statement (EBin (Eq, v1, e1)), _) + , Some (Expression_statement (EBin (Eq, v2, e2)), _) ) + when Poly.(v1 = v2) -> + (Expression_statement (EBin (Eq, v1, ECond (cond, e1, e2))), loc) :: rem + | Variable_statement ((Var as k), l1) -> + let x = + List.map l1 ~f:(function + | DPattern (p, e) -> + Variable_statement (k, [ DPattern (p, e) ]), loc + | DIdent (ident, None) -> + Variable_statement (k, [ DIdent (ident, None) ]), loc + | DIdent (ident, Some (exp, pc)) -> ( + match assign_op (EVar ident, exp) with + | Some e -> Expression_statement e, loc + | None -> + ( Variable_statement + (k, [ DIdent (ident, Some (exp, pc)) ]) + , loc ))) + in + x @ rem + | _ -> (st, loc) :: rem)) end