stage4/generate_c/generate_var_list.cc
changeset 160 59d58f5e6caa
parent 158 eb8a5df69bb0
child 166 09004f402097
--- a/stage4/generate_c/generate_var_list.cc	Mon Dec 15 17:23:48 2008 +0100
+++ b/stage4/generate_c/generate_var_list.cc	Fri Dec 19 15:09:29 2008 +0100
@@ -65,9 +65,21 @@
     } declarationtype_t;
 
     declarationtype_t current_declarationtype;
-  
+    
+    typedef enum {
+      none_vtc,
+      variable_vtc,
+      pointer_vtc,
+      array_vtc,
+      structure_vtc,
+      function_block_vtc
+    } vartypecategory_t;
+    
+    vartypecategory_t current_var_type_category;
+    
   private:
     symbol_c *current_var_type_symbol;
+    symbol_c *current_var_type_name;
     unsigned int current_var_number;
     unsigned int step_number;
     unsigned int transition_number;
@@ -82,24 +94,34 @@
     : generate_c_typedecl_c(s4o_ptr) {
       search_fb_typedecl = new search_fb_typedecl_c(scope);
       current_var_number = 0;
-      current_var_type_symbol = NULL;
+      current_var_type_symbol = current_var_type_name = NULL;
       current_declarationtype = none_dt;
+      current_var_type_category = none_vtc;
     }
     
     ~generate_var_list_c(void) {
       delete search_fb_typedecl;
     }
     
-    void update_var_type_symbol(symbol_c *symbol, bool is_fb = false) {
-      
-      this->current_var_type_symbol = spec_init_sperator_c::get_spec(symbol);
-      if (this->current_var_type_symbol == NULL)
+    void update_var_type_symbol(symbol_c *symbol) {
+      
+      this->current_var_type_name = spec_init_sperator_c::get_spec(symbol);
+      if (this->current_var_type_name == NULL)
         ERROR;
       
-      if (is_fb)
-        this->current_var_type_symbol = search_fb_typedecl->get_decl(this->current_var_type_symbol);
-      else
-        this->current_var_type_symbol = (symbol_c *)(this->current_var_type_symbol->accept(search_base_type));
+      this->current_var_type_symbol = search_fb_typedecl->get_decl(this->current_var_type_name);
+      if (this->current_var_type_symbol != NULL)
+        this->current_var_type_category = function_block_vtc;
+      else {
+        this->current_var_type_symbol = (symbol_c *)(this->current_var_type_name->accept(search_base_type));
+        
+        structure_element_declaration_list_c *structure_symbol = dynamic_cast<structure_element_declaration_list_c *>(this->current_var_type_symbol);
+        if (structure_symbol != NULL)
+          this->current_var_type_category = structure_vtc;
+        else
+          this->current_var_type_category = variable_vtc;
+      }
+      
       if (this->current_var_type_symbol == NULL)
         ERROR;
     }
@@ -128,20 +150,36 @@
       s4o.print("\n");
     }
     
