Project

General

Profile

« Previous | Next » 

Revision 59020713

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

Some progress on EMF bqckend. Refactoring machines code

View differences:

src/backends/EMF/EMF_backend.ml
375 375
      pp_emf_eexpr ee
376 376
  in
377 377
  incr cpt
378

  
379
let pp_emf_spec_mode fmt m =
380
  fprintf fmt "{@[";
381
  fprintf fmt "\"mode_id\": \"%s\",@ "
382
    m.mode_id;
383
  fprintf fmt "\"require\": [%a],@ "
384
    pp_emf_eexprs m.ensure;
385
  fprintf fmt "\"require\": [%a],@ "
386
    pp_emf_eexprs m.require;
387
  fprintf fmt "@]}"
388
  
389
let pp_emf_spec_modes = pp_emf_list pp_emf_spec_mode
390

  
391
let pp_emf_spec_import fmt i =
392
  fprintf fmt "{@[";
393
  fprintf fmt "\"contract\": \"%s\",@ "
394
    i.import_nodeid;
395
  fprintf fmt "\"inputs\": [%a],@ "
396
    pp_emf_exprs i.inputs;
397
  fprintf fmt "\"outputs\": [%a],@ "
398
    pp_emf_exprs i.outputs;
399
  fprintf fmt "@]}"
400
  
401
let pp_emf_spec_imports = pp_emf_list pp_emf_spec_import
402

  
403
let pp_emf_spec fmt spec =
404
  fprintf fmt "{ @[<hov 0>";
405
  fprintf fmt "\"consts\": [%a],@ "
406
    pp_emf_consts spec.consts;
407
  fprintf fmt "\"locals\": [%a],@ "
408
    pp_emf_vars_decl spec.locals;
409
  fprintf fmt "\"stmts\": [%a],@ "
410
    pp_emf_stmts spec.stmts;
411
  fprintf fmt "\"assume\": [%a],@ "
412
    pp_emf_eexprs spec.assume;
413
  fprintf fmt "\"guarantees\": [%a],@ "
414
    pp_emf_eexprs spec.guarantees;
415
  fprintf fmt "\"modes\": [%a],@ "
416
    pp_emf_spec_modes spec.modes;
417
  fprintf fmt "\"imports\": [%a]@ "
418
    pp_emf_spec_imports spec.imports;  
419
  fprintf fmt "@] }"
378 420
  
379 421
let pp_emf_annots cpt fmt annots = fprintf_list ~sep:",@ " (pp_emf_annot cpt) fmt annots.annots
380 422
let pp_emf_annots_list cpt fmt annots_list = fprintf_list ~sep:",@ " (pp_emf_annots cpt) fmt annots_list
423

  
424
  
425
                                           
381 426
let pp_machine fmt m =
382 427
  let instrs = (*merge_branches*) m.mstep.step_instrs in
383 428
  try
384 429
    fprintf fmt "@[<v 2>\"%a\": {@ "
385
       print_protect (fun fmt -> pp_print_string fmt m.mname.node_id);
430
      print_protect (fun fmt -> pp_print_string fmt m.mname.node_id);
431
    fprintf fmt "\"imported\": \"false\",@ ";
386 432
    fprintf fmt "\"kind\": %t,@ "
387 433
      (fun fmt -> if not ( snd (get_stateless_status m) )
388 434
	then fprintf fmt "\"stateful\""
......
399 445
    fprintf fmt "\"original_name\": \"%s\",@ " m.mname.node_id;
400 446
    fprintf fmt "\"instrs\": {@[<v 0> %a@]@ },@ "
401 447
      (pp_emf_instrs m) instrs;
448
    (match m.mspec with None -> () | Some spec -> fprintf fmt "\"spec\": %a,@ " pp_emf_spec spec);
402 449
    fprintf fmt "\"annots\": {@[<v 0> %a@]@ }" (pp_emf_annots_list (ref 0)) m.mannot;
403 450
    fprintf fmt "@]@ }"
404 451
  with Unhandled msg -> (
......
408 455
    eprintf "node skipped - no output generated@ @]@."
409 456
  )
410 457

  
458
let pp_emf_imported_node fmt top =
459
  let ind = Corelang.imported_node_of_top top in
460
   try
461
    fprintf fmt "@[<v 2>\"%a\": {@ "
462
      print_protect (fun fmt -> pp_print_string fmt ind.nodei_id);
463
    fprintf fmt "\"imported\": \"true\",@ ";
464
    fprintf fmt "\"inputs\": [%a],@ "
465
      pp_emf_vars_decl ind.nodei_inputs;
466
    fprintf fmt "\"outputs\": [%a],@ "
467
      pp_emf_vars_decl ind.nodei_outputs;
468
    fprintf fmt "\"original_name\": \"%s\",@ " ind.nodei_id;
469
    (match ind.nodei_spec with None -> () | Some spec -> fprintf fmt "\"spec\": %a" pp_emf_spec spec);
470
    fprintf fmt "@]@ }"
471
  with Unhandled msg -> (
472
    eprintf "[Error] @[<v 0>EMF backend@ Issues while translating node %s@ "
473
      ind.nodei_id;
474
    eprintf "%s@ " msg;
475
    eprintf "node skipped - no output generated@ @]@."
476
  )
411 477
(****************************************************)
412 478
(* Main function: iterates over node and print them *)
413 479
(****************************************************)
......
425 491
  fprintf fmt "@ @]},@ "
426 492
    
427 493
let translate fmt basename prog machines =
428
   (* record_types prog; *)
494
  (* record_types prog; *)
429 495
  fprintf fmt "@[<v 0>{@ ";
430 496
  pp_meta fmt basename;
497
  (* Typedef *)
498
  fprintf fmt "\"typedef\": [@[<v 0>%a@]],@ "
499
    (pp_emf_list pp_emf_typedef) (Corelang.get_typedefs prog);
500
  fprintf fmt "\"consts\": [@[<v 0>%a@]],@ "
501
    (pp_emf_list pp_emf_top_const) (Corelang.get_consts prog);
502
  fprintf fmt "\"imported_nodes\": @[<v 0>{@ ";
503
  pp_emf_list pp_emf_imported_node fmt (Corelang.get_imported_nodes prog);
504
  fprintf fmt "}@],@ ";
431 505
  fprintf fmt "\"nodes\": @[<v 0>{@ ";
432 506
  (* Previous alternative: mapping normalized lustre to EMF: 
433 507
     fprintf_list ~sep:",@ " pp_decl fmt prog; *)
434
  fprintf_list ~sep:",@ " pp_machine fmt (List.rev machines);
508
  pp_emf_list pp_machine fmt (List.rev machines);
435 509
  fprintf fmt "}@]@ }";
436 510
  fprintf fmt "@]@ }"
437 511

  
src/backends/EMF/EMF_common.ml
76 76
*)
77 77
  
78 78
  
79
let pp_tag_type fmt typ =
80
  let rec aux tydec_desc =
81
  match tydec_desc with  
82
  | Tydec_int -> fprintf fmt "int"
83
  | Tydec_real -> fprintf fmt "real"
84
  | Tydec_bool -> fprintf fmt "bool"
85
  | Tydec_clock ty -> aux ty
86
  | Tydec_enum const_list -> (
87
    let size = List.length const_list in
88
    if size < 255 then
89
      fprintf fmt "uint8"
90
    else if size < 65535 then
91
      fprintf fmt "uint16"
92
    else
93
      assert false (* Too much states. This not reasonable *)
94
  )
95
  | Tydec_const _ | Tydec_struct _ | Tydec_array _ | Tydec_any -> eprintf "unhandled cst tag in EMF: %a@." Printers.pp_var_type_dec_desc tydec_desc; assert false
96
  in
97
  aux typ.tydef_desc
98 79

  
99
     
100
let pp_cst_type fmt c (*infered_typ*) =
101
  match c with
102
  | Const_tag t ->
103
     let typ = (Corelang.typedef_of_top (Hashtbl.find Corelang.tag_table t)) in
104
     if typ.tydef_id = "bool" then
105
       fprintf fmt "bool"
106
     else
107
       pp_tag_type fmt typ
