Project

General

Profile

« Previous | Next » 

Revision 217837e2

Added by Pierre-Loïc Garoche over 6 years ago

Unified compilation of lusi and lus files
Different parsers yet but shared process.
In case of lusi input the C backend is bypassed since the .h is generated from the lusic and no C code should be generated since it may overwrite existing manually written code

But

View differences:

src/compiler_common.ml
35 35
      end
36 36
  end
37 37

  
38
(* Loading Lusi file and filling type tables with parsed
38
(* Loading Lus/Lusi file and filling type tables with parsed
39 39
   functions/nodes *)
40
let parse_header own filename =
40
let parse filename extension =
41 41
  Location.set_input filename;
42
  let h_in = open_in filename in
43
  let lexbuf = Lexing.from_channel h_in in
42
  let f_in = open_in filename in
43
  let lexbuf = Lexing.from_channel f_in in
44 44
  Location.init lexbuf filename;
45 45
  (* Parsing *)
46
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. parsing header file %s@ " filename);
46
  let prog = 
47 47
    try
48
      let header = Parse.header Parser_lustre.header Lexer_lustre.token lexbuf in
49
      (*ignore (Modules.load_header ISet.empty header);*)
50
      close_in h_in;
51
      header
48
      match extension with
49
        ".lusi" ->
50
        Log.report ~level:1
51
          (fun fmt -> fprintf fmt ".. parsing header file %s@ " filename);
52
        Parse.header Parser_lustre.header Lexer_lustre.token lexbuf 
53
      | ".lus" ->
54
         Log.report ~level:1 
55
           (fun fmt -> fprintf fmt ".. parsing source file %s@ " filename);
56
         Parse.prog Parser_lustre.prog Lexer_lustre.token lexbuf
57
      | _ -> assert false
52 58
    with
53 59
    | (Parse.Error err) as exc -> 
54
      Parse.report_error err;
55
      raise exc
60
       Parse.report_error err;
61
       raise exc
56 62
    | Corelang.Error (loc, err) as exc -> (
57 63
      eprintf "Parsing error: %a%a@."
58
	Error.pp_error_msg err
59
	Location.pp_loc loc;
64
        Error.pp_error_msg err
65
        Location.pp_loc loc;
60 66
      raise exc
61 67
    )
62

  
63
let parse_source source_name =
64
  (* Loading the input file *)
65
  Location.set_input source_name;
66
  let s_in = open_in source_name in
67
  let lexbuf = Lexing.from_channel s_in in
68
  Location.init lexbuf source_name;
69

  
70
  (* Parsing *)
71
  Log.report ~level:1 
72
    (fun fmt -> fprintf fmt ".. parsing source file %s@ " source_name);
73
  try
74
    let prog = Parse.prog Parser_lustre.prog Lexer_lustre.token lexbuf in
75
    (*ignore (Modules.load_program ISet.empty prog);*)
76
    close_in s_in;
77
    prog
78
  with
79
  | (Parse.Error err) as exc -> 
80
    Parse.report_error err;
81
    raise exc
82
  | Corelang.Error (loc, err) as exc ->
83
    eprintf "Parsing error: %a%a@."
84
      Error.pp_error_msg err
85
      Location.pp_loc loc;
86
    raise exc
68
  in
69
  close_in f_in;
70
  prog
71
    
87 72

  
88 73
let expand_automata decls =
89 74
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. expanding automata@ ");
......
169 154
   (Env.initial, Env.initial)
170 155
 *)
171 156

  
172
let generate_lusic_header destname lusic_ext =	
173
  match !Options.output with
174
  | "C" -> C_backend_lusic.print_lusic_to_h destname lusic_ext
175
  | _ -> ()
176 157
	 
177 158

  
178 159
    
src/compiler_stages.ml
15 15
   compiled header *)
