Project

General

Profile

Download (10.4 KB) Statistics
| Branch: | Tag: | Revision:
1
open Format
2

    
3
open Machine_code_types
4
open Lustre_types
5
open Corelang
6
open Machine_code_common
7

    
8
(** Exception for unsupported features in Ada backend **)
9
exception Ada_not_supported of string
10

    
11
(** All the pretty print functions common to the ada backend **)
12

    
13
(* Misc pretty print functions *)
14

    
15
(** Print a cleaned an identifier for ada exportation : Ada names must not start by an
16
    underscore and must not contain a double underscore
17
   @param var name to be cleaned*)
18
let pp_clean_ada_identifier fmt name =
19
  let base_size = String.length name in
20
  assert(base_size > 0);
21
  let rec remove_double_underscore s = function
22
    | i when i == String.length s - 1 -> s
23
    | i when String.get s i == '_' && String.get s (i+1) == '_' ->
24
        remove_double_underscore (sprintf "%s%s" (String.sub s 0 i) (String.sub s (i+1) (String.length s-i-1))) i
25
    | i -> remove_double_underscore s (i+1)
26
  in
27
  let name = remove_double_underscore name 0 in
28
  let prefix = if String.length name != base_size
29
                  || String.get name 0 == '_' then
30
                  "ada"
31
               else
32
                  ""
33
  in
34
  fprintf fmt "%s%s" prefix name
35

    
36

    
37
(* Package pretty print functions *)
38

    
39
(** Print the name of a package associated to a machine.
40
   @param fmt the formater to print on
41
   @param machine the machine
42
**)
43
let pp_package_name fmt node =
44
    fprintf fmt "%a" pp_clean_ada_identifier node.node_id
45

    
46
(** Print the ada package introduction sentence it can be used for body and
47
declaration. Boolean parameter body should be true if it is a body delcaration.
48
   @param fmt the formater to print on
49
   @param fmt the formater to print on
50
   @param machine the machine
51
**)
52
let pp_begin_package body fmt machine =
53
  fprintf fmt "package %s%a is"
54
    (if body then "body " else "")
55
    pp_package_name machine.mname
56

    
57
(** Print the ada package conclusion sentence.
58
   @param fmt the formater to print on
59
   @param machine the machine
60
**)
61
let pp_end_package fmt machine =
62
  fprintf fmt "end %a" pp_package_name machine.mname
63

    
64
(** Print the access of an item from an other package.
65
   @param fmt the formater to print on
66
   @param package the package to use
67
   @param item the item which is accessed
68
**)
69
let pp_package_access fmt (package, item) =
70
  fprintf fmt "%t.%t" package item
71

    
72
(** Print the name of the main procedure.
73
   @param fmt the formater to print on
74
   @param main_machine the machine associated to the main node
75
**)
76
let pp_main_procedure_name main_machine fmt =
77
  fprintf fmt "main"
78

    
79
(** Print the name of the main ada file.
80
   @param fmt the formater to print on
81
   @param main_machine the machine associated to the main node
82
**)
83
let pp_main_filename fmt main_machine =
84
  fprintf fmt "%t.adb" (pp_main_procedure_name main_machine)
85

    
86
(** Extract a node from an instance.
87
   @param instance the instance
88
**)
89
let extract_node instance =
90
  let (_, (node, _)) = instance in
91
  match node.top_decl_desc with
92
    | Node nd         -> nd
93
    | _ -> assert false (*TODO*)
94

    
95
(** Print a with statement to include a node.
96
   @param fmt the formater to print on
97
   @param node the node
98
**)
99
let pp_with_node fmt node =
100
  fprintf fmt "private with %a" pp_package_name node
101

    
102

    
103
(* Type pretty print functions *)
104

    
105
(** Print a type declaration
106
   @param fmt the formater to print on
107
   @param pp_name a format printer which print the type name
108
   @param pp_value a format printer which print the type definition
109
**)
110
let pp_type_decl fmt (pp_name, pp_definition) =
111
  fprintf fmt "type %t is %t" pp_name pp_definition
112

    
113
(** Print a private type declaration
114
   @param fmt the formater to print on
115
   @param pp_name a format printer which print the type name
116
**)
117
let pp_private_limited_type_decl fmt pp_name =
118
  let pp_definition fmt = fprintf fmt "limited private" in
