338 /***********************************************************************/ |
338 /***********************************************************************/ |
339 /***********************************************************************/ |
339 /***********************************************************************/ |
340 /***********************************************************************/ |
340 /***********************************************************************/ |
341 /***********************************************************************/ |
341 /***********************************************************************/ |
342 |
342 |
|
343 /* A helper class that analyses if the datatype of a variable is 'complex'. */ |
|
344 /* 'complex' means that it is either a strcuture or an array! */ |
|
345 class analyse_variable_c: public search_visitor_c { |
|
346 private: |
|
347 static analyse_variable_c *singleton_; |
|
348 |
|
349 public: |
|
350 analyse_variable_c(void) {}; |
|
351 |
|
352 static bool is_complex_type(symbol_c *symbol) { |
|
353 if (NULL == symbol) ERROR; |
|
354 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR; |
|
355 return ( get_datatype_info_c::is_structure(symbol->datatype) |
|
356 || get_datatype_info_c::is_array (symbol->datatype) |
|
357 ); |
|
358 } |
|
359 |
|
360 |
|
361 private: |
|
362 symbol_c *last_fb, *first_non_fb_identifier; |
|
363 |
|
364 public: |
|
365 /* returns the first element (from left to right) in a structured variable that is not a FB, i.e. is either a structure or an array! */ |
|
366 /* eg: |
|
367 * fb1.fb2.fb3.real returns ?????? |
|
368 * fb1.fb2.struct1.real returns struct1 |
|
369 * struct1.real returns struct1 |
|
370 */ |
|
371 static symbol_c *find_first_nonfb(symbol_c *symbol) { |
|
372 if (NULL == singleton_) singleton_ = new analyse_variable_c(); |
|
373 if (NULL == singleton_) ERROR; |
|
374 if (NULL == symbol) ERROR; |
|
375 |
|
376 singleton_->last_fb = NULL; |
|
377 singleton_->first_non_fb_identifier = NULL; |
|
378 return (symbol_c *)symbol->accept(*singleton_); |
|
379 } |
|
380 |
|
381 /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */ |
|
382 /* eg: |
|
383 * fb1.fb2.fb3.real returns FALSE |
|
384 * fb1.fb2.struct1.real returns TRUE |
|
385 * struct1.real returns TRUE |
|
386 */ |
|
387 static bool contains_complex_type(symbol_c *symbol) { |
|
388 if (NULL == symbol) ERROR; |
|
389 if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR; |
|
390 |
|
391 symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol); |
|
392 return is_complex_type(first_non_fb->datatype); |
|
393 } |
|
394 |
|
395 |
|
396 /* returns the datatype of the variable returned by find_first_nonfb() */ |
|
397 /* eg: |
|
398 * fb1.fb2.fb3.real returns ?????? |
|
399 * fb1.fb2.struct1.real returns datatype of struct1 |
|
400 * struct1.real returns datatype of struct1 |
|
401 */ |
|
402 static search_var_instance_decl_c::vt_t first_nonfb_vardecltype(symbol_c *symbol, symbol_c *scope) { |
|
403 if (NULL == symbol) ERROR; |
|
404 if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR; |
|
405 |
|
406 symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol); |
|
407 if (NULL != singleton_->last_fb) { |
|
408 scope = singleton_->last_fb->datatype; |
|
409 symbol = singleton_->first_non_fb_identifier; |
|
410 } |
|
411 |
|
412 search_var_instance_decl_c search_var_instance_decl(scope); |
|
413 |
|
414 return search_var_instance_decl.get_vartype(symbol); |
|
415 } |
|
416 |
|
417 |
|
418 /*********************/ |
|
419 /* B 1.4 - Variables */ |
|
420 /*********************/ |
|
421 void *visit(symbolic_variable_c *symbol) { |
|
422 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR; |
|
423 if (!get_datatype_info_c::is_function_block(symbol->datatype)) { |
|
424 first_non_fb_identifier = symbol; |
|
425 return (void *)symbol; |
|
426 } |
|
427 last_fb = symbol; |
|
428 return NULL; |
|
429 } |
|
430 |
|
431 /*************************************/ |
|
432 /* B.1.4.2 Multi-element Variables */ |
|
433 /*************************************/ |
|
434 |
|
435 // SYM_REF2(structured_variable_c, record_variable, field_selector) |
|
436 void *visit(structured_variable_c *symbol) { |
|
437 symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this); |
|
438 if (NULL != res) return res; |
|
439 |
|
440 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR; |
|
441 if (!get_datatype_info_c::is_function_block(symbol->datatype)) { |
|
442 first_non_fb_identifier = symbol->field_selector; |
|
443 return (void *)symbol; |
|
444 } |
|
445 |
|
446 last_fb = symbol; |
|
447 return NULL; |
|
448 } |
|
449 |
|
450 /* subscripted_variable '[' subscript_list ']' */ |
|
451 //SYM_REF2(array_variable_c, subscripted_variable, subscript_list) |
|
452 void *visit(array_variable_c *symbol) { |
|
453 void *res = symbol->subscripted_variable->accept(*this); |
|
454 if (NULL != res) return res; |
|
455 return (void *)symbol; |
|
456 } |
|
457 |
|
458 |
|
459 }; |
|
460 |
|
461 analyse_variable_c *analyse_variable_c::singleton_ = NULL; |
|
462 |
|
463 /***********************************************************************/ |
|
464 /***********************************************************************/ |
|
465 /***********************************************************************/ |
|
466 /***********************************************************************/ |
|
467 |
343 |
468 |
344 #include "generate_c_st.cc" |
469 #include "generate_c_st.cc" |
345 #include "generate_c_il.cc" |
470 #include "generate_c_il.cc" |
346 #include "generate_c_inlinefcall.cc" |
471 #include "generate_c_inlinefcall.cc" |
347 |
472 |
586 arrayname_im, |
711 arrayname_im, |
587 arraydeclaration_im |
712 arraydeclaration_im |
588 } inlinearray_mode_t; |
713 } inlinearray_mode_t; |
589 |
714 |
590 private: |
715 private: |
591 stage4out_c *s4o_ptr; |
|
592 std::map<std::string, int> inline_array_defined; |
716 std::map<std::string, int> inline_array_defined; |
593 std::string current_array_name; |
717 std::string current_array_name; |
594 inlinearray_mode_t current_mode; |
718 inlinearray_mode_t current_mode; |
595 |
719 |
596 public: |
720 public: |
597 generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
721 generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
598 : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { |
722 : generate_c_typedecl_c(s4o_incl_ptr) { |
599 generate_c_datatypes_c::s4o_ptr = s4o_ptr; |
|
600 current_mode = none_im; |
723 current_mode = none_im; |
601 }; |
724 }; |
602 virtual ~generate_c_datatypes_c(void) { |
725 virtual ~generate_c_datatypes_c(void) { |
603 while (!inline_array_defined.empty()) { |
726 while (!inline_array_defined.empty()) { |
604 inline_array_defined.erase(inline_array_defined.begin()); |
727 inline_array_defined.erase(inline_array_defined.begin()); |
780 /* array_specification [ASSIGN array_initialization] */ |
903 /* array_specification [ASSIGN array_initialization] */ |
781 /* array_initialization may be NULL ! */ |
904 /* array_initialization may be NULL ! */ |
782 void *visit(array_spec_init_c *symbol) { |
905 void *visit(array_spec_init_c *symbol) { |
783 switch (current_mode) { |
906 switch (current_mode) { |
784 case arraydeclaration_im: |
907 case arraydeclaration_im: |
|
908 { |
|
909 array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification); |
|
910 if (specification != NULL) |
|
911 symbol->array_specification->accept(*this); |
|
912 } |
|
913 break; |
785 case arrayname_im: |
914 case arrayname_im: |
786 { |
915 { |
787 array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification); |
916 array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification); |
788 if (specification != NULL) |
917 if (specification != NULL) |
789 symbol->array_specification->accept(*this); |
918 symbol->array_specification->accept(*this); |
|
919 identifier_c *name = dynamic_cast<identifier_c*>(symbol->array_specification); |
|
920 if (name != NULL) |
|
921 s4o_incl.print(name->value); |
790 } |
922 } |
791 break; |
923 break; |
792 default: |
924 default: |
793 return generate_c_typedecl_c::visit(symbol); |
925 return generate_c_typedecl_c::visit(symbol); |
794 break; |
926 break; |
1011 /***********************************************************************/ |
1143 /***********************************************************************/ |
1012 /***********************************************************************/ |
1144 /***********************************************************************/ |
1013 /***********************************************************************/ |
1145 /***********************************************************************/ |
1014 |
1146 |
1015 |
1147 |
1016 class generate_c_pous_c: public generate_c_typedecl_c { |
1148 class generate_c_pous_c: public generate_c_base_c { |
1017 private: |
1149 private: |
1018 stage4out_c *s4o_ptr; |
1150 stage4out_c &s4o_incl; |
1019 |
1151 |
1020 public: |
1152 public: |
1021 generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
1153 generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
1022 : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { |
1154 : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { |
1023 generate_c_pous_c::s4o_ptr = s4o_ptr; |
|
1024 }; |
1155 }; |
1025 virtual ~generate_c_pous_c(void) {} |
1156 virtual ~generate_c_pous_c(void) {} |
1026 |
1157 |
1027 private: |
1158 private: |
1028 void print_end_of_block_label(void) { |
1159 void print_end_of_block_label(void) { |
1615 /***********************************************************************/ |
1746 /***********************************************************************/ |
1616 /***********************************************************************/ |
1747 /***********************************************************************/ |
1617 /***********************************************************************/ |
1748 /***********************************************************************/ |
1618 /***********************************************************************/ |
1749 /***********************************************************************/ |
1619 |
1750 |
1620 class generate_c_config_c: public generate_c_typedecl_c { |
1751 class generate_c_config_c: public generate_c_base_c { |
1621 private: |
1752 private: |
1622 stage4out_c *s4o_ptr; |
1753 stage4out_c &s4o_incl; |
1623 stage4out_c *s4o_incl_ptr; |
|
1624 |
1754 |
1625 public: |
1755 public: |
1626 generate_c_config_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
1756 generate_c_config_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
1627 : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { |
1757 : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { |
1628 generate_c_config_c::s4o_ptr = s4o_ptr; |
|
1629 generate_c_config_c::s4o_incl_ptr = s4o_incl_ptr; |
|
1630 }; |
1758 }; |
1631 |
1759 |
1632 virtual ~generate_c_config_c(void) {} |
1760 virtual ~generate_c_config_c(void) {} |
1633 |
1761 |
1634 typedef enum { |
1762 typedef enum { |