stage4/generate_c/generate_c.cc
changeset 870 9c6c588fd708
parent 864 300c27c08753
child 872 3d682f87c870
equal deleted inserted replaced
822:a7d9e0b8636b 870:9c6c588fd708
   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) {
  1052 
  1183 
  1053   public:
  1184   public:
  1054 /********************/
  1185 /********************/
  1055 /* 2.1.6 - Pragmas  */
  1186 /* 2.1.6 - Pragmas  */
  1056 /********************/
  1187 /********************/
  1057 void *visit(enable_code_generation_pragma_c * symbol)   {s4o_ptr->enable_output();  return NULL;}
  1188 void *visit(enable_code_generation_pragma_c * symbol)   {s4o.enable_output();  return NULL;}
  1058 void *visit(disable_code_generation_pragma_c * symbol)  {s4o_ptr->disable_output(); return NULL;} 
  1189 void *visit(disable_code_generation_pragma_c * symbol)  {s4o.disable_output(); return NULL;} 
  1059 
  1190 
  1060 /*************************/
  1191 /*************************/
  1061 /* B.1 - Common elements */
  1192 /* B.1 - Common elements */
  1062 /*************************/
  1193 /*************************/
  1063 /*******************************************/
  1194 /*******************************************/
  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 {
  1644 public:
  1772 public:
  1645 /********************/
  1773 /********************/
  1646 /* 2.1.6 - Pragmas  */
  1774 /* 2.1.6 - Pragmas  */
  1647 /********************/
  1775 /********************/
  1648 void *visit(enable_code_generation_pragma_c * symbol)   {
  1776 void *visit(enable_code_generation_pragma_c * symbol)   {
  1649     s4o_ptr->enable_output();
  1777     s4o.enable_output();
  1650     s4o_incl_ptr->enable_output();
  1778     s4o_incl.enable_output();
  1651     return NULL;
  1779     return NULL;
  1652 }
  1780 }
  1653 
  1781 
  1654 void *visit(disable_code_generation_pragma_c * symbol)  {
  1782 void *visit(disable_code_generation_pragma_c * symbol)  {
  1655     s4o_ptr->disable_output();
  1783     s4o.disable_output();
  1656     s4o_incl_ptr->disable_output();    
  1784     s4o_incl.disable_output();    
  1657     return NULL;
  1785     return NULL;
  1658 }
  1786 }
  1659     
  1787     
  1660     
  1788     
  1661 /********************************/
  1789 /********************************/