29 stage4out_c &s4o_incl; |
29 stage4out_c &s4o_incl; |
30 |
30 |
31 private: |
31 private: |
32 symbol_c* current_type_name; |
32 symbol_c* current_type_name; |
33 bool array_is_derived; |
33 bool array_is_derived; |
34 |
|
35 generate_c_base_c *basedecl; |
34 generate_c_base_c *basedecl; |
36 |
35 |
37 public: |
36 public: |
38 generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { |
|
39 current_typedefinition = none_td; |
|
40 current_basetypedeclaration = none_bd; |
|
41 current_type_name = NULL; |
|
42 basedecl = new generate_c_base_c(&s4o_incl); |
|
43 } |
|
44 generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { |
37 generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { |
45 current_typedefinition = none_td; |
38 current_typedefinition = none_td; |
46 current_basetypedeclaration = none_bd; |
39 current_basetypedeclaration = none_bd; |
47 current_type_name = NULL; |
40 current_type_name = NULL; |
48 basedecl = new generate_c_base_c(&s4o_incl); |
41 basedecl = new generate_c_base_c(&s4o_incl); |
191 return NULL; |
181 return NULL; |
192 } |
182 } |
193 |
183 |
194 /* integer_type_name '(' subrange')' */ |
184 /* integer_type_name '(' subrange')' */ |
195 void *visit(subrange_specification_c *symbol) { |
185 void *visit(subrange_specification_c *symbol) { |
|
186 TRACE("subrange_specification_c"); |
196 if (current_typedefinition == subrange_td) { |
187 if (current_typedefinition == subrange_td) { |
197 switch (current_basetypedeclaration) { |
188 switch (current_basetypedeclaration) { |
198 case subrangebasetype_bd: |
189 case subrangebasetype_bd: |
199 symbol->integer_type_name->accept(*basedecl); |
190 symbol->integer_type_name->accept(*basedecl); |
200 break; |
191 break; |
201 case subrangetest_bd: |
192 case subrangetest_bd: |
202 if (symbol->subrange != NULL) { |
193 if (symbol->subrange != NULL) { |
203 current_type_name->accept(*this); |
194 s4o_incl.print("static inline "); |
204 s4o.print(" __CHECK_"); |
195 current_type_name->accept(*basedecl); |
205 current_type_name->accept(*this); |
196 s4o_incl.print(" __CHECK_"); |
206 s4o.print("("); |
197 current_type_name->accept(*basedecl); |
207 current_type_name->accept(*this); |
198 s4o_incl.print("("); |
208 s4o.print(" value) {\n"); |
199 current_type_name->accept(*basedecl); |
209 s4o.indent_right(); |
200 s4o_incl.print(" value) {\n"); |
210 |
201 s4o_incl.indent_right(); |
211 if (search_base_type_c::type_is_subrange(symbol->integer_type_name)) { |
202 |
212 s4o.print(s4o.indent_spaces + "value = __CHECK_"); |
203 /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */ |
|
204 /* For this reason, the following condition will always be false, and therefore this is a block |
|
205 * of dead code. However, let's not delete it for now. It might come in useful for IEC 61131-3 v3. |
|
206 * For the moment, we just comment it out! |
|
207 */ |
|
208 /* |
|
209 if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) { |
|
210 s4o_incl.print(s4o_incl.indent_spaces + "value = __CHECK_"); |
213 symbol->integer_type_name->accept(*this); |
211 symbol->integer_type_name->accept(*this); |
214 s4o.print("(value);\n"); |
212 s4o_incl.print("(value);\n"); |
215 } |
213 } |
|
214 */ |
216 |
215 |
217 symbol->subrange->accept(*this); |
216 symbol->subrange->accept(*this); |
218 |
217 |
219 s4o.indent_left(); |
218 s4o_incl.indent_left(); |
220 s4o.print("}\n"); |
219 s4o_incl.print("}\n"); |
221 } |
220 } |
222 else { |
221 else { |
223 s4o.print("#define __CHECK_"); |
222 s4o_incl.print("#define __CHECK_"); |
224 current_type_name->accept(*this); |
223 current_type_name->accept(*basedecl); |
225 s4o.print(" __CHECK_"); |
224 s4o_incl.print(" __CHECK_"); |
226 symbol->integer_type_name->accept(*this); |
225 symbol->integer_type_name->accept(*basedecl); |
227 s4o.print("\n"); |
226 s4o_incl.print("\n"); |
228 } |
227 } |
229 break; |
228 break; |
230 default: |
229 default: |
231 break; |
230 break; |
232 } |
231 } |
233 } |
232 } |
234 else { |
233 return NULL; |
235 symbol->integer_type_name->accept(*basedecl); |
234 } |
236 } |
235 |
237 return NULL; |
|
238 } |
|
239 |
236 |
240 /* signed_integer DOTDOT signed_integer */ |
237 /* signed_integer DOTDOT signed_integer */ |
241 void *visit(subrange_c *symbol) { |
238 void *visit(subrange_c *symbol) { |
|
239 TRACE("subrange_c"); |
242 int dimension; |
240 int dimension; |
243 switch (current_typedefinition) { |
241 switch (current_typedefinition) { |
244 case array_td: |
242 case array_td: |
245 if (current_basetypedeclaration == arraysubrange_bd) { |
243 if (current_basetypedeclaration == arraysubrange_bd) { |
246 s4o_incl.print("["); |
244 s4o_incl.print("["); |
249 } |
247 } |
250 else |
248 else |
251 symbol->lower_limit->accept(*this); |
249 symbol->lower_limit->accept(*this); |
252 break; |
250 break; |
253 case subrange_td: |
251 case subrange_td: |
254 s4o.print(s4o.indent_spaces + "if (value < "); |
252 s4o_incl.print(s4o_incl.indent_spaces + "if (value < "); |
255 symbol->lower_limit->accept(*this); |
253 symbol->lower_limit->accept(*basedecl); |
256 s4o.print(")\n"); |
254 s4o_incl.print(")\n"); |
257 s4o.indent_right(); |
255 s4o_incl.indent_right(); |
258 s4o.print(s4o.indent_spaces + "return "); |
256 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
259 symbol->lower_limit->accept(*this); |
257 symbol->lower_limit->accept(*basedecl); |
260 s4o.print(";\n"); |
258 s4o_incl.print(";\n"); |
261 s4o.indent_left(); |
259 s4o_incl.indent_left(); |
262 s4o.print(s4o.indent_spaces + "else if (value > "); |
260 s4o_incl.print(s4o_incl.indent_spaces + "else if (value > "); |
263 symbol->upper_limit->accept(*this); |
261 symbol->upper_limit->accept(*basedecl); |
264 s4o.print(")\n"); |
262 s4o_incl.print(")\n"); |
265 s4o.indent_right(); |
263 s4o_incl.indent_right(); |
266 s4o.print(s4o.indent_spaces + "return "); |
264 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
267 symbol->upper_limit->accept(*this); |
265 symbol->upper_limit->accept(*basedecl); |
268 s4o.print(";\n"); |
266 s4o_incl.print(";\n"); |
269 s4o.indent_left(); |
267 s4o_incl.indent_left(); |
270 s4o.print(s4o.indent_spaces + "else\n"); |
268 s4o_incl.print(s4o_incl.indent_spaces + "else\n"); |
271 s4o.indent_right(); |
269 s4o_incl.indent_right(); |
272 s4o.print(s4o.indent_spaces + "return value;\n"); |
270 s4o_incl.print(s4o_incl.indent_spaces + "return value;\n"); |
273 s4o.indent_left(); |
271 s4o_incl.indent_left(); |
274 default: |
272 default: |
275 break; |
273 break; |
276 } |
274 } |
277 return NULL; |
275 return NULL; |
278 } |
276 } |
309 } |
307 } |
310 |
308 |
311 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
309 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
312 /* enumerated_value_list ',' enumerated_value */ |
310 /* enumerated_value_list ',' enumerated_value */ |
313 void *visit(enumerated_value_list_c *symbol) { |
311 void *visit(enumerated_value_list_c *symbol) { |
|
312 TRACE("enumerated_value_list_c"); |
314 print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); |
313 print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); |
315 return NULL; |
314 return NULL; |
316 } |
315 } |
317 |
316 |
318 /* enumerated_type_name '#' identifier */ |
317 /* enumerated_type_name '#' identifier */ |
319 void *visit(enumerated_value_c *symbol) { |
318 /* Handled by generate_c_base_c class!! |
320 if (current_typedefinition == enumerated_td) |
319 void *visit(enumerated_value_c *symbol) {} |
321 current_type_name->accept(*basedecl); |
320 */ |
322 else { |
|
323 if (NULL == symbol->datatype) { |
|
324 debug_c::print(symbol); |
|
325 ERROR; |
|
326 } |
|
327 symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype); |
|
328 if (NULL == type_name) { |
|
329 // ERROR_MSG("generate_c does not support anonymous enumerated data types."); |
|
330 } else |
|
331 type_name->accept(*basedecl); |
|
332 } |
|
333 s4o_incl.print("__"); |
|
334 symbol->value->accept(*basedecl); |
|
335 return NULL; |
|
336 } |
|
337 |
321 |
338 /* identifier ':' array_spec_init */ |
322 /* identifier ':' array_spec_init */ |
339 void *visit(array_type_declaration_c *symbol) { |
323 void *visit(array_type_declaration_c *symbol) { |
340 TRACE("array_type_declaration_c"); |
324 TRACE("array_type_declaration_c"); |
341 |
325 |
410 break; |
395 break; |
411 } |
396 } |
412 return NULL; |
397 return NULL; |
413 } |
398 } |
414 |
399 |
415 /* helper symbol for array_specification */ |
|
416 /* array_subrange_list ',' subrange */ |
|
417 void *visit(array_subrange_list_c *symbol) { |
|
418 print_list(symbol); |
|
419 return NULL; |
|
420 } |
|
421 |
400 |
422 /* TYPE type_declaration_list END_TYPE */ |
401 /* TYPE type_declaration_list END_TYPE */ |
423 void *visit(data_type_declaration_c *symbol) { |
402 void *visit(data_type_declaration_c *symbol) { |
424 TRACE("data_type_declaration_c"); |
403 TRACE("data_type_declaration_c"); |
425 symbol->type_declaration_list->accept(*this); |
404 symbol->type_declaration_list->accept(*this); |
426 s4o.print("\n\n"); |
405 s4o_incl.print("\n\n"); |
427 return NULL; |
406 return NULL; |
428 } |
407 } |
429 |
408 |
430 /* helper symbol for data_type_declaration */ |
409 /* helper symbol for data_type_declaration */ |
431 void *visit(type_declaration_list_c *symbol) { |
410 void *visit(type_declaration_list_c *symbol) { |
441 symbol->simple_type_name->accept(*basedecl); |
420 symbol->simple_type_name->accept(*basedecl); |
442 s4o_incl.print(","); |
421 s4o_incl.print(","); |
443 symbol->simple_spec_init->accept(*this); |
422 symbol->simple_spec_init->accept(*this); |
444 s4o_incl.print(")\n"); |
423 s4o_incl.print(")\n"); |
445 |
424 |
446 if (search_base_type_c::type_is_subrange(symbol->simple_type_name)) { |
425 if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) { |
447 s4o.print("#define __CHECK_"); |
426 s4o_incl.print("#define __CHECK_"); |
448 current_type_name->accept(*this); |
427 current_type_name->accept(*basedecl); |
449 s4o.print(" __CHECK_"); |
428 s4o_incl.print(" __CHECK_"); |
450 symbol->simple_spec_init->accept(*this); |
429 symbol->simple_spec_init->accept(*this); |
451 s4o.print("\n"); |
430 s4o_incl.print("\n"); |
452 } |
431 } |
453 |
432 |
454 return NULL; |
433 return NULL; |
455 } |
434 } |
456 |
435 |