108
  | Const_int _ -> fprintf fmt "int" (*!Options.int_type*)
109
  | Const_real _ -> fprintf fmt "real" (*!Options.real_type*)
110
  | Const_string _ -> fprintf fmt "string" 
111
  | _ -> eprintf "cst: %a@." Printers.pp_const c; assert false
80
let rec pp_emf_dim fmt dim_expr =
81
  fprintf fmt "{";
82
  (let open Dimension in
83
   match dim_expr.dim_desc with
84
   | Dbool b -> fprintf fmt "\"kind\": \"bool\",@ \"value\": \"%b\"" b
85
   | Dint i -> fprintf fmt "\"kind\": \"int\",@ \"value\": \"%i\"" i
86
   | Dident s -> fprintf fmt "\"kind\": \"ident\",@ \"value\": \"%s\"" s
87
   | Dappl(f, args) -> fprintf fmt "\"kind\": \"fun\",@ \"id\": \"%s\",@ \"args\": [@[%a@]]"
88
                         f (Utils.fprintf_list ~sep:",@ " pp_emf_dim) args 
89
   | Dite(i,t,e) -> fprintf fmt "\"kind\": \"ite\",@ \"guard\": \"%a\",@ \"then\": %a,@ \"else\": %a"
90
                      pp_emf_dim i pp_emf_dim t pp_emf_dim e 
91
   | Dlink e -> pp_emf_dim fmt e
92
   | Dvar
93
   | Dunivar -> assert false (* unresolved *)
94
  );
95
  fprintf fmt "}"
112 96

  
113
let rec pp_infered_type fmt t =
114
  let open Types in
115
  if is_bool_type t  then fprintf fmt "bool" else
116
  if is_int_type t then fprintf fmt "int" else (* !Options.int_type *)
117
  if is_real_type t then fprintf fmt "real" else (* !Options.real_type *)
118
  match t.tdesc with
119
  | Tclock t ->
120
     pp_infered_type fmt t
121
  | Tstatic (_, t) ->
122
     fprintf fmt "%a" pp_infered_type t
123
  | Tconst id ->
124
    (* This is a type id for a enumerated type, eg. introduced by automata *)
125
     let typ =
126
       (Corelang.typedef_of_top (Hashtbl.find Corelang.type_table (Tydec_const id)))
127
     in
128
     pp_tag_type fmt typ
129
   | Tlink ty -> 
130
       pp_infered_type fmt ty 
131
   | _ -> eprintf "unhandled type: %a@." Types.print_node_ty t; assert false
132 97
     
98

  
99

  
100
(* First try to print the declared one *)
133 101
let rec pp_concrete_type dec_t infered_t fmt =
134 102
  match dec_t with
135
  | Tydec_int -> fprintf fmt "int" (* !Options.int_type *)
136
  | Tydec_real -> fprintf fmt "real" (* !Options.real_type *)
103
  | Tydec_any -> (* Dynamical built variable. No declared type. Shall
104
                    use the infered one. *)
105
     pp_infered_type fmt infered_t
106
  | Tydec_int -> fprintf fmt "{ \"kind\": \"int\" }" (* !Options.int_type *)
107
  | Tydec_real -> fprintf fmt "{ \"kind\": \"real\" }" (* !Options.real_type *)
137 108
  (* TODO we could add more concrete types here if they were available in
138 109
     dec_t *)
139
  | Tydec_bool -> fprintf fmt "bool"
110
  | Tydec_bool -> fprintf fmt "{ \"kind\": \"bool\" }"
140 111
  | Tydec_clock t -> pp_concrete_type t infered_t fmt
141 112
  | Tydec_const id -> (
142
    (* This is a type id for a enumerated type, eg. introduced by automata *)
113
    (* This is an alias type *)
114

  
115
    (* id for a enumerated type, eg. introduced by automata *)
143 116
    let typ = (Corelang.typedef_of_top (Hashtbl.find Corelang.type_table dec_t)) in
144
    pp_tag_type fmt typ
117
    (* Print the type name associated to this enumerated type. This is
118
       basically an integer *)
119
    pp_tag_type id typ infered_t fmt
120
  )
121
                    
122
  | Tydec_struct _ | Tydec_enum _ ->
123
     assert false (* should not happen. These type are only built when
124
                     declaring a type in the prefix of the lustre
125
                     file. They shall not be associated to variables
126
                   *)
127
    
128
  | Tydec_array (dim, e) -> (
129
    let inf_base = match infered_t.Typing.tdesc with
130
      | Typing.Tarray(_,t) -> t
131
      | _ ->   (* returing something useless, hoping that the concrete
132
                  datatype will return something usefull *)
133
         Typing.new_var ()
134
    in
135
    fprintf fmt "{ \"kind\": \"array\", \"base_type\": %t, \"dim\": %a }"
136
      (pp_concrete_type e inf_base)
137
      pp_emf_dim dim
145 138
  )
146
  | Tydec_any -> pp_infered_type fmt infered_t 
147
  | _ -> eprintf
148
     "unhandled construct in type printing for EMF backend: %a@."
149
     Printers.pp_var_type_dec_desc dec_t; raise (Failure "var")
139
                          
140
(* | _ -> eprintf
141
 *          "unhandled construct in type printing for EMF backend: %a@."
142
 *          Printers.pp_var_type_dec_desc dec_t; raise (Failure "var") *)
143
and pp_tag_type id typ inf fmt =
144
  (* We ought to represent these types as values: enum will become int, we keep the name for structs *)
145
  let rec aux tydec_desc =
146
    match tydec_desc with  
147
    | Tydec_int 
148
      | Tydec_real 
149
      | Tydec_bool
150
      | Tydec_array _ -> pp_concrete_type tydec_desc inf fmt
151
    | Tydec_const id ->
152
       (* Alias of an alias: unrolling definitions *)
153
       let typ = (Corelang.typedef_of_top
154
                    (Hashtbl.find Corelang.type_table tydec_desc))
155
       in
156
       pp_tag_type id typ inf fmt
150 157
       
158
    | Tydec_clock ty -> aux ty
159
    | Tydec_enum const_list -> ( (* enum can be mapped to int *)
160
      let size = List.length const_list in
161
      fprintf fmt "{ \"name\": \"%s\", \"kind\": \"enum\", \"size\": \"%i\" }" id size
162
    )
163
    | Tydec_struct _ ->
164
       fprintf fmt "{ \"name\": \"%s\", \"kind\": \"struct\" }" id
165
    | Tydec_any -> (* shall not happen: a declared type cannot be
166
                      bound to type any *)
167
       assert false
168
  in
169
  aux typ.tydef_desc
170
and pp_infered_type fmt t =
171
  (* Shall only be used for variable types that were not properly declared. Ie generated at compile time. *)
172
  let open Types in
173
  if is_bool_type t  then fprintf fmt "bool" else
174
    if is_int_type t then fprintf fmt "int" else (* !Options.int_type *)
175
      if is_real_type t then fprintf fmt "real" else (* !Options.real_type *)
176
        match t.tdesc with
177
        | Tclock t ->
178
           pp_infered_type fmt t
179
        | Tstatic (_, t) ->
180
           fprintf fmt "%a" pp_infered_type t
181
        | Tconst id ->
182
           (* This is a type id for a enumerated type, eg. introduced by automata *)
183
           let typ =
184
             (Corelang.typedef_of_top
185
                (Hashtbl.find Corelang.type_table (Tydec_const id)))
186
           in
187
           pp_tag_type id typ t fmt
188
        | Tlink ty -> 
189
           pp_infered_type fmt ty 
190
        | _ -> eprintf "unhandled type: %a@." Types.print_node_ty t; assert false
151 191

  
152 192
(*let pp_cst_type fmt v =
153 193
  match v.value_desc with
154 194
  | Cst c-> pp_cst_type c v.value_type fmt (* constants do not have declared type (yet) *)
155 195
  | _ -> assert false
156 196
*)
157
       
197

  
198
(* Provide both the declared type and the infered one. *)
158 199
let pp_var_type fmt v =
159 200
  try
160 201
    if Machine_types.is_specified v then
