26 List.assoc l (Misc.ListExt.inv_assoc strings)
29 | AstClight of Clight.program
30 | AstCminor of Cminor.program
31 | AstRTLabs of RTLabs.program
32 | AstRTL of RTL.program
33 | AstERTL of ERTL.program
34 | AstLTL of LTL.program
35 | AstLIN of LIN.program
36 | AstASM of ASM.program
38 let language_of_ast = function
39 | AstClight _ -> Clight
40 | AstCminor _ -> Cminor
41 | AstRTLabs _ -> RTLabs
48 let extension = function
49 | ASM -> ["s" ; "hex"]
51 | language -> [to_string language]
55 | `Source of string * string
58 let parse ?is_lustre_file ?remove_lustre_externals = function
62 (ClightParser.process ?is_lustre_file ?remove_lustre_externals source)
68 (SyntacticAnalysis.process
69 ~lexer_init: (fun filename -> Lexing.from_channel (open_in filename))
70 ~lexer_fun: CminorLexer.token
71 ~parser_fun: CminorParser.program
76 (* FIXME: Will be completed in the next commits. *)
80 | AstClight a -> ClightPrinter.print_program a
81 | AstCminor a -> CminorPrinter.print_program a
82 | AstRTLabs a -> RTLabsPrinter.print_program a
83 | AstRTL a -> RTLPrinter.print_program a
84 | AstERTL a -> ERTLPrinter.print_program a
85 | AstLTL a -> LTLPrinter.print_program a
86 | AstLIN a -> LINPrinter.print_program a
87 | AstASM a -> ASMPrinter.print_program a
89 let labelize = function
91 AstClight (ClightLabelling.add_cost_labels p)
95 AstCminor (CminorLabelling.add_cost_labels p)
99 (* For the other languages, no labelling is defined. *)
103 let clight_to_cminor = function
105 AstCminor (ClightToCminor.translate p)
108 let cminor_to_rtlabs = function
110 AstRTLabs (CminorToRTLabs.translate p)
113 let rtlabs_to_rtl = function
115 AstRTL (RTLabsToRTL.translate p)
118 let rtl_to_ertl = function
120 AstERTL (RTLToERTL.translate p)
123 let ertl_to_ltl = function
125 AstLTL (ERTLToLTL.translate p)
128 let ltl_to_lin = function
130 AstLIN (LTLToLIN.translate p)
133 let lin_to_asm = function
135 AstASM (LINToASM.translate p)
138 (* We explicitly denote the compilation chain as a list of
139 passes that must be composed to translate a program
140 from a source language to a target language. *)
141 let compilation_chain = [
142 (* Source language | Target language | Compilation function *)
143 Clight, Cminor, clight_to_cminor;
144 Cminor, RTLabs, cminor_to_rtlabs;
145 RTLabs, RTL, rtlabs_to_rtl;
146 RTL, ERTL, rtl_to_ertl;
147 ERTL, LTL, ertl_to_ltl;
148 LTL, LIN, ltl_to_lin;
149 LIN, ASM, lin_to_asm;
152 let compile debug src tgt =
153 (* Find the maximal suffix of the chain that starts with the
155 let rec subchain = function
157 (* The chain is assumed to be well-formed: such a suffix
160 | ((l, _, _) :: _) as chain when l = src -> chain
161 | _ :: chain -> subchain chain
163 (* Compose the atomic translations to build a compilation function
164 from [src] to [tgt]. Again, we assume that the compilation chain
165 is well-formed. Thus, if we cannot find [tgt] in the compilation
166 chain then the user must have made a mistake to ask for a
167 translation from [src] to [tgt]. *)
168 let rec compose iprogs src tgt chains ast =
169 if src = tgt then List.rev (ast :: iprogs)
173 Error.global_error "During compilation configuration"
174 (Printf.sprintf "It is not possible to compile from `%s' to `%s'."
178 | (l1, l2, src_to_l2) :: chain ->
180 let l2_to_tgt = compose iprogs l2 tgt chain in
183 (Printf.sprintf "%s -> %s"
188 ast :: l2_to_tgt iprog
190 compose [] src tgt (subchain compilation_chain)
193 (** [add_runtime ast] adds runtime functions for the operations not supported by
194 the target processor. *)
195 let add_runtime = function
197 AstClight (Runtime.replace_unsupported (ClightSwitch.simplify p))
199 (* For the other languages, no runtime functios are defined. *)
203 let compute_costs = function
205 (* Computing costs on Clight programs cannot be done directly
206 because the control-flow is not explicit. Yet, for
207 incremental construction and test of the compiler, we
208 build a stupid mapping from labels to costs for a Clight
209 program that gives cost 1 to every label. *)
210 CostLabel.constant_map (ClightAnnotator.cost_labels p) 1
213 (* Computing costs on Cminor programs cannot be done directly
214 because the control-flow is not explicit. Yet, for
215 incremental construction and test of the compiler, we
216 build a stupid mapping from labels to costs for a Cminor
217 program that gives cost 1 to every label. *)
218 CostLabel.constant_map (CminorAnnotator.cost_labels p) 1
224 Error.warning "during cost computing"
226 "Cost computing is not implemented for language `%s'. Please compile to ASM if you want to annotate the input."
227 (to_string (language_of_ast ast))) ;
232 let instrument costs_mapping = function
234 let (p', cost_id, cost_incr, extern_cost_variables) =
235 ClightAnnotator.instrument p costs_mapping in
236 (AstClight p', cost_id, cost_incr, extern_cost_variables)
239 let (p', cost_id, cost_incr) = CminorAnnotator.instrument p costs_mapping in
240 (AstCminor p', cost_id, cost_incr)
243 Error.warning "during instrumentation"
245 "Instrumentation is not implemented for source language `%s'."
246 (to_string (language_of_ast p)));
247 (p, "", "", StringTools.Map.empty)
249 let annotate input_ast final =
250 let costs_mapping = Misc.Timed.profile "Compute costs" compute_costs final in
251 Misc.Timed.profile "Instrument" (instrument costs_mapping) input_ast
253 let string_output asm_pretty = function
255 [ClightPrinter.print_program p]
257 [CminorPrinter.print_program p]
259 [RTLabsPrinter.print_program p]
261 [RTLPrinter.print_program p]
263 [ERTLPrinter.print_program p]
265 [LTLPrinter.print_program p]
267 [LINPrinter.print_program p]
269 (if asm_pretty then [Pretty.print_program p]
270 else ["Pretty print not requested"]) @
271 [ASMPrinter.print_program p]
273 let save asm_pretty exact_output filename suffix ast =
274 let ext_chopped_filename =
275 if exact_output then filename
277 try Filename.chop_extension filename
278 with Invalid_argument ("Filename.chop_extension") -> filename in
279 let ext_chopped_filename = ext_chopped_filename ^ suffix in
281 List.map (fun ext -> ext_chopped_filename ^ "." ^ ext)
282 (extension (language_of_ast ast)) in
283 let output_filenames =
284 if exact_output then ext_filenames
285 else List.map Misc.SysExt.alternative ext_filenames in
286 let output_strings = string_output asm_pretty ast in
288 let cout = open_out filename in
289 output_string cout s;
292 List.iter2 f output_filenames output_strings
294 let save_cost exact_name filename cost_id cost_incr extern_cost_variables =
296 if exact_name then filename
298 try Filename.chop_extension filename
299 with Invalid_argument ("Filename.chop_extension") -> filename in
300 let cout = open_out (filename ^ ".cerco") in
301 let f fun_name cost_var =
302 output_string cout (fun_name ^ " " ^ cost_var ^ "\n") in
303 output_string cout (cost_id ^ "\n");
304 output_string cout (cost_incr ^ "\n");
305 StringTools.Map.iter f extern_cost_variables;
309 let save_stack exact_name filename stack_id
310 stack_max_id stack_incr extern_stack_variables =
312 if exact_name then filename
314 try Filename.chop_extension filename
315 with Invalid_argument ("Filename.chop_extension") -> filename in
316 let cout = open_out (filename ^ ".stack_cerco") in
317 let f fun_name stack_var =
318 output_string cout (fun_name ^ " " ^ stack_var ^ "\n") in
319 output_string cout (stack_id ^ "\n");
320 output_string cout (stack_max_id ^ "\n");
321 output_string cout (stack_incr ^ "\n");
322 StringTools.Map.iter f extern_stack_variables;
327 let interpret debug = function
329 ClightInterpret.interpret debug p
331 CminorInterpret.interpret debug p
333 RTLabsInterpret.interpret debug p
335 RTLInterpret.interpret debug p
337 ERTLInterpret.interpret debug p
339 LTLInterpret.interpret debug p
341 LINInterpret.interpret debug p
343 ASMInterpret.interpret debug p
346 lustre_test lustre_test_cases lustre_test_cycles
347 lustre_test_min_int lustre_test_max_int = function
350 (ClightLustreMain.add lustre_test lustre_test_cases lustre_test_cycles
351 lustre_test_min_int lustre_test_max_int p)
353 Error.global_error "during main generation"
354 "Lustre testing is only available with C programs."
360 let annotate_stack_size cost_incr = function
362 let (p', stack_id, stack_max_id, stack_incr, extern_stack_variables) =
363 AnnotStackSize.instrument cost_incr p in
364 (AstClight p', stack_id, stack_max_id, stack_incr, extern_stack_variables)
367 let (p', stack_id, stack_incr) = CminorAnnotator.instrument p costs_mapping in
368 (AstCminor p', stack_id, stack_incr)
371 Error.warning "during instrumentation"
373 "Instrumentation is not implemented for source language `%s'."
374 (to_string (language_of_ast p)));
375 (p, "", "", "", StringTools.Map.empty)