Project

General

Profile

« Previous | Next » 

Revision ca7ff3f7

Added by LĂ©lio Brun 8 months ago

reformatting

View differences:

src/compiler_stages.ml
6 6
exception StopPhase1 of program_t
7 7

  
8 8
let dynamic_checks () =
9
  match !Options.output, !Options.spec with
10
  | "C", "C" -> true
11
  | _ -> false
12

  
9
  match !Options.output, !Options.spec with "C", "C" -> true | _ -> false
13 10

  
14 11
let generate_c_header = ref false
15 12

  
16 13
(* check whether a source file has a compiled header, if not, generate the
17 14
   compiled header *)
18
let compile_source_to_header prog computed_types_env computed_clocks_env dirname basename extension =
15
let compile_source_to_header prog computed_types_env computed_clocks_env dirname
16
    basename extension =
19 17
  let destname = !Options.dest_dir ^ "/" ^ basename in
20 18
  let lusic_ext = ".lusic" in
21 19
  let header_name = destname ^ lusic_ext in
22 20
  let from_lusi = extension = ".lusi" in
23
  begin
24
    if (* Generating the lusic file *)
25
      (* because input is a lusi *)
26
      from_lusi
27
      (* or because it is a lus but no lusic exists *)
28
      || (extension = ".lus" && not (Sys.file_exists header_name))
29
      (* or the lusic exists but is not generated from a lusi, hence it
30
         has te be regenerated *)
31
      || (let lusic = Lusic.read_lusic destname lusic_ext in
32
          not lusic.Lusic.from_lusi)
33
    then
34
      begin
35
        Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. generating compiled header file %s@,"
36
                                header_name);
37
        Lusic.write_lusic
38
          from_lusi (* is it a lusi file ? *)
39
          (if from_lusi then prog else Lusic.extract_header dirname basename prog)
40
          destname
41
          lusic_ext;
42
        generate_c_header := !Options.output = "C";
43
      end
44
    else (* Lusic exists and is usable. Checking compatibility *)
45
      begin
46
        Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. loading compiled header file %s@,"
47
                                header_name);
48
        let lusic = Lusic.read_lusic destname lusic_ext in
49
        Lusic.check_obsolete lusic destname;
50
        let header = lusic.Lusic.contents in
51
        let (declared_types_env, declared_clocks_env) = Modules.get_envs_from_top_decls header in
52
        check_compatibility
53
          (prog, computed_types_env, computed_clocks_env)
54
          (header, declared_types_env, declared_clocks_env)
55
      end
56
  end
57

  
21
  if
22
    (* Generating the lusic file *)
23
    (* because input is a lusi *)
24
    from_lusi
25
    (* or because it is a lus but no lusic exists *)
26
    || (extension = ".lus" && not (Sys.file_exists header_name))
27
    (* or the lusic exists but is not generated from a lusi, hence it has te be
28
       regenerated *)
29
    ||
30
    let lusic = Lusic.read_lusic destname lusic_ext in
31
    not lusic.Lusic.from_lusi
32
  then (
33
    Log.report ~level:1 (fun fmt ->
34
        fprintf fmt "@ .. generating compiled header file %s@," header_name);
35
    Lusic.write_lusic from_lusi
36
      (* is it a lusi file ? *)
37
      (if from_lusi then prog else Lusic.extract_header dirname basename prog)
38
      destname lusic_ext;
39
    generate_c_header := !Options.output = "C")
40
  else (
41
    (* Lusic exists and is usable. Checking compatibility *)
42
    Log.report ~level:1 (fun fmt ->
43
        fprintf fmt "@ .. loading compiled header file %s@," header_name);
44
    let lusic = Lusic.read_lusic destname lusic_ext in
45
    Lusic.check_obsolete lusic destname;
46
    let header = lusic.Lusic.contents in
47
    let declared_types_env, declared_clocks_env =
48
      Modules.get_envs_from_top_decls header
49
    in
50
    check_compatibility
51
      (prog, computed_types_env, computed_clocks_env)
52
      (header, declared_types_env, declared_clocks_env))
58 53

  
59 54
(* From prog to prog *)
60 55
let stage1 params prog dirname basename extension =
......
64 59
  (* Removing automata *)