161 202
      Machine_types.pp_var_type fmt v
162 203
    else
163 204
      pp_concrete_type v.var_dec_type.ty_dec_desc v.var_type fmt
164
  with Failure _ -> eprintf "failed var: %a@." Printers.pp_var v; assert false
205
  with Failure msg -> eprintf "failed var: %a@.%s@." Printers.pp_var v msg; assert false
165 206
    
166 207
(******** Other print functions *)
167
    
208

  
209
let pp_emf_list ?(eol:('a, formatter, unit) Pervasives.format="") pp fmt l =
210
  match l with
211
    [] -> ()
212
  | _ -> fprintf fmt "@[";
213
         Utils.fprintf_list ~sep:",@ " pp fmt l;
214
         fprintf fmt "@]%(%)" eol
215
  
216
(* Print the variable declaration *)
168 217
let pp_emf_var_decl fmt v =
169 218
  fprintf fmt "@[{\"name\": \"%a\", \"datatype\":\"%a\", \"original_name\": \"%a\"}@]"
170 219
    pp_var_name v
171 220
    pp_var_type v
172 221
    Printers.pp_var_name v
173
    
174
let pp_emf_vars_decl fmt vl =
175
  fprintf fmt "@[";
176
  Utils.fprintf_list ~sep:",@ " pp_emf_var_decl fmt vl;
177
  fprintf fmt "@]"
222

  
223
let pp_emf_vars_decl = pp_emf_list pp_emf_var_decl
224

  
225
 
178 226
  
179 227
let reset_name id =
180 228
  "reset_" ^ id
......
187 235
    let const_list = match typ.tydef_desc with Tydec_enum tl -> tl | _ -> assert false in
188 236
    fprintf fmt "%i" (get_idx t const_list)
189 237

  
190
let pp_emf_cst fmt c =
238
let pp_cst_type c inf fmt (*infered_typ*) =
239
  match c with
240
  | Const_tag t ->
241
     let typ = (Corelang.typedef_of_top (Hashtbl.find Corelang.tag_table t)) in
242
     if typ.tydef_id = "bool" then
243
       fprintf fmt "bool"
244
     else
245
       pp_tag_type t typ inf fmt
246
  | Const_int _ -> fprintf fmt "int" (*!Options.int_type*)
247
  | Const_real _ -> fprintf fmt "real" (*!Options.real_type*)
248
  | Const_string _ -> fprintf fmt "string" 
249
  | _ -> eprintf "cst: %a@." Printers.pp_const c; assert false
250

  
251
    
252
let pp_emf_cst c inf fmt =
253
  let pp_typ fmt =
254
    fprintf fmt "\"datatype\": \"";
255
    pp_cst_type c inf fmt;
256
    fprintf fmt "\"@ "
257
  in
191 258
  match c with
192 259
  | Const_tag t->
193 260
     let typ = (Corelang.typedef_of_top (Hashtbl.find Corelang.tag_table t)) in
......
195 262
       fprintf fmt "{@[\"type\": \"constant\",@ ";
196 263
       fprintf fmt"\"value\": \"%a\",@ "
197 264
	 Printers.pp_const c;
198
       fprintf fmt "\"datatype\": \"%a\"@ " pp_cst_type c;
265
       pp_typ fmt;
199 266
       fprintf fmt "@]}"
200 267
     )
201 268
     else (
......
203 270
	 pp_tag_id t;
204 271
       fprintf fmt "\"origin_type\": \"%s\",@ \"origin_value\": \"%s\",@ "
205 272
	 typ.tydef_id t;
206
       fprintf fmt "\"datatype\": \"%a\"@ " pp_cst_type c;
273
       pp_typ fmt;
207 274
       fprintf fmt "@]}"
208 275
     )
209 276
  | Const_string s ->
210
    fprintf fmt "{@[\"type\": \"constant\",@ \"value\": \"%s\",@ " s;
211
    fprintf fmt "\"datatype\": \"%a\"@ " pp_cst_type c;
212
    fprintf fmt "@]}"
277
     fprintf fmt "{@[\"type\": \"constant\",@ \"value\": \"%s\",@ " s;
278
     pp_typ fmt;
279
     fprintf fmt "@]}"
213 280
     
214 281
  | _ -> (
215 282
    fprintf fmt "{@[\"type\": \"constant\",@ \"value\": \"%a\",@ "
216 283
      Printers.pp_const c;
217
    fprintf fmt "\"datatype\": \"%a\"@ " pp_cst_type c;
284
    pp_typ fmt;
218 285
    fprintf fmt "@]}"
219 286
  )
220 287
  
221
  
288
(* Print a value: either a constant or a variable value *)
222 289
let pp_emf_cst_or_var m fmt v =
223 290
  match v.value_desc with
224
  | Cst c -> pp_emf_cst fmt c
291
  | Cst c -> pp_emf_cst c v.value_type fmt 
225 292
  | Var v -> (
226 293
    fprintf fmt "{@[\"type\": \"variable\",@ \"value\": \"%a\",@ "
227 294
      pp_var_name v;
......
239 306
    
240 307
let rec pp_emf_expr fmt e =
241 308
  match e.expr_desc with
242
  | Expr_const c -> pp_emf_cst fmt c
309
  | Expr_const c -> pp_emf_cst c e.expr_type fmt 
243 310
  | Expr_ident id ->
244 311
     fprintf fmt "{@[\"type\": \"variable\",@ \"value\": \"%a\",@ "
245 312
       print_protect (fun fmt -> pp_print_string fmt id);
......
254 321
  | Expr_tuple el ->
255 322
     fprintf fmt "[@[<hov 0>%a@ @]]"
256 323
       (Utils.fprintf_list ~sep:",@ " pp_emf_expr) el
324
 (* Missing these 
325
  | Expr_ite   of expr * expr * expr
326
  | Expr_arrow of expr * expr
327
  | Expr_fby of expr * expr
328
  | Expr_array of expr list
329
  | Expr_access of expr * Dimension.dim_expr
330
  | Expr_power of expr * Dimension.dim_expr
331
  | Expr_pre of expr
332
  | Expr_when of expr * ident * label
333
  | Expr_merge of ident * (label * expr) list
334
  | Expr_appl of call_t
335
  *)
257 336
  | _ -> (
258 337
    Log.report ~level:2
259 338
      (fun fmt ->
......
274 353
(* | Expr_when of expr * ident * label *)
275 354
(* | Expr_merge of ident * (label * expr) list *)
276 355
(* | Expr_appl of call_t *)
277
     
278 356

  
357
let pp_emf_exprs = pp_emf_list pp_emf_expr
358
       
359
let pp_emf_const fmt v =
360
  fprintf fmt "@[{\"name\": \"%a\", \"datatype\":\"%a\", \"original_name\": \"%a\", \"value\": \"%a\"}@]"
361
    pp_var_name v
362
    pp_var_type v
363
    Printers.pp_var_name v
364
    pp_emf_expr (match v.var_dec_value with None -> assert false | Some e -> e)
365

  
366
let pp_emf_consts = pp_emf_list pp_emf_const
367
                  
279 368
let pp_emf_eexpr fmt ee =
280 369
  fprintf fmt "{@[<hov 0>\"quantifiers\": \"%a\",@ \"qfexpr\": @[%a@]@] }"
281 370
    (Utils.fprintf_list ~sep:"; " Printers.pp_quantifiers) ee.eexpr_quantifiers
282 371
    pp_emf_expr ee.eexpr_qfexpr
283
    
284
    
372

  
373
let pp_emf_eexprs = pp_emf_list pp_emf_eexpr
374

  
375
(*
376
                      TODO Thanksgiving
377

  
378
                      trouver un moyen de transformer en machine code les instructions de chaque spec
379
                      peut etre associer a chaque imported node une minimachine
380
                      et rajouter un champ a spec dans machine code pour stoquer memoire et instr
381
 *)                
382
                 
383
let pp_emf_stmt fmt stmt =
384
  match stmt with
385
  | Aut _ -> assert false
386
  | Eq eq -> (
387
    fprintf fmt "@[ @[<v 2>\"%a\": {@ " (Utils.fprintf_list ~sep:"_" pp_print_string) eq.eq_lhs;
388
    fprintf fmt "\"lhs\": [%a],@ " (Utils.fprintf_list ~sep:", " (fun fmt vid -> fprintf fmt "\"%s\"" vid)) eq.eq_lhs;
389
    fprintf fmt "\"rhs\": \"%a\",@ " pp_emf_expr eq.eq_rhs;
390
    fprintf fmt "@]@]@ }"
391
  )
392

  
393
let pp_emf_stmts = pp_emf_list pp_emf_stmt 
394
  
395
(* Printing the type declaration, not its use *)
396
let rec pp_emf_typ_dec fmt tydef_dec =
397
  fprintf fmt "{";
398
  (match tydef_dec with
399
   | Tydec_any -> fprintf fmt "\"kind\": \"any\""
400
   | Tydec_int -> fprintf fmt "\"kind\": \"int\""
401
   | Tydec_real -> fprintf fmt "\"kind\": \"real\""
402
   | Tydec_bool-> fprintf fmt "\"kind\": \"bool\""
403
   | Tydec_clock ck -> pp_emf_typ_dec fmt ck
404
   | Tydec_const c -> fprintf fmt "\"kind\": \"alias\",@ \"value\": \"%s\"" c
405
   | Tydec_enum el -> fprintf fmt "\"kind\": \"enum\",@ \"elements\": [%a]"
406
                        (Utils.fprintf_list ~sep:", " (fun fmt e -> fprintf fmt "\"%s\"" e)) el
407
   | Tydec_struct s -> fprintf fmt "\"kind\": \"struct\",@ \"fields\": [%a]"
408
                         (Utils.fprintf_list ~sep:", " (fun fmt (id,typ) ->
409
                              fprintf fmt "\"%s\": %a" id pp_emf_typ_dec typ)) s
410
   | Tydec_array (dim, typ) -> fprintf fmt "\"kind\": \"array\",@ \"dim\": @[%a@],@ \"base\": %a"
411
                               pp_emf_dim dim
412
                               pp_emf_typ_dec typ
413
  );
414
  fprintf fmt "}"
415
 
416
let pp_emf_typedef fmt typdef_top =
417
  let typedef = Corelang.typedef_of_top typdef_top in
418
  fprintf fmt "\"%s\": @[%a@]" typedef.tydef_id pp_emf_typ_dec typedef.tydef_desc 
419
  
420
let pp_emf_top_const fmt const_top = 
421
  let const = Corelang.const_of_top const_top in
422
  fprintf fmt "\"%s\": " const.const_id;
423
  pp_emf_cst const.const_value const.const_type fmt
424

  
285 425
(* Local Variables: *)
286 426
(* compile-command: "make -C ../.." *)
287 427
(* End: *)
src/compiler_stages.ml
188 188
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. normalization@,");
189 189
  let prog = Normalization.normalize_prog params prog in
190 190
  Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
191

  
191
  
192 192
  (* Compatibility with Lusi *)
193 193
  (* If compiling a lusi, generate the lusic. If this is a lus file, Check the existence of a lusi (Lustre Interface file) *)
194 194
  compile_source_to_header
195 195
    prog !Global.type_env !Global.clock_env dirname basename extension;
196 196

  
197

  
197 198
  let prog =
198 199
    if !Options.mpfr
199 200
    then
src/corelang.ml
220 220
    eexpr_quantifiers = [];
221 221
    eexpr_type = Types.new_var ();
222 222
    eexpr_clock = Clocks.new_var true;
223
    eexpr_normalized = None;
224 223
    eexpr_loc = loc }
225 224

  
226 225
let extend_eexpr q e = { e with eexpr_quantifiers = q@e.eexpr_quantifiers }
......
805 804
     eexpr_tag = Utils.new_tag ();
806 805
     eexpr_qfexpr = rename_expr f_node f_var ee.eexpr_qfexpr;
807 806
     eexpr_quantifiers = List.map (fun (typ,vdecls) -> typ, rename_vars f_node f_var vdecls) ee.eexpr_quantifiers;
808
     eexpr_normalized = Utils.option_map 
809
       (fun (vdecl, eqs, vdecls) ->
810
	 rename_var f_node f_var vdecl,
811
	 List.map (rename_eq f_node f_var) eqs,
812
	 rename_vars f_node f_var vdecls
813
       ) ee.eexpr_normalized;
814
     
815 807
   }
816 808
 
817 809
     
......
1035 1027
     eexpr_type = expr.expr_type;
1036 1028
     eexpr_clock = expr.expr_clock;
1037 1029
     eexpr_loc = expr.expr_loc;
1038
     eexpr_normalized = None
1039 1030
   }
1040 1031
 (* and expr_desc_to_eexpr_desc expr_desc = *)
1041 1032
 (*   let conv = expr_to_eexpr in *)
src/corelang.mli
86 86
val const_xor: constant -> constant -> constant
87 87
val const_impl: constant -> constant -> constant
88 88

  
89
val get_var: ident -> var_decl list -> var_decl
89 90
val get_node_vars: node_desc -> var_decl list
90 91
val get_node_var: ident -> node_desc -> var_decl
91 92
val get_node_eqs: node_desc -> eq list * automata_desc list
src/lustre_types.ml
118 118
     eexpr_quantifiers: (quantifier_type * var_decl list) list;
119 119
     mutable eexpr_type: Types.type_expr;
120 120
     mutable eexpr_clock: Clocks.clock_expr;
121
     mutable eexpr_normalized: (var_decl * eq list * var_decl list) option;
121
     (* mutable eexpr_normalized: (var_decl * eq list * var_decl list) option; *)
122 122
     eexpr_loc: Location.t}