119
  pp_type_decl fmt (pp_name, pp_definition)
120

    
121
(** Print the type of the state variable.
122
   @param fmt the formater to print on
123
**)
124
let pp_state_type fmt =
125
  (* Type and variable names live in the same environement in Ada so name of
126
     this type and of the associated parameter : pp_state_name must be
127
     different *)
128
  fprintf fmt "TState"
129

    
130
(** Print the integer type name.
131
   @param fmt the formater to print on
132
**)
133
let pp_integer_type fmt = fprintf fmt "Integer"
134

    
135
(** Print the float type name.
136
   @param fmt the formater to print on
137
**)
138
let pp_float_type fmt = fprintf fmt "Float"
139

    
140
(** Print the boolean type name.
141
   @param fmt the formater to print on
142
**)
143
let pp_boolean_type fmt = fprintf fmt "Boolean"
144

    
145
(** Print the type of a variable.
146
   @param fmt the formater to print on
147
   @param id the variable
148
**)
149
let pp_var_type fmt id =
150
  (match (Types.repr id.var_type).Types.tdesc with
151
    | Types.Tbasic Types.Basic.Tint -> pp_integer_type fmt
152
    | Types.Tbasic Types.Basic.Treal -> pp_float_type fmt
153
    | Types.Tbasic Types.Basic.Tbool -> pp_boolean_type fmt
154
    | _ -> eprintf "Type error : %a@." Types.print_ty id.var_type; assert false (*TODO*)
155
  )
156

    
157

    
158
(* Variable pretty print functions *)
159

    
160
(** Represent the possible mode for a type of a procedure parameter **)
161
type parameter_mode = NoMode | In | Out | InOut
162

    
163
(** Print a parameter_mode.
164
   @param fmt the formater to print on
165
   @param mode the modifier
166
**)
167
let pp_parameter_mode fmt mode =
168
  fprintf fmt "%s" (match mode with
169
                     | NoMode -> ""
170
                     | In     -> "in"
171
                     | Out    -> "out"
172
                     | InOut  -> "in out")
173

    
174
(** Print the name of the state variable.
175
   @param fmt the formater to print on
176
**)
177
let pp_state_name fmt =
178
  fprintf fmt "state"
179

    
180

    
181
(** Print the name of a variable.
182
   @param fmt the formater to print on
183
   @param id the variable
184
**)
185
let pp_var_name fmt id =
186
  fprintf fmt "%a" pp_clean_ada_identifier id.var_id
187

    
188
(** Print a variable declaration
189
   @param mode input/output mode of the parameter
190
   @param pp_name a format printer wich print the variable name
191
   @param pp_type a format printer wich print the variable type
192
   @param fmt the formater to print on
193
   @param id the variable
194
**)
195
let pp_var_decl fmt (mode, pp_name, pp_type) =
196
  fprintf fmt "%t: %a%s%t"
197
    pp_name
198
    pp_parameter_mode mode
199
    (if mode = NoMode then "" else " ")
200
    pp_type
201

    
202
(** Print variable declaration for machine variable
203
   @param mode input/output mode of the parameter
204
   @param fmt the formater to print on
205
   @param id the variable
206
**)
207
let pp_machine_var_decl mode fmt id =
208
  let pp_name = function fmt -> pp_var_name fmt id in
209
  let pp_type = function fmt -> pp_var_type fmt id in
210
  pp_var_decl fmt (mode, pp_name, pp_type)
211

    
212
(** Print variable declaration for state variable
213
   @param fmt the formater to print on
214
   @param mode input/output mode of the parameter
215
**)
216
let pp_state_var_decl fmt mode =
217
  let pp_name = pp_state_name in
218
  let pp_type = pp_state_type in
219
  pp_var_decl fmt (mode, pp_name, pp_type)
220

    
221
(** Print the declaration of a state element of node.
222
   @param instance name of the variable
223
   @param fmt the formater to print on
224
   @param instance node
225
**)
226
let pp_node_state_decl name fmt node =
227
  let pp_package fmt = pp_package_name fmt node in
228
  let pp_type fmt = pp_package_access fmt (pp_package, pp_state_type) in
229
  let pp_name fmt = pp_clean_ada_identifier fmt name in