16 16
let compile_source_to_header prog computed_types_env computed_clocks_env dirname basename extension =
17 17
  let destname = !Options.dest_dir ^ "/" ^ basename in
18
  let lusic_ext = extension ^ "c" in
18
  let lusic_ext = ".lusic" in
19 19
  let header_name = destname ^ lusic_ext in
20 20
  begin
21
    if not (Sys.file_exists header_name) then
21
    if (* Generating the lusic file *)
22
      extension = ".lusi" (* because input is a lusi *)
23
      || (extension = ".lus" &&
24
            not (Sys.file_exists header_name))
25
           (* or because it is a lus but not lusic exists *)
26
      || (let lusic = Lusic.read_lusic destname lusic_ext in
27
          not lusic.Lusic.from_lusi)
28
         (* or the lusic exists but is not generated from a lusi, hence it
29
            has te be regenerated *)
30
    then
22 31
      begin
23 32
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
24
	Lusic.write_lusic false (Lusic.extract_header dirname basename prog) destname lusic_ext;
25
	if !Options.output = "C" then Lusic.print_lusic_to_h destname lusic_ext
33
	Lusic.write_lusic
34
          (extension = ".lusi") (* is it a lusi file ? *)
35
          (if extension = ".lusi" then prog else Lusic.extract_header dirname basename prog)
36
          destname
37
          lusic_ext;
38
        let _ =
39
          match !Options.output with
40
          | "C" -> C_backend_lusic.print_lusic_to_h destname lusic_ext
41
          | _ -> ()
42
        in
43
        ()
44
      end
45
    else (* Lusic exists and is usable. Checking compatibility *)
46
      begin
47
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," 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)
26 55
      end
27
    else
28
      let lusic = Lusic.read_lusic destname lusic_ext in
29
      if not lusic.Lusic.from_lusi then
30
	begin
31
	  Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
32
       	  Lusic.write_lusic false (Lusic.extract_header dirname basename prog) destname lusic_ext;
33
	  (*List.iter (fun top_decl -> Format.eprintf "lusic: %a@." Printers.pp_decl top_decl) lusic.Lusic.contents;*)
34
	  if !Options.output = "C" then Lusic.print_lusic_to_h destname lusic_ext
35
	end
36
      else
37
	begin
38
	  Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name);
39
	  Lusic.check_obsolete lusic destname;
40
	  let header = lusic.Lusic.contents in
41
	  let (declared_types_env, declared_clocks_env) = Modules.get_envs_from_top_decls header in
42
	  check_compatibility
43
	    (prog, computed_types_env, computed_clocks_env)
44
	    (header, declared_types_env, declared_clocks_env)
45
	end
46 56
  end
47 57

  
48 58

  
49 59
(* From prog to prog *)
50
let stage1 params prog dirname basename =
60
let stage1 params prog dirname basename extension =
51 61
  (* Updating parent node information for variables *)
52 62
  Compiler_common.update_vdecl_parents_prog prog;
53 63

  
......
56 66
  Log.report ~level:4 (fun fmt -> fprintf fmt ".. after automata expansion:@,  @[<v 2>@,%a@]@ " Printers.pp_prog prog);
57 67

  
58 68
  (* Importing source *)
59
  let prog, dependencies, (typ_env, clk_env) = Modules.load ~is_header:false prog in
60

  
69
  let prog, dependencies, (typ_env, clk_env) = Modules.load ~is_header:(extension = ".lusi") prog in
70
  
61 71
  (* Registering types and clocks for future checks *)
62 72
  Global.type_env := Env.overwrite !Global.type_env typ_env;
63 73
  Global.clock_env := Env.overwrite !Global.clock_env clk_env;
......
135 145
  create_dest_dir ();
136 146

  
137 147
  (* Compatibility with Lusi *)
138
  (* Checking the existence of a lusi (Lustre Interface file) *)
139
  let extension = ".lusi" in
140
  compile_source_to_header prog !Global.type_env !Global.clock_env dirname basename extension;