123 123

  
124 124
and expr_annot =
src/machine_code.ml
20 20

  
21 21

  
22 22
       
23
(* translate_<foo> : node -> context -> <foo> -> machine code/expression *)
23
(* translate_<foo> : vars -> context -> <foo> -> machine code/expression *)
24 24
(* the context contains  m : state aka memory variables  *)
25 25
(*                      si : initialization instructions *)
26 26
(*                       j : node aka machine instances  *)
27 27
(*                       d : local variables             *)
28 28
(*                       s : step instructions           *)
29
let translate_ident node (m, si, j, d, s) id =
29
let translate_ident vars _ (* (m, si, j, d, s) *) id =
30 30
  (* Format.eprintf "trnaslating ident: %s@." id; *)
31
  try (* id is a node var *)
32
    let var_id = get_node_var id node in
31
  try (* id is a var that shall be visible here , ie. in vars *)
32
    let var_id = get_var id vars in
33 33
    mk_val (Var var_id) var_id.var_type
34 34
  with Not_found ->
35 35
    try (* id is a constant *)
36
      let vdecl = (Corelang.var_decl_of_const (const_of_top (Hashtbl.find Corelang.consts_table id))) in
36
      let vdecl = (Corelang.var_decl_of_const
37
                     (const_of_top (Hashtbl.find Corelang.consts_table id)))
38
      in
37 39
      mk_val (Var vdecl) vdecl.var_type
38 40
    with Not_found ->
39 41
      (* id is a tag *)
40
      (* DONE construire une liste des enum declarés et alors chercher dedans la liste
41
	 qui contient id *)
42
      (* DONE construire une liste des enum declarés et alors chercher
43
         dedans la liste qui contient id *)
42 44
      try
43 45
        let typ = (typedef_of_top (Hashtbl.find Corelang.tag_table id)).tydef_id in
44 46
        mk_val (Cst (Const_tag id)) (Type_predef.type_const typ)
