Revision 9e5f8085
Added by Guillaume DAVY over 4 years ago
src/backends/Ada/ada_backend_common.ml | ||
---|---|---|
31 | 31 |
in |
32 | 32 |
fprintf fmt "%s%s" prefix name |
33 | 33 |
|
34 |
(** Encapsulate a pretty print function to lower case its result when applied |
|
35 |
@param pp the pretty print function |
|
36 |
@param fmt the formatter |
|
37 |
@param arg the argument of the pp function |
|
38 |
**) |
|
39 |
let pp_lowercase pp fmt = |
|
40 |
let str = asprintf "%t" pp in |
|
41 |
fprintf fmt "%s" (String. lowercase_ascii str) |
|
42 |
|
|
43 |
(** Print a filename by lowercasing the base and appending an extension. |
|
44 |
@param extension the extension to append to the package name |
|
45 |
@param fmt the formatter |
|
46 |
@param pp_name the file base name printer |
|
47 |
**) |
|
48 |
let pp_filename extension fmt pp_name = |
|
49 |
fprintf fmt "%t.%s" |
|
50 |
(pp_lowercase pp_name) |
|
51 |
extension |
|
52 |
|
|
34 | 53 |
|
35 | 54 |
(* Package pretty print functions *) |
36 | 55 |
|
37 |
(** Print the name of a package associated to a machine. |
|
56 |
(** Print the name of the arrow package. |
|
57 |
@param fmt the formater to print on |
|
58 |
**) |
|
59 |
let pp_arrow_package_name fmt = fprintf fmt "Arrow" |
|
60 |
|
|
61 |
(** Print the name of a package associated to a node. |
|
38 | 62 |
@param fmt the formater to print on |
39 | 63 |
@param machine the machine |
40 | 64 |
**) |
41 |
let pp_package_name fmt node = |
|
42 |
fprintf fmt "%a" pp_clean_ada_identifier node.node_id |
|
65 |
let pp_package_name fmt machine = |
|
66 |
if String.equal Arrow.arrow_id machine.mname.node_id then |
|
67 |
fprintf fmt "%t" pp_arrow_package_name |
|
68 |
else |
|
69 |
fprintf fmt "%a" pp_clean_ada_identifier machine.mname.node_id |
|
43 | 70 |
|
44 | 71 |
(** Print the ada package introduction sentence it can be used for body and |
45 | 72 |
declaration. Boolean parameter body should be true if it is a body delcaration. |
... | ... | |
50 | 77 |
let pp_begin_package body fmt machine = |
51 | 78 |
fprintf fmt "package %s%a is" |
52 | 79 |
(if body then "body " else "") |
53 |
pp_package_name machine.mname
|
|
80 |
pp_package_name machine |
|
54 | 81 |
|
55 | 82 |
(** Print the ada package conclusion sentence. |
56 | 83 |
@param fmt the formater to print on |
57 | 84 |
@param machine the machine |
58 | 85 |
**) |
59 | 86 |
let pp_end_package fmt machine = |
60 |
fprintf fmt "end %a" pp_package_name machine.mname
|
|
87 |
fprintf fmt "end %a" pp_package_name machine |
|
61 | 88 |
|
62 | 89 |
(** Print the access of an item from an other package. |
63 | 90 |
@param fmt the formater to print on |
... | ... | |
69 | 96 |
|
70 | 97 |
(** Print the name of the main procedure. |
71 | 98 |
@param fmt the formater to print on |
72 |
@param main_machine the machine associated to the main node |
|
73 | 99 |
**) |
74 |
let pp_main_procedure_name main_machine fmt =
|
|
100 |
let pp_main_procedure_name fmt = |
|
75 | 101 |
fprintf fmt "main" |
76 | 102 |
|
77 |
(** Print the name of the main ada file. |
|
78 |
@param fmt the formater to print on |
|
79 |
@param main_machine the machine associated to the main node |
|
80 |
**) |
|
81 |
let pp_main_filename fmt main_machine = |
|
82 |
fprintf fmt "%t.adb" (pp_main_procedure_name main_machine) |
|
83 |
|
|
84 | 103 |
(** Extract a node from an instance. |
85 | 104 |
@param instance the instance |
86 | 105 |
**) |
... | ... | |
90 | 109 |
| Node nd -> nd |
91 | 110 |
| _ -> assert false (*TODO*) |
92 | 111 |
|
93 |
(** Print a with statement to include a node.
|
|
112 |
(** Print a with statement to include a machine.
|
|
94 | 113 |
@param fmt the formater to print on |
95 |
@param node the node
|
|
114 |
@param machine the machine
|
|
96 | 115 |
**) |
97 |
let pp_with_node fmt node =
|
|
98 |
fprintf fmt "private with %a" pp_package_name node
|
|
116 |
let pp_with_machine fmt machine =
|
|
117 |
fprintf fmt "private with %a" pp_package_name machine
|
|
99 | 118 |
|
100 | 119 |
|
101 | 120 |
(* Type pretty print functions *) |
... | ... | |
108 | 127 |
let pp_type_decl fmt (pp_name, pp_definition) = |
109 | 128 |
fprintf fmt "type %t is %t" pp_name pp_definition |
110 | 129 |
|
111 |
(** Print a private type declaration |
|
130 |
(** Print a limited private type declaration
|
|
112 | 131 |
@param fmt the formater to print on |
113 | 132 |
@param pp_name a format printer which print the type name |
114 | 133 |
**) |
... | ... | |
140 | 159 |
**) |
141 | 160 |
let pp_boolean_type fmt = fprintf fmt "Boolean" |
142 | 161 |
|
143 |
(** Print the type of a variable.
|
|
162 |
(** Print the type of a polymorphic type.
|
|
144 | 163 |
@param fmt the formater to print on |
145 |
@param id the variable
|
|
164 |
@param id the id of the polymorphic type
|
|
146 | 165 |
**) |
147 |
let pp_var_type fmt id = |
|
148 |
(match (Types.repr id.var_type).Types.tdesc with |
|
149 |
| Types.Tbasic Types.Basic.Tint -> pp_integer_type fmt |
|
166 |
let pp_polymorphic_type fmt id = |
|
167 |
fprintf fmt "T_%i" id |
|
168 |
|
|
169 |
(** Print a type. |
|
170 |
@param fmt the formater to print on |
|
171 |
@param type the type |
|
172 |
**) |
|
173 |
let pp_type fmt typ = |
|
174 |
(match (Types.repr typ).Types.tdesc with |
|
175 |
| Types.Tbasic Types.Basic.Tint -> pp_integer_type fmt |
|
150 | 176 |
| Types.Tbasic Types.Basic.Treal -> pp_float_type fmt |
151 | 177 |
| Types.Tbasic Types.Basic.Tbool -> pp_boolean_type fmt |
152 |
| _ -> eprintf "Type error : %a@." Types.print_ty id.var_type; assert false (*TODO*) |
|
178 |
| Types.Tunivar -> pp_polymorphic_type fmt typ.tid |
|
179 |
| _ -> eprintf "Type error : %a@." Types.print_ty typ; assert false (*TODO*) |
|
153 | 180 |
) |
154 | 181 |
|
182 |
(** Print the type of a variable. |
|
183 |
@param fmt the formater to print on |
|
184 |
@param id the variable |
|
185 |
**) |
|
186 |
let pp_var_type fmt id = |
|
187 |
pp_type fmt id.var_type |
|
188 |
|
|
189 |
(** Extract all the inputs and outputs. |
|
190 |
@param machine the machine |
|
191 |
@return a list of all the var_decl of a macine |
|
192 |
**) |
|
193 |
let get_all_vars_machine m = |
|
194 |
m.mmemory@m.mstep.step_inputs@m.mstep.step_outputs@m.mstatic |
|
195 |
|
|
196 |
(** Check if a type is polymorphic. |
|
197 |
@param typ the type |
|
198 |
@return true if its polymorphic |
|
199 |
**) |
|
200 |
let is_Tunivar typ = (Types.repr typ).tdesc == Types.Tunivar |
|
201 |
|
|
202 |
(** Find all polymorphic type : Types.Tunivar in a machine. |
|
203 |
@param machine the machine |
|
204 |
@return a list of id corresponding to polymorphic type |
|
205 |
**) |
|
206 |
let find_all_polymorphic_type m = |
|
207 |
let vars = get_all_vars_machine m in |
|
208 |
let extract id = id.var_type.tid in |
|
209 |
let polymorphic_type_vars = |
|
210 |
List.filter (function x-> is_Tunivar x.var_type) vars in |
|
211 |
List.sort_uniq (-) (List.map extract polymorphic_type_vars) |
|
212 |
|
|
213 |
(** Print a package name with polymorphic types specified. |
|
214 |
@param substitution correspondance between polymorphic type id and their instantiation |
|
215 |
@param fmt the formater to print on |
|
216 |
@param machine the machine |
|
217 |
**) |
|
218 |
let pp_package_name_with_polymorphic substitution fmt machine = |
|
219 |
let polymorphic_types = find_all_polymorphic_type machine in |
|
220 |
assert(List.length polymorphic_types = List.length substitution); |
|
221 |
let substituion = List.sort_uniq (fun x y -> fst x - fst y) substitution in |
|
222 |
assert(List.for_all2 (fun poly1 (poly2, _) -> poly1 = poly2) |
|
223 |
polymorphic_types substituion); |
|
224 |
let instantiated_types = snd (List.split substitution) in |
|
225 |
fprintf fmt "%a%t%a" |
|
226 |
pp_package_name machine |
|
227 |
(Utils.pp_final_char_if_non_empty "_" instantiated_types) |
|
228 |
(Utils.fprintf_list ~sep:"_" pp_type) instantiated_types |
|
229 |
|
|
155 | 230 |
|
156 | 231 |
(* Variable pretty print functions *) |
157 | 232 |
|
... | ... | |
207 | 282 |
let pp_type = function fmt -> pp_var_type fmt id in |
208 | 283 |
pp_var_decl fmt (mode, pp_name, pp_type) |
209 | 284 |
|
210 |
(** Print variable declaration for state variable |
|
285 |
(** Print variable declaration for a local state variable
|
|
211 | 286 |
@param fmt the formater to print on |
212 | 287 |
@param mode input/output mode of the parameter |
213 | 288 |
**) |
... | ... | |
216 | 291 |
let pp_type = pp_state_type in |
217 | 292 |
pp_var_decl fmt (mode, pp_name, pp_type) |
218 | 293 |
|
219 |
(** Print the declaration of a state element of node. |
|
220 |
@param instance name of the variable |
|
294 |
(** Print the declaration of a state element of a machine. |
|
295 |
@param substitution correspondance between polymorphic type id and their instantiation |
|
296 |
@param name name of the variable |
|
221 | 297 |
@param fmt the formater to print on |
222 |
@param instance node
|
|
298 |
@param machine the machine
|
|
223 | 299 |
**) |
224 |
let pp_node_state_decl name fmt node =
|
|
225 |
let pp_package fmt = pp_package_name fmt node in
|
|
300 |
let pp_node_state_decl substitution name fmt machine =
|
|
301 |
let pp_package fmt = pp_package_name_with_polymorphic substitution fmt machine in
|
|
226 | 302 |
let pp_type fmt = pp_package_access fmt (pp_package, pp_state_type) in |
227 | 303 |
let pp_name fmt = pp_clean_ada_identifier fmt name in |
228 | 304 |
pp_var_decl fmt (NoMode, pp_name, pp_type) |
Also available in: Unified diff
Ada: Add support for arrows as an independent generic package, instantiated in each
package using it. It required a lot of refactoring.