141

  
148
  (* If compiling a lusi, generate the lusic. If this is a lus file, Check the existence of a lusi (Lustre Interface file) *)
149
  compile_source_to_header
150
    prog !Global.type_env !Global.clock_env dirname basename extension;
151
 
152
    
142 153
  Typing.uneval_prog_generics prog;
143 154
  Clock_calculus.uneval_prog_generics prog;
144 155

  
......
246 257

  
247 258

  
248 259
(* printing code *)
249
let stage3 prog machine_code dependencies basename =
260
let stage3 prog machine_code dependencies basename extension =
250 261
  let basename    =  Filename.basename basename in
251
  match !Options.output with
252
    "C" -> 
262
  match !Options.output, extension with
263
    "C", ".lus" -> 
264
     begin
265
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,");
266
       C_backend.translate_to_c
267
	 (* alloc_header_file source_lib_file source_main_file makefile_file *)
268
	 basename prog machine_code dependencies
269
     end
270
  |  "C", _ -> 
253 271
      begin
254
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,");
255
	C_backend.translate_to_c
256
	  (* alloc_header_file source_lib_file source_main_file makefile_file *)
257
	  basename prog machine_code dependencies
272
      	Log.report ~level:1 (fun fmt -> fprintf fmt ".. no C code generation for lusi@,");
258 273
      end
259
  | "java" ->
274
  | "java", _ ->
260 275
     begin
261 276
       (Format.eprintf "internal error: sorry, but not yet supported !"; assert false)
262 277
     (*let source_file = basename ^ ".java" in
......
266 281
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?");
267 282
       Java_backend.translate_to_java source_fmt basename normalized_prog machine_code;*)
268 283
     end
269
  | "horn" ->
284
  | "horn", _ ->
270 285
     begin
271 286
       let destname = !Options.dest_dir ^ "/" ^ basename in
272 287
       let source_file = destname ^ ".smt2" in (* Could be changed *)
......
283 298
	 Horn_backend_traces.traces_file fmt basename prog machine_code;
284 299
       )
285 300
     end
286
  | "lustre" ->
301
  | "lustre", _ ->
287 302
     begin
288 303
       let destname = !Options.dest_dir ^ "/" ^ basename in
289
       let source_file = destname ^ ".lustrec.lus" in (* Could be changed *)
304
       let source_file = destname ^ ".lustrec" ^ extension  in (* Could be changed *)
305
       Log.report ~level:1 (fun fmt -> fprintf fmt ".. exporting processed file as %s@," source_file);
290 306
       let source_out = open_out source_file in
291 307
       let fmt = formatter_of_out_channel source_out in
292 308
       Printers.pp_prog fmt prog;
......
294 310
       (*	Lustre_backend.translate fmt basename normalized_prog machine_code *)
295 311
       ()
296 312
     end
297
  | "emf" ->
313
  | "emf", _ ->
298 314
     begin
299 315
       let destname = !Options.dest_dir ^ "/" ^ basename in
300 316
       let source_file = destname ^ ".emf" in (* Could be changed *)
src/main_lustre_compiler.ml
34 34
    close_out h_out
35 35
  end
36 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
    (* Disbaled today, should be done anyway when following the regular compilation 
46
ignore (Modules.load ~is_header:true ISet.empty header); *)
47
    ignore (check_top_decls header); (* typing/clocking with an empty env *)
48
    create_dest_dir ();
49
    Log.report ~level:1
50
      (fun fmt -> fprintf fmt ".. generating compiled header file %sc@," (destname ^ extension));
51
    Lusic.write_lusic true header destname lusic_ext;
52
    generate_lusic_header destname lusic_ext;
53

  
54

  
55

  
56
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@ ")
57
  end
