Adding support for using arrays in POU interface
authorlaurent
Tue, 15 Dec 2009 16:29:44 +0100
changeset 237 cece842c7417
parent 236 c55b02ca2342
child 238 0919986a5c98
Adding support for using arrays in POU interface
absyntax_utils/function_param_iterator.cc
lib/iec_types_all.h
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_c_vardecl.cc
--- a/absyntax_utils/function_param_iterator.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/absyntax_utils/function_param_iterator.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -294,7 +294,14 @@
 
 /*  var1_list ':' array_specification */
 //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
-void *function_param_iterator_c::visit(array_var_declaration_c *symbol) {TRACE("array_var_declaration_c"); return symbol->var1_list->accept(*this);}
+void *function_param_iterator_c::visit(array_var_declaration_c *symbol) {
+	TRACE("array_var_declaration_c");
+
+	current_param_default_value = NULL;
+	current_param_type = symbol->array_specification;
+
+	return symbol->var1_list->accept(*this);
+}
 
 /*  var1_list ':' structure_type_name */
 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name)
--- a/lib/iec_types_all.h	Tue Dec 15 11:18:19 2009 +0100
+++ b/lib/iec_types_all.h	Tue Dec 15 16:29:44 2009 +0100
@@ -47,7 +47,9 @@
 } __IEC_##type##_p;
 
 #define __DECLARE_ARRAY_TYPE(base, type, size)\
-typedef base type size;\
+typedef struct {\
+  base table size;\
+} type;\
 __DECLARE_COMPLEX_STRUCT(type);
 
 #define __DECLARE_STRUCT_TYPE(elements, type)\
--- a/stage4/generate_c/generate_c.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/stage4/generate_c/generate_c.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -331,7 +331,7 @@
       unsigned long long least_common_tick = least_common_ticktime / common_ticktime;
       if (least_common_tick >> 32)
         ERROR;
-      return (unsigned long)(~(((unsigned long)-2) % (unsigned long)least_common_tick) + 1);
+      return (unsigned long)(~(((unsigned long)-1) % (unsigned long)least_common_tick) + 1);
     }
 
 /*  TASK task_name task_initialization */
@@ -1294,7 +1294,7 @@
       current_resource_name->accept(*this);
       s4o.print("\n\n");
       
-      s4o.print("extern int common_ticktime__;\n\n");
+      s4o.print("extern unsigned long long common_ticktime__;\n\n");
 
       s4o.print("#include \"accessor.h\"\n\n");
 
@@ -1652,7 +1652,7 @@
     const char *current_name;
     const char *current_builddir;
 
-    unsigned long common_ticktime;
+    unsigned long long common_ticktime;
 
   public:
     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
--- a/stage4/generate_c/generate_c_il.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/stage4/generate_c/generate_c_il.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -660,6 +660,7 @@
       current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
       symbol->subscripted_variable->accept(*this);
       if (current_array_type != NULL) {
+    	s4o.print(".table");
         symbol->subscript_list->accept(*this);
         current_array_type = NULL;
       }
@@ -669,6 +670,7 @@
     	current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
     	symbol->subscripted_variable->accept(*this);
     	if (current_array_type != NULL) {
+          s4o.print(".table");
     	  symbol->subscript_list->accept(*this);
     	  current_array_type = NULL;
     	}
@@ -697,15 +699,26 @@
 /******************************************/
 /* B 1.4.3 - Declaration & Initialisation */
 /******************************************/
+
+/* helper symbol for structure_initialization */
+/* structure_element_initialization_list ',' structure_element_initialization */
 void *visit(structure_element_initialization_list_c *symbol) {
   generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
   structure_initialization->init_structure_default(this->current_param_type);
-  structure_initialization->current_mode = generate_c_structure_initialization_c::initializationvalue_sm;
-  symbol->accept(*structure_initialization);
+  structure_initialization->init_structure_values(symbol);
   delete structure_initialization;
   return NULL;
 }
 
+/* helper symbol for array_initialization */
+/* array_initial_elements_list ',' array_initial_elements */
+void *visit(array_initial_elements_list_c *symbol) {
+  generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+  array_initialization->init_array_size(this->current_param_type);
+  array_initialization->init_array_values(symbol);
+  delete array_initialization;
+  return NULL;
+}
 /****************************************/
 /* B.2 - Language IL (Instruction List) */
 /****************************************/
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -303,13 +303,7 @@
           symbol->field_selector->accept(*this);
           break;
         default:
-          if (this->is_variable_prefix_null()) {
-        	symbol->record_variable->accept(*this);
-        	s4o.print(".");
-        	symbol->field_selector->accept(*this);
-          }
-          else
-        	print_getter(symbol);
+          print_getter(symbol);
           break;
       }
       return NULL;
