|
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, (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 ) |
126 | 127 |
|
127 | | - | {value = Some _ as opt; _} -> |
| 128 | + | {value = Some _ as opt; _} -> |
128 | 129 | block_with_opt_expr block opt, true |
129 | 130 |
|
130 | 131 |
|
131 | 132 | (** TODO: make everything expression make inlining hard, and code not readable? |
132 | | - 1. readability dpends on how we print the expression |
| 133 | + 1. readability dpends on how we print the expression |
133 | 134 | 2. inlining needs generate symbols, which are statements, type mismatch |
134 | 135 | we need capture [Exp e] |
135 | 136 |
|
136 | | - can we call them all [statement]? statement has no value |
| 137 | + can we call them all [statement]? statement has no value |
137 | 138 | *) |
138 | 139 | (* | {block = [{statement_desc = Exp e }]; value = None ; _}, _ *) |
139 | 140 | (* -> *) |
140 | 141 | (* append { x with block = []; value = Some e} y *) |
141 | 142 | (* | _ , {block = [{statement_desc = Exp e }]; value = None ; _} *) |
142 | 143 | (* -> *) |
143 | 144 | (* append x { y with block = []; value = Some e} *) |
144 | | - |
145 | | -let rec append_output (x : t ) (y : t ) : t = |
| 145 | + |
| 146 | +let rec append_output (x : t ) (y : t ) : t = |
146 | 147 | match x , y with (* ATTTENTION: should not optimize [opt_e2], it has to conform to [NeedValue]*) |
147 | | - | {finished = True; _ }, _ -> x |
148 | | - | _, {block = []; value= None; finished = Dummy } -> x |
| 148 | + | { output_finished = True; _ }, _ -> x |
| 149 | + | _, {block = []; value= None; output_finished = Dummy } -> x |
149 | 150 | (* finished = true --> value = E.undefined otherwise would throw*) |
150 | | - | {block = []; value= None; _ }, y -> y |
151 | | - | {block = []; value= Some _; _}, {block = []; value= None; _ } -> x |
152 | | - | {block = []; value = Some e1; _}, ({block = []; value = Some e2; finished } as z) -> |
153 | | - 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 |
154 | 155 | then z |
155 | 156 | (* It would optimize cases like [module aliases] |
156 | | - Bigarray, List |
| 157 | + Bigarray, List |
157 | 158 | *) |
158 | 159 | else |
159 | | - {block = []; value = Some (E.seq e1 e2); finished} |
| 160 | + {block = []; value = Some (E.seq e1 e2); output_finished} |
160 | 161 | (* {block = [S.exp e1]; value = Some e2(\* (E.seq e1 e2) *\); finished} *) |
161 | 162 |
|
162 | | - | {block = block1; value = opt_e1; _}, {block = block2; value = opt_e2; finished} -> |
| 163 | + | {block = block1; value = opt_e1; _}, {block = block2; value = opt_e2; output_finished} -> |
163 | 164 | let block1 = unnest_block block1 in |
164 | 165 | make (block1 @ (opt_expr_with_block opt_e1 @@ unnest_block block2)) |
165 | | - ?value:opt_e2 ~finished |
| 166 | + ?value:opt_e2 ~output_finished:output_finished |
166 | 167 |
|
167 | 168 |
|
168 | 169 |
|
169 | 170 |
|
170 | 171 | (* Fold right is more efficient *) |
171 | | -let concat (xs : t list) : t = |
| 172 | +let concat (xs : t list) : t = |
172 | 173 | Ext_list.fold_right (fun x acc -> append_output x acc) xs dummy |
173 | 174 |
|
174 | | -let to_string x = |
| 175 | +let to_string x = |
175 | 176 | Js_dump.string_of_block (output_as_block x) |
0 commit comments