58 37

  
59 38

  
60 39

  
61 40

  
62 41

  
63 42
(* compile a .lus source file *)
64
let rec compile_source dirname basename extension =
43
let rec compile dirname basename extension =
65 44
  let source_name = dirname ^ "/" ^ basename ^ extension in
66 45

  
67 46
  Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 0>");
68 47

  
69 48
  (* Parsing source *)
70
  let prog = parse_source source_name in
49
  let prog = parse source_name extension in
71 50

  
72 51
  let prog =
73
    if !Options.mpfr then
52
    if !Options.mpfr &&
53
         extension = ".lus" (* trying to avoid the injection of the module for lusi files *) 
54
    then
74 55
      Mpfr.mpfr_module::prog
75 56
    else
76 57
      prog
......
80 61
  let prog, dependencies = 
81 62
    Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 2>.. Phase 1 : Normalisation@,");
82 63
    try 
83
      Compiler_stages.stage1 params prog dirname basename
64
      Compiler_stages.stage1 params prog dirname basename extension
84 65
    with Compiler_stages.StopPhase1 prog -> (
85 66
      if !Options.lusi then
86 67
	begin
......
118 99
  let machine_code = Plugins.refine_machine_code prog machine_code in
119 100
  Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ @ ");
120 101
  
121
  Compiler_stages.stage3 prog machine_code dependencies basename;
102
  Compiler_stages.stage3 prog machine_code dependencies basename extension;
122 103
  begin
123 104
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@.");
124 105
    (* We stop the process here *)
......
127 108

  
128 109
let compile dirname basename extension =
129 110
  match extension with
130
  | ".lusi"  -> compile_header dirname basename extension
131
  | ".lus"   -> compile_source dirname basename extension
111
  | ".lusi"  
112
  | ".lus"   -> compile dirname basename extension
132 113
  | _        -> assert false
133 114

  
134 115
let anonymous filename =
src/main_lustre_testgen.ml
44 44
  Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v>");
45 45

  
46 46
  (* Parsing source *)
47
  let prog = parse_source source_name in
47
  let prog = parse source_name extension in
48 48
  let params = Backends.get_normalization_params () in
49
  let prog, dependencies = Compiler_stages.stage1 params prog dirname basename in
49
  let prog, dependencies = Compiler_stages.stage1 params prog dirname basename extension in
50 50

  
51 51
  (* Two cases
52 52
     - generation of coverage conditions
src/main_lustre_verifier.ml
48 48
  decr Options.verbose_level;
49 49

  
50 50
  (* Parsing source *)
51
  let prog = parse_source source_name in
51
  let prog = parse source_name extension in
52 52

  
53 53
  (* Checking which solver is active *)
54 54
  incr Options.verbose_level;
......
63 63
      incr Options.verbose_level;
64 64
      let params = Verifier.get_normalization_params () in
65 65
      decr Options.verbose_level;
66
      Compiler_stages.stage1 params prog dirname basename
66
      Compiler_stages.stage1 params prog dirname basename extension
67 67
    with Compiler_stages.StopPhase1 prog -> (
68 68
        assert false
69 69
    )
src/modules.ml
213 213
         )
214 214
      | Include name ->
215 215
         let basename = Options_management.name_dependency (true, name) "" in
216
         let include_src = Compiler_common.parse_source basename in
217
         load_rec ~is_header:false accu include_src
218
                         
219

  
216
         if Filename.check_suffix basename ".lus" then
217
           let include_src = Compiler_common.parse basename ".lus" in
218
           load_rec ~is_header:false accu include_src
219
         else
220
           raise (Error (decl.top_decl_loc, LoadError("include requires a lustre file")))
221
   
220 222
      | Node nd ->
221 223
         if is_header then
222 224
           raise (Error(decl.top_decl_loc,
src/parsers/parse.ml
41 41
  | Node_spec_error s       -> fprintf fmt "Impossible to parse the following node specification:@.%s@.@?" s
42 42

  
43 43
let report_error (loc, err) =
44
  eprintf "Syntax error: %a%a@."
44
  eprintf "Syntax error: %a@.%a@."
45 45
    pp_error err
46 46
    Location.pp_loc loc
47 47

  
src/parsers/parser_lustre.mly
361 361
    { merge_contracts (mk_contract_var $2 true None $4 (get_loc())) $6 }
362 362
| CONST IDENT COL typeconst EQ expr SCOL contract
363 363
    { merge_contracts (mk_contract_var $2 true (Some(mktyp $4)) $6 (get_loc())) $8 }
364
| VAR IDENT EQ expr SCOL contract
365
    { merge_contracts (mk_contract_var $2 false None $4 (get_loc())) $6 }
366 364
| VAR IDENT COL typeconst EQ expr SCOL contract
367 365
    { merge_contracts (mk_contract_var $2 false (Some(mktyp $4)) $6 (get_loc())) $8 }
368 366
| ASSUME qexpr SCOL contract
src/printers.ml
289 289
    (fun fmt -> match e.eexpr_quantifiers with [] -> () | _ -> fprintf fmt ";")
290 290
    pp_expr e.eexpr_qfexpr
291 291

  
292
    
293
let pp_spec_eq fmt eq = 
294
  fprintf fmt "var %a : %a = %a;" 
295
    pp_eq_lhs eq.eq_lhs
296
    Types.print_node_ty eq.eq_rhs.expr_type
297
    pp_expr eq.eq_rhs
298
  
299
let pp_spec_stmt fmt stmt =
300
  match stmt with
301
  | Eq eq -> pp_spec_eq fmt eq
302
  | Aut aut -> assert false (* Not supported yet *)
303
             
304
  
292 305
let pp_spec fmt spec =
293
  fprintf fmt "@[<hov 2>(*@@ ";
294 306
  (* const are prefixed with const in pp_var and with nothing for regular
295 307
     variables. We adapt the call to produce the appropriate output. *)
296
  fprintf_list ~sep:"@,@@ " (fun fmt v ->
297
    fprintf fmt "%s%a = %t;"
298
      (if v.var_dec_const then "" else "var")
308
    fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt v ->
309
    fprintf fmt "const %a = %t;"
299 310
      pp_var v
300
      (fun fmt -> match v.var_dec_value with None -> () | Some e -> pp_expr fmt e)
301
  ) fmt (spec.consts @ spec.locals);
302
  fprintf_list ~sep:"@,@@ " (fun fmt r -> fprintf fmt "assume %a;" pp_eexpr r) fmt spec.assume;
303
  fprintf_list ~sep:"@,@@ " (fun fmt r -> fprintf fmt "guarantees %a;" pp_eexpr r) fmt spec.guarantees;
304
  fprintf_list ~sep:"@,@@ " (fun fmt mode ->
311
      (fun fmt -> match v.var_dec_value with None -> assert false | Some e -> pp_expr fmt e)
312
    ) fmt spec.consts;
313
  
314
  fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt s -> pp_spec_stmt fmt s) fmt spec.stmts;
315
  fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt r -> fprintf fmt "assume %a;" pp_eexpr r) fmt spec.assume;
316
  fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt r -> fprintf fmt "guarantees %a;" pp_eexpr r) fmt spec.guarantees;
