|
1 | 1 | (* Copyright (C) 2015-2016 Bloomberg Finance L.P.
|
2 |
| - * |
| 2 | + * |
3 | 3 | * This program is free software: you can redistribute it and/or modify
|
4 | 4 | * it under the terms of the GNU Lesser General Public License as published by
|
5 | 5 | * the Free Software Foundation, either version 3 of the License, or
|
|
17 | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 | 19 | * GNU Lesser General Public License for more details.
|
20 |
| - * |
| 20 | + * |
21 | 21 | * You should have received a copy of the GNU Lesser General Public License
|
22 | 22 | * along with this program; if not, write to the Free Software
|
23 | 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
|
24 | 24 |
|
25 | 25 |
|
26 | 26 |
|
27 |
| -module E = Js_exp_make |
28 |
| -module S = Js_stmt_make |
| 27 | +module E = Js_exp_make |
| 28 | +module S = Js_stmt_make |
29 | 29 |
|
30 |
| -type finished = |
31 |
| - | True |
32 |
| - | False |
| 30 | +type finished = |
| 31 | + | True |
| 32 | + | False |
33 | 33 | | Dummy (* Have no idea, so that when [++] is applied, always use the other *)
|
34 | 34 |
|
35 |
| -type t = { |
| 35 | +type t = { |
36 | 36 | block : J.block ;
|
37 | 37 | value : J.expression option;
|
38 |
| - finished : finished ; |
| 38 | + output_finished : finished ; |
39 | 39 |
|
40 | 40 | }
|
41 | 41 |
|
42 | 42 | type continuation = Lam_compile_context.continuation
|
43 | 43 |
|
44 |
| -let make ?value ?(finished=False) block = |
45 |
| - { block ; value ; finished } |
| 44 | +let make ?value ?(output_finished=False) block = |
| 45 | + { block ; value ; output_finished } |
46 | 46 |
|
47 | 47 |
|
48 |
| -let dummy = |
49 |
| - {value = None; block = []; finished = Dummy } |
| 48 | +let dummy = |
| 49 | + {value = None; block = []; output_finished = Dummy } |
50 | 50 |
|
51 |
| -let output_of_expression |
| 51 | +let output_of_expression |
52 | 52 | (continuation : continuation)
|
53 | 53 | (should_return : Lam_compile_context.return_type)
|
54 | 54 | (lam : Lam.t) (exp : J.expression) : t =
|
55 |
| - begin match continuation, should_return with |
56 |
| - | EffectCall, ReturnFalse -> |
57 |
| - if Lam_analysis.no_side_effects lam |
| 55 | + begin match continuation, should_return with |
| 56 | + | EffectCall, ReturnFalse -> |
| 57 | + if Lam_analysis.no_side_effects lam |
58 | 58 | then dummy
|
59 |
| - else {block = []; value = Some exp ; finished = False} |
60 |
| - | Declare (kind, n), ReturnFalse -> |
| 59 | + else {block = []; value = Some exp ; output_finished = False} |
| 60 | + | Declare (kind, n), ReturnFalse -> |
61 | 61 | make [ S.define_variable ~kind n exp]
|
62 |
| - | Assign n ,ReturnFalse -> |
| 62 | + | Assign n ,ReturnFalse -> |
63 | 63 | make [S.assign n exp ]
|
64 | 64 | | EffectCall, ReturnTrue _ ->
|
65 |
| - make [S.return_stmt exp] ~finished:True |
66 |
| - | (Declare _ | Assign _ ), ReturnTrue _ -> |
67 |
| - make [S.unknown_lambda lam] ~finished:True |
68 |
| - | NeedValue, _ -> |
69 |
| - {block = []; value = Some exp; finished = False } |
| 65 | + make [S.return_stmt exp] ~output_finished:True |
| 66 | + | (Declare _ | Assign _ ), ReturnTrue _ -> |
| 67 | + make [S.unknown_lambda lam] ~output_finished:True |
| 68 | + | NeedValue, _ -> |
| 69 | + {block = []; value = Some exp; output_finished = False } |
70 | 70 | end
|
71 | 71 |
|
72 |
| -let output_of_block_and_expression |
73 |
| - (continuation : continuation) |
| 72 | +let output_of_block_and_expression |
| 73 | + (continuation : continuation) |
74 | 74 | (should_return : Lam_compile_context.return_type)
|
75 |
| - (lam : Lam.t) (block : J.block) exp : t = |
76 |
| - match continuation, should_return with |
| 75 | + (lam : Lam.t) (block : J.block) exp : t = |
| 76 | + match continuation, should_return with |
77 | 77 | | EffectCall, ReturnFalse -> make block ~value:exp
|
78 |
| - | Declare (kind,n), ReturnFalse -> |
| 78 | + | Declare (kind,n), ReturnFalse -> |
79 | 79 | make (block @ [ S.define_variable ~kind n exp])
|
80 |
| - | Assign n, ReturnFalse -> make (block @ [S.assign n exp]) |
81 |
| - | EffectCall, ReturnTrue _ -> make (block @ [S.return_stmt exp]) ~finished:True |
| 80 | + | Assign n, ReturnFalse -> make (block @ [S.assign n exp]) |
| 81 | + | EffectCall, ReturnTrue _ -> make (block @ [S.return_stmt exp]) ~output_finished:True |
82 | 82 | | (Declare _ | Assign _), ReturnTrue _ ->
|
83 |
| - make [S.unknown_lambda lam] ~finished:True |
84 |
| - | NeedValue, (ReturnTrue _ | ReturnFalse) -> |
| 83 | + make [S.unknown_lambda lam] ~output_finished:True |
| 84 | + | NeedValue, (ReturnTrue _ | ReturnFalse) -> |
85 | 85 | make block ~value:exp
|
86 | 86 |
|
87 | 87 |
|
88 | 88 |
|
89 |
| -let block_with_opt_expr block (x : J.expression option) : J.block = |
90 |
| - match x with |
| 89 | +let block_with_opt_expr block (x : J.expression option) : J.block = |
| 90 | + match x with |
91 | 91 | | None -> block
|
92 | 92 | | Some x when Js_analyzer.no_side_effect_expression x -> block
|
93 | 93 | | Some x -> block @ [S.exp x ]
|
94 | 94 |
|
95 |
| -let opt_expr_with_block (x : J.expression option) block : J.block = |
96 |
| - match x with |
| 95 | +let opt_expr_with_block (x : J.expression option) block : J.block = |
| 96 | + match x with |
97 | 97 | | None -> block
|
98 | 98 | | Some x when Js_analyzer.no_side_effect_expression x -> block
|
99 | 99 | | Some x -> (S.exp x) :: block
|
100 |
| - |
101 | 100 |
|
102 |
| -let rec unnest_block (block : J.block) : J.block = |
103 |
| - match block with |
104 |
| - | [{statement_desc = Block block}] -> unnest_block block |
105 |
| - | _ -> block |
106 | 101 |
|
107 |
| -let output_as_block ( x : t) : J.block = |
108 |
| - match x with |
109 |
| - | {block; value = opt; finished} -> |
| 102 | +let rec unnest_block (block : J.block) : J.block = |
| 103 | + match block with |
| 104 | + | [{statement_desc = Block block}] -> unnest_block block |
| 105 | + | _ -> block |
| 106 | + |
| 107 | +let output_as_block ( x : t) : J.block = |
| 108 | + match x with |
| 109 | + | {block; value = opt; output_finished} -> |
110 | 110 | let block = unnest_block block in
|
111 |
| - if finished = True then block |
112 |
| - else |
| 111 | + if output_finished = True then block |
| 112 | + else |
113 | 113 | block_with_opt_expr block opt
|
114 |
| - |
115 | 114 |
|
116 |
| -let to_break_block (x : t) : J.block * bool = |
117 |
| - let block = unnest_block x.block in |
118 |
| - match x with |
119 |
| - | {finished = True; _ } -> |
| 115 | + |
| 116 | +let to_break_block (x : t) : J.block * bool = |
| 117 | + let block = unnest_block x.block in |
| 118 | + match x with |
| 119 | + | {output_finished = True; _ } -> |
120 | 120 | block, false
|
121 | 121 | (* value does not matter when [finished] is true
|
122 | 122 | TODO: check if it has side efects
|
123 | 123 | *)
|
124 |
| - | { value = None; finished } -> |
125 |
| - block, |
126 |
| - (match finished with | True -> false | (False | Dummy) -> true ) |
| 124 | + | { value = None; output_finished } -> |
| 125 | + block, |
| 126 | + (match output_finished with | True -> false | (False | Dummy) -> true ) |
127 | 127 |
|
128 |
| - | {value = Some _ as opt; _} -> |
| 128 | + | {value = Some _ as opt; _} -> |
129 | 129 | block_with_opt_expr block opt, true
|
130 | 130 |
|
131 | 131 |
|
132 | 132 | (** TODO: make everything expression make inlining hard, and code not readable?
|
133 |
| - 1. readability dpends on how we print the expression |
| 133 | + 1. readability dpends on how we print the expression |
134 | 134 | 2. inlining needs generate symbols, which are statements, type mismatch
|
135 | 135 | we need capture [Exp e]
|
136 | 136 |
|
137 |
| - can we call them all [statement]? statement has no value |
| 137 | + can we call them all [statement]? statement has no value |
138 | 138 | *)
|
139 | 139 | (* | {block = [{statement_desc = Exp e }]; value = None ; _}, _ *)
|
140 | 140 | (* -> *)
|
141 | 141 | (* append { x with block = []; value = Some e} y *)
|
142 | 142 | (* | _ , {block = [{statement_desc = Exp e }]; value = None ; _} *)
|
143 | 143 | (* -> *)
|
144 | 144 | (* append x { y with block = []; value = Some e} *)
|
145 |
| - |
146 |
| -let rec append_output (x : t ) (y : t ) : t = |
| 145 | + |
| 146 | +let rec append_output (x : t ) (y : t ) : t = |
147 | 147 | match x , y with (* ATTTENTION: should not optimize [opt_e2], it has to conform to [NeedValue]*)
|
148 |
| - | {finished = True; _ }, _ -> x |
149 |
| - | _, {block = []; value= None; finished = Dummy } -> x |
| 148 | + | { output_finished = True; _ }, _ -> x |
| 149 | + | _, {block = []; value= None; output_finished = Dummy } -> x |
150 | 150 | (* finished = true --> value = E.undefined otherwise would throw*)
|
151 |
| - | {block = []; value= None; _ }, y -> y |
152 |
| - | {block = []; value= Some _; _}, {block = []; value= None; _ } -> x |
153 |
| - | {block = []; value = Some e1; _}, ({block = []; value = Some e2; finished } as z) -> |
154 |
| - if Js_analyzer.no_side_effect_expression e1 |
| 151 | + | {block = []; value= None; _ }, y -> y |
| 152 | + | {block = []; value= Some _; _}, {block = []; value= None; _ } -> x |
| 153 | + | {block = []; value = Some e1; _}, ({block = []; value = Some e2; output_finished } as z) -> |
| 154 | + if Js_analyzer.no_side_effect_expression e1 |
155 | 155 | then z
|
156 | 156 | (* It would optimize cases like [module aliases]
|
157 |
| - Bigarray, List |
| 157 | + Bigarray, List |
158 | 158 | *)
|
159 | 159 | else
|
160 |
| - {block = []; value = Some (E.seq e1 e2); finished} |
| 160 | + {block = []; value = Some (E.seq e1 e2); output_finished} |
161 | 161 | (* {block = [S.exp e1]; value = Some e2(\* (E.seq e1 e2) *\); finished} *)
|
162 | 162 |
|
163 |
| - | {block = block1; value = opt_e1; _}, {block = block2; value = opt_e2; finished} -> |
| 163 | + | {block = block1; value = opt_e1; _}, {block = block2; value = opt_e2; output_finished} -> |
164 | 164 | let block1 = unnest_block block1 in
|
165 | 165 | make (block1 @ (opt_expr_with_block opt_e1 @@ unnest_block block2))
|
166 |
| - ?value:opt_e2 ~finished |
| 166 | + ?value:opt_e2 ~output_finished:output_finished |
167 | 167 |
|
168 | 168 |
|
169 | 169 |
|
170 | 170 |
|
171 | 171 | (* Fold right is more efficient *)
|
172 |
| -let concat (xs : t list) : t = |
| 172 | +let concat (xs : t list) : t = |
173 | 173 | Ext_list.fold_right (fun x acc -> append_output x acc) xs dummy
|
174 | 174 |
|
175 |
| -let to_string x = |
| 175 | +let to_string x = |
176 | 176 | Js_dump.string_of_block (output_as_block x)
|
0 commit comments