65 60
  let prog = expand_automata prog in
66 61
  Log.report ~level:4 (fun fmt ->
67
      fprintf fmt "@[<v 2>.. after automata expansion:@ %a@]@ "
68
        Printers.pp_prog prog
69
        (* Utils.Format.pp_print_nothing () *)
70
    );
62
      fprintf fmt "@[<v 2>.. after automata expansion:@ %a@]@ " Printers.pp_prog
63
        prog
64
      (* Utils.Format.pp_print_nothing () *));
71 65

  
72 66
  (* Importing source *)
73
  let prog, dependencies, (typ_env, clk_env) = Modules.load ~is_header:(extension = ".lusi") prog in
67
  let prog, dependencies, (typ_env, clk_env) =
68
    Modules.load ~is_header:(extension = ".lusi") prog
69
  in
74 70
  (* Registering types and clocks for future checks *)
75 71
  Global.type_env := Env.overwrite !Global.type_env typ_env;
76 72
  Global.clock_env := Env.overwrite !Global.clock_env clk_env;
77
  
73

  
78 74
  (* (\* Extracting dependencies (and updating Global.(type_env/clock_env) *\)
79 75
   * let dependencies = import_dependencies prog in *)
80 76

  
......
84 80
  let prog = resolve_contracts prog in
85 81
  let prog = SortProg.sort prog in
86 82
  Log.report ~level:3 (fun fmt ->
87
      Format.fprintf fmt "@ @[<v 2>.. contracts resolved:@ %a@ @]@ " Printers.pp_prog prog);
83
      Format.fprintf fmt "@ @[<v 2>.. contracts resolved:@ %a@ @]@ "
84
        Printers.pp_prog prog);
88 85

  
89 86
  (* Consolidating main node *)
90 87
  let _ =
91 88
    match !Options.main_node with
92
    | "" -> ()
89
    | "" ->
90
      ()
93 91
    | main_node -> (
94 92
      Global.main_node := main_node;
95
      try
96
        ignore (Corelang.node_from_name main_node)
97
      with Not_found -> (
98
        Format.eprintf "Code generation error: %a@." Error.pp_error_msg Error.Main_not_found;
99
        raise (Error.Error (Location.dummy_loc, Error.Main_not_found))
100
    ))
93
      try ignore (Corelang.node_from_name main_node)
94
      with Not_found ->
95
        Format.eprintf "Code generation error: %a@." Error.pp_error_msg
96
          Error.Main_not_found;
97
        raise (Error.Error (Location.dummy_loc, Error.Main_not_found)))
101 98
  in
102
  
99

  
103 100
  (* Perform inlining before any analysis *)
104 101
  let _, prog =
105 102
    if !Options.global_inline && !Global.main_node <> "" then
106
      (if !Options.witnesses then prog else []),
107
      Inliner.global_inline prog
103
      (if !Options.witnesses then prog else []), Inliner.global_inline prog
108 104
    else (* if !Option.has_local_inline *)
109
      [],
110
      Inliner.local_inline prog (* type_env clock_env *)
105
      [], Inliner.local_inline prog
106
    (* type_env clock_env *)
111 107
  in
112 108

  
113 109
  (* Checking stateless/stateful status *)
114
  if Plugins.check_force_stateful () then
115
    force_stateful_decls prog
116
  else
117
    check_stateless_decls prog;
110
  if Plugins.check_force_stateful () then force_stateful_decls prog
111
  else check_stateless_decls prog;
118 112

  
119 113
  (* Typing *)
120 114
  Global.type_env := type_decls !Global.type_env prog;
......
125 119
  (* Registering and checking machine types *)
126 120
  if Machine_types.is_active then Machine_types.load prog;
127 121

  
128

  
129 122
  (* Generating a .lusi header file only *)
130 123
  if !Options.lusi || !Options.print_nodes then
131 124
    (* We stop here the processing and produce the current prog. It will be
132 125
       exported as a lusi *)
133 126
    raise (StopPhase1 prog);
134 127

  
135
  (* Optimization of prog:
136
     - Unfold consts
137
     - eliminate trivial expressions
138
   *)