317
  fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt mode ->
305 318
    fprintf fmt "mode %s (@[@ %a@ %a@]);" 
306 319
      mode.mode_id
307
      (fprintf_list ~sep:"@ " (fun fmt r -> fprintf fmt "require %a;" pp_eexpr r)) mode.require
308
      (fprintf_list ~sep:"@ " (fun fmt r -> fprintf fmt "ensure %a;" pp_eexpr r)) mode.ensure
320
      (fprintf_list ~eol:"@," ~sep:"@ " (fun fmt r -> fprintf fmt "require %a;" pp_eexpr r)) mode.require
321
      (fprintf_list ~eol:"@," ~sep:"@ " (fun fmt r -> fprintf fmt "ensure %a;" pp_eexpr r)) mode.ensure
309 322
  ) fmt spec.modes;
310
  fprintf_list ~sep:"@,@@ " (fun fmt import ->
323
  fprintf_list ~eol:"@, " ~sep:"@, " (fun fmt import ->
311 324
    fprintf fmt "import %s (%a) returns (%a);" 
312 325
      import.import_nodeid
313 326
      (fprintf_list ~sep:"@ " pp_expr) import.inputs
314 327
      (fprintf_list ~sep:"@ " pp_expr) import.outputs
315
  ) fmt spec.imports;
316
  fprintf fmt "@]*)";
317
  ()
328
  ) fmt spec.imports