230
  pp_var_decl fmt (NoMode, pp_name, pp_type)
231

    
232

    
233
(* Prototype pretty print functions *)
234

    
235
(** Print the name of the reset procedure **)
236
let pp_reset_procedure_name fmt = fprintf fmt "reset"
237

    
238
(** Print the name of the step procedure **)
239
let pp_step_procedure_name fmt = fprintf fmt "step"
240

    
241
(** Print the name of the init procedure **)
242
let pp_init_procedure_name fmt = fprintf fmt "init"
243

    
244
(** Print the name of the clear procedure **)
245
let pp_clear_procedure_name fmt = fprintf fmt "clear"
246

    
247
(** Print the prototype of a procedure with non input/outputs
248
   @param fmt the formater to print on
249
   @param name the name of the procedure
250
**)
251
let pp_simple_prototype pp_name fmt =
252
  fprintf fmt "procedure %t" pp_name
253

    
254
(** Print the prototype of a machine procedure. The first parameter is always
255
the state, state_modifier specify the modifier applying to it. The next
256
parameters are inputs and the last parameters are the outputs.
257
   @param state_mode the input/output mode for the state parameter
258
   @param input list of the input parameter of the procedure
259
   @param output list of the output parameter of the procedure
260
   @param fmt the formater to print on
261
   @param name the name of the procedure
262
**)
263
let pp_base_prototype state_mode input output fmt pp_name =
264
  fprintf fmt "procedure %t(@[<v>%a%t@[%a@]%t@[%a@])@]"
265
    pp_name
266
    pp_state_var_decl state_mode
267
    (Utils.pp_final_char_if_non_empty ";@," input)
268
    (Utils.fprintf_list ~sep:";@ " (pp_machine_var_decl In)) input
269
    (Utils.pp_final_char_if_non_empty ";@," output)
270
    (Utils.fprintf_list ~sep:";@ " (pp_machine_var_decl Out)) output
271

    
272
(** Print the prototype of the step procedure of a machine.
273
   @param m the machine
274
   @param fmt the formater to print on
275
   @param pp_name name function printer
276
**)
277
let pp_step_prototype m fmt =
278
  pp_base_prototype InOut m.mstep.step_inputs m.mstep.step_outputs fmt pp_step_procedure_name
279

    
280
(** Print the prototype of the reset procedure of a machine.
281
   @param m the machine
282
   @param fmt the formater to print on
283
   @param pp_name name function printer
284
**)
285
let pp_reset_prototype m fmt =
286
  pp_base_prototype InOut m.mstatic [] fmt pp_reset_procedure_name
287

    
288
(** Print the prototype of the init procedure of a machine.
289
   @param m the machine
290
   @param fmt the formater to print on
291
   @param pp_name name function printer
292
**)
293
let pp_init_prototype m fmt =
294
  pp_base_prototype Out m.mstatic [] fmt pp_init_procedure_name
295

    
296
(** Print the prototype of the clear procedure of a machine.
297
   @param m the machine
298
   @param fmt the formater to print on
299
   @param pp_name name function printer
300
**)
301
let pp_clear_prototype m fmt =
302
  pp_base_prototype InOut m.mstatic [] fmt pp_clear_procedure_name
303

    
304

    
305
(* Procedure pretty print functions *)
306

    
307
(** Print the definition of a procedure
308
   @param pp_name the procedure name printer
309
   @param pp_prototype the prototype printer
310
   @param pp_instr local var printer
311
   @param pp_instr instruction printer
312
   @param fmt the formater to print on
313
   @param locals locals var list
314
   @param instrs instructions list
315
**)
316
let pp_procedure_definition pp_name pp_prototype pp_local pp_instr fmt (locals, instrs) =
317
  fprintf fmt "@[<v>%t is%t@[<v>%a%t@]@,begin@,  @[<v>%a%t@]@,end %t@]"
318
    pp_prototype
319
    (Utils.pp_final_char_if_non_empty "@,  " locals)
320
    (Utils.fprintf_list ~sep:";@," pp_local) locals
321
    (Utils.pp_final_char_if_non_empty ";" locals)
322
    (Utils.fprintf_list ~sep:";@," pp_instr) instrs
323
    (Utils.pp_final_char_if_non_empty ";" instrs)
324
    pp_name
(5-5/6)