Project

General

Profile

« Previous | Next » 

Revision 90cc3b8e

Added by LĂ©lio Brun over 3 years ago

some rewriting in C backend pretty-printer

View differences:

src/backends/C/c_backend_src.ml
9 9
(*                                                                  *)
10 10
(********************************************************************)
11 11

  
12
open Format
12
open Utils.Format
13 13
open Lustre_types
14 14
open Machine_code_types
15 15
open Corelang
16 16
open Machine_code_common
17 17
open C_backend_common
18 18

  
19
module type MODIFIERS_SRC =
20
sig
19
module type MODIFIERS_SRC = sig
21 20
end
22 21

  
23
module EmptyMod =
24
struct
22
module EmptyMod = struct
25 23
end
26 24

  
27
module Main = functor (Mod: MODIFIERS_SRC) -> 
28
struct
25
module Main = functor (Mod: MODIFIERS_SRC) -> struct
29 26

  
30
(********************************************************************************************)
31
(*                    Instruction Printing functions                                        *)
32
(********************************************************************************************)
27
  (********************************************************************************************)
28
  (*                    Instruction Printing functions                                        *)
29
  (********************************************************************************************)
33 30

  
34 31

  
35
(* Computes the depth to which multi-dimension array assignments should be expanded.
36
   It equals the maximum number of nested static array constructions accessible from root [v].
37
*)
32
  (* Computes the depth to which multi-dimension array assignments should be expanded.
33
     It equals the maximum number of nested static array constructions accessible from root [v].
34
  *)
38 35
  let rec expansion_depth v =
39 36
    match v.value_desc with
40 37
    | Cst cst -> expansion_depth_cst cst
......
45 42
    | Power _  -> 0 (*1 + expansion_depth v*)
46 43
  and expansion_depth_cst c = 
47 44
    match c with
48
      Const_array cl -> 1 + List.fold_right (fun c -> max (expansion_depth_cst c)) cl 0
45
    | Const_array cl ->
46
      1 + List.fold_right (fun c -> max (expansion_depth_cst c)) cl 0
49 47
    | _ -> 0
50
  
48

  
51 49
  let rec merge_static_loop_profiles lp1 lp2 =
52 50
    match lp1, lp2 with
53 51
    | []      , _        -> lp2
54 52
    | _       , []       -> lp1
55 53
    | p1 :: q1, p2 :: q2 -> (p1 || p2) :: merge_static_loop_profiles q1 q2
56 54

  
57
(* Returns a list of bool values, indicating whether the indices must be static or not *)
55
  (* Returns a list of bool values, indicating whether the indices must be static or not *)
58 56
  let rec static_loop_profile v =
59 57
    match v.value_desc with
60 58
    | Cst cst  -> static_loop_profile_cst cst
61 59
    | Var _  -> []
62
    | Fun (_, vl) -> List.fold_right (fun v lp -> merge_static_loop_profiles lp (static_loop_profile v)) vl []
63
    | Array vl    -> true :: List.fold_right (fun v lp -> merge_static_loop_profiles lp (static_loop_profile v)) vl []
64
    | Access (v, _) -> (match (static_loop_profile v) with [] -> [] | _ :: q -> q)
65
    | Power (v, _)  -> false :: static_loop_profile v
60
    | Fun (_, vl) ->
61
      List.fold_right
62
        (fun v lp -> merge_static_loop_profiles lp (static_loop_profile v)) vl []
63
    | Array vl    ->
64
      true :: List.fold_right
65
        (fun v lp -> merge_static_loop_profiles lp (static_loop_profile v)) vl []
66
    | Access (v, _) ->
67
      begin match static_loop_profile v with [] -> [] | _ :: q -> q end
68
    | Power (v, _) -> false :: static_loop_profile v
66 69
  and static_loop_profile_cst cst =
67 70
    match cst with
68
      Const_array cl -> List.fold_right 
69
	(fun c lp -> merge_static_loop_profiles lp (static_loop_profile_cst c))
70
	cl 
71
	[]
71
      Const_array cl ->
72
      List.fold_right
73
        (fun c lp -> merge_static_loop_profiles lp (static_loop_profile_cst c))
74
        cl []
72 75
    | _ -> [] 
73
  
74
  
75
let rec is_const_index v =
76
  match v.value_desc with
77
  | Cst (Const_int _) -> true
78
  | Fun (_, vl)       -> List.for_all is_const_index vl
79
  | _                 -> false
80

  
81
type loop_index = LVar of ident | LInt of int ref | LAcc of value_t
76

  
77
  let rec is_const_index v =
78
    match v.value_desc with
79
    | Cst (Const_int _) -> true
80
    | Fun (_, vl)       -> List.for_all is_const_index vl
81
    | _                 -> false
82

  
83
  type loop_index = LVar of ident | LInt of int ref | LAcc of value_t
82 84
(*
83 85
let rec value_offsets v offsets =
84 86
 match v, offsets with
......
90 92
 | _                        , LInt r :: q -> value_offsets (Access (v, Cst (Const_int !r))) q
91 93
 | _                        , LVar i :: q -> value_offsets (Access (v, Var i)) q
92 94
*)
93
(* Computes the list of nested loop variables together with their dimension bounds.
94
   - LInt r stands for loop expansion (no loop variable, but int loop index)
95
   - LVar v stands for loop variable v
96
*)
97
let rec mk_loop_variables m ty depth =
98
 match (Types.repr ty).Types.tdesc, depth with
99
 | Types.Tarray (d, ty'), 0       ->
100
   let v = mk_loop_var m () in
101
   (d, LVar v) :: mk_loop_variables m ty' 0
102
 | Types.Tarray (d, ty'), _       ->
103
   let r = ref (-1) in
104
   (d, LInt r) :: mk_loop_variables m ty' (depth - 1)
105
 | _                    , 0       -> []
106
 | _                              -> assert false
107

  
108
let reorder_loop_variables loop_vars =
109
  let (int_loops, var_loops) = 
110
    List.partition (function (_, LInt _) -> true | _ -> false) loop_vars
111
  in
112
  var_loops @ int_loops
113

  
114
(* Prints a one loop variable suffix for arrays *)
115
let pp_loop_var _ pp_val fmt lv =
116
 match snd lv with
117
 | LVar v -> fprintf fmt "[%s]" v
118
 | LInt r -> fprintf fmt "[%d]" !r
119
 | LAcc i -> fprintf fmt "[%a]" pp_val i
120

  
121
(* Prints a suffix of loop variables for arrays *)
122
let pp_suffix m pp_val fmt loop_vars =
123
 Utils.fprintf_list ~sep:"" (pp_loop_var m pp_val) fmt loop_vars
124

  
125
(* Prints a value expression [v], with internal function calls only.
126
   [pp_var] is a printer for variables (typically [pp_c_var_read]),
127
   but an offset suffix may be added for array variables
128
*)
129
(* Prints a constant value before a suffix (needs casting) *)
130
let rec pp_c_const_suffix var_type fmt c =
131
  match c with
132
    | Const_int i          -> pp_print_int fmt i
133
    | Const_real r         -> Real.pp fmt r
134
    | Const_tag t          -> pp_c_tag fmt t
135
    | Const_array ca       -> let var_type = Types.array_element_type var_type in
136
                              fprintf fmt "(%a[]){%a }" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_c_const_suffix var_type)) ca
137
    | Const_struct fl       -> fprintf fmt "{%a }" (Utils.fprintf_list ~sep:", " (fun fmt (f, c) -> (pp_c_const_suffix (Types.struct_field_type var_type f)) fmt c)) fl
138
    | Const_string _
139
      | Const_modeid _ -> assert false (* string occurs in annotations not in C *)
95
  (* Computes the list of nested loop variables together with their dimension bounds.
96
     - LInt r stands for loop expansion (no loop variable, but int loop index)
97
     - LVar v stands for loop variable v
98
  *)
99
  let rec mk_loop_variables m ty depth =
100
    match (Types.repr ty).Types.tdesc, depth with
