Project

General

Profile

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

    
3
(** Represent the possible mode for a type of a procedure parameter **)
4
type parameter_mode = AdaNoMode | AdaIn | AdaOut | AdaInOut
5

    
6
type kind_def =
7
  | AdaType
8
  | AdaProcedure
9
  | AdaFunction
10
  | AdaPackageDecl
11
  | AdaPackageBody
12

    
13
type visibility = AdaNoVisibility | AdaPrivate | AdaLimitedPrivate
14

    
15
type printer = Format.formatter -> unit
16

    
17
type ada_with = (bool * bool * printer list * printer list) option
18

    
19
type ada_var_decl = parameter_mode * printer * printer * ada_with
20

    
21
type ada_local_decl =
22
  | AdaLocalVar of ada_var_decl
23
  | AdaLocalPackage of (printer * printer * (printer * printer) list)
24

    
25
type def_content =
26
  | AdaNoContent
27
  | AdaPackageContent of printer
28
  | AdaSimpleContent of printer
29
  | AdaVisibilityDefinition of visibility
30
  | AdaProcedureContent of (ada_local_decl list list * printer list)
31
  | AdaRecord of ada_var_decl list list
32
  | AdaPackageInstanciation of (printer * (printer * printer) list)
33

    
34
(** Print a parameter_mode. @param fmt the formater to print on @param mode the
35
    modifier **)
36
let pp_parameter_mode fmt mode =
37
  fprintf fmt "%s"
38
    (match mode with
39
    | AdaNoMode ->
40
      ""
41
    | AdaIn ->
42
      "in"
43
    | AdaOut ->
44
      "out"
45
    | AdaInOut ->
46
      "in out")
47

    
48
let pp_kind_def fmt kind_def =
49
  fprintf fmt "%s"
50
    (match kind_def with
51
    | AdaType ->
52
      "type"
53
    | AdaProcedure ->
54
      "procedure"
55
    | AdaFunction ->
56
      "function"
57
    | AdaPackageDecl ->
58
      "package"
59
    | AdaPackageBody ->
60
      "package body")
61

    
62
let pp_visibility fmt visibility =
63
  fprintf fmt "%s"
64
    (match visibility with
65
    | AdaNoVisibility ->
66
      ""
67
    | AdaPrivate ->
68
      "private"
69
    | AdaLimitedPrivate ->
70
      "limited private")
71

    
72
(** Print the integer type name. @param fmt the formater to print on **)
73
let pp_integer_type fmt = fprintf fmt "Integer"
74

    
75
(** Print the float type name. @param fmt the formater to print on **)
76
let pp_float_type fmt = fprintf fmt "Float"
77

    
78
(** Print the boolean type name. @param fmt the formater to print on **)
79
let pp_boolean_type fmt = fprintf fmt "Boolean"
80

    
81
let pp_group ~sep pp_list fmt =
82
  assert (pp_list != []);
83
  fprintf fmt "@[%a@]" (Utils.fprintf_list ~sep (fun fmt pp -> pp fmt)) pp_list
84

    
85
let pp_args ~sep fmt = function
86
  | [] ->
87
    fprintf fmt ""
88
  | args ->
89
    fprintf fmt " (@[<v>%a)@]"
90
      (Utils.fprintf_list ~sep (fun fmt pp -> pp fmt))
91
      args
92

    
93
let pp_block fmt pp_item_list =
94
  fprintf fmt "%t@[<v>%a@]%t"
95
    (Utils.pp_final_char_if_non_empty "  " pp_item_list)
96
    (Utils.fprintf_list ~sep:";@," (fun fmt pp -> pp fmt))
97
    pp_item_list
98
    (Utils.pp_final_char_if_non_empty ";@," pp_item_list)
99

    
100
let pp_and l fmt = fprintf fmt "(%t)" (pp_group ~sep:"@ and then " l)
101

    
102
let pp_or l fmt = fprintf fmt "(%t)" (pp_group ~sep:"@ or " l)
103

    
104
let pp_ada_with fmt = function
105
  | None ->
106
    fprintf fmt ""
107
  | Some (ghost, import, pres, posts) ->
108
    assert (ghost || import || pres != [] || posts != []);
109
    let contract = pres @ posts in
110
    let pp_ghost fmt =
111
      if not ghost then fprintf fmt ""
112
      else
113
        fprintf fmt " Ghost%t" (fun fmt ->
114
            if contract != [] || import then fprintf fmt ",@,"
115
            else fprintf fmt "")
116
    in
117
    let pp_import fmt =
118
      if not import then fprintf fmt ""
119
      else
120
        fprintf fmt " Import%t"
121
          (Utils.pp_final_char_if_non_empty ",@," contract)
122
    in
123
    let pp_aspect aspect fmt pps =
124
      if pps = [] then fprintf fmt ""
125
      else fprintf fmt "%s => %t" aspect (pp_and pps)
126
    in
127
    let pp_contract fmt =
128
      if contract = [] then fprintf fmt ""
129
      else
130
        let sep fmt =
131
          if pres != [] && posts != [] then fprintf fmt ",@,"
132
          else fprintf fmt ""