45
      with Not_found -> (Format.eprintf "internal error: Machine_code.translate_ident %s" id;
47
      with Not_found -> (Format.eprintf
48
                           "internal error: Machine_code.translate_ident %s"
49
                           id;
46 50
                         assert false)
47 51

  
48
let rec control_on_clock node ((m, si, j, d, s) as args) ck inst =
52
let rec control_on_clock vars ((m, si, j, d, s) as args) ck inst =
49 53
 match (Clocks.repr ck).cdesc with
50 54
 | Con    (ck1, cr, l) ->
51 55
   let id  = Clocks.const_of_carrier cr in
52
   control_on_clock node args ck1 (mkinstr
56
   control_on_clock vars args ck1 (mkinstr
53 57
				     (* TODO il faudrait prendre le lustre
54 58
					associé à instr et rajouter print_ck_suffix
55 59
					ck) de clocks.ml *)
56
				     (MBranch (translate_ident node args id,
60
				     (MBranch (translate_ident vars args id,
57 61
					       [l, [inst]] )))
58 62
 | _                   -> inst
59 63

  
......
79 83
  | "C" -> specialize_to_c expr
80 84
  | _   -> expr
81 85

  
82
let rec translate_expr node ((m, si, j, d, s) as args) expr =
86
let rec translate_expr vars ((m, si, j, d, s) as args) expr =
83 87
  let expr = specialize_op expr in
88
  (* all calls are using the same arguments (vars for the variable
89
     enviroment and args for computed memories). No fold constructs
90
     here. We can do partial evaluation of translate_expr *)
91
  let translate_expr = translate_expr vars args in 
84 92
  let value_desc = 
85 93
    match expr.expr_desc with
86 94
    | Expr_const v                     -> Cst v
87
    | Expr_ident x                     -> (translate_ident node args x).value_desc
88
    | Expr_array el                    -> Array (List.map (translate_expr node args) el)
89
    | Expr_access (t, i)               -> Access (translate_expr node args t, translate_expr node args (expr_of_dimension i))
90
    | Expr_power  (e, n)               -> Power  (translate_expr node args e, translate_expr node args (expr_of_dimension n))
95
    | Expr_ident x                     -> (translate_ident vars args x).value_desc
96
    | Expr_array el                    -> Array (List.map translate_expr el)
97
    | Expr_access (t, i)               -> Access (translate_expr t,
98
                                                  translate_expr 
99
                                                    (expr_of_dimension i))
100
    | Expr_power  (e, n)               -> Power  (translate_expr e,
101
                                                  translate_expr
102
                                                    (expr_of_dimension n))
91 103
    | Expr_tuple _
92
    | Expr_arrow _ 
93
    | Expr_fby _
94
    | Expr_pre _                       -> (Printers.pp_expr Format.err_formatter expr; Format.pp_print_flush Format.err_formatter (); raise NormalizationError)
95
    | Expr_when    (e1, _, _)          -> (translate_expr node args e1).value_desc
104
      | Expr_arrow _ 
105
      | Expr_fby _
106
      | Expr_pre _                       -> (Printers.pp_expr
107
                                               Format.err_formatter expr;
108
                                             Format.pp_print_flush
109
                                               Format.err_formatter ();
110
                                             raise NormalizationError)
111
                                          
112
    | Expr_when    (e1, _, _)          -> (translate_expr e1).value_desc
96 113
    | Expr_merge   (x, _)              -> raise NormalizationError
97 114
    | Expr_appl (id, e, _) when Basic_library.is_expr_internal_fun expr ->
98
      let nd = node_from_name id in
99
      Fun (node_name nd, List.map (translate_expr node args) (expr_list_of_expr e))
115
       let nd = node_from_name id in
116
       Fun (node_name nd, List.map translate_expr (expr_list_of_expr e))
100 117
    | Expr_ite (g,t,e) -> (
101 118
      (* special treatment depending on the active backend. For horn backend, ite
102 119
	 are preserved in expression. While they are removed for C or Java
103 120
	 backends. *)
104 121
      match !Options.output with
105 122
      | "horn" -> 
106
	 Fun ("ite", [translate_expr node args g; translate_expr node args t; translate_expr node args e])
123
	 Fun ("ite", [translate_expr g; translate_expr t; translate_expr e])
107 124
      | "C" | "java" | _ -> 
108 125
	 (Format.eprintf "Normalization error for backend %s: %a@."
109 126
	    !Options.output
......
114 131
  in
115 132
  mk_val value_desc expr.expr_type
116 133

  
117
let translate_guard node args expr =
134
let translate_guard vars args expr =
118 135
  match expr.expr_desc with
119
  | Expr_ident x  -> translate_ident node args x
120
  | _ -> (Format.eprintf "internal error: translate_guard %s %a@." node.node_id Printers.pp_expr expr;assert false)
136
  | Expr_ident x  -> translate_ident vars args x
137
  | _ -> (Format.eprintf "internal error: translate_guard %a@."
138
            Printers.pp_expr expr;
139
          assert false)
121 140

  
122
let rec translate_act node ((m, si, j, d, s) as args) (y, expr) =
141
let rec translate_act vars ((m, si, j, d, s) as args) (y, expr) =
142
  let translate_act = translate_act vars args in
143
  let translate_guard = translate_guard vars args in
144
  let translate_ident = translate_ident vars args in
145
  let translate_expr = translate_expr vars args in
123 146
  let eq = Corelang.mkeq Location.dummy_loc ([y.var_id], expr) in
124 147
  match expr.expr_desc with
125
  | Expr_ite   (c, t, e) -> let g = translate_guard node args c in
148
  | Expr_ite   (c, t, e) -> let g = translate_guard c in
126 149
			    mk_conditional ?lustre_eq:(Some eq) g
127
                              [translate_act node args (y, t)]
128
                              [translate_act node args (y, e)]
129
  | Expr_merge (x, hl)   -> mkinstr ?lustre_eq:(Some eq) (MBranch (translate_ident node args x,
130
                                     List.map (fun (t,  h) -> t, [translate_act node args (y, h)]) hl))
131
  | _                    -> mkinstr ?lustre_eq:(Some eq)  (MLocalAssign (y, translate_expr node args expr))
150
                              [translate_act (y, t)]
151
                              [translate_act (y, e)]
152
  | Expr_merge (x, hl)   -> mkinstr ?lustre_eq:(Some eq)
153
                              (MBranch (translate_ident x,
154
                                        List.map (fun (t,  h) ->
155
                                            t, [translate_act (y, h)])
156
                                          hl))
157
  | _                    -> mkinstr ?lustre_eq:(Some eq)
158
                              (MLocalAssign (y, translate_expr expr))
132 159

  
133
let reset_instance node args i r c =
160
let reset_instance vars args i r c =
134 161
  match r with
135 162
  | None        -> []
136
  | Some r      -> let g = translate_guard node args r in
137
                   [control_on_clock node args c (mk_conditional g [mkinstr (MReset i)] [mkinstr (MNoReset i)])]
163
  | Some r      -> let g = translate_guard vars args r in
164
                   [control_on_clock
165
                      vars
166
                      args
167
                      c
168
                      (mk_conditional
169
                         g
170
                         [mkinstr (MReset i)]
171
                         [mkinstr (MNoReset i)])
172
                   ]
173

  
174
let translate_eq vars ((m, si, j, d, s) as args) eq =
175
  let translate_expr = translate_expr vars args in
176
  let translate_act = translate_act vars args in
177
  let control_on_clock = control_on_clock vars args in
178
  let reset_instance = reset_instance vars args in
138 179

  
139
let translate_eq node ((m, si, j, d, s) as args) eq =
140
  (* Format.eprintf "translate_eq %a with clock %a@." Printers.pp_node_eq eq Clocks.print_ck eq.eq_rhs.expr_clock;  *)
180
  (* Format.eprintf "translate_eq %a with clock %a@." 
181
     Printers.pp_node_eq eq Clocks.print_ck eq.eq_rhs.expr_clock;  *)
141 182
  match eq.eq_lhs, eq.eq_rhs.expr_desc with
142 183
  | [x], Expr_arrow (e1, e2)                     ->
143
     let var_x = get_node_var x node in
144
     let o = new_instance node Arrow.arrow_top_decl eq.eq_rhs.expr_tag in
145
     let c1 = translate_expr node args e1 in
146
     let c2 = translate_expr node args e2 in
184
     let var_x = get_var x vars in
185
     let o = new_instance Arrow.arrow_top_decl eq.eq_rhs.expr_tag in
186
     let c1 = translate_expr e1 in
187
     let c2 = translate_expr e2 in
147 188
     (m,
148 189
      mkinstr (MReset o) :: si,
149 190
      Utils.IMap.add o (Arrow.arrow_top_decl, []) j,
150 191
      d,
151
      (control_on_clock node args eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStep ([var_x], o, [c1;c2])))) :: s)
152
  | [x], Expr_pre e1 when VSet.mem (get_node_var x node) d     ->
153
     let var_x = get_node_var x node in
192
      (control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStep ([var_x], o, [c1;c2])))) :: s)
