Project

General

Profile

Revision 01d48bb0 src/backends/C/c_backend_common.ml

View differences:

src/backends/C/c_backend_common.ml
51 51
    var_dec_type = mktyp Location.dummy_loc Tydec_any;
52 52
    var_dec_clock = mkclock Location.dummy_loc Ckdec_any;
53 53
    var_dec_const = false;
54
    var_dec_value = None;
54 55
    var_type = Type_predef.type_arrow (Types.new_var ()) (Types.new_var ());
55 56
    var_clock = Clocks.new_var true;
56 57
    var_loc = loc }
......
133 134
      (Utils.duplicate 0 (Dimension.size_const_dimension d))
134 135
  | _ -> assert false
135 136

  
137

  
138
let pp_c_tag fmt t =
139
 pp_print_string fmt (if t = tag_true then "1" else if t = tag_false then "0" else t)
140

  
141
(* Prints a constant value *)
142
let rec pp_c_const fmt c =
143
  match c with
144
    | Const_int i     -> pp_print_int fmt i
145
    | Const_real r    -> pp_print_string fmt r
146
    | Const_float r   -> pp_print_float fmt r
147
    | Const_tag t     -> pp_c_tag fmt t
148
    | Const_array ca  -> fprintf fmt "{%a }" (Utils.fprintf_list ~sep:", " pp_c_const) ca
149
    | Const_struct fl -> fprintf fmt "{%a }" (Utils.fprintf_list ~sep:", " (fun fmt (f, c) -> pp_c_const fmt c)) fl
150
    | Const_string _ -> assert false (* string occurs in annotations not in C *)
151

  
152
(* Prints a value expression [v], with internal function calls only.
153
   [pp_var] is a printer for variables (typically [pp_c_var_read]),
154
   but an offset suffix may be added for array variables
155
*)
156
let rec pp_c_val self pp_var fmt v =
157
  match v with
158
  | Cst c         -> pp_c_const fmt c
159
  | Array vl      -> fprintf fmt "{%a}" (Utils.fprintf_list ~sep:", " (pp_c_val self pp_var)) vl
160
  | Access (t, i) -> fprintf fmt "%a[%a]" (pp_c_val self pp_var) t (pp_c_val self pp_var) i
161
  | Power (v, n)  -> assert false
162
  | LocalVar v    -> pp_var fmt v
163
  | StateVar v    ->
164
    (* array memory vars are represented by an indirection to a local var with the right type,
165
       in order to avoid casting everywhere. *)
166
    if Types.is_array_type v.var_type
167
    then fprintf fmt "%a" pp_var v
168
    else fprintf fmt "%s->_reg.%a" self pp_var v
169
  | Fun (n, vl)   -> Basic_library.pp_c n (pp_c_val self pp_var) fmt vl
170

  
171
(* Access to the value of a variable:
172
   - if it's not a scalar output, then its name is enough
173
   - otherwise, dereference it (it has been declared as a pointer,
174
     despite its scalar Lustre type)
175
   - moreover, dereference memory array variables.
176
*)
177
let pp_c_var_read m fmt id =
178
  if Types.is_address_type id.var_type
179
  then
180
    if is_memory m id
181
    then fprintf fmt "(*%s)" id.var_id
182
    else fprintf fmt "%s" id.var_id
183
  else
184
    if is_output m id
185
    then fprintf fmt "*%s" id.var_id
186
    else fprintf fmt "%s" id.var_id
187

  
188
(* Addressable value of a variable, the one that is passed around in calls:
189
   - if it's not a scalar non-output, then its name is enough
190
   - otherwise, reference it (it must be passed as a pointer,
191
     despite its scalar Lustre type)
192
*)
193
let pp_c_var_write m fmt id =
194
  if Types.is_address_type id.var_type
195
  then
196
    fprintf fmt "%s" id.var_id
197
  else
198
    if is_output m id
199
    then
200
      fprintf fmt "%s" id.var_id
201
    else
202
      fprintf fmt "&%s" id.var_id
203

  
136 204
(* Declaration of an input variable:
137 205
   - if its type is array/matrix/etc, then declare it as a mere pointer,
138 206
     in order to cope with unknown/parametric array dimensions, 
......
159 227
     known in order to statically allocate memory, 
160 228
     so we print the full type
161 229
*)
162
let pp_c_decl_local_var fmt id =
163
  pp_c_type id.var_id fmt id.var_type