318 329

  
330
let pp_spec_as_comment fmt spec =
331
  fprintf fmt "@[<hov 2>(*@@ ";
332
  pp_spec fmt spec;
333
  fprintf fmt "@]*)@ "
319 334
    
320 335
let pp_node fmt nd =
321 336
  fprintf fmt "@[<v 0>";
......
327 342
    pp_node_args nd.node_outputs;
328 343
  (* Contracts *)
329 344
  fprintf fmt "%a%t"
330
    (fun fmt s -> match s with Some s -> pp_spec fmt s | _ -> ()) nd.node_spec
345
    (fun fmt s -> match s with Some s -> pp_spec_as_comment fmt s | _ -> ()) nd.node_spec
331 346
    (fun fmt -> match nd.node_spec with None -> () | Some _ -> fprintf fmt "@ ");
332 347
  (* Locals *)
333 348
  fprintf fmt "%a" (fun fmt locals ->
......
361 376
(*fprintf fmt "@ /* Scheduling: %a */ @ " (fprintf_list ~sep:", " pp_print_string) (Scheduling.schedule_node nd)*)
362 377

  
363 378
let pp_imported_node fmt ind = 
364
  fprintf fmt "@[<v>%s %s (%a) returns (%a)@]"
379
  fprintf fmt "@[<v 0>";
380
  (* Prototype *)
381
  fprintf fmt  "%s @[<hov 0>%s (@[%a)@]@ returns (@[%a)@]@]@ "
365 382
    (if ind.nodei_stateless then "function" else "node")
366 383
    ind.nodei_id
367 384
    pp_node_args ind.nodei_inputs
368
    pp_node_args ind.nodei_outputs
385
    pp_node_args ind.nodei_outputs;
386
  (* Contracts *)
387
  fprintf fmt "%a%t"
388
    (fun fmt s -> match s with Some s -> pp_spec_as_comment fmt s | _ -> ()) ind.nodei_spec
389
    (fun fmt -> match ind.nodei_spec with None -> () | Some _ -> fprintf fmt "@ ");
390
  fprintf fmt "@]@ "
391
  
369 392

  
370 393
let pp_const_decl fmt cdecl =
371 394
  fprintf fmt "%s = %a;" cdecl.const_id pp_const cdecl.const_value
src/tools/stateflow/sf_sem.ml
82 82
     Format.fprintf auto_fmt "%a@." Printers.pp_prog prog;
83 83

  
84 84
     let params = Backends.get_normalization_params () in
85
     let prog, deps = Compiler_stages.stage1 params prog "" "" in
85
     let prog, deps = Compiler_stages.stage1 params prog "" "" ".lus" in
86 86

  
87 87

  
88 88
     Options.print_dec_types := false;
src/typing.ml
27 27
open Format
28 28

  
29 29

  
30
(* TODO general remark: expect in the add_vdelc, it seems to me that
31
   all the pairs (env, vd_env) should be replace with just env, since
32
   vd_env is never used and the env element is always extract with a
33
   fst *)
34

  
35
   
30 36
module type EXPR_TYPE_HUB =
31 37
sig
32 38
  type type_expr 
......
663 669
    let check_vd_env vd_env =
664 670
      ignore (List.fold_left add_vdecl [] vd_env)
665 671

  
666
    let type_spec env c =
672
    let type_spec env spec =
673
      let vd_env = spec.consts @ spec.locals in
674
      check_vd_env vd_env;
675
      let env = type_var_decl_list ((* this argument seems useless to me, cf TODO at top of the file*) vd_env) env vd_env in
676
      (* typing stmts *)
677
      let eqs = List.map (fun s -> match s with Eq eq -> eq | _ -> assert false) spec.stmts  in
678
      let undefined_vars_init =
679
        List.fold_left
680
          (fun uvs v -> ISet.add v.var_id uvs)
681
          ISet.empty spec.locals
682
      in
683
      let _ =
684
        List.fold_left
685
          (type_eq (env, vd_env) (false (*is_main*)))
686
          undefined_vars_init
687
          eqs
688
      in
689
      
667 690
      (*TODO 
668 691
        enrich env locally with locals and consts
669 692
        type each pre/post as a boolean expr
......
699 722
          type_subtyping_arg (new_env, vd_env) is_main false assert_expr (* Type_predef. *)type_bool
700 723
        )  nd.node_asserts;
701 724
      (* Typing spec/contracts *)
702
      (match nd.node_spec with None -> () | Some spec -> ignore (type_spec (new_env, vd_env) spec));
725
      (match nd.node_spec with None -> () | Some spec -> ignore (type_spec new_env spec));
703 726
      (* Typing annots *)
704 727
      List.iter (fun annot ->
705 728
          List.iter (fun (_, eexpr) -> ignore (type_eexpr (new_env, vd_env) eexpr)) annot.annots
......
719 742
      Env.add_value env nd.node_id ty_node
720 743

  
721 744
    let type_imported_node env nd loc =
722
      let new_env = type_var_decl_list nd.nodei_inputs env nd.nodei_inputs in
723 745
      let vd_env = nd.nodei_inputs@nd.nodei_outputs in
724 746
      check_vd_env vd_env;
725
      ignore(type_var_decl_list vd_env new_env nd.nodei_outputs);
747
      let delta_env = type_var_decl_list vd_env env nd.nodei_inputs in
748
      let delta_env = type_var_decl_list vd_env delta_env nd.nodei_outputs in
749
      let new_env = Env.overwrite env delta_env in
750
      (* Typing spec *)
751
      (match nd.nodei_spec with None -> () | Some spec -> ignore (type_spec new_env spec)); 
726 752
      let ty_ins = type_of_vlist nd.nodei_inputs in
727 753
      let ty_outs = type_of_vlist nd.nodei_outputs in
728 754
      let ty_node = new_ty (Tarrow (ty_ins,ty_outs)) in
src/utils/utils.ml
253 253
let pp_newline_if_non_empty l =
254 254
  (fun fmt -> match l with [] -> () | _ -> Format.fprintf fmt "@,")
255 255

  
256
let rec fprintf_list ~sep:sep f fmt = function
256
let fprintf_list ?(eol:('a, formatter, unit) Pervasives.format = "") ~sep:sep f fmt l =
257
  let rec aux fmt = function
257 258
  | []   -> ()
258 259
  | [e]  -> f fmt e
259
  | x::r -> Format.fprintf fmt "%a%(%)%a" f x sep (fprintf_list ~sep f) r
260

  
260
  | x::r -> Format.fprintf fmt "%a%(%)%a" f x sep aux r
261
  in
262
  match l with
263
  | [] -> ()
264
  | _ -> (
265
    aux fmt l;
266
    Format.fprintf fmt "%(%)" eol
267
  )                 
268
   
261 269
let pp_list l pp_fun beg_str end_str sep_str =
262 270
  if (beg_str="\n") then
263 271
    print_newline ()

Also available in: Unified diff