139
  
128
  (* Optimization of prog: - Unfold consts - eliminate trivial expressions *)
140 129
  let prog =
141
    if !Options.const_unfold || !Options.optimization >= 5 then
142
      begin
143
        Log.report ~level:1 (fun fmt -> fprintf fmt ".. eliminating constants and aliases@,");
144
        Optimize_prog.prog_unfold_consts prog
145
      end
146
    else
147
      prog
130
    if !Options.const_unfold || !Options.optimization >= 5 then (
131
      Log.report ~level:1 (fun fmt ->
132
          fprintf fmt ".. eliminating constants and aliases@,");
133
      Optimize_prog.prog_unfold_consts prog)
134
    else prog
148 135
  in
149
  
136

  
150 137
  (* Delay calculus *)
151
  (* TO BE DONE LATER (Xavier)
152
     if(!Options.delay_calculus)
153
     then
154
     begin
155
     Log.report ~level:1 (fun fmt -> fprintf fmt ".. initialisation analysis@?");
156
     try
157
     Delay_calculus.delay_prog Basic_library.delay_env prog
158
     with (Delay.Error (loc,err)) as exc ->
159
     Location.print loc;
160
     eprintf "%a" Delay.pp_error err;
161
     Utils.track_exception ();
162
     raise exc
163
     end;
164
   *)
138
  (* TO BE DONE LATER (Xavier) if(!Options.delay_calculus) then begin Log.report
139
     ~level:1 (fun fmt -> fprintf fmt ".. initialisation analysis@?"); try
140
     Delay_calculus.delay_prog Basic_library.delay_env prog with (Delay.Error
141
     (loc,err)) as exc -> Location.print loc; eprintf "%a" Delay.pp_error err;
142
     Utils.track_exception (); raise exc end; *)
165 143

  
166 144
  (* Creating destination directory if needed *)
167 145
  create_dest_dir ();
168
  
146

  
169 147
  Typing.uneval_prog_generics prog;
170 148
  Clock_calculus.uneval_prog_generics prog;
171 149

  
172

  
173
  (* Disabling witness option. Could but reactivated later
174
  if !Options.global_inline && !Options.main_node <> "" && !Options.witnesses then
175
    begin
176
      let orig = Corelang.copy_prog orig in
177
      Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating witness file@,");
178
      check_stateless_decls orig;
179
      let _ = Typing.type_prog type_env orig in
180
      let _ = Clock_calculus.clock_prog clock_env orig in
181
      Typing.uneval_prog_generics orig;
182
      Clock_calculus.uneval_prog_generics orig;
183
      Inliner.witness
184
	basename
185
	!Options.main_node
186
	orig prog type_env clock_env
187
    end;
188
   *)
189

  
190
  (* Computes and stores generic calls for each node,
191
     only useful for ANSI C90 compliant generic node compilation *)
150
  (* Disabling witness option. Could but reactivated later if
151
     !Options.global_inline && !Options.main_node <> "" && !Options.witnesses
152
     then begin let orig = Corelang.copy_prog orig in Log.report ~level:1 (fun
153
     fmt -> fprintf fmt ".. generating witness file@,"); check_stateless_decls
154
     orig; let _ = Typing.type_prog type_env orig in let _ =
155
     Clock_calculus.clock_prog clock_env orig in Typing.uneval_prog_generics
156
     orig; Clock_calculus.uneval_prog_generics orig; Inliner.witness basename
157
     !Options.main_node orig prog type_env clock_env end; *)
158

  
159
  (* Computes and stores generic calls for each node, only useful for ANSI C90
160
     compliant generic node compilation *)
192 161
  if !Options.ansi then Causality.NodeDep.compute_generic_calls prog;
162

  
193 163
  (*Hashtbl.iter (fun id td -> match td.Corelang.top_decl_desc with
194 164
    Corelang.Node nd -> Format.eprintf "%s calls %a" id
195 165
    Causality.NodeDep.pp_generic_calls nd | _ -> ()) Corelang.node_table;*)
196 166

  
197
  (* If some backend involving dynamic checks are active, then node annotations become runtime checks *)
198
  let prog =