@@ -326,21 +320,13 @@
           current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
           symbol->subscripted_variable->accept(*this);
           if (current_array_type != NULL) {
+            s4o.print(".table");
             symbol->subscript_list->accept(*this);
             current_array_type = NULL;
           }
           break;
         default:
-          if (this->is_variable_prefix_null()) {
-        	current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
-        	symbol->subscripted_variable->accept(*this);
-        	if (current_array_type != NULL) {
-        	  symbol->subscript_list->accept(*this);
-        	  current_array_type = NULL;
-        	}
-          }
-          else
-        	print_getter(symbol);
+          print_getter(symbol);
           break;
       }
       return NULL;
--- a/stage4/generate_c/generate_c_st.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -295,7 +295,8 @@
       current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
       symbol->subscripted_variable->accept(*this);
       if (current_array_type != NULL) {
-        symbol->subscript_list->accept(*this);
+        s4o.print(".table");
+    	symbol->subscript_list->accept(*this);
         current_array_type = NULL;
       }
       break;
@@ -304,6 +305,7 @@
     	current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
     	symbol->subscripted_variable->accept(*this);
     	if (current_array_type != NULL) {
+          s4o.print(".table");
     	  symbol->subscript_list->accept(*this);
     	  current_array_type = NULL;
     	}
@@ -332,15 +334,27 @@
 /******************************************/
 /* B 1.4.3 - Declaration & Initialisation */
 /******************************************/
+
+/* helper symbol for structure_initialization */
+/* structure_element_initialization_list ',' structure_element_initialization */
 void *visit(structure_element_initialization_list_c *symbol) {
   generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
   structure_initialization->init_structure_default(this->current_param_type);
-  structure_initialization->current_mode = generate_c_structure_initialization_c::initializationvalue_sm;
-  symbol->accept(*structure_initialization);
+  structure_initialization->init_structure_values(symbol);
   delete structure_initialization;
   return NULL;
 }
 
+/* helper symbol for array_initialization */
+/* array_initial_elements_list ',' array_initial_elements */
+void *visit(array_initial_elements_list_c *symbol) {
+  generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+  array_initialization->init_array_size(this->current_param_type);
+  array_initialization->init_array_values(symbol);
+  delete array_initialization;
+  return NULL;
+}
+
 /***************************************/
 /* B.3 - Language ST (Structured Text) */
 /***************************************/
--- a/stage4/generate_c/generate_c_vardecl.cc	Tue Dec 15 11:18:19 2009 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Tue Dec 15 16:29:44 2009 +0100
@@ -79,10 +79,9 @@
   public:
     typedef enum {
       none_am,
-      dimensioncount_am,
-      initializationvalue_am,
-      arrayassignment_am,
-      varlistparse_am
+      arraysize_am,
+      typedecl_am,
+      initializationvalue_am
     } arrayinitialization_mode_t;
 
     arrayinitialization_mode_t current_mode;
@@ -92,7 +91,6 @@
     symbol_c* array_default_initialization;
 
   private:
-    int dimension_number;
     int current_dimension;
     int array_size;
     int defined_values_count;
@@ -102,55 +100,46 @@
     generate_c_array_initialization_c(stage4out_c *s4o_ptr): generate_c_typedecl_c(s4o_ptr) {}
     ~generate_c_array_initialization_c(void) {}
 