133
        in
134
        fprintf fmt "@,  @[<v>%a%t%a@]" (pp_aspect "Pre") pres sep
135
          (pp_aspect "Post") posts
136
    in
137
    fprintf fmt " with%t%t%t" pp_ghost pp_import pp_contract
138

    
139
(** Print instanciation of a generic type in a new statement. @param fmt the
140
    formater to print on @param id id of the polymorphic type @param typ the new
141
    type **)
142
let pp_generic_instanciation (pp_name, pp_type) fmt =
143
  fprintf fmt "%t => %t" pp_name pp_type
144

    
145
(** Print a variable declaration with mode @param mode input/output mode of the
146
    parameter @param pp_name a format printer wich print the variable name
147
    @param pp_type a format printer wich print the variable type @param fmt the
148
    formater to print on @param id the variable **)
149
let pp_var_decl (mode, pp_name, pp_type, with_statement) fmt =
150
  fprintf fmt "%t: %a%s%t%a" pp_name pp_parameter_mode mode
151
    (if mode = AdaNoMode then "" else " ")
152
    pp_type pp_ada_with with_statement
153

    
154
let apply_var_decl_lists var_list =
155
  List.map (fun l -> List.map pp_var_decl l) var_list
156

    
157
let pp_generic fmt = function
158
  | [] ->
159
    fprintf fmt ""
160
  | l ->
161
    fprintf fmt "generic@,%a" pp_block l
162

    
163
let pp_opt intro fmt = function
164
  | None ->
165
    fprintf fmt ""
166
  | Some pp ->
167
    fprintf fmt " %s %t" intro pp
168

    
169
let rec pp_local local fmt =
170
  match local with
171
  | AdaLocalVar var ->
172
    pp_var_decl var fmt
173
  | AdaLocalPackage (pp_name, pp_base_name, instanciations) ->
174
    pp_package_instanciation pp_name pp_base_name fmt instanciations
175

    
176
and pp_content pp_name fmt = function
177
  | AdaNoContent ->
178
    fprintf fmt ""
179
  | AdaVisibilityDefinition visbility ->
180
    fprintf fmt " is %a" pp_visibility visbility
181
  | AdaPackageContent pp_package ->
182
    fprintf fmt " is@,  @[<v>%t;@]@,end %t" pp_package pp_name
183
  | AdaSimpleContent pp_content ->
184
    fprintf fmt " is@,  @[<v 2>(%t)@]" pp_content
185
  | AdaProcedureContent (local_list, pp_instr_list) ->
186
    fprintf fmt " is@,%abegin@,%aend %t" pp_block
187
      (List.map (fun l -> pp_group ~sep:";@;" (List.map pp_local l)) local_list)
188
      pp_block pp_instr_list pp_name
189
  | AdaRecord var_list ->
190
    assert (var_list != []);
191
    let pp_lists = apply_var_decl_lists var_list in
192
    fprintf fmt " is@,  @[<v>record@,  @[<v>%a@]@,end record@]" pp_block
193
      (List.map (pp_group ~sep:";@;") pp_lists)
194
  | AdaPackageInstanciation (pp_name, instanciations) ->
195
    fprintf fmt " is new %t%a" pp_name (pp_args ~sep:",@,")
196
      (List.map pp_generic_instanciation instanciations)
197

    
198
and pp_def fmt
199
    (pp_generics, kind_def, pp_name, args, pp_type_opt, content, pp_with_opt) =
200
  let pp_arg_lists = apply_var_decl_lists args in
201
  fprintf fmt "%a%a %t%a%a%a%a" pp_generic pp_generics pp_kind_def kind_def
202
    pp_name (pp_args ~sep:";@,")
203
    (List.map (pp_group ~sep:";@,") pp_arg_lists)
204
    (pp_opt "return") pp_type_opt (pp_content pp_name) content pp_ada_with
205
    pp_with_opt
206

    
207
and pp_package_instanciation pp_name pp_base_name fmt instanciations =
208
  pp_def fmt
209
    ( [],
210
      AdaPackageDecl,
211
      pp_name,
212
      [],
213
      None,
214
      AdaPackageInstanciation (pp_base_name, instanciations),
215
      None )
216

    
217
let pp_adastring pp_content fmt = fprintf fmt "\"%t\"" pp_content
218

    
219
(** Print the ada package introduction sentence it can be used for body and
220
    declaration. Boolean parameter body should be true if it is a body
221
    delcaration. @param fmt the formater to print on @param fmt the formater to
222
    print on @param machine the machine **)
223
let pp_package pp_name pp_generics body fmt pp_content =
224
  let kind = if body then AdaPackageBody else AdaPackageDecl in
225
  pp_def fmt
226
    (pp_generics, kind, pp_name, [], None, AdaPackageContent pp_content, None)
227

    
228
(** Print a new statement instantiating a generic package. @param fmt the
229
    formater to print on @param substitutions the instanciation substitution
230
    @param machine the machine to instanciate **)
231

    
232
(** Print a type declaration @param fmt the formater to print on @param pp_name
233
    a format printer which print the type name @param pp_value a format printer
234
    which print the type definition **)