-    void declare_variables(symbol_c *symbol, const char* type = "VAR") {
+    void declare_variables(symbol_c *symbol) {
       list_c *list = dynamic_cast<list_c *>(symbol);
       /* should NEVER EVER occur!! */
       if (list == NULL) ERROR;
 
       for(int i = 0; i < list->n; i++) {
-        declare_variable(list->elements[i], type);
-      }
-    }
-    
-    void declare_variable(symbol_c *symbol, const char* type = "VAR") {
+        declare_variable(list->elements[i]);
+      }
+    }
+    
+    void declare_variable(symbol_c *symbol) {
       print_var_number();
       s4o.print(";");
-      s4o.print(type);
+      switch (this->current_var_type_category) {
+        case pointer_vtc:
+          s4o.print("PT");
+          break;
+        case array_vtc:
+          s4o.print("ARRAY");
+          break;
+        case structure_vtc:
+          s4o.print("STRUCT");
+          break;
+        case function_block_vtc:
+          s4o.print("FB");
+          break;
+        default:
+          s4o.print("VAR");
+          break;
+      }
       s4o.print(";");
       print_symbol_list();
       symbol->accept(*this);
@@ -149,17 +187,26 @@
       print_symbol_list();
       symbol->accept(*this);
       s4o.print(";");
-      if (strcmp(type, "FB") == 0) {
-        SYMBOL *current_name;
-        current_name = new SYMBOL;
-        current_name->symbol = symbol;
-        current_symbol_list.push_back(*current_name);
-        this->current_var_type_symbol->accept(*this);
-        current_symbol_list.pop_back();
-      }
-      else {
-        this->current_var_type_symbol->accept(*this);
-        s4o.print(";\n");
+      switch (this->current_var_type_category) {
+        case structure_vtc:
+        case function_block_vtc:
+          this->current_var_type_name->accept(*this);
+          s4o.print(";\n");
+          SYMBOL *current_name;
+          current_name = new SYMBOL;
+          current_name->symbol = symbol;
+          current_symbol_list.push_back(*current_name);
+          this->current_var_type_symbol->accept(*this);
+          current_symbol_list.pop_back();
+          break;
+        case array_vtc:
+          this->current_var_type_name->accept(*this);
+          s4o.print(";\n");
+          break;
+        default:
+          this->current_var_type_symbol->accept(*this);
+          s4o.print(";\n");
+          break;
       }
     }
     
@@ -209,8 +256,10 @@
          */
         update_var_type_symbol(symbol->located_var_spec_init);
         
-        if (symbol->variable_name != NULL)
-          declare_variable(symbol->variable_name, "PT");
+        if (symbol->variable_name != NULL) {
+          this->current_var_type_category = pointer_vtc;
+          declare_variable(symbol->variable_name);
+        }
         
         current_var_type_symbol = NULL;
         return NULL;
@@ -224,7 +273,8 @@
        * current_var_init_symbol private variables...
        */
       update_var_type_symbol(symbol->array_spec_init);
-    
+      
+      this->current_var_type_category = array_vtc;
       declare_variables(symbol->var1_list);
     
       /* Values no longer in scope, and therefore no longer used.
@@ -272,10 +322,10 @@
       /* Start off by setting the current_var_type_symbol and
        * current_var_init_symbol private variables...
        */
-      update_var_type_symbol(symbol, true);
+      update_var_type_symbol(symbol);
     
       /* now to produce the c equivalent... */
-      declare_variables(symbol->fb_name_list, "FB");
+      declare_variables(symbol->fb_name_list);
     
       /* Values no longer in scope, and therefore no longer used.
        * Make an effort to keep them set to NULL when not in use
@@ -297,14 +347,12 @@
       /* Start off by setting the current_var_type_symbol and
        * current_var_init_symbol private variables...
        */
-      this->current_var_type_symbol = (symbol_c *)(symbol->specification->accept(*search_fb_typedecl));
-      if (this->current_var_type_symbol == NULL) {
-        this->current_var_type_symbol = symbol->specification;
-      
-        declare_variable(symbol->global_var_name, "PT");
-      }
-      else
-        declare_variable(symbol->global_var_name, "FB");
+      update_var_type_symbol(symbol);
+      
+      /* now to produce the c equivalent... */
+      if (this->current_var_type_category == variable_vtc)
+        this->current_var_type_category = pointer_vtc;
+      declare_variable(symbol->global_var_name);
       
       /* Values no longer in scope, and therefore no longer used.
        * Make an effort to keep them set to NULL when not in use
@@ -350,7 +398,8 @@
     // SYM_REF2(global_var_spec_c, global_var_name, location)
     void *visit(global_var_spec_c *symbol) {
       if (symbol->global_var_name != NULL)
-        declare_variable(symbol->global_var_name, "PT");
+        this->current_var_type_category = pointer_vtc;
+        declare_variable(symbol->global_var_name);
       return NULL;
     }
     
@@ -381,6 +430,31 @@
       return NULL;
     }
 
+    void *visit(structure_element_declaration_list_c *symbol) {
+      for(int i = 0; i < symbol->n; i++) {
+        symbol->elements[i]->accept(*this);
+      }
+      return NULL;
+    }
+
+    void *visit(structure_element_declaration_c *symbol) {
+      /* Start off by setting the current_var_type_symbol and
+       * current_var_init_symbol private variables...
+       */
+      update_var_type_symbol(symbol->spec_init);
+      
+      /* now to produce the c equivalent... */
+      declare_variable(symbol->structure_element_name);
+      
+      /* Values no longer in scope, and therefore no longer used.
+       * Make an effort to keep them set to NULL when not in use
+       * in order to catch bugs as soon as possible...
+       */
+      reset_var_type_symbol();
+      
+      return NULL;
+    }
+
 /**************************************/
 /* B.1.5 - Program organization units */
 /**************************************/
@@ -397,8 +471,6 @@
 /*****************************/
     void *visit(function_block_declaration_c *symbol) {
       if (current_declarationtype == variables_dt && configuration_defined) {
-        symbol->fblock_name->accept(*this);
-        s4o.print(";\n");
         symbol->var_declarations->accept(*this);
         symbol->fblock_body->accept(*this);
       }
@@ -410,8 +482,6 @@
 /**********************/
     void *visit(program_declaration_c *symbol) {
       if (current_declarationtype == variables_dt && configuration_defined) {
-        symbol->program_type_name->accept(*this);
-        s4o.print(";\n");
         symbol->var_declarations->accept(*this);
         symbol->function_block_body->accept(*this);
       }
@@ -552,9 +622,9 @@
           /* Start off by setting the current_var_type_symbol and
            * current_var_init_symbol private variables...
            */
-          update_var_type_symbol(symbol->program_type_name, true);
+          update_var_type_symbol(symbol->program_type_name);
           
-          declare_variable(symbol->program_name, "FB");
+          declare_variable(symbol->program_name);
           
           /* Values no longer in scope, and therefore no longer used.
            * Make an effort to keep them set to NULL when not in use