-    void init_array_dimensions(symbol_c *array_specification) {
-      dimension_number = 0;
-      current_dimension = 0;
+    void init_array_size(symbol_c *array_specification) {
       array_size = 1;
       defined_values_count = 0;
       current_initialization_count = 0;
       array_base_type = array_default_value = array_default_initialization = NULL;
       
-      current_mode = dimensioncount_am;
+      current_mode = arraysize_am;
       array_specification->accept(*this);
     }
 
     void init_array(symbol_c *var1_list, symbol_c *array_specification, symbol_c *array_initialization) {
       int i;
       
-      init_array_dimensions(array_specification);
+      init_array_size(array_specification);
       
-      current_mode = initializationvalue_am;
       s4o.print("\n");
       s4o.print(s4o.indent_spaces + "{\n");
       s4o.indent_right();
-      s4o.print(s4o.indent_spaces + "int index[");
-      print_integer(dimension_number);
-      s4o.print("];\n");
       s4o.print(s4o.indent_spaces);
       s4o.print("static const ");
+
+      current_mode = typedecl_am;
       array_specification->accept(*this);
+
       s4o.print(" temp = ");
+
       init_array_values(array_initialization);
+
       s4o.print(";\n");
-      
-      current_mode = arrayassignment_am;
-      array_specification->accept(*this);
-      
-      current_mode = varlistparse_am;
       var1_list->accept(*this);
-      
-      current_mode = arrayassignment_am;
-      for (i = 0; i < dimension_number; i++) {
-        s4o.indent_left();
-        s4o.print(s4o.indent_spaces + "}\n");
-      }
       s4o.indent_left();
       s4o.print(s4o.indent_spaces + "}");
     }
     
     void init_array_values(symbol_c *array_initialization) {
-      s4o.print("{");
+      s4o.print("{{");
+
+      current_mode = initializationvalue_am;
       array_initialization->accept(*this);
+
       if (array_default_initialization != NULL && defined_values_count < array_size)
         array_default_initialization->accept(*this);
       if (defined_values_count < array_size) {
@@ -161,14 +150,14 @@
           defined_values_count++;
         }
       }
-      s4o.print("}");
+
+      s4o.print("}}");
     }
     
     void *visit(identifier_c *type_name) {
       symbol_c *type_decl;
       switch (current_mode) {
-        case dimensioncount_am:
-        case arrayassignment_am:
+        case arraysize_am:
           /* look up the type declaration... */
           type_decl = type_symtable.find_value(type_name);
           if (type_decl == type_symtable.end_value())
@@ -192,19 +181,7 @@
         s4o.print("(");
         print_variable_prefix();
         symbol->elements[i]->accept(*this);
-        s4o.print(",temp");
-        for (j = 0; j < dimension_number; j++) {
-          s4o.print("[index[");
-          print_integer(j);
-          s4o.print("]]");
-        }
-        s4o.print(",");
-        for (j = 0; j < dimension_number; j++) {
-          s4o.print("[index[");
-          print_integer(j);
-          s4o.print("]]");
-        }
-        s4o.print(");\n");
+        s4o.print(", temp);\n");
       }
       return NULL;
     }