235
let pp_type_decl pp_name visibility fmt =
236
  let v =
237
    match visibility with
238
    | AdaNoVisibility ->
239
      AdaNoContent
240
    | _ ->
241
      AdaVisibilityDefinition visibility
242
  in
243
  pp_def fmt ([], AdaType, pp_name, [], None, v, None)
244

    
245
let pp_record pp_name fmt var_lists =
246
  pp_def fmt ([], AdaType, pp_name, [], None, AdaRecord var_lists, None)
247

    
248
let pp_procedure pp_name args pp_with_opt fmt content =
249
  pp_def fmt ([], AdaProcedure, pp_name, args, None, content, pp_with_opt)
250

    
251
let pp_predicate pp_name args imported fmt content_opt =
252
  let content, with_st =
253
    match content_opt with
254
    | Some content ->
255
      AdaSimpleContent content, None
256
    | None ->
257
      AdaNoContent, Some (true, imported, [], [])
258
  in
259
  pp_def fmt
260
    ([], AdaFunction, pp_name, args, Some pp_boolean_type, content, with_st)
261

    
262
(** Print a cleaned an identifier for ada exportation : Ada names must not start
263
    by an underscore and must not contain a double underscore @param var name to
264
    be cleaned*)
265
let pp_clean_ada_identifier fmt name =
266
  let reserved_words =
267
    [
268
      "abort";
269
      "else";
270
      "new";
271
      "return";
272
      "boolean";
273
      "integer";
274
      "abs";
275
      "elsif";
276
      "not";
277
      "reverse";
278
      "abstract";
279
      "end";
280
      "null";
281
      "accept";
282
      "entry";
283
      "select";
284
      "access";
285
      "exception";
286
      "of";
287
      "separate";
288
      "aliased";
289
      "exit";
290
      "or";
291
      "some";
292
      "all";
293
      "others";
294
      "subtype";
295
      "and";
296
      "for";
297
      "out";
298
      "synchronized";
299
      "array";
300
      "function";
301
      "overriding";
302
      "at";
303
      "tagged";
304
      "generic";
305
      "package";
306
      "task";
307
      "begin";
308
      "goto";
309
      "pragma";
310
      "terminate";
311
      "body";
312
      "private";
313
      "then";
314
      "if";
315
      "procedure";
316
      "type";
317
      "case";
318
      "in";
319
      "protected";
320
      "constant";
321
      "interface";
322
      "until";
323
      "is";
324
      "raise";
325
      "use";
326
      "declare";
327
      "\trange";
328
      "delay";
329
      "limited";
330
      "record";
331
      "when";
332
      "delta";
333
      "loop";
334
      "rem";
335
      "while";
336
      "digits";
337
      "renames";
338
      "with";
339
      "do";
340
      "mod";
341
      "requeue";
342
      "xor";
343
      "float";
344
    ]
345
  in
346
  let base_size = String.length name in
347
  assert (base_size > 0);
348
  let rec remove_double_underscore s = function
349
    | i when i == String.length s - 1 ->
350
      s
351
    | i when String.get s i == '_' && String.get s (i + 1) == '_' ->
352
      remove_double_underscore
353
        (sprintf "%s%s" (String.sub s 0 i)
354
           (String.sub s (i + 1) (String.length s - i - 1)))
355
        i
356
    | i ->
357
      remove_double_underscore s (i + 1)
358
  in
359
  let name =
360
    if String.get name (base_size - 1) == '_' then name ^ "ada" else name
361
  in
362
  let name = remove_double_underscore name 0 in
363
  let prefix =
364
    if
365
      String.length name != base_size
366
      || String.get name 0 == '_'
367
      || List.exists (String.equal (String.lowercase_ascii name)) reserved_words
368
    then "ada"
369
    else ""
370
  in
371
  fprintf fmt "%s%s" prefix name
372

    
373
(** Print the access of an item from an other package. @param fmt the formater
374
    to print on @param package the package to use @param item the item which is
375
    accessed **)
376
let pp_package_access (pp_package, pp_item) fmt =
377
  fprintf fmt "%t.%t" pp_package pp_item
378

    
379
let pp_with visibility fmt pp_pakage_name =
380
  fprintf fmt "%a with %t" pp_visibility visibility pp_pakage_name
381

    
382
(** Print a one line comment with the final new line character to avoid
383
    commenting anything else. @param fmt the formater to print on @param s the
384
    comment without newline character **)
385
let pp_oneline_comment fmt s =
386
  assert (not (String.contains s '\n'));
387
  fprintf fmt "-- %s@," s
388

    
389
let pp_call fmt (pp_name, args) =
390
  fprintf fmt "%t%a" pp_name (pp_args ~sep:",@ ")
391
    (List.map (pp_group ~sep:",@,") args)
392

    
393
(** Print the complete name of variable. @param m the machine to check if it is
394
    memory @param fmt the formater to print on @param var the variable **)
395
let pp_access pp_state pp_var fmt = fprintf fmt "%t.%t" pp_state pp_var
396

    
397
let pp_old pp fmt = fprintf fmt "%t'Old" pp
(8-8/11)