Project

General

Profile

Download (9.83 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 = AdaType | AdaProcedure | AdaFunction | AdaPackageDecl | AdaPackageBody
7

    
8
type visibility = AdaNoVisibility | AdaPrivate | AdaLimitedPrivate
9

    
10
type printer = Format.formatter -> unit
11

    
12
type ada_var_decl = parameter_mode * printer * printer
13

    
14
type ada_local_decl =
15
  | AdaLocalVar of ada_var_decl
16
  | AdaLocalPackage of (printer * printer * ((printer*printer) list))
17

    
18
type def_content =
19
  | AdaNoContent
20
  | AdaPackageContent of (Format.formatter -> unit)
21
  | AdaVisibilityDefinition of visibility
22
  | AdaProcedureContent of ((ada_local_decl list list) * (printer list))
23
  | AdaRecord of ((ada_var_decl list) list)
24
  | AdaPackageInstanciation of (printer * (printer * printer) list)
25

    
26
(** Print a parameter_mode.
27
   @param fmt the formater to print on
28
   @param mode the modifier
29
**)
30
let pp_parameter_mode fmt mode =
31
  fprintf fmt "%s" (match mode with
32
                     | AdaNoMode -> ""
33
                     | AdaIn     -> "in"
34
                     | AdaOut    -> "out"
35
                     | AdaInOut  -> "in out")
36

    
37
let pp_kind_def fmt kind_def =
38
  fprintf fmt "%s" (match kind_def with
39
                     | AdaType        -> "type"
40
                     | AdaProcedure   -> "procedure"
41
                     | AdaFunction    -> "function"
42
                     | AdaPackageDecl -> "package"
43
                     | AdaPackageBody -> "package body")
44

    
45
let pp_visibility fmt visibility =
46
  fprintf fmt "%s" (match visibility with
47
                     | AdaNoVisibility     -> ""
48
                     | AdaPrivate          -> "private"
49
                     | AdaLimitedPrivate   -> "limited private")
50

    
51
let pp_group ~sep:sep pp_list fmt =
52
  assert(pp_list != []);
53
  fprintf fmt "@[%a@]"
54
    (Utils.fprintf_list ~sep:sep (fun fmt pp->pp fmt)) pp_list
55

    
56
let pp_args ~sep:sep fmt = function
57
  | [] -> fprintf fmt ""
58
  | args -> fprintf fmt " (@[<v>%a)@]" (Utils.fprintf_list ~sep:sep (fun fmt pp->pp fmt)) args
59

    
60
let pp_block fmt pp_item_list =
61
  fprintf fmt "%t@[<v>%a@]%t"
62
    (Utils.pp_final_char_if_non_empty "  " pp_item_list)
63
    (Utils.fprintf_list ~sep:";@," (fun fmt pp -> pp fmt)) pp_item_list
64
    (Utils.pp_final_char_if_non_empty ";@," pp_item_list)
65

    
66
(** Print instanciation of a generic type in a new statement.
67
   @param fmt the formater to print on
68
   @param id id of the polymorphic type
69
   @param typ the new type
70
**)
71
let pp_generic_instanciation (pp_name, pp_type) fmt =
72
  fprintf fmt "%t => %t" pp_name pp_type
73

    
74
(** Print a variable declaration with mode
75
   @param mode input/output mode of the parameter
76
   @param pp_name a format printer wich print the variable name
77
   @param pp_type a format printer wich print the variable type
78
   @param fmt the formater to print on
79
   @param id the variable
80
**)
81
let pp_var_decl (mode, pp_name, pp_type) fmt =
82
  fprintf fmt "%t: %a%s%t"
83
    pp_name
84
    pp_parameter_mode mode
85
    (if mode = AdaNoMode then "" else " ")
86
    pp_type
87

    
88
let apply_var_decl_lists var_list =
89
  List.map (fun l-> List.map pp_var_decl l) var_list
90

    
91
let pp_generic fmt = function
92
    | [] -> fprintf fmt ""
93
    | l -> fprintf fmt "generic@,%a" pp_block l
94

    
95
let pp_opt intro fmt = function
96
  | None -> fprintf fmt ""
97
  | Some pp -> fprintf fmt " %s %t" intro pp
98

    
99
let rec pp_local local fmt =
100
  match local with
101
    | AdaLocalVar var -> pp_var_decl var fmt
102
    | AdaLocalPackage (pp_name, pp_base_name, instanciations) ->
103
        pp_package_instanciation pp_name pp_base_name fmt instanciations
104
and pp_content pp_name fmt = function
105
  | AdaNoContent ->
106
      fprintf fmt ""
107
  | AdaVisibilityDefinition visbility ->
108
      fprintf fmt " is %a" pp_visibility visbility
109
  | AdaPackageContent pp_package ->
110
      fprintf fmt " is@,  @[<v>%t;@]@,end %t" pp_package pp_name
111
  | AdaProcedureContent (local_list, pp_instr_list) ->
112
      fprintf fmt " is@,%abegin@,%aend %t"
113
        pp_block (List.map (fun l -> pp_group ~sep:";@," (List.map pp_local l)) local_list)
114
        pp_block pp_instr_list
115
        pp_name
116
  | AdaRecord var_list ->
117
      assert(var_list != []);
118
      let pp_lists = apply_var_decl_lists var_list in
119
      fprintf fmt " is@,  @[<v>record@,  @[<v>%a@]@,end record@]"
120
        pp_block (List.map (pp_group ~sep:";@,") pp_lists)
121
  | AdaPackageInstanciation (pp_name, instanciations) ->
122
      fprintf fmt " is new %t%a"
123
        pp_name
124
        (pp_args ~sep:",@,") (List.map pp_generic_instanciation instanciations)
125
and pp_def fmt (pp_generics, kind_def, pp_name, args, pp_type_opt, content, pp_spec_opt) =
126
  let pp_arg_lists = apply_var_decl_lists args in
127
  fprintf fmt "%a%a %t%a%a%a%a"
128
    pp_generic pp_generics
129
    pp_kind_def kind_def
130
    pp_name
131
    (pp_args ~sep:";@,") (List.map (pp_group ~sep:";@,") pp_arg_lists)
132
    (pp_opt "return") pp_type_opt
133
    (pp_content pp_name) content
134
    (pp_opt   "with") pp_spec_opt
135
and pp_package_instanciation pp_name pp_base_name fmt instanciations =
136
  pp_def fmt ([], AdaPackageDecl, pp_name, [], None, (AdaPackageInstanciation (pp_base_name, instanciations)), None)
137

    
138
(** Print the ada package introduction sentence it can be used for body and
139
declaration. Boolean parameter body should be true if it is a body delcaration.
140
   @param fmt the formater to print on
141
   @param fmt the formater to print on
142
   @param machine the machine
143
**)
144
let pp_package pp_name pp_generics body fmt pp_content =
145
  let kind = if body then AdaPackageBody else AdaPackageDecl in
146
  pp_def fmt (pp_generics, kind, pp_name, [], None, (AdaPackageContent pp_content), None)
147

    
148
(** Print a new statement instantiating a generic package.
149
   @param fmt the formater to print on
150
   @param substitutions the instanciation substitution
151
   @param machine the machine to instanciate
152
**)
153

    
154
(** Print a type declaration
155
   @param fmt the formater to print on
156
   @param pp_name a format printer which print the type name
157
   @param pp_value a format printer which print the type definition
158
**)
159
let pp_type_decl pp_name visibility fmt =
160
  pp_def fmt ([], AdaType, pp_name, [], None, AdaVisibilityDefinition visibility, None)
161

    
162
let pp_record pp_name fmt var_lists =
163
  pp_def fmt ([], AdaType, pp_name, [], None, AdaRecord var_lists, None)
164

    
165
let pp_procedure pp_name args pp_with_opt fmt content =
166
  pp_def fmt ([], AdaProcedure, pp_name, args, None, content, pp_with_opt)
167

    
168

    
169

    
170

    
171
(** Print a cleaned an identifier for ada exportation : Ada names must not start by an
172
    underscore and must not contain a double underscore
173
   @param var name to be cleaned*)
174
let pp_clean_ada_identifier fmt name =
175
  let reserved_words = ["abort"; "else"; "new"; "return"; "boolean"; "integer";
176
                        "abs"; "elsif"; "not"; "reverse"; "abstract"; "end";
177
                        "null"; "accept"; "entry"; "select"; "access";
178
                        "exception"; "of"; "separate"; "aliased"; "exit";
179
                        "or"; "some"; "all"; "others"; "subtype"; "and";
180
                        "for"; "out"; "synchronized"; "array"; "function";
181
                        "overriding"; "at"; "tagged"; "generic"; "package";
182
                        "task"; "begin"; "goto"; "pragma"; "terminate";
183
                        "body"; "private"; "then"; "if"; "procedure"; "type";
184
                        "case"; "in"; "protected"; "constant"; "interface";
185
                        "until"; "is"; "raise"; "use"; "declare"; "	range";
186
                        "delay"; "limited"; "record"; "when"; "delta"; "loop";
187
                        "rem"; "while"; "digits"; "renames"; "with"; "do";
188
                        "mod"; "requeue"; "xor"; "float"] in
189
  let base_size = String.length name in
190
  assert(base_size > 0);
191
  let rec remove_double_underscore s = function
192
    | i when i == String.length s - 1 -> s
193
    | i when String.get s i == '_' && String.get s (i+1) == '_' ->
194
        remove_double_underscore (sprintf "%s%s" (String.sub s 0 i) (String.sub s (i+1) (String.length s-i-1))) i
195
    | i -> remove_double_underscore s (i+1)
196
  in
197
  let name = if String.get name (base_size-1) == '_' then name^"ada" else name in
198
  let name = remove_double_underscore name 0 in
199
  let prefix = if String.length name != base_size
200
                  || String.get name 0 == '_' 
201
                  || List.exists (String.equal (String.lowercase_ascii name)) reserved_words then
202
                  "ada"
203
               else
204
                  ""
205
  in
206
  fprintf fmt "%s%s" prefix name
207

    
208
(** Print the access of an item from an other package.
209
   @param fmt the formater to print on
210
   @param package the package to use
211
   @param item the item which is accessed
212
**)
213
let pp_package_access (pp_package, pp_item) fmt =
214
  fprintf fmt "%t.%t" pp_package pp_item
215

    
216
let pp_with visibility fmt pp_pakage_name =
217
  fprintf fmt "%a with %t" pp_visibility visibility pp_pakage_name
218

    
219
(** Print a one line comment with the final new line character to avoid
220
      commenting anything else.
221
   @param fmt the formater to print on
222
   @param s the comment without newline character
223
**)
224
let pp_oneline_comment fmt s =
225
  assert (not (String.contains s '\n'));
226
  fprintf fmt "-- %s@," s
227

    
228
let pp_call fmt (pp_name, args) =
229
  fprintf fmt "%t%a"
230
    pp_name
231
    (pp_args ~sep:",@ ") (List.map (pp_group ~sep:",@ ") args)
232

    
233

    
234
(*
235

    
236
(** Print a precondition in aspect
237
   @param fmt the formater to print on
238
   @param expr the expession to print as pre
239
**)
240
let pp_pre fmt expr =
241
  fprintf fmt "Pre => %a"
242
    pp_clean_ada_identifier expr
243

    
244
(** Print a postcondition in aspect
245
   @param fmt the formater to print on
246
   @param expr the expession to print as pre
247
**)
248
let pp_post fmt ident =
249
  fprintf fmt "Post => %a"
250
    pp_clean_ada_identifier ident
251

    
252
(** Print the declaration of a procedure with a contract
253
   @param pp_prototype the prototype printer
254
   @param fmt the formater to print on
255
   @param contract the contract for the function to declare
256
**)
257
let pp_contract guarantees fmt =
258
  fprintf fmt "@,  @[<v>Global => null%t%a@]"
259
    (Utils.pp_final_char_if_non_empty ",@," guarantees)
260
    (Utils.fprintf_list ~sep:",@," pp_post) guarantees
261

    
262
*)
263

    
264

    
265

    
266

    
267

    
(9-9/12)