@@ -217,7 +194,7 @@
     /* array_initialization may be NULL ! */
     void *visit(array_spec_init_c *symbol) {
       switch (current_mode) {
-        case dimensioncount_am:
+        case arraysize_am:
           array_default_initialization = symbol->array_initialization;
           break;
         default:
@@ -231,7 +208,7 @@
     void *visit(array_specification_c *symbol) {
       symbol->array_subrange_list->accept(*this);
       switch (current_mode) {
-        case dimensioncount_am:
+        case arraysize_am:
           array_base_type = symbol->non_generic_type_name;
           array_default_value = (symbol_c *)symbol->non_generic_type_name->accept(*type_initial_value_c::instance());;
           if (array_default_value == NULL) ERROR;
@@ -246,23 +223,9 @@
     //SYM_REF2(subrange_c, lower_limit, upper_limit)
     void *visit(subrange_c *symbol) {
       switch (current_mode) {
-        case dimensioncount_am:
-          dimension_number++;
+        case arraysize_am:
           array_size *= extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
           break;
-        case arrayassignment_am:
-          s4o.print(s4o.indent_spaces + "for (index[");
-          print_integer(current_dimension);
-          s4o.print("] = 0; index[");
-          print_integer(current_dimension);
-          s4o.print("] <= ");
-          print_integer(extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit));
-          s4o.print("; index[");
-          print_integer(current_dimension);
-          s4o.print("]++) {\n");
-          s4o.indent_right();
-          current_dimension++;
-          break;
         default:
           break;
       }
@@ -519,9 +482,9 @@
   public:
     typedef enum {
       none_sm,
+      initdefault_sm,
       typedecl_sm,
-      initializationvalue_sm,
-      varlistparse_sm
+      initializationvalue_sm
     } structureinitialization_mode_t;
 
     structureinitialization_mode_t current_mode;
@@ -538,7 +501,7 @@
       structure_type_decl = NULL;
       current_element_type = NULL;
       
-      current_mode = typedecl_sm;
+      current_mode = initdefault_sm;
       structure_type_name->accept(*this);
     }
 
@@ -547,28 +510,34 @@
       
       init_structure_default(structure_type_name);
       
-      current_mode = initializationvalue_sm;
       s4o.print("\n");
       s4o.print(s4o.indent_spaces + "{\n");
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       s4o.print("static const ");
+
+      current_mode = typedecl_sm;
       structure_type_name->accept(*this);
+
       s4o.print(" temp = ");
-      structure_initialization->accept(*this);
+
+      init_structure_values(structure_initialization);
+
       s4o.print(";\n");
-      
-      current_mode = varlistparse_sm;
       var1_list->accept(*this);
-      
       s4o.indent_left();
       s4o.print(s4o.indent_spaces + "}");
     }
 
+    void init_structure_values(symbol_c *structure_initialization) {
+      current_mode = initializationvalue_sm;
+      structure_initialization->accept(*this);
+    }
+
     void *visit(identifier_c *type_name) {
       symbol_c *type_decl;
       switch (current_mode) {
-        case typedecl_sm:
+        case initdefault_sm:
           /* look up the type declaration... */
           type_decl = type_symtable.find_value(type_name);
           if (type_decl == type_symtable.end_value())
@@ -605,7 +574,7 @@
     /* structure_element_declaration_list structure_element_declaration ';' */
     void *visit(structure_element_declaration_list_c *symbol) {
       switch (current_mode) {
-        case typedecl_sm:
+        case initdefault_sm:
           structure_type_decl = (symbol_c *)symbol;
           break;
         default:
@@ -649,10 +618,8 @@
             
         if (initialization_analyzer.get_initialization_type() == initialization_analyzer_c::struct_it) {
           generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
-          structure_initialization->set_variable_prefix(get_variable_prefix());
           structure_initialization->init_structure_default(current_element_type);
-          structure_initialization->current_mode = generate_c_structure_initialization_c::initializationvalue_sm;
-          element_value->accept(*structure_initialization);
+          structure_initialization->init_structure_values(element_value);
           delete structure_initialization;
         }
         else {
@@ -667,9 +634,7 @@
     /* array_initial_elements_list ',' array_initial_elements */
     void *visit(array_initial_elements_list_c *symbol) {
       generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
-      array_initialization->set_variable_prefix(get_variable_prefix());
-      array_initialization->init_array_dimensions(current_element_type);
-      array_initialization->current_mode = generate_c_array_initialization_c::initializationvalue_am;
+      array_initialization->init_array_size(current_element_type);
       array_initialization->init_array_values(symbol);
       delete array_initialization;
       return NULL;
@@ -682,10 +647,8 @@
 /* structure_element_initialization_list ',' structure_element_initialization */
 void *generate_c_array_initialization_c::visit(structure_element_initialization_list_c *symbol) {
   generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
-  structure_initialization->set_variable_prefix(get_variable_prefix());
   structure_initialization->init_structure_default(array_base_type);
-  structure_initialization->current_mode = generate_c_structure_initialization_c::initializationvalue_sm;
-  symbol->accept(*structure_initialization);
+  structure_initialization->init_structure_values(symbol);
   delete structure_initialization;
   return NULL;
 }
@@ -1534,16 +1497,42 @@
   return NULL;
 }
 
-#if 0
 /*  var1_list ':' array_specification */
-SYM_REF2(array_var_declaration_c, var1_list, array_specification)
-#endif
+//SYM_REF2(array_var_declaration_c, var1_list, array_specification)
+void *visit(array_var_declaration_c *symbol) {
+  TRACE("array_var_declaration_c");
+  /* Please read the comments inside the var1_init_decl_c
+   * visitor, as they apply here too.
+   */
+
+  /* Start off by setting the current_var_type_symbol and
+   * current_var_init_symbol private variables...
+   */
+  update_type_init(symbol->array_specification);
+
+  /* now to produce the c equivalent... */
+  if (wanted_varformat == constructorinit_vf) {
+    generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+    array_initialization->set_variable_prefix(get_variable_prefix());
+    array_initialization->init_array(symbol->var1_list, this->current_var_type_symbol, this->current_var_init_symbol);
+    delete array_initialization;
+  }
+  else
+    symbol->var1_list->accept(*this);
+
+  /* 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...
+   */
+  void_type_init();
+
+  return NULL;
+}
 
 void *visit(array_initial_elements_list_c *symbol) {
   if (wanted_varformat == localinit_vf) {
 	generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
-	array_initialization->init_array_dimensions(this->current_var_type_symbol);
-	array_initialization->current_mode = generate_c_array_initialization_c::initializationvalue_am;
+	array_initialization->init_array_size(this->current_var_type_symbol);
 	array_initialization->init_array_values(this->current_var_init_symbol);
 	delete array_initialization;
   }
@@ -1586,8 +1575,7 @@
   if (wanted_varformat == localinit_vf) {
     generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
     structure_initialization->init_structure_default(this->current_var_type_symbol);
-    structure_initialization->current_mode = generate_c_structure_initialization_c::initializationvalue_sm;
-    this->current_var_init_symbol->accept(*structure_initialization);
+    structure_initialization->init_structure_values(this->current_var_init_symbol);
 	delete structure_initialization;
   }
   return NULL;