199
    if dynamic_checks () then
200
      Spec.enforce_spec_prog prog
201
    else
202
      prog
203
  in
204

  
167
  (* If some backend involving dynamic checks are active, then node annotations
168
     become runtime checks *)
169
  let prog = if dynamic_checks () then Spec.enforce_spec_prog prog else prog in
205 170

  
206 171
  (* (\* Registering and checking machine types *\) *)
207 172
  (* Machine_types.load prog; *)
......
209 174
  (* Normalization phase *)
210 175
  Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. normalization@ ");
211 176
  let prog = Normalization.normalize_prog params prog in
212
  Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@ "
213
                          Printers.pp_prog_short prog);
214
  Log.report ~level:3  (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@ "
215
                           Printers.pp_prog prog);
216
  
177
  Log.report ~level:2 (fun fmt ->
178
      fprintf fmt "@[<v 2>@ %a@]@ " Printers.pp_prog_short prog);
179
  Log.report ~level:3 (fun fmt ->
180
      fprintf fmt "@[<v 2>@ %a@]@ " Printers.pp_prog prog);
181

  
217 182
  (* Compatibility with Lusi *)
218
  (* If compiling a lusi, generate the lusic. If this is a lus file, Check the existence of a lusi (Lustre Interface file) *)
183
  (* If compiling a lusi, generate the lusic. If this is a lus file, Check the
184
     existence of a lusi (Lustre Interface file) *)
219 185
  if !Options.compile_header then
220
    compile_source_to_header
221
      prog !Global.type_env !Global.clock_env dirname basename extension;
222

  
186
    compile_source_to_header prog !Global.type_env !Global.clock_env dirname
187
      basename extension;
223 188

  
224 189
  let prog =
225
    if !Options.mpfr
226
    then
227
      begin
228
	Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. targetting MPFR library@,");
229
	Mpfr.inject_prog prog
230
      end
231
    else
232
      begin
233
	Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. keeping floating-point numbers@,");
234
	prog
235
      end in
236
  Log.report ~level:3 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
190
    if !Options.mpfr then (
191
      Log.report ~level:1 (fun fmt ->
192
          fprintf fmt "@ .. targetting MPFR library@,");
193
      Mpfr.inject_prog prog)
194
    else (
195
      Log.report ~level:1 (fun fmt ->
196
          fprintf fmt "@ .. keeping floating-point numbers@,");
197
      prog)
198
  in
