21 * This code is made available on the understanding that it will not be |
21 * This code is made available on the understanding that it will not be |
22 * used in safety-critical situations without a full and competent review. |
22 * used in safety-critical situations without a full and competent review. |
23 */ |
23 */ |
24 #include <stdlib.h> |
24 #include <stdlib.h> |
25 |
25 |
|
26 |
|
27 /* Ths class contains two main classes: |
|
28 * - generate_c_typedecl_c |
|
29 * - generate_c_implicit_typedecl_c |
|
30 * |
|
31 * and an auxiliary class |
|
32 * - generate_datatypes_aliasid_c |
|
33 * |
|
34 * |
|
35 * Both the generate_c_typedecl_c and the generate_c_implicit_typedecl_c may set a stage4 |
|
36 * annotation (in the stage4 annotation map of each symbol_c) named |
|
37 * "generate_c_annotaton__implicit_type_id" |
|
38 * If this annotation is set, the generate_c_base_c will print out this value instead of |
|
39 * the datatype's name! |
|
40 * |
|
41 * |
|
42 * |
|
43 * generate_c_typedecl_c |
|
44 * --------------------- |
|
45 * Given a datatype object (i.e. an object in the AST that is also used to define a datatype, |
|
46 * typically one that may be returned by search_basetype_c), this class will generate the |
|
47 * C code to declare an equivakent datatype in C. |
|
48 * Note that array datatypes are handled in a special way; instead of using the name given |
|
49 * to it in the IEC 61131-3 source code, and new alias is created for the datatype name in C. |
|
50 * Eplanations why we do this may be found further on... |
|
51 * |
|
52 * |
|
53 * generate_c_implicit_typedecl_c |
|
54 * ------------------------------ |
|
55 * Given a POU or a derived datatype declaration, it will search for any implicitly defined |
|
56 * datatypes in that POU/datatype declaration. Implicit datatypes are datatypes that are not |
|
57 * explicitly declared and given a name. Example: |
|
58 * VAR a: ARRAY [9..11] of INT; END_VAR |
|
59 * Here, the array is implictly delcared. |
|
60 * For eac implicitly defined datatype, an alias for that datatype is created (by calling |
|
61 * generate_datatypes_aliasid_c), and a C declaration is generated in C source code (by |
|
62 * calling generate_c_typedecl_c). |
|
63 * |
|
64 * |
|
65 * generate_datatypes_aliasid_c |
|
66 * ---------------------------- |
|
67 * Given a datatype object (i.e. an object in the AST that defines a datatype), it will create |
|
68 * an alias name for that datatype. |
|
69 * This class is used by both the generate_c_implicit_typedecl_c, and the generate_c_typedecl_c |
|
70 * classes! |
|
71 */ |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 /* generate an alias/name (identifier) for array and REF_TO datatypes */ |
|
79 /* |
|
80 * The generated alias is created based on the structure of the datatype itself, in order to |
|
81 * guarantee that any two datatypes that have the same internal format will result in the same |
|
82 * alias. |
|
83 * examples: |
|
84 * ARRAY [9..11] of INT --> __ARRAY_9_11_OF_INT |
|
85 * REF_TO INT --> __REF_TO_INT |
|
86 * ARRAY [9..11] of REF_TO INT --> __ARRAY_9_11_OF___REF_TO_INT |
|
87 */ |
|
88 class generate_datatypes_aliasid_c: fcall_visitor_c { |
|
89 |
|
90 private: |
|
91 //std::map<std::string, int> inline_array_defined; |
|
92 std::string current_array_name; |
|
93 static generate_datatypes_aliasid_c *singleton_; |
|
94 |
|
95 public: |
|
96 generate_datatypes_aliasid_c(void) {}; |
|
97 |
|
98 virtual ~generate_datatypes_aliasid_c(void) { |
|
99 //inline_array_defined.clear(); // Not really necessary... |
|
100 } |
|
101 |
|
102 /* implement the virtual member function declared in fcall_visitor_c */ |
|
103 // by default generate an ERROR if a visit method is called, unless it is explicitly handled in generate_datatypes_aliasid_c |
|
104 void fcall(symbol_c *symbol) {ERROR;} |
|
105 |
|
106 static identifier_c *create_id(symbol_c *symbol) { |
|
107 if (NULL == singleton_) singleton_ = new generate_datatypes_aliasid_c(); |
|
108 if (NULL == singleton_) ERROR; |
|
109 singleton_->current_array_name = ""; |
|
110 symbol->accept(*singleton_); |
|
111 const char *str1 = singleton_->current_array_name.c_str(); |
|
112 char *str2 = (char *)malloc(strlen(str1)+1); |
|
113 if (NULL == str2) ERROR; |
|
114 strcpy(str2, str1); |
|
115 identifier_c *id = new identifier_c(str2); |
|
116 /* Copy all the anotations in the symbol_c object 'symbol' to the newly created 'id' object |
|
117 * This includes the location (in the IEC 61131-3 source file) annotations set in stage1_2, |
|
118 * the symbol->datatype set in stage3, and any other anotaions that may be created in the future! |
|
119 */ |
|
120 *(dynamic_cast<symbol_c *>(id)) = *(dynamic_cast<symbol_c *>(symbol)); |
|
121 return id; |
|
122 } |
|
123 |
|
124 /*************************/ |
|
125 /* B.1 - Common elements */ |
|
126 /*************************/ |
|
127 /**********************/ |
|
128 /* B.1.3 - Data types */ |
|
129 /**********************/ |
|
130 /***********************************/ |
|
131 /* B 1.3.1 - Elementary Data Types */ |
|
132 /***********************************/ |
|
133 /***********************************/ |
|
134 /* B 1.3.2 - Generic Data Types */ |
|
135 /***********************************/ |
|
136 /********************************/ |
|
137 /* B 1.3.3 - Derived data types */ |
|
138 /********************************/ |
|
139 /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ |
|
140 void *visit(ref_spec_c *symbol) { |
|
141 current_array_name = "__REF_TO_"; |
|
142 current_array_name += get_datatype_info_c::get_id_str(symbol->type_name); |
|
143 return NULL; |
|
144 } |
|
145 |
|
146 /******************************************/ |
|
147 /* B 1.4.3 - Declaration & Initialization */ |
|
148 /******************************************/ |
|
149 /* array_specification [ASSIGN array_initialization] */ |
|
150 /* array_initialization may be NULL ! */ |
|
151 void *visit(array_spec_init_c *symbol) { |
|
152 if (NULL == symbol->datatype) ERROR; |
|
153 symbol->datatype->accept(*this); // the base datatype should be an array_specification_c !! |
|
154 return NULL; |
|
155 } |
|
156 |
|
157 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
|
158 void *visit(array_specification_c *symbol) { |
|
159 current_array_name = "__ARRAY_OF_"; |
|
160 if ( get_datatype_info_c::is_ref_to(symbol->non_generic_type_name) |
|
161 && (get_datatype_info_c::get_ref_to(symbol->non_generic_type_name) != NULL)) { |
|
162 /* handle situations where we have 2 impliclitly defined datatype, namely a REF_TO inside an ARRAY |
|
163 * e.g. TYPE array_of_ref_to_sint : ARRAY [1..3] OF REF_TO SINT; END_TYPE |
|
164 * The second condition (get_datatype_info_c::get_ref_to(symbol->non_generic_type_name) != NULL) |
|
165 * in the above if() is to make sure we use the standard algorithm if the array is of a previously |
|
166 * defined REF_TO type, in which case symbol->non_generic_type_name will reference an identifier_c! |
|
167 * e.g. TYPE array_of_ref_to_sint : ARRAY [1..3] OF REF_TO SINT; END_TYPE |
|
168 */ |
|
169 current_array_name += "__REF_TO_"; |
|
170 current_array_name += get_datatype_info_c::get_id_str(get_datatype_info_c::get_ref_to(symbol->non_generic_type_name)); |
|
171 } else { |
|
172 current_array_name += get_datatype_info_c::get_id_str(symbol->non_generic_type_name); |
|
173 } |
|
174 symbol->array_subrange_list->accept(*this); |
|
175 return NULL; |
|
176 } |
|
177 |
|
178 /* helper symbol for array_specification */ |
|
179 /* array_subrange_list ',' subrange */ |
|
180 void *visit(array_subrange_list_c *symbol) { |
|
181 for(int i = 0; i < symbol->n; i++) {symbol->elements[i]->accept(*this);} |
|
182 return NULL; |
|
183 } |
|
184 |
|
185 /* signed_integer DOTDOT signed_integer */ |
|
186 //SYM_REF2(subrange_c, lower_limit, upper_limit) |
|
187 void *visit(subrange_c *symbol) { |
|
188 current_array_name += "_"; |
|
189 std::stringstream ss; |
|
190 ss << symbol->dimension; |
|
191 current_array_name += ss.str(); |
|
192 return NULL; |
|
193 } |
|
194 |
|
195 |
|
196 }; |
|
197 |
|
198 |
|
199 generate_datatypes_aliasid_c *generate_datatypes_aliasid_c::singleton_ = NULL; |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 /***************************************************************************************/ |
|
208 /***************************************************************************************/ |
|
209 /***************************************************************************************/ |
|
210 /***************************************************************************************/ |
|
211 |
|
212 /* Given an object in the AST that defines a datatype, generate the C source code that declares an |
|
213 * equivalent dataype in C. |
|
214 * WARNING: This class maintains internal state in the datatypes_already_defined map. |
|
215 * Using multiple isntances of this class may result in different C source code |
|
216 * compared to when a single instance of this class is used for all datatype declarations! |
|
217 * |
|
218 * Except for arrays, the C datatype will have the same name as the name of the datatype in the |
|
219 * IEC 61131-3 source code. |
|
220 * For arrays an alias is created for each datatype. This alias has the property of being equal |
|
221 * for arrays with the same internal structure. |
|
222 * |
|
223 * Example: |
|
224 * TYPE |
|
225 * array1: ARRAY [9..11] of INT; |
|
226 * array2: ARRAY [9..11] of INT; |
|
227 * END_TYPE |
|
228 * |
|
229 * will result in both arrays having the same name (__ARRAY_9_11_OF_INT) in the C source code. |
|
230 * |
|
231 * A single C datatype declaration will be generated for both arrays |
|
232 * (the datatypes_already_defined keeps track of which datatypes have already been declared in C) |
|
233 * This method of handling arrays is needed when the relaxed datatype model is used |
|
234 * (see get_datatype_info_c for explanation on the relaxed datatype model). |
|
235 */ |
|
236 /* Notice that this class inherits from generate_c_base_c, and not from generate_c_base_and_typeid_c. |
|
237 * This is intentional! |
|
238 * Whenever this class needs to print out the id of a datatype, it will explicitly use a private instance |
|
239 * (generate_c_typeid) of generate_c_base_and_typeid_c! |
|
240 */ |
26 class generate_c_typedecl_c: public generate_c_base_c { |
241 class generate_c_typedecl_c: public generate_c_base_c { |
27 |
242 |
28 protected: |
243 protected: |
29 stage4out_c &s4o_incl; |
244 stage4out_c &s4o_incl; |
30 |
245 |
31 private: |
246 private: |
32 symbol_c* current_type_name; |
247 symbol_c* current_type_name; |
33 bool array_is_derived; |
248 generate_c_base_and_typeid_c *generate_c_typeid; |
34 generate_c_base_c *basedecl; |
249 std::map<std::string, int> datatypes_already_defined; |
35 |
250 |
36 public: |
251 public: |
37 generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { |
252 generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) /*, generate_c_print_typename(s4o_ptr) */{ |
38 current_typedefinition = none_td; |
253 current_typedefinition = none_td; |
39 current_basetypedeclaration = none_bd; |
254 current_basetypedeclaration = none_bd; |
40 current_type_name = NULL; |
255 current_type_name = NULL; |
41 basedecl = new generate_c_base_c(&s4o_incl); |
256 generate_c_typeid = new generate_c_base_and_typeid_c(&s4o_incl); |
42 } |
257 } |
43 ~generate_c_typedecl_c(void) { |
258 ~generate_c_typedecl_c(void) { |
44 delete basedecl; |
259 delete generate_c_typeid; |
45 } |
260 } |
46 |
261 |
47 typedef enum { |
262 typedef enum { |
48 none_td, |
263 none_td, |
49 enumerated_td, |
264 enumerated_td, |
182 void *visit(subrange_specification_c *symbol) { |
393 void *visit(subrange_specification_c *symbol) { |
183 TRACE("subrange_specification_c"); |
394 TRACE("subrange_specification_c"); |
184 if (current_typedefinition == subrange_td) { |
395 if (current_typedefinition == subrange_td) { |
185 switch (current_basetypedeclaration) { |
396 switch (current_basetypedeclaration) { |
186 case subrangebasetype_bd: |
397 case subrangebasetype_bd: |
187 symbol->integer_type_name->accept(*basedecl); |
398 symbol->integer_type_name->accept(*generate_c_typeid); |
188 break; |
399 break; |
189 case subrangetest_bd: |
400 case subrangetest_bd: |
190 if (symbol->subrange != NULL) { |
401 if (symbol->subrange != NULL) { |
191 s4o_incl.print("static inline "); |
402 s4o_incl.print("static inline "); |
192 current_type_name->accept(*basedecl); |
403 current_type_name->accept(*generate_c_typeid); |
193 s4o_incl.print(" __CHECK_"); |
404 s4o_incl.print(" __CHECK_"); |
194 current_type_name->accept(*basedecl); |
405 current_type_name->accept(*generate_c_typeid); |
195 s4o_incl.print("("); |
406 s4o_incl.print("("); |
196 current_type_name->accept(*basedecl); |
407 current_type_name->accept(*generate_c_typeid); |
197 s4o_incl.print(" value) {\n"); |
408 s4o_incl.print(" value) {\n"); |
198 s4o_incl.indent_right(); |
409 s4o_incl.indent_right(); |
199 |
410 |
200 /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */ |
411 /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */ |
201 /* For this reason, the following condition will always be false, and therefore this is a block |
412 /* For this reason, the following condition will always be false, and therefore this is a block |
245 else |
456 else |
246 symbol->lower_limit->accept(*this); |
457 symbol->lower_limit->accept(*this); |
247 break; |
458 break; |
248 case subrange_td: |
459 case subrange_td: |
249 s4o_incl.print(s4o_incl.indent_spaces + "if (value < "); |
460 s4o_incl.print(s4o_incl.indent_spaces + "if (value < "); |
250 symbol->lower_limit->accept(*basedecl); |
461 symbol->lower_limit->accept(*generate_c_typeid); |
251 s4o_incl.print(")\n"); |
462 s4o_incl.print(")\n"); |
252 s4o_incl.indent_right(); |
463 s4o_incl.indent_right(); |
253 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
464 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
254 symbol->lower_limit->accept(*basedecl); |
465 symbol->lower_limit->accept(*generate_c_typeid); |
255 s4o_incl.print(";\n"); |
466 s4o_incl.print(";\n"); |
256 s4o_incl.indent_left(); |
467 s4o_incl.indent_left(); |
257 s4o_incl.print(s4o_incl.indent_spaces + "else if (value > "); |
468 s4o_incl.print(s4o_incl.indent_spaces + "else if (value > "); |
258 symbol->upper_limit->accept(*basedecl); |
469 symbol->upper_limit->accept(*generate_c_typeid); |
259 s4o_incl.print(")\n"); |
470 s4o_incl.print(")\n"); |
260 s4o_incl.indent_right(); |
471 s4o_incl.indent_right(); |
261 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
472 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
262 symbol->upper_limit->accept(*basedecl); |
473 symbol->upper_limit->accept(*generate_c_typeid); |
263 s4o_incl.print(";\n"); |
474 s4o_incl.print(";\n"); |
264 s4o_incl.indent_left(); |
475 s4o_incl.indent_left(); |
265 s4o_incl.print(s4o_incl.indent_spaces + "else\n"); |
476 s4o_incl.print(s4o_incl.indent_spaces + "else\n"); |
266 s4o_incl.indent_right(); |
477 s4o_incl.indent_right(); |
267 s4o_incl.print(s4o_incl.indent_spaces + "return value;\n"); |
478 s4o_incl.print(s4o_incl.indent_spaces + "return value;\n"); |
317 */ |
528 */ |
318 |
529 |
319 /* identifier ':' array_spec_init */ |
530 /* identifier ':' array_spec_init */ |
320 void *visit(array_type_declaration_c *symbol) { |
531 void *visit(array_type_declaration_c *symbol) { |
321 TRACE("array_type_declaration_c"); |
532 TRACE("array_type_declaration_c"); |
|
533 |
|
534 // NOTE: remeber that symbol->array_spec_init may point to an identifier_c, which is why we use symbol->array_spec_init->datatype instead! |
|
535 if (NULL == symbol->array_spec_init->datatype) ERROR; |
|
536 identifier_c *id = generate_datatypes_aliasid_c::create_id(symbol->array_spec_init->datatype); |
|
537 |
|
538 /* NOTE An array_type_declaration_c will be created in stage4 for each implicitly defined array, |
|
539 * and this generate_c_typedecl_c will be called to define that array in C. |
|
540 * However, every implictly defined array with the exact same parameters will be mapped |
|
541 * to the same identifier (e.g: __ARRAY_OF_INT_33 where 33 is the number of elements in the array). |
|
542 * In order for the C compiler not to find the same datatype being defined two or more times, |
|
543 * we will keep track of the array datatypes that have already been declared, and henceforth |
|
544 * only declare arrays that have not been previously defined. |
|
545 */ |
|
546 if (datatypes_already_defined.find(id->value) != datatypes_already_defined.end()) |
|
547 goto end; // already defined. No need to define it again!! |
|
548 datatypes_already_defined[id->value] = 1; // insert this datatype into the list of already defined arrays! |
|
549 |
322 current_typedefinition = array_td; |
550 current_typedefinition = array_td; |
323 current_type_name = symbol->identifier; |
551 current_type_name = id; |
324 |
552 |
325 int implicit_id_count = symbol->array_spec_init->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
553 s4o_incl.print("__DECLARE_ARRAY_TYPE("); |
326 if (implicit_id_count > 1) ERROR; |
554 current_type_name->accept(*generate_c_typeid); |
327 if (implicit_id_count == 1) |
|
328 s4o_incl.print("__DECLARE_DERIVED_TYPE("); |
|
329 else |
|
330 s4o_incl.print("__DECLARE_ARRAY_TYPE("); |
|
331 current_type_name->accept(*basedecl); |
|
332 s4o_incl.print(","); |
555 s4o_incl.print(","); |
333 symbol->array_spec_init->accept(*this); |
556 symbol->array_spec_init->accept(*this); |
334 s4o_incl.print(")\n"); |
557 s4o_incl.print(")\n"); |
335 |
558 |
336 current_type_name = NULL; |
559 current_type_name = NULL; |
337 current_typedefinition = none_td; |
560 current_typedefinition = none_td; |
|
561 |
|
562 end: |
|
563 symbol ->anotations_map["generate_c_annotaton__implicit_type_id"] = id; |
|
564 symbol->datatype ->anotations_map["generate_c_annotaton__implicit_type_id"] = id; |
|
565 symbol->array_spec_init->anotations_map["generate_c_annotaton__implicit_type_id"] = id; // probably not needed, bu let's play safe. |
|
566 |
338 return NULL; |
567 return NULL; |
339 } |
568 } |
340 |
569 |
341 |
570 |
342 |
571 |
343 /* array_specification [ASSIGN array_initialization] */ |
572 /* array_specification [ASSIGN array_initialization] */ |
344 /* array_initialization may be NULL ! */ |
573 /* array_initialization may be NULL ! */ |
345 void *visit(array_spec_init_c *symbol) { |
574 void *visit(array_spec_init_c *symbol) { |
346 TRACE("array_spec_init_c"); |
575 TRACE("array_spec_init_c"); |
347 int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
|
348 if (implicit_id_count > 1) ERROR; |
|
349 if (implicit_id_count == 1) { |
|
350 /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype |
|
351 * has already been defined. So, we simly print out the id of that C datatpe... |
|
352 */ |
|
353 symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl); |
|
354 return NULL; |
|
355 } |
|
356 // if (current_typedefinition != array_td) {debug_c::print(symbol); ERROR;} |
|
357 symbol->array_specification->accept(*this); |
576 symbol->array_specification->accept(*this); |
358 return NULL; |
577 return NULL; |
359 } |
578 } |
360 |
579 |
361 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
580 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
362 void *visit(array_specification_c *symbol) { |
581 void *visit(array_specification_c *symbol) { |
363 TRACE("array_specification_c"); |
582 TRACE("array_specification_c"); |
364 int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
|
365 if (implicit_id_count > 1) ERROR; |
|
366 if (implicit_id_count == 1) { |
|
367 /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype |
|
368 * has already been defined. So, we simly print out the id of that C datatpe... |
|
369 */ |
|
370 symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl); |
|
371 return NULL; |
|
372 } |
|
373 // The 2nd and 3rd argument of a call to the __DECLARE_ARRAY_TYPE macro! |
583 // The 2nd and 3rd argument of a call to the __DECLARE_ARRAY_TYPE macro! |
374 symbol->non_generic_type_name->accept(*this); |
584 symbol->non_generic_type_name->accept(/*generate_c_print_typename*/*generate_c_typeid); |
375 s4o_incl.print(","); |
585 s4o_incl.print(","); |
376 current_basetypedeclaration = arraysubrange_bd; |
586 current_basetypedeclaration = arraysubrange_bd; |
377 symbol->array_subrange_list->accept(*this); |
587 symbol->array_subrange_list->accept(*this); |
378 current_basetypedeclaration = none_bd; |
588 current_basetypedeclaration = none_bd; |
379 return NULL; |
589 return NULL; |
626 |
834 |
627 |
835 |
628 |
836 |
629 /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ |
837 /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ |
630 // SYM_REF1(ref_spec_c, type_name) |
838 // SYM_REF1(ref_spec_c, type_name) |
631 void *visit(ref_spec_c *symbol) { |
839 void *visit(ref_spec_c *symbol) { |
632 int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
840 symbol->type_name->accept(/*generate_c_print_typename*/*generate_c_typeid); |
633 if (implicit_id_count > 1) ERROR; |
|
634 if (implicit_id_count == 1) { |
|
635 /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype |
|
636 * has already been defined. So, we simly print out the id of that C datatpe... |
|
637 */ |
|
638 symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl); |
|
639 return NULL; |
|
640 } |
|
641 /* This is NOT part of an implicitly declared datatype (i.e. we are being called from an visit(ref_type_decl_c *), |
|
642 * through the visit(ref_spec_init_c*)), so we need to simply print out the name of the datatype we reference to. |
|
643 */ |
|
644 symbol->type_name->accept(*this); |
|
645 s4o_incl.print("*"); |
841 s4o_incl.print("*"); |
646 return NULL; |
842 return NULL; |
647 } |
843 } |
648 |
844 |
649 /* For the moment, we do not support initialising reference data types */ |
845 /* For the moment, we do not support initialising reference data types */ |
650 /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ |
846 /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ |
651 /* NOTE: ref_initialization may be NULL!! */ |
847 /* NOTE: ref_initialization may be NULL!! */ |
652 // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) |
848 // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) |
653 void *visit(ref_spec_init_c *symbol) { |
849 void *visit(ref_spec_init_c *symbol) { |
654 int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
850 return symbol->ref_spec->accept(*generate_c_typeid); |
655 if (implicit_id_count > 1) ERROR; |
|
656 if (implicit_id_count == 1) { |
|
657 /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype |
|
658 * has already been defined. So, we simly print out the id of that C datatpe... |
|
659 */ |
|
660 symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl); |
|
661 return NULL; |
|
662 } |
|
663 /* This is NOT part of an implicitly declared datatype (i.e. we are being called from an visit(ref_type_decl_c *)), |
|
664 * so we need to simply print out the name of the datatype we reference to. |
|
665 */ |
|
666 return symbol->ref_spec->accept(*this); |
|
667 } |
851 } |
668 |
852 |
669 /* ref_type_decl: identifier ':' ref_spec_init */ |
853 /* ref_type_decl: identifier ':' ref_spec_init */ |
670 // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) |
854 // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) |
671 void *visit(ref_type_decl_c *symbol) { |
855 void *visit(ref_type_decl_c *symbol) { |
672 TRACE("ref_type_decl_c"); |
856 TRACE("ref_type_decl_c"); |
|
857 |
|
858 /* NOTE An ref_type_decl_c will be created in stage4 for each implicitly defined REF_TO datatype, |
|
859 * and this generate_c_typedecl_c will be called to define that REF_TO datatype in C. |
|
860 * However, every implictly defined REF_TO datatype with the exact same parameters will be mapped |
|
861 * to the same identifier (e.g: __REF_TO_INT). |
|
862 * In order for the C compiler not to find the same datatype being defined two or more times, |
|
863 * we will keep track of the datatypes that have already been declared, and henceforth |
|
864 * only declare the datatypes that have not been previously defined. |
|
865 */ |
|
866 if (datatypes_already_defined.find(((identifier_c *)(symbol->ref_type_name))->value) != datatypes_already_defined.end()) |
|
867 return NULL; // already defined. No need to define it again!! |
|
868 datatypes_already_defined[((identifier_c *)(symbol->ref_type_name))->value] = 1; // insert this datatype into the list of already defined arrays! |
673 |
869 |
674 current_type_name = NULL; |
870 current_type_name = NULL; |
675 current_typedefinition = none_td; |
871 current_typedefinition = none_td; |
676 |
872 |
677 s4o_incl.print("__DECLARE_REFTO_TYPE("); |
873 s4o_incl.print("__DECLARE_REFTO_TYPE("); |
678 symbol->ref_type_name->accept(*basedecl); |
874 symbol->ref_type_name->accept(*generate_c_typeid); |
679 s4o_incl.print(", "); |
875 s4o_incl.print(", "); |
680 symbol->ref_spec_init->accept(*this); |
876 symbol->ref_spec_init->accept(*this); |
681 s4o_incl.print(")\n"); |
877 s4o_incl.print(")\n"); |
682 |
878 |
683 current_type_name = NULL; |
879 current_type_name = NULL; |
684 current_typedefinition = none_td; |
880 current_typedefinition = none_td; |
685 |
881 |
686 return NULL; |
882 return NULL; |
687 } |
883 } |
688 |
|
689 |
|
690 |
|
691 |
|
692 |
884 |
693 |
885 |
694 |
886 |
695 /*********************/ |
887 /*********************/ |
696 /* B 1.4 - Variables */ |
888 /* B 1.4 - Variables */ |
791 /********************************/ |
983 /********************************/ |
792 /* B 3.2.4 Iteration Statements */ |
984 /* B 3.2.4 Iteration Statements */ |
793 /********************************/ |
985 /********************************/ |
794 /* leave for derived classes... */ |
986 /* leave for derived classes... */ |
795 |
987 |
796 |
|
797 |
|
798 |
|
799 }; /* generate_c_typedecl_c */ |
988 }; /* generate_c_typedecl_c */ |
800 |
989 |
801 |
990 |
802 |
991 |
|
992 /***********************************************************************/ |
|
993 /***********************************************************************/ |
|
994 /***********************************************************************/ |
|
995 /***********************************************************************/ |
|
996 /***********************************************************************/ |
|
997 |
|
998 |
|
999 /* This class will generate a new datatype for each implicitly declared array datatype |
|
1000 * (i.e. arrays declared in a variable declaration, or a struct datatype declaration...) |
|
1001 * It will do the same for implicitly declared REF_TO datatypes. |
|
1002 * |
|
1003 * Each new implicitly datatype will be atributed an alias, and a C datatype will be declared for that alias. |
|
1004 * The alias itself will be stored (annotated) in the datatype object in the AST, using the annotation |
|
1005 * map reserved for stage4 anotations. The alias is stored under the "generate_c_annotaton__implicit_type_id" |
|
1006 * entry, and this entry will then be used whenever the name of the datatype is needed (to declare a varable, |
|
1007 * for example). |
|
1008 * |
|
1009 * The class will be called once for each POU declaration, and once for each derived datatype declaration. |
|
1010 * |
|
1011 * e.g.: |
|
1012 * VAR x: ARRAY [1..3] OF INT; END_VAR <---- ARRAY datatype is implicitly declared inside the variable declaration |
|
1013 * VAR y: REF_TO INT; END_VAR <---- REF_TO datatype is implicitly declared inside the variable declaration |
|
1014 * TYPE STRUCT |
|
1015 * a: ARRAY [1..3] OF INT; <---- ARRAY datatype is implicitly declared inside the struct type declaration |
|
1016 * b: REF_TO INT; <---- REF_TO datatype is implicitly declared inside the struct type declaration |
|
1017 * c: INT; |
|
1018 * END_STRUCT |
|
1019 * END_TYPE |
|
1020 */ |
|
1021 class generate_c_implicit_typedecl_c: public iterator_visitor_c { |
|
1022 private: |
|
1023 generate_c_typedecl_c *generate_c_typedecl_; |
|
1024 generate_c_typedecl_c generate_c_typedecl_local; |
|
1025 symbol_c *prefix; |
|
1026 public: |
|
1027 generate_c_implicit_typedecl_c(stage4out_c *s4o, generate_c_typedecl_c *generate_c_typedecl=NULL) |
|
1028 : generate_c_typedecl_local(s4o) { |
|
1029 generate_c_typedecl_ = generate_c_typedecl; |
|
1030 if (NULL == generate_c_typedecl_) |
|
1031 generate_c_typedecl_ = &generate_c_typedecl_local; |
|
1032 prefix = NULL; |
|
1033 }; |
|
1034 virtual ~generate_c_implicit_typedecl_c(void) { |
|
1035 } |
|
1036 |
|
1037 /*************************/ |
|
1038 /* B.1 - Common elements */ |
|
1039 /*************************/ |
|
1040 /**********************/ |
|
1041 /* B.1.3 - Data types */ |
|
1042 /**********************/ |
|
1043 /********************************/ |
|
1044 /* B 1.3.3 - Derived data types */ |
|
1045 /********************************/ |
|
1046 /* identifier ':' array_spec_init */ |
|
1047 void *visit(array_type_declaration_c *symbol) {return NULL;} // This is not an implicitly defined array! |
|
1048 |
|
1049 /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ |
|
1050 void *visit(ref_spec_c *symbol) { |
|
1051 identifier_c *id = generate_datatypes_aliasid_c::create_id(symbol); |
|
1052 /* Warning: The following is dangerous... |
|
1053 * We are asking the generate_c_typedecl_c visitor to visit a newly created ref_spec_init_c object |
|
1054 * that has not been through stage 3, and therefore does not have stage 3 annotations filled in. |
|
1055 * This will only work if generate_c_typedecl_c does ot depend on the stage 3 annotations! |
|
1056 */ |
|
1057 ref_spec_init_c ref_spec(symbol, NULL); |
|
1058 ref_type_decl_c ref_decl(id, &ref_spec); |
|
1059 ref_decl.accept(*generate_c_typedecl_); |
|
1060 symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = id; |
|
1061 return NULL; |
|
1062 } |
|
1063 |
|
1064 /* For the moment, we do not support initialising reference data types */ |
|
1065 /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ |
|
1066 /* NOTE: ref_initialization may be NULL!! */ |
|
1067 // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) |
|
1068 void *visit(ref_spec_init_c *symbol) { |
|
1069 symbol->ref_spec->accept(*this); |
|
1070 int implicit_id_count = symbol->ref_spec->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
|
1071 if (implicit_id_count > 1) ERROR; |
|
1072 if (implicit_id_count == 1) |
|
1073 symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = symbol->ref_spec->anotations_map["generate_c_annotaton__implicit_type_id"]; |
|
1074 return NULL; |
|
1075 } |
|
1076 |
|
1077 /* ref_type_decl: identifier ':' ref_spec_init */ |
|
1078 void *visit(ref_type_decl_c *symbol) {return NULL;} // This is not an implicitly defined REF_TO! |
|
1079 |
|
1080 /******************************************/ |
|
1081 /* B 1.4.3 - Declaration & Initialization */ |
|
1082 /******************************************/ |
|
1083 void *visit(edge_declaration_c *symbol) {return NULL;} |
|
1084 void *visit(en_param_declaration_c *symbol) {return NULL;} |
|
1085 void *visit(eno_param_declaration_c *symbol) {return NULL;} |
|
1086 |
|
1087 /* array_specification [ASSIGN array_initialization] */ |
|
1088 /* array_initialization may be NULL ! */ |
|
1089 void *visit(array_spec_init_c *symbol) { |
|
1090 symbol->array_specification->accept(*this); |
|
1091 int implicit_id_count = symbol->array_specification->anotations_map.count("generate_c_annotaton__implicit_type_id"); |
|
1092 if (implicit_id_count > 1) ERROR; |
|
1093 if (implicit_id_count == 1) |
|
1094 symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = symbol->array_specification->anotations_map["generate_c_annotaton__implicit_type_id"]; |
|
1095 return NULL; |
|
1096 } |
|
1097 |
|
1098 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
|
1099 void *visit(array_specification_c *symbol) { |
|
1100 identifier_c *id = generate_datatypes_aliasid_c::create_id(symbol); |
|
1101 /* Warning: The following is dangerous... |
|
1102 * We are asking the generate_c_typedecl_c visitor to visit a newly created array_type_declaration_c object |
|
1103 * that has not been through stage 3, and therefore does not have stage 3 annotations filled in. |
|
1104 * This will only work if generate_c_typedecl_c does ot depend on the stage 3 annotations! |
|
1105 */ |
|
1106 array_spec_init_c array_spec(symbol, NULL); |
|
1107 array_type_declaration_c array_decl(id, &array_spec); |
|
1108 array_decl.datatype = symbol->datatype; |
|
1109 array_spec.datatype = symbol->datatype; |
|
1110 array_decl.accept(*generate_c_typedecl_); |
|
1111 symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = id; |
|
1112 return NULL; |
|
1113 } |
|
1114 |
|
1115 /* var1_list ':' initialized_structure */ |
|
1116 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) |
|
1117 void *visit(structured_var_init_decl_c *symbol) {return NULL;} |
|
1118 |
|
1119 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */ |
|
1120 /* structure_initialization -> may be NULL ! */ |
|
1121 void *visit(fb_name_decl_c *symbol) {return NULL;} |
|
1122 |
|
1123 /* var1_list ':' structure_type_name */ |
|
1124 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) |
|
1125 void *visit(structured_var_declaration_c *symbol) {return NULL;} |
|
1126 |
|
1127 |
|
1128 /***********************/ |
|
1129 /* B 1.5.1 - Functions */ |
|
1130 /***********************/ |
|
1131 void *visit(function_declaration_c *symbol) { |
|
1132 prefix = symbol->derived_function_name; |
|
1133 symbol->var_declarations_list->accept(*this); |
|
1134 prefix = NULL; |
|
1135 return NULL; |
|
1136 } |
|
1137 /*****************************/ |
|
1138 /* B 1.5.2 - Function Blocks */ |
|
1139 /*****************************/ |
|
1140 void *visit(function_block_declaration_c *symbol) { |
|
1141 prefix = symbol->fblock_name; |
|
1142 symbol->var_declarations->accept(*this); |
|
1143 prefix = NULL; |
|
1144 return NULL; |
|
1145 } |
|
1146 /**********************/ |
|
1147 /* B 1.5.3 - Programs */ |
|
1148 /**********************/ |
|
1149 void *visit(program_declaration_c *symbol) { |
|
1150 prefix = symbol->program_type_name; |
|
1151 symbol->var_declarations->accept(*this); |
|
1152 prefix = NULL; |
|
1153 return NULL; |
|
1154 } |
|
1155 }; |
|
1156 |
|
1157 |
|
1158 |
|
1159 |
|
1160 |