101
    | Types.Tarray (d, ty'), 0 ->
102
      let v = mk_loop_var m () in
103
      (d, LVar v) :: mk_loop_variables m ty' 0
104
    | Types.Tarray (d, ty'), _ ->
105
      let r = ref (-1) in
106
      (d, LInt r) :: mk_loop_variables m ty' (depth - 1)
107
    | _, 0 -> []
108
    | _ -> assert false
140 109

  
110
  let reorder_loop_variables loop_vars =
111
    let (int_loops, var_loops) =
112
      List.partition (function (_, LInt _) -> true | _ -> false) loop_vars
113
    in
114
    var_loops @ int_loops
115

  
116
  (* Prints a one loop variable suffix for arrays *)
117
  let pp_loop_var pp_val fmt lv =
118
    match snd lv with
119
    | LVar v -> fprintf fmt "[%s]" v
120
    | LInt r -> fprintf fmt "[%d]" !r
121
    | LAcc i -> fprintf fmt "[%a]" pp_val i
122

  
123
  (* Prints a suffix of loop variables for arrays *)
124
  let pp_suffix pp_val =
125
    pp_print_list ~pp_sep:pp_print_nothing (pp_loop_var pp_val)
126

  
127
  (* Prints a value expression [v], with internal function calls only.
128
     [pp_var] is a printer for variables (typically [pp_c_var_read]),
129
     but an offset suffix may be added for array variables
130
  *)
131
  (* Prints a constant value before a suffix (needs casting) *)
132
  let rec pp_c_const_suffix var_type fmt c =
133
    match c with
134
    | Const_int i ->
135
      pp_print_int fmt i
136
    | Const_real r ->
137
      Real.pp fmt r
138
    | Const_tag t ->
139
      pp_c_tag fmt t
140
    | Const_array ca ->
141
      let var_type = Types.array_element_type var_type in
142
      fprintf fmt "(%a[])%a"
143
        (pp_c_type "") var_type
144
        (pp_print_braced (pp_c_const_suffix var_type)) ca
145
    | Const_struct fl ->
146
      pp_print_braced
147
        (fun fmt (f, c) ->
148
           (pp_c_const_suffix (Types.struct_field_type var_type f)) fmt c)
149
        fmt fl
150
    | Const_string _
151
    | Const_modeid _ -> assert false (* string occurs in annotations not in C *)
141 152

  
142
(* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *)
143
let rec pp_value_suffix m self var_type loop_vars pp_var fmt value =
144
  (*Format.eprintf "pp_value_suffix: %a %a %a@." Types.print_ty var_type Machine_code.pp_val value pp_suffix loop_vars;*)
145
  let pp_suffix = pp_suffix m (pp_value_suffix m self var_type [] pp_var) in
146
  (
153
  (* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *)
154
  let rec pp_value_suffix m self var_type loop_vars pp_var fmt value =
155
    (*eprintf "pp_value_suffix: %a %a %a@." Types.print_ty var_type Machine_code.pp_val value pp_suffix loop_vars;*)
156
    let pp_suffix = pp_suffix (pp_value_suffix m self var_type [] pp_var) in
147 157
    match loop_vars, value.value_desc with
148 158
    | (x, LAcc i) :: q, _ when is_const_index i ->
149
       let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in
150
       pp_value_suffix m self var_type ((x, LInt r)::q) pp_var fmt value
159
      let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in
160
      pp_value_suffix m self var_type ((x, LInt r)::q) pp_var fmt value
151 161
    | (_, LInt r) :: q, Cst (Const_array cl) ->
152
       let var_type = Types.array_element_type var_type in
153
       pp_value_suffix m self var_type q pp_var fmt (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
154
    | (_, LInt r) :: q, Array vl      ->
155
       let var_type = Types.array_element_type var_type in
156
       pp_value_suffix m self var_type q pp_var fmt (List.nth vl !r)
157
    | loop_var    :: q, Array vl      ->
158
       let var_type = Types.array_element_type var_type in
159
       Format.fprintf fmt "(%a[]){%a }%a" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type q pp_var)) vl pp_suffix [loop_var]
160
    | []              , Array vl      ->
161
       let var_type = Types.array_element_type var_type in
162
       Format.fprintf fmt "(%a[]){%a }" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type [] pp_var)) vl
163
    | _           :: q, Power (v, _)  ->
164
       pp_value_suffix m self var_type q pp_var fmt v
165
    | _               , Fun (n, vl)   ->
166
       pp_basic_lib_fun (Types.is_int_type value.value_type) n (pp_value_suffix m self var_type loop_vars pp_var) fmt vl
167
    | _               , Access (v, i) ->
168
       let var_type = Type_predef.type_array (Dimension.mkdim_var ()) var_type in
169
       pp_value_suffix m self var_type ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_var fmt v
170
    | _               , Var v    ->
171
       if is_memory m v then (
172
         (* array memory vars are represented by an indirection to a local var with the right type,
173
	    in order to avoid casting everywhere. *)
174
         if Types.is_array_type v.var_type
175
         then Format.fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
176
         else Format.fprintf fmt "%s->_reg.%a%a" self pp_var v pp_suffix loop_vars
177
       )
178
       else (
179
         Format.fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
180
       )
181
    | _               , Cst cst       -> pp_c_const_suffix var_type fmt cst
182
    | _               , _             -> (Format.eprintf "internal error: C_backend_src.pp_value_suffix %a %a %a@." Types.print_ty var_type (pp_val m) value pp_suffix loop_vars; assert false)
183
  )
184
   
185
(* Subsumes C_backend_common.pp_c_val to cope with aggressive substitution
186
   which may yield constant arrays in expressions.
187
   Type is needed to correctly print constant arrays.
188
 *)
189
let pp_c_val m self pp_var fmt v =
190
  pp_value_suffix m self v.value_type [] pp_var fmt v
191

  
192
let pp_basic_assign pp_var fmt typ var_name value =
193
  if Types.is_real_type typ && !Options.mpfr
194
  then
195
    Mpfr.pp_inject_assign pp_var fmt var_name value
196
  else
197
    fprintf fmt "%a = %a;" 
198
      pp_var var_name
199
      pp_var value
200

  
201
(* type_directed assignment: array vs. statically sized type
202
   - [var_type]: type of variable to be assigned
203
   - [var_name]: name of variable to be assigned
204
   - [value]: assigned value
205
   - [pp_var]: printer for variables
206
*)
207
let pp_assign m self pp_var fmt var_type var_name value =
208
  let depth = expansion_depth value in
209
  (*Format.eprintf "pp_assign %a %a %a %d@." Types.print_ty var_type pp_val var_name pp_val value depth;*)
210
  let loop_vars = mk_loop_variables m var_type depth in
211
  let reordered_loop_vars = reorder_loop_variables loop_vars in
212
  let rec aux typ fmt vars =
213
    match vars with
214
    | [] ->
215
       pp_basic_assign (pp_value_suffix m self var_type loop_vars pp_var) fmt typ var_name value
216
    | (d, LVar i) :: q ->
217
       let typ' = Types.array_element_type typ in
218
      (*eprintf "pp_aux %a %s@." Dimension.pp_dimension d i;*)
219
      fprintf fmt "@[<v 2>{@,int %s;@,for(%s=0;%s<%a;%s++)@,%a @]@,}"
220
	i i i pp_c_dimension d i
