stage4/generate_c/generate_c.cc
changeset 863 06820d03a433
parent 854 13d0b67de111
child 864 300c27c08753
equal deleted inserted replaced
854:13d0b67de111 863:06820d03a433
   340 /***********************************************************************/
   340 /***********************************************************************/
   341 /***********************************************************************/
   341 /***********************************************************************/
   342 
   342 
   343 /* A helper class that analyses if the datatype of a variable is 'complex'. */
   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!               */
   344 /* 'complex' means that it is either a strcuture or an array!               */
   345 class analyse_variable_c: public null_visitor_c {
   345 class analyse_variable_c: public search_visitor_c {
   346   private:
   346   private:
   347     static analyse_variable_c *singleton_;
   347     static analyse_variable_c *singleton_;
   348     bool   contains_complex_type_res;
       
   349 
   348 
   350   public:
   349   public:
   351     analyse_variable_c(void) {};
   350     analyse_variable_c(void) {};
   352     
   351     
   353     static bool is_complex_type(symbol_c *symbol) {
   352     static bool is_complex_type(symbol_c *symbol) {
   354       if (NULL == symbol)           ERROR;
   353       if (NULL == symbol) ERROR;
   355       if (!get_datatype_info_c::is_type_valid     (symbol->datatype)) ERROR;
   354       if (!get_datatype_info_c::is_type_valid     (symbol->datatype)) ERROR;
   356       return (   get_datatype_info_c::is_structure(symbol->datatype) 
   355       return (   get_datatype_info_c::is_structure(symbol->datatype) 
   357               || get_datatype_info_c::is_array    (symbol->datatype) 
   356               || get_datatype_info_c::is_array    (symbol->datatype) 
   358              );
   357              );
   359     }
   358     }
   360 
   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     
   361     /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */
   381     /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */
   362     /* eg:
   382     /* eg:
   363      *      fb1.fb2.fb3.real       returns FALSE
   383      *      fb1.fb2.fb3.real       returns FALSE
   364      *      fb1.fb2.struct1.real   returns TRUE
   384      *      fb1.fb2.struct1.real   returns TRUE
   365      *      struct1.real           returns TRUE
   385      *      struct1.real           returns TRUE
   366      */
   386      */
   367     static bool contains_complex_type(symbol_c *symbol) {
   387     static bool contains_complex_type(symbol_c *symbol) {
   368       if (NULL == singleton_)       singleton_ = new analyse_variable_c();
   388       if (NULL == symbol) ERROR;
   369       if (NULL == singleton_)       ERROR;
   389       if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
   370       if (NULL == symbol)           ERROR;
   390       
   371       if (NULL == symbol->datatype) ERROR;
   391       symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
   372       
   392       return is_complex_type(first_non_fb->datatype);
   373       singleton_->contains_complex_type_res = false;
   393     }
   374       symbol->accept(*singleton_);
   394     
   375       return singleton_->contains_complex_type_res;
   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);
   376     }
   415     }
   377     
   416     
   378     
   417     
   379     /*********************/
   418     /*********************/
   380     /* B 1.4 - Variables */
   419     /* B 1.4 - Variables */
   381     /*********************/
   420     /*********************/
   382     void *visit(symbolic_variable_c *symbol) {
   421     void *visit(symbolic_variable_c *symbol) {
   383       contains_complex_type_res |= is_complex_type(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;
   384       return NULL;
   428       return NULL;
   385     }
   429     }
   386     
   430     
   387     /*************************************/
   431     /*************************************/
   388     /* B.1.4.2   Multi-element Variables */
   432     /* B.1.4.2   Multi-element Variables */
   389     /*************************************/
   433     /*************************************/
   390     
   434     
   391     // SYM_REF2(structured_variable_c, record_variable, field_selector)
   435     // SYM_REF2(structured_variable_c, record_variable, field_selector)
   392     void *visit(structured_variable_c *symbol) {
   436     void *visit(structured_variable_c *symbol) {
   393       symbol->record_variable->accept(*this);
   437       symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this);
   394       /* do not set the contains_complex_type_res to TRUE if this structured_variable_c is accessing a FB instance! */
   438       if (NULL != res) return res;
   395       if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
   439       
   396       contains_complex_type_res |= get_datatype_info_c::is_structure(symbol->datatype);
   440       if (!get_datatype_info_c::is_type_valid    (symbol->datatype)) ERROR;
   397       return NULL;
   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;      
   398     }
   448     }
   399     
   449     
   400     /*  subscripted_variable '[' subscript_list ']' */
   450     /*  subscripted_variable '[' subscript_list ']' */
   401     //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   451     //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   402     void *visit(array_variable_c *symbol) {
   452     void *visit(array_variable_c *symbol) {
   403       contains_complex_type_res |= true;
   453       void *res = symbol->subscripted_variable->accept(*this);
   404       return NULL;
   454       if (NULL != res) return res;
   405     }
   455       return (void *)symbol;      
   406 
   456     }
       
   457 
       
   458     
   407 };
   459 };
   408 
   460 
   409 analyse_variable_c *analyse_variable_c::singleton_ = NULL;
   461 analyse_variable_c *analyse_variable_c::singleton_ = NULL;
   410 
   462 
   411 /***********************************************************************/
   463 /***********************************************************************/