merge
authormjsousa
Tue, 11 Feb 2014 10:55:27 +0000
changeset 864 300c27c08753
parent 862 2b6b1202f8a8 (current diff)
parent 863 06820d03a433 (diff)
child 865 7365c3e5c9ae
merge
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_st.cc
--- a/stage4/generate_c/generate_c.cc	Sun Feb 09 08:05:44 2014 +0000
+++ b/stage4/generate_c/generate_c.cc	Tue Feb 11 10:55:27 2014 +0000
@@ -342,22 +342,42 @@
 
 /* A helper class that analyses if the datatype of a variable is 'complex'. */
 /* 'complex' means that it is either a strcuture or an array!               */
-class analyse_variable_c: public null_visitor_c {
+class analyse_variable_c: public search_visitor_c {
   private:
     static analyse_variable_c *singleton_;
-    bool   contains_complex_type_res;
 
   public:
     analyse_variable_c(void) {};
     
     static bool is_complex_type(symbol_c *symbol) {
-      if (NULL == symbol)           ERROR;
+      if (NULL == symbol) ERROR;
       if (!get_datatype_info_c::is_type_valid     (symbol->datatype)) ERROR;
       return (   get_datatype_info_c::is_structure(symbol->datatype) 
               || get_datatype_info_c::is_array    (symbol->datatype) 
              );
     }
 
+    
+  private:
+    symbol_c *last_fb, *first_non_fb_identifier;
+
+  public:  
+    /* 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! */
+    /* eg:
+     *      fb1.fb2.fb3.real       returns ??????
+     *      fb1.fb2.struct1.real   returns struct1
+     *      struct1.real           returns struct1
+     */
+    static symbol_c *find_first_nonfb(symbol_c *symbol) {
+      if (NULL == singleton_)       singleton_ = new analyse_variable_c();
+      if (NULL == singleton_)       ERROR;
+      if (NULL == symbol)           ERROR;
+      
+      singleton_->last_fb                 = NULL;
+      singleton_->first_non_fb_identifier = NULL;
+      return (symbol_c *)symbol->accept(*singleton_);
+    }
+    
     /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */
     /* eg:
      *      fb1.fb2.fb3.real       returns FALSE
@@ -365,14 +385,33 @@
      *      struct1.real           returns TRUE
      */
     static bool contains_complex_type(symbol_c *symbol) {
-      if (NULL == singleton_)       singleton_ = new analyse_variable_c();
-      if (NULL == singleton_)       ERROR;
-      if (NULL == symbol)           ERROR;
-      if (NULL == symbol->datatype) ERROR;
-      
-      singleton_->contains_complex_type_res = false;
-      symbol->accept(*singleton_);
-      return singleton_->contains_complex_type_res;
+      if (NULL == symbol) ERROR;
+      if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+      
+      symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+      return is_complex_type(first_non_fb->datatype);
+    }
+    
+    
+    /* returns the datatype of the variable returned by find_first_nonfb() */
+    /* eg:
+     *      fb1.fb2.fb3.real       returns ??????
+     *      fb1.fb2.struct1.real   returns datatype of struct1
+     *      struct1.real           returns datatype of struct1
+     */
+    static search_var_instance_decl_c::vt_t first_nonfb_vardecltype(symbol_c *symbol, symbol_c *scope) {
+      if (NULL == symbol) ERROR;
+      if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+      
+      symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+      if (NULL != singleton_->last_fb) {
+        scope = singleton_->last_fb->datatype;
+        symbol = singleton_->first_non_fb_identifier;
+      }
+      
+      search_var_instance_decl_c search_var_instance_decl(scope);
+      
+      return search_var_instance_decl.get_vartype(symbol);
     }
     
     
@@ -380,7 +419,12 @@
     /* B 1.4 - Variables */
     /*********************/
     void *visit(symbolic_variable_c *symbol) {
-      contains_complex_type_res |= is_complex_type(symbol);
+      if (!get_datatype_info_c::is_type_valid    (symbol->datatype)) ERROR;
+      if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+         first_non_fb_identifier = symbol; 
+         return (void *)symbol;
+      }
+      last_fb = symbol;
       return NULL;
     }
     
@@ -390,20 +434,28 @@
     
     // SYM_REF2(structured_variable_c, record_variable, field_selector)
     void *visit(structured_variable_c *symbol) {
-      symbol->record_variable->accept(*this);
-      /* do not set the contains_complex_type_res to TRUE if this structured_variable_c is accessing a FB instance! */
-      if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
-      contains_complex_type_res |= get_datatype_info_c::is_structure(symbol->datatype);
-      return NULL;
+      symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this);
+      if (NULL != res) return res;
+      
+      if (!get_datatype_info_c::is_type_valid    (symbol->datatype)) ERROR;
+      if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+         first_non_fb_identifier = symbol->field_selector; 
+         return (void *)symbol;
+      }
+
+      last_fb = symbol;      
+      return NULL;      
     }
     
     /*  subscripted_variable '[' subscript_list ']' */
     //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
     void *visit(array_variable_c *symbol) {
-      contains_complex_type_res |= true;
-      return NULL;
-    }
-
+      void *res = symbol->subscripted_variable->accept(*this);
+      if (NULL != res) return res;
+      return (void *)symbol;      
+    }
+
+    
 };
 
 analyse_variable_c *analyse_variable_c::singleton_ = NULL;
--- a/stage4/generate_c/generate_c_st.cc	Sun Feb 09 08:05:44 2014 +0000
+++ b/stage4/generate_c/generate_c_st.cc	Tue Feb 11 10:55:27 2014 +0000
@@ -76,10 +76,11 @@
      * so we do not create an object instance when handling
      * a function declaration.
      */
-    search_fb_instance_decl_c *search_fb_instance_decl;
-
+    search_fb_instance_decl_c    *search_fb_instance_decl;
     search_varfb_instance_type_c *search_varfb_instance_type;
     search_var_instance_decl_c   *search_var_instance_decl;
+    
+    symbol_c *scope_;
 
     symbol_c* current_array_type;
     symbol_c* current_param_type;
@@ -98,6 +99,7 @@
       search_fb_instance_decl    = new search_fb_instance_decl_c   (scope);
       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
       search_var_instance_decl   = new search_var_instance_decl_c  (scope);
+      scope_ = scope;
       
       this->set_variable_prefix(variable_prefix);
       current_array_type = NULL;
@@ -128,7 +130,7 @@
 
 
 void *print_getter(symbol_c *symbol) {
-  unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
+  unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol, scope_);
   if (wanted_variablegeneration == fparam_output_vg) {
     if (vartype == search_var_instance_decl_c::external_vt) {
       if (!get_datatype_info_c::is_type_valid    (symbol->datatype)) ERROR;
@@ -178,7 +180,7 @@
   
   bool type_is_complex = false;
   if (fb_symbol == NULL) {
-    unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
+    unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol, scope_);
     type_is_complex = analyse_variable_c::contains_complex_type(symbol);
     if (vartype == search_var_instance_decl_c::external_vt) {
       if (!get_datatype_info_c::is_type_valid    (symbol->datatype)) ERROR;