230
let pp_c_decl_local_var m fmt id =
231
  if id.var_dec_const
232
  then
233
    Format.fprintf fmt "%a = %a"
234
      (pp_c_type id.var_id) id.var_type
235
      (pp_c_val "" (pp_c_var_read m)) (get_const_assign m id)
236
  else
237
    Format.fprintf fmt "%a"
238
      (pp_c_type id.var_id) id.var_type
164 239

  
165 240
let pp_c_decl_array_mem self fmt id =
166 241
  fprintf fmt "%a = (%a) (%s->_reg.%s)"
......
177 252
  then pp_c_type (sprintf "(*%s)" id.var_id) fmt (Types.array_base_type id.var_type)
178 253
  else pp_c_type                  id.var_id  fmt id.var_type
179 254

  
180
(* Access to the value of a variable:
181
   - if it's not a scalar output, then its name is enough
182
   - otherwise, dereference it (it has been declared as a pointer,
183
     despite its scalar Lustre type)
184
   - moreover, dereference memory array variables.
185
*)
186
let pp_c_var_read m fmt id =
187
  if Types.is_address_type id.var_type
188
  then
189
    if is_memory m id
190
    then fprintf fmt "(*%s)" id.var_id
191
    else fprintf fmt "%s" id.var_id
192
  else
193
    if is_output m id
194
    then fprintf fmt "*%s" id.var_id
195
    else fprintf fmt "%s" id.var_id
196

  
197
(* Addressable value of a variable, the one that is passed around in calls:
198
   - if it's not a scalar non-output, then its name is enough
199
   - otherwise, reference it (it must be passed as a pointer,
200
     despite its scalar Lustre type)
201
*)
202
let pp_c_var_write m fmt id =
203
  if Types.is_address_type id.var_type
204
  then
205
    fprintf fmt "%s" id.var_id
206
  else
207
    if is_output m id
208
    then
209
      fprintf fmt "%s" id.var_id
210
    else
211
      fprintf fmt "&%s" id.var_id
212

  
213 255
let pp_c_decl_instance_var fmt (name, (node, static)) = 
214 256
  fprintf fmt "%a *%s" pp_machine_memtype_name (node_name node) name
215 257

  
216
let pp_c_tag fmt t =
217
 pp_print_string fmt (if t = tag_true then "1" else if t = tag_false then "0" else t)
218

  
219
(* Prints a constant value *)
220
let rec pp_c_const fmt c =
221
  match c with
222
    | Const_int i     -> pp_print_int fmt i
223
    | Const_real r    -> pp_print_string fmt r
224
    | Const_float r   -> pp_print_float fmt r
225
    | Const_tag t     -> pp_c_tag fmt t
226
    | Const_array ca  -> fprintf fmt "{%a }" (Utils.fprintf_list ~sep:", " pp_c_const) ca
227
    | Const_struct fl -> fprintf fmt "{%a }" (Utils.fprintf_list ~sep:", " (fun fmt (f, c) -> pp_c_const fmt c)) fl
228
    | Const_string _ -> assert false (* string occurs in annotations not in C *)
229

  
230
(* Prints a value expression [v], with internal function calls only.
231
   [pp_var] is a printer for variables (typically [pp_c_var_read]),
232
   but an offset suffix may be added for array variables
233
*)
234
let rec pp_c_val self pp_var fmt v =
235
  match v with
236
  | Cst c         -> pp_c_const fmt c
237
  | Array vl      -> fprintf fmt "{%a}" (Utils.fprintf_list ~sep:", " (pp_c_val self pp_var)) vl
238
  | Access (t, i) -> fprintf fmt "%a[%a]" (pp_c_val self pp_var) t (pp_c_val self pp_var) i
239
  | Power (v, n)  -> assert false
240
  | LocalVar v    -> pp_var fmt v
241
  | StateVar v    ->
242
    (* array memory vars are represented by an indirection to a local var with the right type,
243
       in order to avoid casting everywhere. *)
244
    if Types.is_array_type v.var_type
245
    then fprintf fmt "%a" pp_var v
246
    else fprintf fmt "%s->_reg.%a" self pp_var v
247
  | Fun (n, vl)   -> Basic_library.pp_c n (pp_c_val self pp_var) fmt vl
248

  
249 258
let pp_c_checks self fmt m =
250 259
  Utils.fprintf_list ~sep:"" 
251 260
    (fun fmt (loc, check) -> 

Also available in: Unified diff