199
  Log.report ~level:3 (fun fmt ->
200
      fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
237 201

  
238 202
  (* Checking array accesses *)
239
  if !Options.check then
240
    begin
241
      Log.report ~level:1 (fun fmt -> fprintf fmt "@ .. checking array accesses@,");
242
      Access.check_prog prog;
243
    end;
244

  
203
  if !Options.check then (
204
    Log.report ~level:1 (fun fmt ->
205
        fprintf fmt "@ .. checking array accesses@,");
206
    Access.check_prog prog);
245 207

  
246 208
  let prog = SortProg.sort_nodes_locals prog in
247 209

  
248 210
  prog, dependencies
249 211

  
250

  
251
    (* from source to machine code, with optimization *)
212
(* from source to machine code, with optimization *)
252 213
let stage2 params prog =
253 214
  (* Computation of node equation scheduling. It also breaks dependency cycles
254 215
     and warns about unused input or memory variables *)
255 216
  Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. scheduling@ ");
256 217
  let prog, node_schs =
257
    try
258
      Scheduling.schedule_prog prog
259
    with Causality.Error _ -> (* Error is not kept. It is recomputed in a more
260
				 systemtic way in AlgebraicLoop module *)
218
    try Scheduling.schedule_prog prog
219
    with Causality.Error _ ->
220
      (* Error is not kept. It is recomputed in a more systemtic way in
221
         AlgebraicLoop module *)
261 222
      AlgebraicLoop.analyze prog
262 223
  in
263 224
  Scheduling.(
......
268 229
    Log.report ~level:3 (fun fmt -> fprintf fmt "@ %a" Printers.pp_prog prog);
269 230
    Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ "));
270 231

  
271
  (* TODO Salsa optimize prog:
272
     - emits warning for programs with pre inside expressions
273
     - make sure each node arguments and memory is bounded by a local annotation
274
     - introduce fresh local variables for each real pure subexpression
275
  *)
232
  (* TODO Salsa optimize prog: - emits warning for programs with pre inside
233
     expressions - make sure each node arguments and memory is bounded by a
234
     local annotation - introduce fresh local variables for each real pure
235
     subexpression *)
276 236
  (* DFS with modular code generation *)
277
  Log.report ~level:1 (fun fmt -> fprintf fmt "@ @[<v 2>.. machines generation@ ");
237
  Log.report ~level:1 (fun fmt ->
238
      fprintf fmt "@ @[<v 2>.. machines generation@ ");
278 239
  let machine_code = Machine_code.translate_prog prog node_schs in
279 240
  Log.report ~level:1 (fun fmt -> fprintf fmt "@]");
280 241

  
281
  Log.report ~level:3 (fun fmt -> fprintf fmt "@ @[<v 2>.. generated machines (unoptimized):@ %a@]@ "
282
                          Machine_code_common.pp_machines machine_code);
242
  Log.report ~level:3 (fun fmt ->
243
      fprintf fmt "@ @[<v 2>.. generated machines (unoptimized):@ %a@]@ "
244
        Machine_code_common.pp_machines machine_code);
283 245

  
284 246
  (* Optimize machine code *)
285 247
  Optimize_machine.optimize params prog node_schs machine_code
286 248

  
287

  
288 249
(* printing code *)
289 250
let stage3 prog machine_code dependencies basename extension =
290
  let basename    =  Filename.basename basename in
251
  let basename = Filename.basename basename in
291 252
  match !Options.output, extension with
292
    "C", ".lus" -> 
293
     begin
294
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,");
295
       C_backend.translate_to_c !generate_c_header
296
	 (* alloc_header_file source_lib_file source_main_file makefile_file *)
297
	 basename prog machine_code dependencies
298
     end
299
(*
300
  |  "acsl", ".lus" -> 
301
     begin
302
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. ACSL annotations generation@,");
303
       ACSL_backend.translate_to_acsl
304
	 (* alloc_header_file source_lib_file source_main_file makefile_file *)
305
	 basename prog machine_code dependencies
306
     end
307
*)
308
  |  "C", _ -> 
309
      begin
310
        C_backend.print_c_header basename;
311
      	Log.report ~level:1 (fun fmt -> fprintf fmt ".. no C code generation for lusi@,");
312
      end
253
  | "C", ".lus" ->
254
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,");
255
    C_backend.translate_to_c !generate_c_header
256
      (* alloc_header_file source_lib_file source_main_file makefile_file *)
257
      basename prog machine_code dependencies
258
  (* | "acsl", ".lus" -> begin Log.report ~level:1 (fun fmt -> fprintf fmt "..
259
     ACSL annotations generation@,"); ACSL_backend.translate_to_acsl (*
260
     alloc_header_file source_lib_file source_main_file makefile_file *)
261
     basename prog machine_code dependencies end *)
262
  | "C", _ ->
263
    C_backend.print_c_header basename;
264
    Log.report ~level:1 (fun fmt ->
265
        fprintf fmt ".. no C code generation for lusi@,")
313 266
  | "java", _ ->
314
     begin
315
       (Format.eprintf "internal error: sorry, but not yet supported !"; assert false)
316
     (*let source_file = basename ^ ".java" in
317
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. opening file %s@,@?" source_file);
318
       let source_out = open_out source_file in
319
       let source_fmt = formatter_of_out_channel source_out in
320
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?");
321
       Java_backend.translate_to_java source_fmt basename normalized_prog machine_code;*)
322
     end
267
    Format.eprintf "internal error: sorry, but not yet supported !";
268
    assert false
269
  (*let source_file = basename ^ ".java" in Log.report ~level:1 (fun fmt ->
270
    fprintf fmt ".. opening file %s@,@?" source_file); let source_out = open_out
271
    source_file in let source_fmt = formatter_of_out_channel source_out in
272
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?");
273
    Java_backend.translate_to_java source_fmt basename normalized_prog
274
    machine_code;*)
323 275
  | "Ada", _ ->
324
    begin
325
      Log.report ~level:1 (fun fmt -> fprintf fmt ".. Ada code generation@.");
326
      Ada_backend.translate_to_ada
327
        basename (Machine_code_common.arrow_machine::machine_code)
328
    end
276
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. Ada code generation@.");
277
    Ada_backend.translate_to_ada basename
278
      (Machine_code_common.arrow_machine :: machine_code)
329 279
  | "horn", _ ->
330
     begin
331
       let destname = !Options.dest_dir ^ "/" ^ basename in
332
       let source_file = destname ^ ".smt2" in (* Could be changed *)
333
       let source_out = open_out source_file in
334
       let fmt = formatter_of_out_channel source_out in
335
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. hornification@,");
336
       Horn_backend.translate fmt prog (Machine_code_common.arrow_machine::machine_code);
337
       (* Tracability file if option is activated *)
338
       if !Options.traces then (
339
	 let traces_file = destname ^ ".traces.xml" in (* Could be changed *)
340
	 let traces_out = open_out traces_file in
341
	 let fmt = formatter_of_out_channel traces_out in
342
         Log.report ~level:1 (fun fmt -> fprintf fmt ".. tracing info@,");
343
	 Horn_backend_traces.traces_file fmt machine_code;
344
       )
345
     end
280
    let destname = !Options.dest_dir ^ "/" ^ basename in
281
    let source_file = destname ^ ".smt2" in
282
    (* Could be changed *)
283
    let source_out = open_out source_file in
284
    let fmt = formatter_of_out_channel source_out in
285
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. hornification@,");
286
    Horn_backend.translate fmt prog
287
      (Machine_code_common.arrow_machine :: machine_code);
288
    (* Tracability file if option is activated *)
289
    if !Options.traces then (
290
      let traces_file = destname ^ ".traces.xml" in
291
      (* Could be changed *)
292
      let traces_out = open_out traces_file in
293
      let fmt = formatter_of_out_channel traces_out in
294
      Log.report ~level:1 (fun fmt -> fprintf fmt ".. tracing info@,");
295
      Horn_backend_traces.traces_file fmt machine_code)
346 296
  | "lustre", _ ->
347
     begin
348
       let destname = !Options.dest_dir ^ "/" ^ basename in
349
       let source_file = destname ^ ".lustrec" ^ extension  in (* Could be changed *)
350
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. exporting processed file as %s@," source_file);
351
       let source_out = open_out source_file in
352
       let fmt = formatter_of_out_channel source_out in
353
       Printers.pp_prog fmt prog;
354
       Format.fprintf fmt "@.@?";
355
       (*	Lustre_backend.translate fmt basename normalized_prog machine_code *)
356
       ()
357
     end
297
    let destname = !Options.dest_dir ^ "/" ^ basename in
298
    let source_file = destname ^ ".lustrec" ^ extension in
299
    (* Could be changed *)
300
    Log.report ~level:1 (fun fmt ->
301
        fprintf fmt ".. exporting processed file as %s@," source_file);
302
    let source_out = open_out source_file in
303
    let fmt = formatter_of_out_channel source_out in
304
    Printers.pp_prog fmt prog;
305
    Format.fprintf fmt "@.@?";
306
    (* Lustre_backend.translate fmt basename normalized_prog machine_code *)
307
    ()
358 308
  | "emf", _ ->
359
     begin
360
       let destname = !Options.dest_dir ^ "/" ^ basename in
361
       let source_file = destname ^ ".json" in (* Could be changed *)
362
       let source_out = open_out source_file in
363
       let fmt = formatter_of_out_channel source_out in
364
       EMF_backend.translate fmt basename prog machine_code;
365
       ()
366
     end
367

  
368
  | _ -> assert false
309
    let destname = !Options.dest_dir ^ "/" ^ basename in
310
    let source_file = destname ^ ".json" in
311
    (* Could be changed *)
312
    let source_out = open_out source_file in
313
    let fmt = formatter_of_out_channel source_out in
314
    EMF_backend.translate fmt basename prog machine_code;
315
    ()
316
  | _ ->
317
    assert false

Also available in: Unified diff