221
	(aux typ') q
222
    | (d, LInt r) :: q ->
223
       (*eprintf "pp_aux %a %d@." Dimension.pp_dimension d (!r);*)
224
       let typ' = Types.array_element_type typ in
225
       let szl = Utils.enumerate (Dimension.size_const_dimension d) in
226
       fprintf fmt "@[<v 2>{@,%a@]@,}"
227
	       (Utils.fprintf_list ~sep:"@," (fun fmt i -> r := i; aux typ' fmt q)) szl
228
    | _ -> assert false
229
  in
230
  begin
162
      let var_type = Types.array_element_type var_type in
163
      pp_value_suffix m self var_type q pp_var fmt
164
        (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
165
    | (_, LInt r) :: q, Array vl ->
166
      let var_type = Types.array_element_type var_type in
167
      pp_value_suffix m self var_type q pp_var fmt (List.nth vl !r)
168
    | loop_var :: q, Array vl      ->
169
      let var_type = Types.array_element_type var_type in
170
      fprintf fmt "(%a[])%a%a"
171
        (pp_c_type "") var_type
172
        (pp_print_braced (pp_value_suffix m self var_type q pp_var)) vl
173
        pp_suffix [loop_var]
174
    | [], Array vl      ->
175
      let var_type = Types.array_element_type var_type in
176
      fprintf fmt "(%a[])%a"
177
        (pp_c_type "") var_type
178
        (pp_print_braced (pp_value_suffix m self var_type [] pp_var)) vl
179
    | _ :: q, Power (v, _)  ->
180
      pp_value_suffix m self var_type q pp_var fmt v
181
    | _, Fun (n, vl)   ->
182
      pp_basic_lib_fun (Types.is_int_type value.value_type) n
183
        (pp_value_suffix m self var_type loop_vars pp_var) fmt vl
184
    | _, Access (v, i) ->
185
      let var_type = Type_predef.type_array (Dimension.mkdim_var ()) var_type in
186
      pp_value_suffix m self var_type
187
        ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_var fmt v
188
    | _, Var v ->
189
      if is_memory m v then
190
        (* array memory vars are represented by an indirection to a local var with the right type,
191
           in order to avoid casting everywhere. *)
192
        if Types.is_array_type v.var_type
193
        then fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
194
        else fprintf fmt "%s->_reg.%a%a" self pp_var v pp_suffix loop_vars
195
      else
196
        fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
197
    | _, Cst cst ->
198
      pp_c_const_suffix var_type fmt cst
199
    | _, _ ->
200
      eprintf "internal error: C_backend_src.pp_value_suffix %a %a %a@."
201
        Types.print_ty var_type (pp_val m) value pp_suffix loop_vars;
202
      assert false
203

  
204
  (* Subsumes C_backend_common.pp_c_val to cope with aggressive substitution
205
     which may yield constant arrays in expressions.
206
     Type is needed to correctly print constant arrays.
207
  *)
208
  let pp_c_val m self pp_var fmt v =
209
    pp_value_suffix m self v.value_type [] pp_var fmt v
210

  
211
  let pp_basic_assign pp_var fmt typ var_name value =
212
    if Types.is_real_type typ && !Options.mpfr
213
    then
214
      Mpfr.pp_inject_assign pp_var fmt (var_name, value)
215
    else
216
      fprintf fmt "%a = %a;"
217
        pp_var var_name
218
        pp_var value
219

  
220
  (* type_directed assignment: array vs. statically sized type
221
     - [var_type]: type of variable to be assigned
222
     - [var_name]: name of variable to be assigned
223
     - [value]: assigned value
224
     - [pp_var]: printer for variables
225
  *)
226
  let pp_assign m self pp_var fmt var_type var_name value =
227
    let depth = expansion_depth value in
228
    (*eprintf "pp_assign %a %a %a %d@." Types.print_ty var_type pp_val var_name pp_val value depth;*)
229
    let loop_vars = mk_loop_variables m var_type depth in
230
    let reordered_loop_vars = reorder_loop_variables loop_vars in
231
    let rec aux typ fmt vars =
232
      match vars with
233
      | [] ->
234
        pp_basic_assign (pp_value_suffix m self var_type loop_vars pp_var)
235
          fmt typ var_name value
236
      | (d, LVar i) :: q ->
237
        let typ' = Types.array_element_type typ in
238
        (*eprintf "pp_aux %a %s@." Dimension.pp_dimension d i;*)
239
        fprintf fmt "@[<v 2>{@,int %s;@,for(%s=0;%s<%a;%s++)@,%a @]@,}"
240
          i i i pp_c_dimension d i
241
          (aux typ') q
242
      | (d, LInt r) :: q ->
243
        (*eprintf "pp_aux %a %d@." Dimension.pp_dimension d (!r);*)
244
        let typ' = Types.array_element_type typ in
245
        let szl = Utils.enumerate (Dimension.size_const_dimension d) in
246
        fprintf fmt "@[<v 2>{@,%a@]@,}"
247
          (pp_print_list (fun fmt i -> r := i; aux typ' fmt q)) szl
248
      | _ -> assert false
249
    in
250
    begin
251
      reset_loop_counter ();
252
      (*reset_addr_counter ();*)
253
      aux var_type fmt reordered_loop_vars;
254
      (*eprintf "end pp_assign@.";*)
255
    end
256

  
257
  let pp_machine_ pp_machine_name fn_name m self fmt inst =
258
    let (node, static) = try List.assoc inst m.minstances with Not_found ->
259
      eprintf "internal error: %s %s %s %s:@." fn_name m.mname.node_id self inst;
260
      raise Not_found
261
    in
262
    fprintf fmt "%a(%a%s->%s);"
263
      pp_machine_name (node_name node)
264
      (pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma
265
         Dimension.pp_dimension) static
266
      self inst
267

  
268
  let pp_machine_reset =
269
    pp_machine_ pp_machine_reset_name "pp_machine_reset"
270

  
271
  let pp_machine_init =
272
    pp_machine_ pp_machine_init_name "pp_machine_init"
273

  
274
  let pp_machine_clear =
275
    pp_machine_ pp_machine_clear_name "pp_machine_clear"
276

  
277
  let has_c_prototype funname dependencies =
278
    (* We select the last imported node with the name funname.
279
       The order of evaluation of dependencies should be
280
       compatible with overloading. (Not checked yet) *)
281
    let imported_node_opt =
282
      List.fold_left
283
        (fun res dep ->
284
           match res with
285
           | Some _ -> res
286
           | None ->
287
             let decls = dep.content in
288
             let matched = fun t -> match t.top_decl_desc with
289
               | ImportedNode nd -> nd.nodei_id = funname
290
               | _ -> false
291
             in
292
             if List.exists matched decls then
293
               match (List.find matched decls).top_decl_desc with
294
               | ImportedNode nd -> Some nd
295
               | _ -> assert false
296
             else
297
               None) None dependencies in
298
    match imported_node_opt with
299
    | None -> false
300
    | Some nd -> (match nd.nodei_prototype with Some "C" -> true | _ -> false)
301

  
302
  let pp_call m self pp_read pp_write fmt i
303
      (inputs: Machine_code_types.value_t list) (outputs: var_decl list) =
304
    try (* stateful node instance *)
305
      let n, _ = List.assoc i m.minstances in
306
      fprintf fmt "%a (%a%a%s->%s);"
307
        pp_machine_step_name (node_name n)
308
        (pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma
309
           (pp_c_val m self pp_read)) inputs
310
        (pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma
311
           pp_write) outputs
312
        self
313
        i
314
    with Not_found -> (* stateless node instance *)
315
      let n, _ = List.assoc i m.mcalls in
316
      fprintf fmt "%a (%a%a);"
317
        pp_machine_step_name (node_name n)
318
        (pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma
319
           (pp_c_val m self pp_read)) inputs
320
        (pp_print_list ~pp_sep:pp_print_comma pp_write) outputs
321

  
322
  let pp_basic_instance_call m self =
323
    pp_call m self (pp_c_var_read m) (pp_c_var_write m)
324

  
325
  let pp_instance_call m self fmt i (inputs: Machine_code_types.value_t list) (outputs: var_decl list) =
326
    let pp_offset pp_var indices fmt var =
327
      fprintf fmt "%a%a"
328
        pp_var var
329
        (pp_print_list ~pp_sep:pp_print_nothing (fun fmt -> fprintf fmt "[%s]"))
330
        indices
331
    in
332
    let rec aux indices fmt typ =
333
      if Types.is_array_type typ
334
      then
335
        let dim = Types.array_type_dimension typ in
336
        let idx = mk_loop_var m () in
337
        fprintf fmt "@[<v 2>{@,int %s;@,for(%s=0;%s<%a;%s++)@,%a @]@,}"
338
          idx idx idx pp_c_dimension dim idx
339
          (aux (idx::indices)) (Types.array_element_type typ)
340
      else
341
        let pp_read  = pp_offset (pp_c_var_read  m) indices in
342
        let pp_write = pp_offset (pp_c_var_write m) indices in
343
        pp_call m self pp_read pp_write fmt i inputs outputs
344
    in
231 345
    reset_loop_counter ();
232
    (*reset_addr_counter ();*)
233
    aux var_type fmt reordered_loop_vars;
234
    (*Format.eprintf "end pp_assign@.";*)
235
  end
236

  
237
let pp_machine_reset (m: machine_t) self fmt inst =
238
  let (node, static) =
239
    try
240
      List.assoc inst m.minstances
241
    with Not_found -> (Format.eprintf "internal error: pp_machine_reset %s %s %s:@." m.mname.node_id self inst; raise Not_found) in
242
  fprintf fmt "%a(%a%t%s->%s);"
243
    pp_machine_reset_name (node_name node)
244
    (Utils.fprintf_list ~sep:", " Dimension.pp_dimension) static
245
    (Utils.pp_final_char_if_non_empty ", " static)
246
    self inst
247

  
248
let pp_machine_init (m: machine_t) self fmt inst =
249
  let (node, static) =
250
    try
251
      List.assoc inst m.minstances
252
    with Not_found -> (Format.eprintf "internal error: pp_machine_init %s %s %s@." m.mname.node_id self inst; raise Not_found) in
253
  fprintf fmt "%a(%a%t%s->%s);"
254
    pp_machine_init_name (node_name node)
255
    (Utils.fprintf_list ~sep:", " Dimension.pp_dimension) static
256
    (Utils.pp_final_char_if_non_empty ", " static)
257
    self inst
258

  
259
let pp_machine_clear (m: machine_t) self fmt inst =
260
  let (node, static) =
261
    try
262
      List.assoc inst m.minstances
263
    with Not_found -> (Format.eprintf "internal error: pp_machine_clear %s %s %s@." m.mname.node_id self inst; raise Not_found) in
264
  fprintf fmt "%a(%a%t%s->%s);"
265
    pp_machine_clear_name (node_name node)
266
    (Utils.fprintf_list ~sep:", " Dimension.pp_dimension) static
267
    (Utils.pp_final_char_if_non_empty ", " static)
268
    self inst
269

  
270
let has_c_prototype funname dependencies =
271
  let imported_node_opt = (* We select the last imported node with the name funname.
272
			       The order of evaluation of dependencies should be
273
			       compatible with overloading. (Not checked yet) *) 
274
    List.fold_left
275
      (fun res dep -> 
276
	match res with
277
	| Some _ -> res
278
	| None ->
279
           let decls = dep.content in
280
	   let matched = fun t -> match t.top_decl_desc with 
281
	                          | ImportedNode nd -> nd.nodei_id = funname 
282
	                          | _ -> false
283
	   in
284
	   if List.exists matched decls then (
285
	     match (List.find matched decls).top_decl_desc with
286
	     | ImportedNode nd -> Some nd
287
	     | _ -> assert false
288
	   )
289
	   else
290
	     None
291
      ) None dependencies in
292
  match imported_node_opt with
293
  | None -> false
294
  | Some nd -> (match nd.nodei_prototype with Some "C" -> true | _ -> false)
295
(*
296
let pp_instance_call dependencies m self fmt i (inputs: value_t list) (outputs: var_decl list) =
297
  try (* stateful node instance *)
298
    let (n,_) = List.assoc i m.minstances in
299
    let (input_types, _) = Typing.get_type_of_call n in
300
    let inputs = List.combine input_types inputs in
301
    fprintf fmt "%a (%a%t%a%t%s->%s);"
302
      pp_machine_step_name (node_name n)
303
      (Utils.fprintf_list ~sep:", " (pp_c_val self (pp_c_var_read m))) inputs
304
      (Utils.pp_final_char_if_non_empty ", " inputs) 
305
      (Utils.fprintf_list ~sep:", " (pp_c_var_write m)) outputs
306
      (Utils.pp_final_char_if_non_empty ", " outputs)
307
      self
308
      i
309
  with Not_found -> (* stateless node instance *)
310
    let (n,_) = List.assoc i m.mcalls in
311
    let (input_types, output_types) = Typing.get_type_of_call n in
312
    let inputs = List.combine input_types inputs in
313
    if has_c_prototype i dependencies
314
    then (* external C function *)
315
      let outputs = List.map2 (fun t v -> t, Var v) output_types outputs in
316
      fprintf fmt "%a = %s(%a);"
317
	(Utils.fprintf_list ~sep:", " (pp_c_val self (pp_c_var_read m))) outputs
318
	i
319
	(Utils.fprintf_list ~sep:", " (pp_c_val self (pp_c_var_read m))) inputs
346
    aux [] fmt (List.hd inputs).Machine_code_types.value_type
347

  
348
  let rec pp_conditional dependencies (m: machine_t) self fmt c tl el =
349
    fprintf fmt "@[<v 2>if (%a) {%a@]@,@[<v 2>} else {%a@]@,}"
350
      (pp_c_val m self (pp_c_var_read m)) c
351
      (pp_print_list ~pp_prologue:pp_print_cut
352
         (pp_machine_instr dependencies m self)) tl
353
      (pp_print_list ~pp_prologue:pp_print_cut
354
         (pp_machine_instr dependencies m self)) el
355

  
356
  and pp_machine_instr dependencies (m: machine_t) self fmt instr =
357
    match get_instr_desc instr with
358
    | MNoReset _ -> ()
359
    | MReset i ->
360
      pp_machine_reset m self fmt i
361
    | MLocalAssign (i,v) ->
362
      pp_assign
363
        m self (pp_c_var_read m) fmt
364
        i.var_type (mk_val (Var i) i.var_type) v
365
    | MStateAssign (i,v) ->
366
      pp_assign
367
        m self (pp_c_var_read m) fmt
368
        i.var_type (mk_val (Var i) i.var_type) v
369
    | MStep ([i0], i, vl) when Basic_library.is_value_internal_fun (mk_val (Fun (i, vl)) i0.var_type)  ->
370
      pp_machine_instr dependencies m self fmt
371
        (update_instr_desc instr (MLocalAssign (i0, mk_val (Fun (i, vl)) i0.var_type)))
372
    | MStep (il, i, vl) when !Options.mpfr && Mpfr.is_homomorphic_fun i ->
373
      pp_instance_call m self fmt i vl il
374
    | MStep ([i0], i, vl) when has_c_prototype i dependencies ->
375
      fprintf fmt "%a = %s%a;"
376
        (pp_c_val m self (pp_c_var_read m)) (mk_val (Var i0) i0.var_type)
377
        i
378
        (pp_print_parenthesized (pp_c_val m self (pp_c_var_read m))) vl
379
    | MStep (il, i, vl) ->
380
      pp_basic_instance_call m self fmt i vl il
381
    | MBranch (_, []) ->
382
      eprintf "internal error: C_backend_src.pp_machine_instr %a@."
383
        (pp_instr m) instr;
384
      assert false
385
    | MBranch (g, hl) ->
386
      if let t = fst (List.hd hl) in t = tag_true || t = tag_false
387
      then (* boolean case, needs special treatment in C because truth value is not unique *)
388
        (* may disappear if we optimize code by replacing last branch test with default *)
389
        let tl = try List.assoc tag_true  hl with Not_found -> [] in
390
        let el = try List.assoc tag_false hl with Not_found -> [] in
391
        pp_conditional dependencies m self fmt g tl el
392
      else (* enum type case *)
393
        (*let g_typ = Typing.type_const Location.dummy_loc (Const_tag (fst (List.hd hl))) in*)
394
        fprintf fmt "@[<v 2>switch(%a) {@,%a@,}@]"
395
          (pp_c_val m self (pp_c_var_read m)) g
396
          (pp_print_list ~pp_open_box:pp_open_vbox0
397
             (pp_machine_branch dependencies m self)) hl
398
    | MSpec s ->
399
      fprintf fmt "@[/*@@ %s */@]@ " s
400
    | MComment s  ->
401
      fprintf fmt "/*%s*/@ " s
402

  
403
  and pp_machine_branch dependencies m self fmt (t, h) =
404
    fprintf fmt "@[<v 2>case %a:@,%a@,break;@]"
405
      pp_c_tag t
406
      (pp_print_list ~pp_open_box:pp_open_vbox0
407
         (pp_machine_instr dependencies m self)) h
408

  
409

  
410
  (********************************************************************************************)
411
  (*                         C file Printing functions                                        *)
412
  (********************************************************************************************)
413

  
414
  let print_const_def fmt tdecl =
415
    let cdecl = const_of_top tdecl in
416
    if !Options.mpfr && Types.(is_real_type (array_base_type cdecl.const_type))
417
    then
418
      fprintf fmt "%a;"
419
        (pp_c_type cdecl.const_id) (Types.dynamic_type cdecl.const_type)
320 420
    else
321
      fprintf fmt "%a (%a%t%a);"
322
	pp_machine_step_name (node_name n)
323
	(Utils.fprintf_list ~sep:", " (pp_c_val self (pp_c_var_read m))) inputs
324
	(Utils.pp_final_char_if_non_empty ", " inputs) 
325
	(Utils.fprintf_list ~sep:", " (pp_c_var_write m)) outputs 
326
*)
327
let rec pp_conditional dependencies (m: machine_t) self fmt c tl el =
328
  fprintf fmt "@[<v 2>if (%a) {%t%a@]@,@[<v 2>} else {%t%a@]@,}"
329
    (pp_c_val m self (pp_c_var_read m)) c
330
    (Utils.pp_newline_if_non_empty tl)
331
    (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) tl
332
    (Utils.pp_newline_if_non_empty el)
333
    (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) el
334

  
335
and pp_machine_instr dependencies (m: machine_t) self fmt instr =
336
  match get_instr_desc instr with 
337
  | MNoReset _ -> ()
338
  | MReset i ->
339
    pp_machine_reset m self fmt i
340
  | MLocalAssign (i,v) ->
341
    pp_assign
342
      m self (pp_c_var_read m) fmt
343
      i.var_type (mk_val (Var i) i.var_type) v
344
  | MStateAssign (i,v) ->
345
    pp_assign
346
      m self (pp_c_var_read m) fmt
347
      i.var_type (mk_val (Var i) i.var_type) v
348
  | MStep ([i0], i, vl) when Basic_library.is_value_internal_fun (mk_val (Fun (i, vl)) i0.var_type)  ->
349
    pp_machine_instr dependencies m self fmt 
350
      (update_instr_desc instr (MLocalAssign (i0, mk_val (Fun (i, vl)) i0.var_type)))
351
  | MStep (il, i, vl) when !Options.mpfr && Mpfr.is_homomorphic_fun i ->
352
     pp_instance_call m self fmt i vl il
353
  | MStep ([i0], i, vl) when has_c_prototype i dependencies -> 
354
    fprintf fmt "%a = %s(%a);" 
355
      (pp_c_val m self (pp_c_var_read m)) (mk_val (Var i0) i0.var_type)
421
      fprintf fmt "%a = %a;"
422
        (pp_c_type cdecl.const_id) cdecl.const_type
423
        pp_c_const cdecl.const_value
424

  
425
  let print_alloc_instance fmt (i, (m, static)) =
426
    fprintf fmt "_alloc->%s = %a %a;"
356 427
      i
357
      (Utils.fprintf_list ~sep:", " (pp_c_val m self (pp_c_var_read m))) vl
358
  | MStep (il, i, vl) ->
359
    pp_basic_instance_call m self fmt i vl il
360
  | MBranch (_, []) -> (Format.eprintf "internal error: C_backend_src.pp_machine_instr %a@." (pp_instr m) instr; assert false)
361
  | MBranch (g, hl) ->
362
    if let t = fst (List.hd hl) in t = tag_true || t = tag_false
363
    then (* boolean case, needs special treatment in C because truth value is not unique *)
364
	 (* may disappear if we optimize code by replacing last branch test with default *)
365
      let tl = try List.assoc tag_true  hl with Not_found -> [] in
366
      let el = try List.assoc tag_false hl with Not_found -> [] in
367
      pp_conditional dependencies m self fmt g tl el
368
    else (* enum type case *)
369
      (*let g_typ = Typing.type_const Location.dummy_loc (Const_tag (fst (List.hd hl))) in*)
370
      fprintf fmt "@[<v 2>switch(%a) {@,%a@,}@]"
371
	(pp_c_val m self (pp_c_var_read m)) g
372
	(Utils.fprintf_list ~sep:"@," (pp_machine_branch dependencies m self)) hl
373
  | MSpec s -> fprintf fmt "@[/*@@ %s */@]@ " s
374
  | MComment s  -> 
375
      fprintf fmt "/*%s*/@ " s
428
      pp_machine_alloc_name (node_name m)
429
      (pp_print_parenthesized Dimension.pp_dimension) static
376 430

  
431
  let print_dealloc_instance fmt (i, (m, _)) =
432
    fprintf fmt "%a (_alloc->%s);"
433
      pp_machine_dealloc_name (node_name m)
434
      i
377 435

  
378
and pp_machine_branch dependencies m self fmt (t, h) =
379
  fprintf fmt "@[<v 2>case %a:@,%a@,break;@]"
380
    pp_c_tag t
381
    (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) h
382

  
383

  
384
(********************************************************************************************)
385
(*                         C file Printing functions                                        *)
386
(********************************************************************************************)
387

  
388
let print_const_def fmt cdecl =
389
  if !Options.mpfr && Types.is_real_type (Types.array_base_type cdecl.const_type)
390
  then
391
    fprintf fmt "%a;@." 
392
      (pp_c_type cdecl.const_id) (Types.dynamic_type cdecl.const_type) 
393
  else
394
    fprintf fmt "%a = %a;@." 
395
      (pp_c_type cdecl.const_id) cdecl.const_type
396
      pp_c_const cdecl.const_value 
397

  
398

  
399
let print_alloc_instance fmt (i, (m, static)) =
400
  fprintf fmt "_alloc->%s = %a (%a);@,"
401
    i
402
    pp_machine_alloc_name (node_name m)
403
    (Utils.fprintf_list ~sep:", " Dimension.pp_dimension) static
404

  
405
let print_dealloc_instance fmt (i, (m, _)) =
406
  fprintf fmt "%a (_alloc->%s);@,"
407
    pp_machine_dealloc_name (node_name m)
408
    i
409

  
410
let print_alloc_const fmt m =
411
  let const_locals = List.filter (fun vdecl -> vdecl.var_dec_const) m.mstep.step_locals in
412
  fprintf fmt "%a%t"
413
    (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) const_locals
414
    (Utils.pp_final_char_if_non_empty ";@," const_locals)
415

  
416
let print_alloc_array fmt vdecl =
417
  let base_type = Types.array_base_type vdecl.var_type in
418
  let size_types = Types.array_type_multi_dimension vdecl.var_type in
419
  let size_type = Dimension.multi_dimension_product vdecl.var_loc size_types in
420
  fprintf fmt "_alloc->_reg.%s = (%a*) malloc((%a)*sizeof(%a));@,assert(_alloc->%s);@,"
421
    vdecl.var_id
422
    (pp_c_type "") base_type
423
    Dimension.pp_dimension size_type
424
    (pp_c_type "") base_type
425
    vdecl.var_id
426

  
427
let print_dealloc_array fmt vdecl =
428
  fprintf fmt "free (_alloc->_reg.%s);@,"
429
    vdecl.var_id
430

  
431
let print_alloc_code fmt m =
432
  let array_mem = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
433
  fprintf fmt "%a *_alloc;@,_alloc = (%a *) malloc(sizeof(%a));@,assert(_alloc);@,%a%areturn _alloc;"
434
    pp_machine_memtype_name m.mname.node_id
435
    pp_machine_memtype_name m.mname.node_id
436
    pp_machine_memtype_name m.mname.node_id
437
    (Utils.fprintf_list ~sep:"" print_alloc_array) array_mem
438
    (Utils.fprintf_list ~sep:"" print_alloc_instance) m.minstances
439

  
440
let print_dealloc_code fmt m =
441
  let array_mem = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
442
  fprintf fmt "%a%afree (_alloc);@,return;"
443
    (Utils.fprintf_list ~sep:"" print_dealloc_array) array_mem
444
    (Utils.fprintf_list ~sep:"" print_dealloc_instance) m.minstances
445

  
446
(* let print_stateless_init_code fmt m self =
447
 *   let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
448
 *   let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
449
 *   fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
450
 *     (print_init_prototype self) (m.mname.node_id, m.mstatic)
451
 *     (\* array mems *\)
452
 *     (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
453
 *     (Utils.pp_final_char_if_non_empty ";@," array_mems)
454
 *     (\* memory initialization *\)
455
 *     (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mmemory
456
 *     (Utils.pp_newline_if_non_empty m.mmemory)
457
 *     (\* sub-machines initialization *\)
458
 *     (Utils.fprintf_list ~sep:"@," (pp_machine_init m self)) minit
459
 *     (Utils.pp_newline_if_non_empty m.minit)
460
 *
461
 * let print_stateless_clear_code fmt m self =
462
 *   let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
463
 *   let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
464
 *   fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
465
 *     (print_clear_prototype self) (m.mname.node_id, m.mstatic)
466
 *     (\* array mems *\)
467
 *     (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
468
 *     (Utils.pp_final_char_if_non_empty ";@," array_mems)
469
 *     (\* memory clear *\)
470
 *     (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mmemory
471
 *     (Utils.pp_newline_if_non_empty m.mmemory)
472
 *     (\* sub-machines clear*\)
473
 *     (Utils.fprintf_list ~sep:"@," (pp_machine_clear m self)) minit
474
 *     (Utils.pp_newline_if_non_empty m.minit) *)
475

  
476
let print_stateless_code dependencies fmt m =
477
  let self = "__ERROR__" in
478
  if not (!Options.ansi && is_generic_node { top_decl_desc = Node m.mname; top_decl_loc = Location.dummy_loc; top_decl_owner = ""; top_decl_itf = false })
479
  then
480
    (* C99 code *)
481
    fprintf fmt "@[<v 2>%a {@,%a%t%a%t@,%a%a%t%a%t%t@]@,}@.@."
482
      print_stateless_prototype (m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs)
483
      (* locals *)
484
      (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) m.mstep.step_locals
485
      (Utils.pp_final_char_if_non_empty ";@," m.mstep.step_locals)
486
      (* locals initialization *)
487
      (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mstep.step_locals
488
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
489
      (* check assertions *)
490
      (pp_c_checks self) m
491
      (* instrs *)
492
      (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) m.mstep.step_instrs
493
      (Utils.pp_newline_if_non_empty m.mstep.step_instrs)
494
      (* locals clear *)
495
      (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mstep.step_locals
496
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
497
      (fun fmt -> fprintf fmt "return;")
498
  else
499
    (* C90 code *)
500
    let (gen_locals, base_locals) = List.partition (fun v -> Types.is_generic_type v.var_type) m.mstep.step_locals in
501
    let gen_calls = List.map (fun e -> let (id, _, _) = call_of_expr e in mk_call_var_decl e.expr_loc id) m.mname.node_gencalls in
502
    fprintf fmt "@[<v 2>%a {@,%a%t%a%t@,%a%a%t%a%t%t@]@,}@.@."
503
      print_stateless_prototype (m.mname.node_id, (m.mstep.step_inputs@gen_locals@gen_calls), m.mstep.step_outputs)
504
      (* locals *)
505
      (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) base_locals
506
      (Utils.pp_final_char_if_non_empty ";" base_locals)
507
      (* locals initialization *)
508
      (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mstep.step_locals
509
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
510
      (* check assertions *)
511
      (pp_c_checks self) m
512
      (* instrs *)
513
      (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) m.mstep.step_instrs
514
      (Utils.pp_newline_if_non_empty m.mstep.step_instrs)
515
      (* locals clear *)
516
      (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mstep.step_locals
517
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
518
      (fun fmt -> fprintf fmt "return;")
519

  
520
let print_reset_code dependencies fmt m self =
521
  let const_locals = List.filter (fun vdecl -> vdecl.var_dec_const) m.mstep.step_locals in
522
  fprintf fmt "@[<v 2>%a {@,%a%t@,%a%treturn;@]@,}@.@."
523
    (print_reset_prototype self) (m.mname.node_id, m.mstatic)
524
    (* constant locals decl *)
525
    (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) const_locals
526
    (Utils.pp_final_char_if_non_empty ";" const_locals)
527
    (* instrs *)
528
    (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) m.minit
529
    (Utils.pp_newline_if_non_empty m.minit)
530

  
531
let print_init_code fmt m self =
532
  let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
533
  let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
534
  fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
535
    (print_init_prototype self) (m.mname.node_id, m.mstatic)
536
    (* array mems *) 
537
    (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
538
    (Utils.pp_final_char_if_non_empty ";@," array_mems)
539
    (* memory initialization *)
540
    (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mmemory
541
    (Utils.pp_newline_if_non_empty m.mmemory)
542
    (* sub-machines initialization *)
543
    (Utils.fprintf_list ~sep:"@," (pp_machine_init m self)) minit
544
    (Utils.pp_newline_if_non_empty m.minit)
545

  
546
let print_clear_code fmt m self =
547
  let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
548
  let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
549
  fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
550
    (print_clear_prototype self) (m.mname.node_id, m.mstatic)
551
    (* array mems *)
552
    (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
553
    (Utils.pp_final_char_if_non_empty ";@," array_mems)
554
    (* memory clear *)
555
    (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mmemory
556
    (Utils.pp_newline_if_non_empty m.mmemory)
557
    (* sub-machines clear*)
558
    (Utils.fprintf_list ~sep:"@," (pp_machine_clear m self)) minit
559
    (Utils.pp_newline_if_non_empty m.minit)
560

  
561
let print_step_code dependencies fmt m self =
562
  if not (!Options.ansi && is_generic_node { top_decl_desc = Node m.mname; top_decl_loc = Location.dummy_loc; top_decl_owner = ""; top_decl_itf = false })
563
  then
564
    (* C99 code *)
565
    let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
566
    fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%t@,%a%a%t%a%t%t@]@,}@.@."
567
      (print_step_prototype self) (m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs)
436
  let const_locals m =
437
    List.filter (fun vdecl -> vdecl.var_dec_const) m.mstep.step_locals
438

  
439
  let pp_c_decl_array_mem self fmt id =
440
    fprintf fmt "%a = (%a) (%s->_reg.%s)"
441
      (pp_c_type (sprintf "(*%s)" id.var_id)) id.var_type
442
      (pp_c_type "(*)") id.var_type
443
      self
444
      id.var_id
445

  
446
  let print_alloc_const fmt m =
447
    pp_print_list
448
      ~pp_sep:(pp_print_endcut ";") ~pp_eol:(pp_print_endcut ";")
449
      (pp_c_decl_local_var m) fmt (const_locals m)
450

  
451
  let print_alloc_array fmt vdecl =
452
    let base_type = Types.array_base_type vdecl.var_type in
453
    let size_types = Types.array_type_multi_dimension vdecl.var_type in
454
    let size_type = Dimension.multi_dimension_product vdecl.var_loc size_types in
455
    fprintf fmt
456
      "_alloc->_reg.%s = (%a*) malloc((%a)*sizeof(%a));@,\
457
       assert(_alloc->%s);"
458
      vdecl.var_id
459
      (pp_c_type "") base_type
460
      Dimension.pp_dimension size_type
461
      (pp_c_type "") base_type
462
      vdecl.var_id
463

  
464
  let print_dealloc_array fmt vdecl =
465
    fprintf fmt "free (_alloc->_reg.%s);"
466
      vdecl.var_id
467

  
468
  let array_mems m =
469
    List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory
470

  
471
  let print_alloc_code fmt m =
472
    fprintf fmt
473
      "%a *_alloc;@,\
474
       _alloc = (%a *) malloc(sizeof(%a));@,\
475
       assert(_alloc);@,\
476
       %a%areturn _alloc;"
477
      pp_machine_memtype_name m.mname.node_id
478
      pp_machine_memtype_name m.mname.node_id
479
      pp_machine_memtype_name m.mname.node_id
480
      (pp_print_list ~pp_sep:pp_print_nothing print_alloc_array) (array_mems m)
481
      (pp_print_list ~pp_sep:pp_print_nothing print_alloc_instance) m.minstances
482

  
483
  let print_dealloc_code fmt m =
484
    fprintf fmt
485
      "%a%afree (_alloc);@,\
486
       return;"
487
      (pp_print_list ~pp_sep:pp_print_nothing print_dealloc_array) (array_mems m)
488
      (pp_print_list ~pp_sep:pp_print_nothing print_dealloc_instance) m.minstances
489

  
490
  (* let print_stateless_init_code fmt m self =
491
   *   let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
492
   *   let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
493
   *   fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
494
   *     (print_init_prototype self) (m.mname.node_id, m.mstatic)
495
   *     (\* array mems *\)
496
   *     (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
497
   *     (Utils.pp_final_char_if_non_empty ";@," array_mems)
498
   *     (\* memory initialization *\)
499
   *     (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mmemory
500
   *     (Utils.pp_newline_if_non_empty m.mmemory)
501
   *     (\* sub-machines initialization *\)
502
   *     (Utils.fprintf_list ~sep:"@," (pp_machine_init m self)) minit
503
   *     (Utils.pp_newline_if_non_empty m.minit)
504
   *
505
   * let print_stateless_clear_code fmt m self =
506
   *   let minit = List.map (fun i -> match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
507
   *   let array_mems = List.filter (fun v -> Types.is_array_type v.var_type) m.mmemory in
508
   *   fprintf fmt "@[<v 2>%a {@,%a%t%a%t%a%treturn;@]@,}@.@."
509
   *     (print_clear_prototype self) (m.mname.node_id, m.mstatic)
510
   *     (\* array mems *\)
511
   *     (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
512
   *     (Utils.pp_final_char_if_non_empty ";@," array_mems)
513
   *     (\* memory clear *\)
514
   *     (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mmemory
515
   *     (Utils.pp_newline_if_non_empty m.mmemory)
516
   *     (\* sub-machines clear*\)
517
   *     (Utils.fprintf_list ~sep:"@," (pp_machine_clear m self)) minit
518
   *     (Utils.pp_newline_if_non_empty m.minit) *)
519

  
520
  let pp_c_check m self fmt (loc, check) =
521
    fprintf fmt "@[<v>%a@,assert (%a);@]"
522
      Location.pp_c_loc loc
523
      (pp_c_val m self (pp_c_var_read m)) check
524

  
525
  let pp_print_function
526
      ~pp_prototype ~prototype
527
      ?(pp_local=pp_print_nothing) ?(base_locals=[])
528
      ?(pp_array_mem=pp_print_nothing) ?(array_mems=[])
529
      ?(pp_init_mpfr_local=pp_print_nothing)
530
      ?(pp_clear_mpfr_local=pp_print_nothing)
531
      ?(mpfr_locals=[])
532
      ?(pp_check=pp_print_nothing) ?(checks=[])
533
      ?(pp_extra=pp_print_nothing)
534
      ?(pp_instr=pp_print_nothing) ?(instrs=[])
535
      fmt =
536
    fprintf fmt
537
      "@[<v 2>%a {@,\
538
       %a%a\
539
       %a%a%a%a%areturn;@]@,\
540
       }"
541
      pp_prototype prototype
568 542
      (* locals *)
569
      (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) m.mstep.step_locals
570
      (Utils.pp_final_char_if_non_empty ";@," m.mstep.step_locals)
543
      (pp_print_list
544
         ~pp_open_box:pp_open_vbox0
545
         ~pp_sep:pp_print_semicolon
546
         ~pp_eol:pp_print_semicolon
547
         pp_local)
548
      base_locals
571 549
      (* array mems *)
572
      (Utils.fprintf_list ~sep:";@," (pp_c_decl_array_mem self)) array_mems
573
      (Utils.pp_final_char_if_non_empty ";@," array_mems)
574
      (* locals initialization *)
575
      (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mstep.step_locals
576
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
577
      (* check assertions *)
578
      (pp_c_checks self) m
579
      (* instrs *)
580
      (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) m.mstep.step_instrs
581
      (Utils.pp_newline_if_non_empty m.mstep.step_instrs)
582
      (* locals clear *)
583
      (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mstep.step_locals
584
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
585
      (fun fmt -> fprintf fmt "return;")
586
  else
587
    (* C90 code *)
588
    let (gen_locals, base_locals) = List.partition (fun v -> Types.is_generic_type v.var_type) m.mstep.step_locals in
589
    let gen_calls = List.map (fun e -> let (id, _, _) = call_of_expr e in mk_call_var_decl e.expr_loc id) m.mname.node_gencalls in
590
    fprintf fmt "@[<v 2>%a {@,%a%t%a%t@,%a%a%t%a%t%t@]@,}@.@."
591
      (print_step_prototype self) (m.mname.node_id, (m.mstep.step_inputs@gen_locals@gen_calls), m.mstep.step_outputs)
592
      (* locals *)
593
      (Utils.fprintf_list ~sep:";@," (pp_c_decl_local_var m)) base_locals
594
      (Utils.pp_final_char_if_non_empty ";" base_locals)
550
      (pp_print_list
551
         ~pp_open_box:pp_open_vbox0
552
         ~pp_sep:pp_print_semicolon
553
         ~pp_eol:pp_print_semicolon
554
         pp_array_mem)
555
      array_mems
595 556
      (* locals initialization *)
596
      (Utils.fprintf_list ~sep:"@," (pp_initialize m self (pp_c_var_read m))) m.mstep.step_locals
597
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
557
      (pp_print_list
558
         ~pp_epilogue:pp_print_cut
559
         pp_init_mpfr_local) (mpfr_vars mpfr_locals)
598 560
      (* check assertions *)
599
      (pp_c_checks self) m
561
      (pp_print_list pp_check) checks
600 562
      (* instrs *)
601
      (Utils.fprintf_list ~sep:"@," (pp_machine_instr dependencies m self)) m.mstep.step_instrs
602
      (Utils.pp_newline_if_non_empty m.mstep.step_instrs)
563
      (pp_print_list
564
         ~pp_open_box:pp_open_vbox0
565
         ~pp_epilogue:pp_print_cut
566
         pp_instr) instrs
603 567
      (* locals clear *)
604
      (Utils.fprintf_list ~sep:"@," (pp_clear m self (pp_c_var_read m))) m.mstep.step_locals
605
      (Utils.pp_newline_if_non_empty m.mstep.step_locals)
606
      (fun fmt -> fprintf fmt "return;")
607

  
608

  
609
(********************************************************************************************)
610
(*                     MAIN C file Printing functions                                       *)
611
(********************************************************************************************)
612

  
613
let print_global_init_code fmt basename prog dependencies =
614
  let baseNAME = file_to_module_name basename in
615
  let constants = List.map const_of_top (get_consts prog) in
616
  fprintf fmt "@[<v 2>%a {@,static %s init = 0;@,@[<v 2>if (!init) { @,init = 1;@,%a%t%a@]@,}@,return;@]@,}@.@."
617
    print_global_init_prototype baseNAME
618
    (pp_c_basic_type_desc Type_predef.type_bool)
619
    (* constants *) 
620
    (Utils.fprintf_list ~sep:"@," (pp_const_initialize empty_machine (pp_c_var_read empty_machine))) constants
621
    (Utils.pp_final_char_if_non_empty "@," dependencies)
622
    (* dependencies initialization *)
623
    (Utils.fprintf_list ~sep:"@," print_import_init) dependencies
624

  
625
let print_global_clear_code  fmt basename prog dependencies =
626
  let baseNAME = file_to_module_name basename in
627
  let constants = List.map const_of_top (get_consts prog) in
628
  fprintf fmt "@[<v 2>%a {@,static %s clear = 0;@,@[<v 2>if (!clear) { @,clear = 1;@,%a%t%a@]@,}@,return;@]@,}@.@."
629
    print_global_clear_prototype baseNAME
630
    (pp_c_basic_type_desc Type_predef.type_bool)
631
    (* constants *) 
632
    (Utils.fprintf_list ~sep:"@," (pp_const_clear (pp_c_var_read empty_machine))) constants
633
    (Utils.pp_final_char_if_non_empty "@," dependencies)
634
    (* dependencies initialization *)
635
    (Utils.fprintf_list ~sep:"@," print_import_clear) dependencies
636

  
637
(* TODO: ACSL 
638
- a contract machine shall not be directly printed in the C source
639
- but a regular machine associated to a contract machine shall integrate the associated statements, updating its memories, at the end of the function body.
640
- last one may print intermediate comment/acsl if/when they are present in the sequence of instruction
641
*)
642
let print_machine dependencies fmt m =
643
  if fst (get_stateless_status m) then
644
    begin
568
      (pp_print_list
569
         ~pp_epilogue:pp_print_cut
570
         pp_clear_mpfr_local) (mpfr_vars mpfr_locals)
571
      (* extra *)
572
      pp_extra ()
573

  
574
  let node_of_machine m = {
575
    top_decl_desc = Node m.mname;
576
    top_decl_loc = Location.dummy_loc;
577
    top_decl_owner = "";
578
    top_decl_itf = false
579
  }
580

  
581
  let print_stateless_code dependencies fmt m =
582
    let self = "__ERROR__" in
583
    if not (!Options.ansi && is_generic_node (node_of_machine m))
584
    then
585
      (* C99 code *)
586
      pp_print_function
587
        ~pp_prototype:print_stateless_prototype
588
        ~prototype:(m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs)
589
        ~pp_local:(pp_c_decl_local_var m)
590
        ~base_locals:m.mstep.step_locals
591
        ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m))
592
        ~pp_clear_mpfr_local:(pp_clear m self (pp_c_var_read m))
593
        ~mpfr_locals:m.mstep.step_locals
594
        ~pp_check:(pp_c_check m self)
595
        ~checks:m.mstep.step_checks
596
        ~pp_instr:(pp_machine_instr dependencies m self)
597
        ~instrs:m.mstep.step_instrs
598
        fmt
599
    else
600
      (* C90 code *)
601
      let gen_locals, base_locals = List.partition (fun v ->
602
          Types.is_generic_type v.var_type) m.mstep.step_locals in
603
      let gen_calls = List.map (fun e ->
604
          let (id, _, _) = call_of_expr e
605
          in mk_call_var_decl e.expr_loc id) m.mname.node_gencalls in
606
      pp_print_function
607
        ~pp_prototype:print_stateless_prototype
608
        ~prototype:(m.mname.node_id,
609
                    m.mstep.step_inputs @ gen_locals @ gen_calls,
610
                    m.mstep.step_outputs)
611
        ~pp_local:(pp_c_decl_local_var m)
612
        ~base_locals
613
        ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m))
614
        ~pp_clear_mpfr_local:(pp_clear m self (pp_c_var_read m))
615
        ~mpfr_locals:m.mstep.step_locals
616
        ~pp_check:(pp_c_check m self)
617
        ~checks:m.mstep.step_checks
618
        ~pp_instr:(pp_machine_instr dependencies m self)
619
        ~instrs:m.mstep.step_instrs
620
        fmt
621

  
622
  let print_reset_code dependencies self fmt m =
623
    pp_print_function
624
      ~pp_prototype:(print_reset_prototype self)
625
      ~prototype:(m.mname.node_id, m.mstatic)
626
      ~pp_local:(pp_c_decl_local_var m)
627
      ~base_locals:(const_locals m)
628
      ~pp_instr:(pp_machine_instr dependencies m self)
629
      ~instrs:m.minit
630
      fmt
631

  
632
  let print_init_code self fmt m =
633
    let minit = List.map (fun i ->
634
        match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
635
    pp_print_function
636
      ~pp_prototype:(print_init_prototype self)
637
      ~prototype:(m.mname.node_id, m.mstatic)
638
      ~pp_array_mem:(pp_c_decl_array_mem self)
639
      ~array_mems:(array_mems m)
640
      ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m))
641
      ~mpfr_locals:m.mmemory
642
      ~pp_extra:(fun fmt () ->
643
          pp_print_list
644
            ~pp_open_box:pp_open_vbox0
645
            ~pp_epilogue:pp_print_cut
646
            (pp_machine_init m self)
647
            fmt minit)
648
      fmt
649

  
650
  let print_clear_code self fmt m =
651
    let minit = List.map (fun i ->
652
        match get_instr_desc i with MReset i -> i | _ -> assert false) m.minit in
653
    pp_print_function
654
      ~pp_prototype:(print_clear_prototype self)
655
      ~prototype:(m.mname.node_id, m.mstatic)
656
      ~pp_array_mem:(pp_c_decl_array_mem self)
657
      ~array_mems:(array_mems m)
658
      ~pp_clear_mpfr_local:(pp_clear m self (pp_c_var_read m))
659
      ~mpfr_locals:m.mmemory
660
      ~pp_extra:(fun fmt () ->
661
          pp_print_list
662
            ~pp_open_box:pp_open_vbox0
663
            ~pp_epilogue:pp_print_cut
664
            (pp_machine_clear m self)
665
            fmt minit)
666
      fmt
667

  
668
  let print_step_code dependencies self fmt m =
669
    if not (!Options.ansi && is_generic_node (node_of_machine m))
670
    then
671
      (* C99 code *)
672
      pp_print_function
673
        ~pp_prototype:(print_step_prototype self)
674
        ~prototype:(m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs)
675
        ~pp_local:(pp_c_decl_local_var m)
676
        ~base_locals:m.mstep.step_locals
677
        ~pp_array_mem:(pp_c_decl_array_mem self)
678
        ~array_mems:(array_mems m)
679
        ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m))
680
        ~pp_clear_mpfr_local:(pp_clear m self (pp_c_var_read m))
681
        ~mpfr_locals:m.mstep.step_locals
682
        ~pp_check:(pp_c_check m self)
683
        ~checks:m.mstep.step_checks
684
        ~pp_instr:(pp_machine_instr dependencies m self)
685
        ~instrs:m.mstep.step_instrs
686
        fmt
687
    else
688
      (* C90 code *)
689
      let gen_locals, base_locals = List.partition (fun v ->
690
          Types.is_generic_type v.var_type) m.mstep.step_locals in
691
      let gen_calls = List.map (fun e ->
692
          let id, _, _ = call_of_expr e in
693
          mk_call_var_decl e.expr_loc id) m.mname.node_gencalls in
694
      pp_print_function
695
        ~pp_prototype:(print_step_prototype self)
696
        ~prototype:(m.mname.node_id,
697
                    m.mstep.step_inputs @ gen_locals @ gen_calls,
698
                    m.mstep.step_outputs)
699
        ~pp_local:(pp_c_decl_local_var m)
700
        ~base_locals
701
        ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m))
702
        ~pp_clear_mpfr_local:(pp_clear m self (pp_c_var_read m))
703
        ~mpfr_locals:m.mstep.step_locals
704
        ~pp_check:(pp_c_check m self)
705
        ~checks:m.mstep.step_checks
706
        ~pp_instr:(pp_machine_instr dependencies m self)
707
        ~instrs:m.mstep.step_instrs
708
        fmt
709

  
710
  (********************************************************************************************)
711
  (*                     MAIN C file Printing functions                                       *)
712
  (********************************************************************************************)
713

  
714
  let pp_const_initialize m pp_var fmt const =
715
    let var = Machine_code_common.mk_val
716
        (Var (Corelang.var_decl_of_const const)) const.const_type in
717
    let rec aux indices value fmt typ =
718
      if Types.is_array_type typ
719
      then
720
        let dim = Types.array_type_dimension typ in
721
        let szl = Utils.enumerate (Dimension.size_const_dimension dim) in
722
        let typ' = Types.array_element_type typ in
723
        let value = match value with
724
          | Const_array ca -> List.nth ca
725
          | _ -> assert false in
726
        pp_print_list
727
          (fun fmt i -> aux (string_of_int i :: indices) (value i) fmt typ') fmt szl
728
      else
729
        let indices = List.rev indices in
730
        let pp_var_suffix fmt var =
731
          fprintf fmt "%a%a" (pp_c_val m "" pp_var) var pp_array_suffix indices in
732
        fprintf fmt "%a@,%a"
733
          (Mpfr.pp_inject_init pp_var_suffix) var
734
          (Mpfr.pp_inject_real pp_var_suffix pp_c_const) (var, value)
735
    in
736
    reset_loop_counter ();
737
    aux [] const.const_value fmt const.const_type
738

  
739
  let pp_const_clear pp_var fmt const =
740
    let m = Machine_code_common.empty_machine in
741
    let var = Corelang.var_decl_of_const const in
742
    let rec aux indices fmt typ =
743
      if Types.is_array_type typ
744
      then
745
        let dim = Types.array_type_dimension typ in
746
        let idx = mk_loop_var m () in
747
        fprintf fmt "@[<v 2>{@,int %s;@,for(%s=0;%s<%a;%s++)@,%a @]@,}"
748
          idx idx idx pp_c_dimension dim idx
749
          (aux (idx::indices)) (Types.array_element_type typ)
750
      else
751
        let indices = List.rev indices in
752
        let pp_var_suffix fmt var =
753
          fprintf fmt "%a%a" (pp_c_var m "" pp_var) var pp_array_suffix indices in
754
        Mpfr.pp_inject_clear pp_var_suffix fmt var
755
    in
756
    reset_loop_counter ();
757
    aux [] fmt var.var_type
758

  
759
  let print_import_init fmt dep =
760
    let baseNAME = file_to_module_name dep.name in
761
    fprintf fmt "%a();" pp_global_init_name baseNAME
762

  
763
  let print_import_clear fmt dep =
764
    let baseNAME = file_to_module_name dep.name in
765
    fprintf fmt "%a();" pp_global_clear_name baseNAME
766

  
767
  let print_global_init_code fmt (basename, prog, dependencies) =
768
    let baseNAME = file_to_module_name basename in
769
    let constants = List.map const_of_top (get_consts prog) in
770
    fprintf fmt
771
      "@[<v 2>%a {@,\
772
       static %s init = 0;@,\
773
       @[<v 2>if (!init) { @,\
774
       init = 1;%a%a@]@,\
775
       }@,\
776
       return;@]@,\
777
       }"
778
      print_global_init_prototype baseNAME
779
      (pp_c_basic_type_desc Type_predef.type_bool)
780
      (* constants *)
781
      (pp_print_list
782
         ~pp_prologue:pp_print_cut
783
         (pp_const_initialize empty_machine (pp_c_var_read empty_machine)))
784
      (mpfr_consts constants)
785
      (* dependencies initialization *)
786
      (pp_print_list
787
         ~pp_prologue:pp_print_cut
788
         print_import_init) (List.filter (fun dep -> dep.local) dependencies)
789

  
790
  let print_global_clear_code fmt (basename, prog, dependencies) =
791
    let baseNAME = file_to_module_name basename in
792
    let constants = List.map const_of_top (get_consts prog) in
793
    fprintf fmt
794
      "@[<v 2>%a {@,\
795
       static %s clear = 0;@,\
796
       @[<v 2>if (!clear) { @,\
797
       clear = 1;%a%a@]@,\
798
       }@,\
799
       return;@]@,\
800
       }"
801
      print_global_clear_prototype baseNAME
802
      (pp_c_basic_type_desc Type_predef.type_bool)
803
      (* constants *)
804
      (pp_print_list
805
         ~pp_prologue:pp_print_cut
806
         (pp_const_clear (pp_c_var_read empty_machine))) (mpfr_consts constants)
807
      (* dependencies initialization *)
808
      (pp_print_list
809
         ~pp_prologue:pp_print_cut
810
         print_import_clear) (List.filter (fun dep -> dep.local) dependencies)
811

  
812
  let print_alloc_function fmt m =
813
    if (not !Options.static_mem) then
814
      (* Alloc functions, only if non static mode *)
815
      fprintf fmt
816
        "@[<v 2>%a {@,\
817
         %a%a@]@,\
818
         }@,\
819
         @[<v 2>%a {@,\
820
         %a%a@]@,\
821
         @,"
822
        print_alloc_prototype (m.mname.node_id, m.mstatic)
823
        print_alloc_const m
824
        print_alloc_code m
825
        print_dealloc_prototype m.mname.node_id
826
        print_alloc_const m
827
        print_dealloc_code m
828

  
829
  let print_mpfr_code self fmt m =
830
    if !Options.mpfr then
831
      fprintf fmt "@,@[<v>%a@,%a@]"
832
        (* Init function *)
833
        (print_init_code self) m
834
        (* Clear function *)
835
        (print_clear_code self) m
836

  
837

  
838
  (* TODO: ACSL
839
     - a contract machine shall not be directly printed in the C source
840
     - but a regular machine associated to a contract machine shall integrate
841
       the associated statements, updating its memories, at the end of the
842
       function body.
843
     - last one may print intermediate comment/acsl if/when they are present in
844
       the sequence of instruction
845
  *)
846
  let print_machine dependencies fmt m =
847
    if fst (get_stateless_status m) then
645 848
      (* Step function *)
646 849
      print_stateless_code dependencies fmt m
647
    end
648
  else
649
    begin
650
      (* Alloc functions, only if non static mode *)
651
      if (not !Options.static_mem) then  
652
	begin
653
	  fprintf fmt "@[<v 2>%a {@,%a%a@]@,}@.@."
654
	    print_alloc_prototype (m.mname.node_id, m.mstatic)
655
	    print_alloc_const m
656
	    print_alloc_code m;
657

  
658
	  fprintf fmt "@[<v 2>%a {@,%a%a@]@,}@.@."
659
	    print_dealloc_prototype m.mname.node_id
660
	    print_alloc_const m
661
	    print_dealloc_code m;
662
	end;
850
    else
663 851
      let self = mk_self m in
664
      (* Reset function *)
665
      print_reset_code dependencies fmt m self;
666
      (* Step function *)
667
      print_step_code dependencies fmt m self;
668
      
669
      if !Options.mpfr then
670
	begin
671
          (* Init function *)
672
	  print_init_code fmt m self;
673
          (* Clear function *)
674
	  print_clear_code fmt m self;
675
	end
676
    end
852
      fprintf fmt "@[<v>%a%a@,%a%a@]"
853
        print_alloc_function m
854
        (* Reset function *)
855
        (print_reset_code dependencies self) m
856
        (* Step function *)
857
        (print_step_code dependencies self) m
858
        (print_mpfr_code self) m
859

  
860
  let print_import_standard source_fmt () =
861
    fprintf source_fmt
862
      "@[<v>#include <assert.h>@,%a%a%a@]"
863
      (if Machine_types.has_machine_type ()
864
       then pp_print_endcut "#include <stdint.h>"
865
       else pp_print_nothing) ()
866
      (if not !Options.static_mem
867
       then pp_print_endcut "#include <stdlib.h>"
868
       else pp_print_nothing) ()
869
      (if !Options.mpfr
870
       then pp_print_endcut "#include <mpfr.h>"
871
       else pp_print_nothing) ()
872

  
873
  let print_extern_alloc_prototype fmt ind =
874
    let static = List.filter (fun v -> v.var_dec_const) ind.nodei_inputs in
875
    fprintf fmt "extern %a;@,extern %a;"
876
      print_alloc_prototype (ind.nodei_id, static)
877
      print_dealloc_prototype ind.nodei_id
878

  
879
  let print_lib_c source_fmt basename prog machines dependencies =
880
    fprintf source_fmt
881
      "@[<v>\
882
       %a\
883
       %a@,\
884
       @,\
885
       %a@,\
886
       %a\
887
       %a\
888
       %a\
889
       %a\
890
       %a\
891
       %a\
892
       @]@."
893
      print_import_standard ()
894
      print_import_prototype
895
      {
896
        local = true;
897
        name = basename;
898
        content = [];
899
        is_stateful=true (* assuming it is stateful *);
900
      }
901

  
902
      (* Print the svn version number and the supported C standard (C90 or C99) *)
903
      pp_print_version ()
904

  
905
      (* Print dependencies *)
906
      (pp_print_list
907
         ~pp_open_box:pp_open_vbox0
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff