Revision 9aaee7f9
Added by Xavier Thirioux almost 9 years ago
src/main_lustre_compiler.ml | ||
---|---|---|
31 | 31 |
let extensions = [".ec"; ".lus"; ".lusi"] |
32 | 32 |
|
33 | 33 |
let check_stateless_decls decls = |
34 |
report ~level:1 (fun fmt -> fprintf fmt ".. checking stateless/stateful status@ "); |
|
34 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. checking stateless/stateful status@ ");
|
|
35 | 35 |
try |
36 | 36 |
Stateless.check_prog decls |
37 | 37 |
with (Stateless.Error (loc, err)) as exc -> |
... | ... | |
41 | 41 |
raise exc |
42 | 42 |
|
43 | 43 |
let type_decls env decls = |
44 |
report ~level:1 (fun fmt -> fprintf fmt ".. typing@ "); |
|
44 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. typing@ ");
|
|
45 | 45 |
let new_env = |
46 | 46 |
begin |
47 | 47 |
try |
... | ... | |
54 | 54 |
end |
55 | 55 |
in |
56 | 56 |
if !Options.print_types then |
57 |
report ~level:1 (fun fmt -> fprintf fmt "@[<v 2> %a@]@ " Corelang.pp_prog_type decls); |
|
57 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2> %a@]@ " Corelang.pp_prog_type decls);
|
|
58 | 58 |
new_env |
59 | 59 |
|
60 | 60 |
let clock_decls env decls = |
61 |
report ~level:1 (fun fmt -> fprintf fmt ".. clock calculus@ "); |
|
61 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. clock calculus@ ");
|
|
62 | 62 |
let new_env = |
63 | 63 |
begin |
64 | 64 |
try |
... | ... | |
69 | 69 |
end |
70 | 70 |
in |
71 | 71 |
if !Options.print_clocks then |
72 |
report ~level:1 (fun fmt -> fprintf fmt "@[<v 2> %a@]@ " Corelang.pp_prog_clock decls); |
|
72 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2> %a@]@ " Corelang.pp_prog_clock decls);
|
|
73 | 73 |
new_env |
74 | 74 |
|
75 | 75 |
(* Loading Lusi file and filling type tables with parsed |
... | ... | |
79 | 79 |
let lexbuf = Lexing.from_channel (open_in filename) in |
80 | 80 |
Location.init lexbuf filename; |
81 | 81 |
(* Parsing *) |
82 |
report ~level:1 (fun fmt -> fprintf fmt ".. parsing header file %s@ " filename); |
|
82 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. parsing header file %s@ " filename);
|
|
83 | 83 |
try |
84 | 84 |
Parse.header own Parser_lustre.header Lexer_lustre.token lexbuf |
85 | 85 |
with |
... | ... | |
117 | 117 |
Stateless.check_compat header |
118 | 118 |
with Sys_error _ -> ( |
119 | 119 |
(* Printing lusi file is necessary *) |
120 |
report ~level:1 |
|
120 |
Log.report ~level:1
|
|
121 | 121 |
(fun fmt -> |
122 | 122 |
fprintf fmt |
123 | 123 |
".. generating lustre interface file %s@," lusi_name); |
... | ... | |
149 | 149 |
Location.init lexbuf source_name; |
150 | 150 |
|
151 | 151 |
(* Parsing *) |
152 |
report ~level:1 |
|
152 |
Log.report ~level:1
|
|
153 | 153 |
(fun fmt -> fprintf fmt "@[<v>.. parsing file %s@," source_name); |
154 | 154 |
let prog = |
155 | 155 |
try |
... | ... | |
166 | 166 |
in |
167 | 167 |
|
168 | 168 |
(* Extracting dependencies *) |
169 |
report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. extracting dependencies@,"); |
|
169 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. extracting dependencies@,");
|
|
170 | 170 |
let dependencies = |
171 | 171 |
List.fold_right |
172 | 172 |
(fun d accu -> match d.Corelang.top_decl_desc with |
... | ... | |
178 | 178 |
List.fold_left (fun (compilation_dep, type_env, clock_env) (s, local) -> |
179 | 179 |
try |
180 | 180 |
let basename = (if local then s else Version.prefix ^ "/include/lustrec/" ^ s ) ^ ".lusi" in |
181 |
report ~level:1 (fun fmt -> fprintf fmt "@[<v 0>Library %s@," basename); |
|
181 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 0>Library %s@," basename);
|
|
182 | 182 |
let comp_dep, lusi_type_env, lusi_clock_env = check_lusi (load_lusi false basename) in |
183 |
report ~level:1 (fun fmt -> fprintf fmt "@]@ "); |
|
183 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ ");
|
|
184 | 184 |
|
185 | 185 |
(s, local, comp_dep)::compilation_dep, |
186 | 186 |
Env.overwrite type_env lusi_type_env, |
... | ... | |
191 | 191 |
) |
192 | 192 |
) ([], Basic_library.type_env, Basic_library.clock_env) dependencies |
193 | 193 |
in |
194 |
report ~level:1 (fun fmt -> fprintf fmt "@]@ "); |
|
194 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ ");
|
|
195 | 195 |
|
196 | 196 |
(* Sorting nodes *) |
197 | 197 |
let prog = SortProg.sort prog in |
... | ... | |
219 | 219 |
if(!Options.delay_calculus) |
220 | 220 |
then |
221 | 221 |
begin |
222 |
report ~level:1 (fun fmt -> fprintf fmt ".. initialisation analysis@?"); |
|
222 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. initialisation analysis@?");
|
|
223 | 223 |
try |
224 | 224 |
Delay_calculus.delay_prog Basic_library.delay_env prog |
225 | 225 |
with (Delay.Error (loc,err)) as exc -> |
... | ... | |
252 | 252 |
(*Hashtbl.iter (fun id td -> match td.Corelang.top_decl_desc with Corelang.Node nd -> Format.eprintf "%s calls %a" id Causality.NodeDep.pp_generic_calls nd | _ -> ()) Corelang.node_table;*) |
253 | 253 |
|
254 | 254 |
(* Normalization phase *) |
255 |
report ~level:1 (fun fmt -> fprintf fmt ".. normalization@,"); |
|
255 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. normalization@,");
|
|
256 | 256 |
(* Special treatment of arrows in lustre backend. We want to keep them *) |
257 | 257 |
if !Options.output = "lustre" then |
258 | 258 |
Normalization.unfold_arrow_active := false; |
259 | 259 |
let prog = Normalization.normalize_prog prog in |
260 |
report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog); |
|
260 |
Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
|
|
261 | 261 |
|
262 | 262 |
(* Checking array accesses *) |
263 | 263 |
if !Options.check then |
264 | 264 |
begin |
265 |
report ~level:1 (fun fmt -> fprintf fmt ".. array access checks@,"); |
|
265 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. array access checks@,");
|
|
266 | 266 |
Access.check_prog prog; |
267 | 267 |
end; |
268 | 268 |
|
269 |
(* Computation of node equation scheduling. It also break dependency cycles. *) |
|
270 |
let prog, node_schs, death_tbls = Scheduling.schedule_prog prog in |
|
269 |
(* Computation of node equation scheduling. It also breaks dependency cycles |
|
270 |
and warns about unused input or memory variables *) |
|
271 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. scheduling@,"); |
|
272 |
let prog, node_schs = Scheduling.schedule_prog prog in |
|
273 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Scheduling.pp_warning_unused node_schs); |
|
274 |
Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog); |
|
271 | 275 |
|
272 | 276 |
(* Optimization of prog: |
273 | 277 |
- Unfold consts |
... | ... | |
281 | 285 |
in |
282 | 286 |
|
283 | 287 |
(* DFS with modular code generation *) |
284 |
report ~level:1 (fun fmt -> fprintf fmt ".. machines generation@,"); |
|
288 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. machines generation@,");
|
|
285 | 289 |
let machine_code = Machine_code.translate_prog prog node_schs in |
286 |
report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," |
|
290 |
Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@,"
|
|
287 | 291 |
(Utils.fprintf_list ~sep:"@ " Machine_code.pp_machine) |
288 | 292 |
machine_code); |
289 | 293 |
|
... | ... | |
297 | 301 |
|
298 | 302 |
(* Creating destination directory if needed *) |
299 | 303 |
if not (Sys.file_exists !Options.dest_dir) then ( |
300 |
report ~level:1 (fun fmt -> fprintf fmt ".. creating destination directory@,"); |
|
304 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. creating destination directory@,");
|
|
301 | 305 |
Unix.mkdir !Options.dest_dir (Unix.stat ".").Unix.st_perm |
302 | 306 |
); |
303 | 307 |
if (Unix.stat !Options.dest_dir).Unix.st_kind <> Unix.S_DIR then ( |
... | ... | |
317 | 321 |
(* let spec_file_opt = if !Options.c_spec then *) |
318 | 322 |
(* ( *) |
319 | 323 |
(* let spec_file = basename ^ "_spec.c" in *) |
320 |
(* report ~level:1 (fun fmt -> fprintf fmt ".. opening files %s, %s and %s@," header_file source_file spec_file); *) |
|
324 |
(* Log.report ~level:1 (fun fmt -> fprintf fmt ".. opening files %s, %s and %s@," header_file source_file spec_file); *)
|
|
321 | 325 |
(* Some spec_file *) |
322 | 326 |
(* ) else ( *) |
323 |
(* report ~level:1 (fun fmt -> fprintf fmt ".. opening files %s and %s@," header_file source_file); *) |
|
327 |
(* Log.report ~level:1 (fun fmt -> fprintf fmt ".. opening files %s and %s@," header_file source_file); *)
|
|
324 | 328 |
(* None *) |
325 | 329 |
(* ) *) |
326 | 330 |
(* in *) |
327 |
report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,"); |
|
331 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,");
|
|
328 | 332 |
C_backend.translate_to_c |
329 | 333 |
header_file source_lib_file source_main_file makefile_file |
330 | 334 |
basename prog machine_code dependencies |
... | ... | |
333 | 337 |
begin |
334 | 338 |
failwith "Sorry, but not yet supported !" |
335 | 339 |
(*let source_file = basename ^ ".java" in |
336 |
report ~level:1 (fun fmt -> fprintf fmt ".. opening file %s@,@?" source_file); |
|
340 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. opening file %s@,@?" source_file);
|
|
337 | 341 |
let source_out = open_out source_file in |
338 | 342 |
let source_fmt = formatter_of_out_channel source_out in |
339 |
report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?"); |
|
343 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?");
|
|
340 | 344 |
Java_backend.translate_to_java source_fmt basename normalized_prog machine_code;*) |
341 | 345 |
end |
342 | 346 |
| "horn" -> |
... | ... | |
358 | 362 |
|
359 | 363 |
| _ -> assert false |
360 | 364 |
in |
361 |
report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@."); |
|
365 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@.");
|
|
362 | 366 |
(* We stop the process here *) |
363 | 367 |
exit 0 |
364 | 368 |
|
Also available in: Unified diff
added warnings for useless variables (at verbose level 1)
- exact definition of 'useless' may be further refined
- display could certainly be improved