193
  | [x], Expr_pre e1 when VSet.mem (get_var x vars) d     ->
194
     let var_x = get_var x vars in
154 195
     (VSet.add var_x m,
155 196
      si,
156 197
      j,
157 198
      d,
158
      control_on_clock node args eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr node args e1))) :: s)
159
  | [x], Expr_fby (e1, e2) when VSet.mem (get_node_var x node) d ->
160
     let var_x = get_node_var x node in
199
      control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e1))) :: s)
200
  | [x], Expr_fby (e1, e2) when VSet.mem (get_var x vars) d ->
201
     let var_x = get_var x vars in
161 202
     (VSet.add var_x m,
162
      mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr node args e1)) :: si,
203
      mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e1)) :: si,
163 204
      j,
164 205
      d,
165
      control_on_clock node args eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr node args e2))) :: s)
206
      control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e2))) :: s)
166 207

  
167 208
  | p  , Expr_appl (f, arg, r) when not (Basic_library.is_expr_internal_fun eq.eq_rhs) ->
168
     let var_p = List.map (fun v -> get_node_var v node) p in
209
     let var_p = List.map (fun v -> get_var v vars) p in
169 210
     let el = expr_list_of_expr arg in
170
     let vl = List.map (translate_expr node args) el in
211
     let vl = List.map translate_expr el in
171 212
     let node_f = node_from_name f in
172 213
     let call_f =
173 214
       node_f,
174 215
       NodeDep.filter_static_inputs (node_inputs node_f) el in
175
     let o = new_instance node node_f eq.eq_rhs.expr_tag in
216
     let o = new_instance node_f eq.eq_rhs.expr_tag in
176 217
     let env_cks = List.fold_right (fun arg cks -> arg.expr_clock :: cks) el [eq.eq_rhs.expr_clock] in
177 218
     let call_ck = Clock_calculus.compute_root_clock (Clock_predef.ck_tuple env_cks) in
178 219
     (*Clocks.new_var true in
......
184 225
      d,
185 226
      (if Stateless.check_node node_f
186 227
       then []
187
       else reset_instance node args o r call_ck) @
188
	(control_on_clock node args call_ck (mkinstr ?lustre_eq:(Some eq) (MStep (var_p, o, vl)))) :: s)
228
       else reset_instance o r call_ck) @
229
	(control_on_clock call_ck (mkinstr ?lustre_eq:(Some eq) (MStep (var_p, o, vl)))) :: s)
189 230
  (*
190 231
    (* special treatment depending on the active backend. For horn backend, x = ite (g,t,e)
191 232
    are preserved. While they are replaced as if g then x = t else x = e in  C or Java
......
204 245

  
205 246
  *)
206 247
  | [x], _                                       -> (
207
    let var_x = get_node_var x node in
248
    let var_x = get_var x vars in
208 249
    (m, si, j, d,
209 250
     control_on_clock
210
       node
211
       args
212 251
       eq.eq_rhs.expr_clock
213
       (translate_act node args (var_x, eq.eq_rhs)) :: s
252
       (translate_act (var_x, eq.eq_rhs)) :: s
214 253
    )
215 254
  )
216 255
  | _                                            ->
......
235 274
let translate_eqs node args eqs =
236 275
  List.fold_right (fun eq args -> translate_eq node args eq) eqs args;;
237 276

  
238
let translate_decl nd sch =
239
  (*Log.report ~level:1 (fun fmt -> Printers.pp_node fmt nd);*)
240
  let schedule = sch.Scheduling_type.schedule in
241
  let sorted_eqs = Scheduling.sort_equations_from_schedule nd schedule in
242
  let constant_eqs = constant_equations nd in
243

  
244
  (* In case of non functional backend (eg. C), additional local variables have
245
     to be declared for each assert *)
246
  let new_locals, assert_instrs, nd_node_asserts =
277
let process_asserts nd =
278
  
247 279
    let exprl = List.map (fun assert_ -> assert_.assert_expr ) nd.node_asserts in
248 280
    if Backends.is_functional () then
249 281
      [], [], exprl  
......
267 299
	  in
268 300
	  assert_var.var_type <- Type_predef.type_bool (* Types.new_ty (Types.Tbool) *); 
269 301
	  let eq = mkeq loc ([var_id], expr) in
270
	  (i+1, assert_var::vars, eq::eqlist, {expr with expr_desc = Expr_ident var_id}::assertlist)
302
          (i+1, assert_var::vars, eq::eqlist, {expr with expr_desc = Expr_ident var_id}::assertlist)
271 303
	) (1, [], [], []) exprl
272 304
      in
273 305
      vars, eql, assertl
274
  in
275
  let locals_list = nd.node_locals @ new_locals in
306
  
307
let translate_decl nd sch =
308
  (*Log.report ~level:1 (fun fmt -> Printers.pp_node fmt nd);*)
309
  let schedule = sch.Scheduling_type.schedule in
310
  let sorted_eqs = Scheduling.sort_equations_from_schedule nd schedule in
311
  let constant_eqs = constant_equations nd in
276 312

  
313
  (* In case of non functional backend (eg. C), additional local variables have
314
     to be declared for each assert *)
315
  let new_locals, assert_instrs, nd_node_asserts = process_asserts nd in
316
  let locals_list = nd.node_locals @ new_locals in
277 317
  let nd = { nd with node_locals = locals_list } in
318
  let vars = get_node_vars nd in
319
  
278 320
  let init_args = VSet.empty, [], Utils.IMap.empty, List.fold_right (fun l -> VSet.add l) locals_list VSet.empty, [] in
279 321
  (* memories, init instructions, node calls, local variables (including memories), step instrs *)
280
  let m0, init0, j0, locals0, s0 = translate_eqs nd init_args constant_eqs in
322

  
323
  let m0, init0, j0, locals0, s0 =
324
    translate_eqs vars init_args constant_eqs
325
  in
326

  
281 327
  assert (VSet.is_empty m0);
282 328
  assert (init0 = []);
283 329
  assert (Utils.IMap.is_empty j0);
284
  let m, init, j, locals, s as context_with_asserts = translate_eqs nd (m0, init0, j0, locals0, []) (assert_instrs@sorted_eqs) in
330

  
331
  let m, init, j, locals, s as context_with_asserts =
332
    translate_eqs
333
      vars
334
      (m0, init0, j0, locals0, [])
335
      (assert_instrs@sorted_eqs)
336
  in
285 337
  let mmap = Utils.IMap.fold (fun i n res -> (i, n)::res) j [] in
286 338
  {
287 339
    mname = nd;
......
295 347
      step_inputs = nd.node_inputs;
296 348
      step_outputs = nd.node_outputs;
297 349
      step_locals = VSet.elements (VSet.diff locals m);
298
      step_checks = List.map (fun d -> d.Dimension.dim_loc, translate_expr nd init_args (expr_of_dimension d)) nd.node_checks;
350
      step_checks = List.map (fun d -> d.Dimension.dim_loc,
351
                                       translate_expr vars init_args
352
                                         (expr_of_dimension d))
353
                      nd.node_checks;
299 354
      step_instrs = (
300 355
	(* special treatment depending on the active backend. For horn backend,
301 356
	   common branches are not merged while they are in C or Java
......
308 363
	else
309 364
	  s
310 365
      );
311
      step_asserts = List.map (translate_expr nd context_with_asserts) nd_node_asserts;
366
      step_asserts = List.map (translate_expr vars context_with_asserts) nd_node_asserts;
312 367
    };
313 368
    mspec = nd.node_spec;
314 369
    mannot = nd.node_annot;
src/machine_code_common.ml
216 216

  
217 217
let new_instance =
218 218
  let cpt = ref (-1) in
219
  fun caller callee tag ->
219
  fun callee tag ->
220 220
    begin
221 221
      let o =
222 222
	if Stateless.check_node callee then
......
225 225
	  Printf.sprintf "ni_%d" (incr cpt; !cpt) in
226 226
      let o =
227 227
	if !Options.ansi && is_generic_node callee
228
	then Printf.sprintf "%s_inst_%d" o (Utils.position (fun e -> e.expr_tag = tag) caller.node_gencalls)
228
	then Printf.sprintf "%s_inst_%d"
229
               o
230
               (incr cpt; !cpt)
229 231
	else o in
230 232
      o
231 233
    end
src/machine_code_common.mli
9 9
val mk_conditional: ?lustre_eq:Lustre_types.eq -> Machine_code_types.value_t -> Machine_code_types.instr_t list -> Machine_code_types.instr_t list -> Machine_code_types.instr_t
10 10
val empty_machine: Machine_code_types.machine_t
11 11
val arrow_machine: Machine_code_types.machine_t
12
val new_instance: Lustre_types.node_desc -> Lustre_types.top_decl -> Lustre_types.tag -> Lustre_types.ident
12
val new_instance: Lustre_types.top_decl -> Lustre_types.tag -> Lustre_types.ident
13 13
val value_of_dimension: Machine_code_types.machine_t -> Dimension.dim_expr -> Machine_code_types.value_t
14 14
val dimension_of_value:Machine_code_types.value_t -> Dimension.dim_expr
15 15
val pp_instr: Machine_code_types.machine_t -> Format.formatter -> Machine_code_types.instr_t -> unit
src/machine_code_types.ml
41 41

  
42 42
type static_call = top_decl * (Dimension.dim_expr list)
43 43

  
44
                 
44 45
type machine_t = {
45 46
  mname: node_desc;
46 47
  mmemory: var_decl list;
src/normalization.ml
170 170
      then
171 171
	let new_aliases =
172 172
	  List.map2
173
	    (mk_fresh_var (norm_ctx.parentid, norm_ctx.vars) expr.expr_loc)
173
	    (mk_fresh_var (norm_ctx.parentid, (norm_ctx.vars@vars)) expr.expr_loc)
174 174
	    (Types.type_list_of_type expr.expr_type)
175 175
	    (Clocks.clock_list_of_clock expr.expr_clock) in
176 176
	let new_def =
177 177
	  mkeq expr.expr_loc (List.map (fun v -> v.var_id) new_aliases, expr)
178 178
	in
179 179
	(* Typing and Registering machine type *) 
180
	let _ = if Machine_types.is_active then Machine_types.type_def (norm_ctx.parentid, norm_ctx.vars) new_aliases expr  in
180
	let _ = if Machine_types.is_active then
181
                  Machine_types.type_def (norm_ctx.parentid, norm_ctx.vars) new_aliases expr
182
        in
181 183
	(new_def::defs, new_aliases@vars), replace_expr new_aliases expr
182 184
      else
183 185
	(defs, vars), expr
......
400 402
let normalize_eq_split norm_ctx defvars eq =
401 403
  try
402 404
    let defs, vars = normalize_eq norm_ctx defvars eq in
403
  List.fold_right (fun eq (def, vars) -> 
404
    let eq_defs = Splitting.tuple_split_eq eq in
405
    if eq_defs = [eq] then
406
      eq::def, vars 
407
    else
408
      List.fold_left (normalize_eq norm_ctx) (def, vars) eq_defs
409
  ) defs ([], vars)  
410

  
411
  with _ -> (
405
    List.fold_right (fun eq (def, vars) -> 
406
        let eq_defs = Splitting.tuple_split_eq eq in
407
        if eq_defs = [eq] then
408
          eq::def, vars 
409
        else
410
          List.fold_left (normalize_eq norm_ctx) (def, vars) eq_defs
411
      ) defs ([], vars)  
412
    
413
  with ex -> (
412 414
    Format.eprintf "Issue normalizing eq split: %a@." Printers.pp_node_eq eq;
413
    assert false
415
    raise ex
414 416
  )
415 417

  
416
let normalize_eexpr decls norm_ctx vars ee = ee (*
417
  (* New output variable *)
418
  let output_id = "spec" ^ string_of_int ee.eexpr_tag in
419
  let output_var = 
420
    mkvar_decl 
421
      ee.eexpr_loc 
422
      (output_id, 
423
       mktyp ee.eexpr_loc Tydec_any, (*TODO: Make it bool when it is spec *)
424
       mkclock ee.eexpr_loc Ckdec_any, 
425
       false (* not a constant *),
426
       None,
427
       None
428
      ) 
418
(* Projecting an eexpr to an eexpr associated to a single
419
   variable. Returns the updated ee, the bounded variable and the
420
   associated statement *)
421
let normalize_pred_eexpr decls norm_ctx (def,vars) ee =
422
  assert (ee.eexpr_quantifiers = []); (* We do not normalize quantifiers yet. This is for very far future. *)
423
  (* don't do anything is eexpr is just a variable *)
424
  let skip =
425
    match ee.eexpr_qfexpr.expr_desc with
426
    | Expr_ident _ | Expr_const _ -> true
427
    | _ -> false
429 428
  in
429
  if skip then
430
    ee, (def, vars)
431
  else (
432
    (* New output variable *)
433
    let output_id = "spec" ^ string_of_int ee.eexpr_tag in
434
    let output_var = 
435
      mkvar_decl 
436
        ee.eexpr_loc 
437
        (output_id, 
438
         mktyp ee.eexpr_loc Tydec_bool, (* It is a predicate, hence a bool *)
439
         mkclock ee.eexpr_loc Ckdec_any, 
440
         false (* not a constant *),
441
         None,
442
         None
443
        ) 
444
    in
445
    let output_expr = expr_of_vdecl output_var in
446
    (* Rebuilding an eexpr with a silly expression, just a variable *)
447
    let ee' = { ee with eexpr_qfexpr = output_expr } in
448

  
449
    (* Now processing a fresh equation output_id = eexpr_qfexpr. We
450
       inline possible calls within, normalize it and type/clock the
451
       result.  *)
452
    let eq = mkeq ee.eexpr_loc ([output_id], ee.eexpr_qfexpr) in
453
    (* Inlining any calls *)
454
    let nodes = get_nodes decls in
455
    let calls = ISet.elements (get_expr_calls nodes ee.eexpr_qfexpr) in
456
    let vars, eqs =
457
      if calls = [] && not (eq_has_arrows eq) then
458
        vars, [eq]    
459
      else
460
        assert false (* TODO *)
461
    in
462
    
463
    (* Normalizing expr and eqs *)
464
    let defs, vars = List.fold_left (normalize_eq_split norm_ctx) (def, vars) eqs in
465
(*    let todefine =
466
      List.fold_left
467
        (fun m x-> if List.exists (fun y-> x.var_id = y.var_id) (locals) then m else ISet.add x.var_id m)
468
        (ISet.add output_id ISet.empty) vars in
469
 *)      
470

  
471
    (* Typing / Clocking *)
472
    try
473
      ignore (Typing.type_var_decl_list vars !Global.type_env vars);
474
        (*
475
    let env = Typing.type_var_decl [] !Global.type_env xxxx output_var in (* typing the variable *)
476
    (* Format.eprintf "typing var %s: %a@." output_id Types.print_ty output_var.var_type; *)
477
    let env = Typing.type_var_decl_list (vars@node.node_outputs@node.node_inputs) env (vars@node.node_outputs@node.node_inputs) in
478
    (*Format.eprintf "Env: %a@.@?" (Env.pp_env Types.print_ty) env;*)
479
    let undefined_vars = List.fold_left (Typing.type_eq (env, quant_vars@vars) false) todefine defs in
480
  (* check that table is empty *)
481
    if (not (ISet.is_empty undefined_vars)) then
482
      raise (Types.Error (ee.eexpr_loc, Types.Undefined_var undefined_vars));
483
    
484
    (*Format.eprintf "normalized eqs %a@.@?" 
485
      (Utils.fprintf_list ~sep:", " Printers.pp_node_eq) defs;  *)
486
         *)
487

  
488
    ee', (defs, vars)
489
    
490
  with (Types.Error (loc,err)) as exc ->
491
    eprintf "Typing error for eexpr %a: %a%a%a@."
492
      Printers.pp_eexpr ee
493
      Types.pp_error err
494
      (Utils.fprintf_list ~sep:", " Printers.pp_node_eq) defs
495
      Location.pp_loc loc
496
  
497
      
498
    ;
499
    raise exc
500
                                     
501
  )
502
    
503
   (*
430 504
  
431 505
  let quant_vars = List.flatten (List.map snd ee.eexpr_quantifiers) in
432 506
  (* Calls are first inlined *)
433
  let nodes = get_nodes decls in
434
  let calls = ISet.elements (get_expr_calls nodes ee.eexpr_qfexpr) in
435
(* TODO remettre egalement, i ly a un probleme de decapsulage de nodes
436
   let calls = List.map 
437
    (fun called_nd -> List.find (fun nd2 -> nd2.node_id = called_nd) nodes) calls 
438
  in
439
*)
507
  
440 508
  (*Format.eprintf "eexpr %a@.calls: %a@.@?" Printers.pp_eexpr ee (Utils.fprintf_list ~sep:", " (fun fmt nd -> pp_print_string fmt nd.node_id)) calls;  *)
441
  let eq = mkeq ee.eexpr_loc ([output_id], ee.eexpr_qfexpr) in
442
  let locals = node.node_locals @ (List.fold_left (fun accu (_, q) -> q@accu) [] ee.eexpr_quantifiers) in  
443 509
  let (new_locals, eqs) =
444 510
    if calls = [] && not (eq_has_arrows eq) then
445 511
      (locals, [eq])     
......
485 551
    raise exc
486 552
                                                 *)    
487 553
 
488
    
489
let normalize_spec decls iovars s = s (*
490
  (* Each stmt is normalized *)
491
  let orig_vars = iovars @ s.locals in
554

  
555
(* We use node local vars to make sure we are creating fresh variables *) 
556
let normalize_spec decls parentid (in_vars, out_vars, l_vars) s =  
557
  (* Original set of variables actually visible from here: iun/out and
558
     spec locals (no node locals) *)
559
  let orig_vars = in_vars @ out_vars @ s.locals in
492 560
  let not_is_orig_var v =
493 561
    List.for_all ((!=) v) orig_vars in
494
  let defs, vars = 
495
    let eqs, auts = List.fold_right (fun (el,al) s -> match s with Eq e -> e::el, al | Aut a -> el, a::al) s.stmts ([], []) in
496
    if auts != [] then assert false; (* Automata should be expanded by now. *)
497
    List.fold_left (normalize_eq node) ([], orig_vars) eqs
562
  let norm_ctx = {
563
      parentid = parentid;
564
      vars = in_vars @ out_vars @ l_vars;
565
      is_output = (fun _ -> false) (* no need to introduce fresh variables for outputs *);
566
    }
567
  in
568
  (* Normalizing existing stmts *)
569
  let eqs, auts = List.fold_right (fun s (el,al)  -> match s with Eq e -> e::el, al | Aut a -> el, a::al) s.stmts ([], []) in
570
  if auts != [] then assert false; (* Automata should be expanded by now. *)
571
  let defsvars = 
572
    List.fold_left (normalize_eq norm_ctx) ([], orig_vars) eqs
573
  in
574
  (* Iterate through predicates and normalize them on the go, creating
575
     fresh variables for any guarantees/assumes/require/ensure *)
576
  let process_predicates l defvars =
577
    List.fold_right (fun ee (accu, defvars) ->
578
        let ee', defvars = normalize_pred_eexpr decls norm_ctx defvars ee in
579
        ee'::accu, defvars
580
      ) l ([], defvars)
498 581
  in
499
  let new_locals = List.filter not_is_orig_var vars in (* removing inouts and initial locals ones *)
500 582

  
501
  (*
583
  
584
  let assume', defsvars = process_predicates s.assume defsvars in
585
  let guarantees', defsvars = process_predicates s.guarantees defsvars in
586
  let modes', (defs, vars) =
587
    List.fold_right (
588
        fun m (accu_m, defsvars) ->
589
        let require', defsvars = process_predicates m.require defsvars in
590
        let ensure', defsvars = process_predicates m.ensure defsvars in
591
        { m with require = require'; ensure = ensure' }:: accu_m, defsvars
592
      ) s.modes ([], defsvars)
593
  in
594
  
595
  let new_locals = List.filter not_is_orig_var vars in (* removing inouts and initial locals ones *)
596
   
502 597
      
503 598
  {s with
504 599
    locals = s.locals @ new_locals;
505 600
    stmts = List.map (fun eq -> Eq eq) defs;
506
  let nee _ = () in
507
  (*normalize_eexpr decls iovars in *)
508
  List.iter nee s.assume;
509
  List.iter nee s.guarantees;
510
  List.iter (fun m -> 
511
      List.iter nee m.require;
512
    List.iter nee m.ensure
513
    ) s.modes;
514
   *)
515
  s
516
                                       *)
601
    assume = assume';
602
    guarantees = guarantees';
603
    modes = modes'
604
  }
605
(* let nee _ = () in
606
 *   (\*normalize_eexpr decls iovars in *\)
607
 *   List.iter nee s.assume;
608
 *   List.iter nee s.guarantees;
609
 *   List.iter (fun m -> 
610
 *       List.iter nee m.require;
611
 *     List.iter nee m.ensure
612
 *     ) s.modes; *)
613
   
614

  
615
                                                                     
616
  
617
  
517 618
    
518 619
(* The normalization phase introduces new local variables
519 620
   - output cannot be memories. If this happen, new local variables acting as
......
534 635
*)
535 636
let normalize_node decls node =
536 637
  reset_cpt_fresh ();
537
  let inputs_outputs = node.node_inputs@node.node_outputs in
538
  let orig_vars = inputs_outputs@node.node_locals in
638
  let orig_vars = node.node_inputs@node.node_outputs@node.node_locals in
539 639
  let not_is_orig_var v =
540 640
    List.for_all ((!=) v) orig_vars in
541 641
  let norm_ctx = {
......
636 736

  
637 737
	 Careful: we do not normalize annotations, since they can have the form
638 738
	 x = (a, b, c) *)
639
      match node.node_spec with None -> None | Some s -> Some (normalize_spec decls inputs_outputs s) 
739
      match node.node_spec with None -> None | Some s -> Some (normalize_spec decls node.node_id (node.node_inputs, node.node_outputs, node.node_locals) s) 
640 740
    end
641 741
  in
642 742
  
......
658 758
  match nd.nodei_spec with
659 759
    None -> nd
660 760
  | Some s ->
661
     let inputs_outputs = nd.nodei_inputs@nd.nodei_outputs in
662
     let s = normalize_spec decls inputs_outputs s in
761
     let s = normalize_spec decls nd.nodei_id (nd.nodei_inputs, nd.nodei_outputs, []) s in
663 762
     { nd with nodei_spec = Some s }
664 763
  
665 764
let normalize_decl (decls: program_t) (decl: top_decl) : top_decl =
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
30
(* TODO general remark: except in the add_vdecl, it seems to me that
31 31
   all the pairs (env, vd_env) should be replace with just env, since
32 32
   vd_env is never used and the env element is always extract with a
33 33
   fst *)
......
686 686
          undefined_vars_init
687 687
          eqs
688 688
      in
689
      
689
      (* Typing each predicate expr *)
690
      let type_pred_ee ee : unit=
691
        type_subtyping_arg (env, vd_env) (false (* not in main *)) (false (* not a const *)) ee.eexpr_qfexpr type_bool
692
      in
693
      List.iter type_pred_ee
694
        (
695
          spec.assume 
696
          @ spec.guarantees
697
          @ List.flatten (List.map (fun m -> m.ensure @ m.require) spec.modes) 
698
        );
690 699
      (*TODO 
691 700
        enrich env locally with locals and consts
692 701
        type each pre/post as a boolean expr

Also available in: Unified diff