lustrec / src / main_lustre_compiler.ml @ 4fda48d3
History | View | Annotate | Download (5.37 KB)
1 |
(********************************************************************) |
---|---|
2 |
(* *) |
3 |
(* The LustreC compiler toolset / The LustreC Development Team *) |
4 |
(* Copyright 2012 - -- ONERA - CNRS - INPT *) |
5 |
(* *) |
6 |
(* LustreC is free software, distributed WITHOUT ANY WARRANTY *) |
7 |
(* under the terms of the GNU Lesser General Public License *) |
8 |
(* version 2.1. *) |
9 |
(* *) |
10 |
(********************************************************************) |
11 |
|
12 |
open Format |
13 |
open Log |
14 |
open Compiler_common |
15 |
|
16 |
open Utils |
17 |
open Lustre_types |
18 |
|
19 |
|
20 |
let usage = "Usage: lustrec [options] \x1b[4msource file\x1b[0m" |
21 |
|
22 |
let extensions = [".ec"; ".lus"; ".lusi"] |
23 |
|
24 |
(* print a .lusi header file from a source prog *) |
25 |
let print_lusi prog dirname basename extension = |
26 |
let header = Lusic.extract_header dirname basename prog in |
27 |
let header_name = dirname ^ "/" ^ basename ^ extension in |
28 |
let h_out = open_out header_name in |
29 |
let h_fmt = formatter_of_out_channel h_out in |
30 |
begin |
31 |
Typing.uneval_prog_generics header; |
32 |
Clock_calculus.uneval_prog_generics header; |
33 |
Printers.pp_lusi_header h_fmt basename header; |
34 |
close_out h_out |
35 |
end |
36 |
|
37 |
(* compile a .lusi header file *) |
38 |
let compile_header dirname basename extension = |
39 |
let destname = !Options.dest_dir ^ "/" ^ basename in |
40 |
let header_name = basename ^ extension in |
41 |
let lusic_ext = extension ^ "c" in |
42 |
begin |
43 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v>"); |
44 |
let header = parse_header true (dirname ^ "/" ^ header_name) in |
45 |
ignore (Modules.load_header ISet.empty header); |
46 |
ignore (check_top_decls header); |
47 |
create_dest_dir (); |
48 |
Log.report ~level:1 |
49 |
(fun fmt -> fprintf fmt ".. generating compiled header file %sc@," (destname ^ extension)); |
50 |
Lusic.write_lusic true header destname lusic_ext; |
51 |
generate_lusic_header destname lusic_ext; |
52 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@ ") |
53 |
end |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
(* compile a .lus source file *) |
60 |
let rec compile_source dirname basename extension = |
61 |
let source_name = dirname ^ "/" ^ basename ^ extension in |
62 |
|
63 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 0>"); |
64 |
|
65 |
(* Parsing source *) |
66 |
let prog = parse_source source_name in |
67 |
|
68 |
let prog = |
69 |
if !Options.mpfr then |
70 |
Mpfr.mpfr_module::prog |
71 |
else |
72 |
prog |
73 |
in |
74 |
let prog, dependencies = |
75 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. Phase 1 : Normalisation@,"); |
76 |
try |
77 |
Compiler_stages.stage1 prog dirname basename |
78 |
with Compiler_stages.StopPhase1 prog -> ( |
79 |
if !Options.lusi then |
80 |
begin |
81 |
let lusi_ext = extension ^ "i" in |
82 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating interface file %s@ " (basename ^ lusi_ext)); |
83 |
print_lusi prog dirname basename lusi_ext; |
84 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@."); |
85 |
exit 0 |
86 |
end |
87 |
else |
88 |
assert false |
89 |
) |
90 |
in |
91 |
Log.report ~level:3 (fun fmt -> fprintf fmt ".. Normalized program:@ %a@ "Printers.pp_prog prog); |
92 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@]@,"); |
93 |
|
94 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. Phase 2 : Machines generation@,"); |
95 |
|
96 |
let machine_code = |
97 |
Compiler_stages.stage2 prog |
98 |
in |
99 |
|
100 |
Log.report ~level:3 (fun fmt -> fprintf fmt ".. Generated machines:@ %a@ " Machine_code_common.pp_machines machine_code); |
101 |
|
102 |
if Scopes.Plugin.show_scopes () then |
103 |
begin |
104 |
let all_scopes = Scopes.compute_scopes prog !Options.main_node in |
105 |
(* Printing scopes *) |
106 |
if !Options.verbose_level >= 1 then |
107 |
Format.printf "Possible scopes are:@ "; |
108 |
Format.printf "@[<v>%a@ @]@ @?" Scopes.print_scopes all_scopes; |
109 |
exit 0 |
110 |
|
111 |
end; |
112 |
let machine_code = Plugins.refine_machine_code prog machine_code in |
113 |
Log.report ~level:1 (fun fmt -> fprintf fmt "xxx@]@ yyy@ "); |
114 |
|
115 |
Compiler_stages.stage3 prog machine_code dependencies basename; |
116 |
begin |
117 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@."); |
118 |
(* We stop the process here *) |
119 |
exit 0 |
120 |
end |
121 |
|
122 |
let compile dirname basename extension = |
123 |
match extension with |
124 |
| ".lusi" -> compile_header dirname basename extension |
125 |
| ".lus" -> compile_source dirname basename extension |
126 |
| _ -> assert false |
127 |
|
128 |
let anonymous filename = |
129 |
let ok_ext, ext = List.fold_left |
130 |
(fun (ok, ext) ext' -> |
131 |
if not ok && Filename.check_suffix filename ext' then |
132 |
true, ext' |
133 |
else |
134 |
ok, ext) |
135 |
(false, "") extensions in |
136 |
if ok_ext then |
137 |
let dirname = Filename.dirname filename in |
138 |
let basename = Filename.chop_suffix (Filename.basename filename) ext in |
139 |
compile dirname basename ext |
140 |
else |
141 |
raise (Arg.Bad ("Can only compile *.lusi, *.lus or *.ec files")) |
142 |
|
143 |
let _ = |
144 |
Global.initialize (); |
145 |
Corelang.add_internal_funs (); |
146 |
try |
147 |
Printexc.record_backtrace true; |
148 |
|
149 |
let options = Options_management.lustrec_options @ (Plugins.options ()) in |
150 |
|
151 |
Arg.parse options anonymous usage |
152 |
with |
153 |
| Parse.Error _ |
154 |
| Types.Error (_,_) | Clocks.Error (_,_) -> exit 1 |
155 |
| Corelang.Error (_ (* loc *), kind) (*| Task_set.Error _*) -> exit (Error.return_code kind) |
156 |
(* | Causality.Error _ -> exit (Error.return_code Error.AlgebraicLoop) *) |
157 |
| Sys_error msg -> (eprintf "Failure: %s@." msg); exit 1 |
158 |
| exc -> (track_exception (); raise exc) |
159 |
|
160 |
(* Local Variables: *) |
161 |
(* compile-command:"make -C .." *) |
162 |
(* End: *) |