Adding support for compiling direct array specification inside variable declaration
authorlaurent
Wed, 14 Sep 2011 22:58:39 +0200
changeset 377 60b012b7793f
parent 376 7dcbd8418771
child 378 7f2e120c7352
Adding support for compiling direct array specification inside variable declaration
absyntax_utils/Makefile.am
absyntax_utils/Makefile.in
absyntax_utils/absyntax_utils.hh
absyntax_utils/array_dimension_iterator.cc
absyntax_utils/array_dimension_iterator.hh
absyntax_utils/case_element_iterator.cc
absyntax_utils/case_element_iterator.hh
absyntax_utils/search_base_type.cc
absyntax_utils/search_base_type.hh
absyntax_utils/search_varfb_instance_type.cc
lib/accessor.h
stage1_2/iec_bison.yy
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_c_vardecl.cc
stage4/generate_c/generate_var_list.cc
--- a/absyntax_utils/Makefile.am	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/Makefile.am	Wed Sep 14 22:58:39 2011 +0200
@@ -6,6 +6,7 @@
 	absyntax_utils.cc \
 	add_en_eno_param_decl.cc \
 	decompose_var_instance_name.cc \
+	array_dimension_iterator.cc \
 	case_element_iterator.cc \
 	function_call_iterator.cc \
 	function_call_param_iterator.cc \
--- a/absyntax_utils/Makefile.in	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/Makefile.in	Wed Sep 14 22:58:39 2011 +0200
@@ -73,6 +73,7 @@
 am_libabsyntax_utils_a_OBJECTS = absyntax_utils.$(OBJEXT) \
 	add_en_eno_param_decl.$(OBJEXT) \
 	decompose_var_instance_name.$(OBJEXT) \
+	array_dimension_iterator.$(OBJEXT) \
 	case_element_iterator.$(OBJEXT) \
 	function_call_iterator.$(OBJEXT) \
 	function_call_param_iterator.$(OBJEXT) \
@@ -205,6 +206,7 @@
 	absyntax_utils.cc \
 	add_en_eno_param_decl.cc \
 	decompose_var_instance_name.cc \
+	array_dimension_iterator.cc \
 	case_element_iterator.cc \
 	function_call_iterator.cc \
 	function_call_param_iterator.cc \
@@ -304,6 +306,7 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/absyntax_utils.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_en_eno_param_decl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_dimension_iterator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/case_element_iterator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decompose_var_instance_name.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function_call_iterator.Po@am__quote@
--- a/absyntax_utils/absyntax_utils.hh	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/absyntax_utils.hh	Wed Sep 14 22:58:39 2011 +0200
@@ -102,6 +102,7 @@
 /***********************************************************************/
 
 #include "spec_init_separator.hh"
+#include "array_dimension_iterator.hh"
 #include "case_element_iterator.hh"
 #include "function_param_iterator.hh"
 #include "function_call_iterator.hh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/absyntax_utils/array_dimension_iterator.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -0,0 +1,139 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+
+/*
+ * Array dimension iterator.
+ * Iterate through the dimensions of array specification.
+ *
+ * This is part of the 4th stage that generates
+ * a c++ source program equivalent to the IL and ST
+ * code.
+ */
+
+/* Given a array_specification_c, iterate through
+ * each subrange, returning the symbol of each subrange
+ * ...array_dimension_iterator_c
+ */
+
+
+
+
+#include "array_dimension_iterator.hh"
+
+
+//#define DEBUG
+#ifdef DEBUG
+#define TRACE(classname) printf("\n____%s____\n",classname);
+#else
+#define TRACE(classname)
+#endif
+
+
+#define ERROR error_exit(__FILE__,__LINE__)
+/* function defined in main.cc */
+extern void error_exit(const char *file_name, int line_no);
+
+void* array_dimension_iterator_c::iterate_list(list_c *list) {
+  void *res;
+  for (int i = 0; i < list->n; i++) {
+    res = list->elements[i]->accept(*this);
+    if (res != NULL)
+        return res;
+  }
+  return NULL;
+}
+
+/* start off at the first case element once again... */
+void array_dimension_iterator_c::reset(void) {
+  current_array_dimension = NULL;
+}
+
+
+/* initialize the iterator object.
+ * We must be given a reference to a array_specification_c that will be analyzed...
+ */
+array_dimension_iterator_c::array_dimension_iterator_c(symbol_c *symbol) {
+  /* do some consistency check... */
+  array_specification_c* array_spec = dynamic_cast<array_specification_c*>(symbol);
+
+  if (NULL == array_spec) ERROR;
+
+  /* OK. Now initialize this object... */
+  this->array_specification = symbol;
+  reset();
+}
+
+
+
+/* Skip to the next subrange. After object creation,
+ * the object references on subrange _before_ the first, so
+ * this function must be called once to get the object to
+ * reference the first subrange...
+ *
+ * Returns the subrange symbol!
+ */
+symbol_c *array_dimension_iterator_c::next(void) {
+  void *res = array_specification->accept(*this);
+  if (res == NULL) 
+    return NULL;
+
+  return current_array_dimension;
+}
+
+/********************************/
+/* B 1.3.3 - Derived data types */
+/********************************/
+/*  signed_integer DOTDOT signed_integer */
+void *array_dimension_iterator_c::visit(subrange_c *symbol) {
+  if (current_array_dimension == symbol) {
+	current_array_dimension = NULL;
+  }
+  else if (current_array_dimension == NULL) {
+	current_array_dimension = symbol;
+	return symbol;
+  }
+
+  /* Not found! */
+  return NULL;
+}
+
+/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+void *array_dimension_iterator_c::visit(array_specification_c *symbol) {
+  return symbol->array_subrange_list->accept(*this);
+}
+
+/* array_subrange_list ',' subrange */
+void *array_dimension_iterator_c::visit(array_subrange_list_c *symbol) {
+  return iterate_list(symbol);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/absyntax_utils/array_dimension_iterator.hh	Wed Sep 14 22:58:39 2011 +0200
@@ -0,0 +1,101 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+
+/*
+ * Array dimension iterator.
+ * Iterate through the dimensions of array specification.
+ *
+ * This is part of the 4th stage that generates
+ * a c++ source program equivalent to the IL and ST
+ * code.
+ */
+
+/* Given a array_specification_c, iterate through
+ * each subrange, returning the symbol of each subrange
+ * ...array_dimension_iterator_c
+ */
+
+
+#include "../absyntax/visitor.hh"
+
+
+class array_dimension_iterator_c : public null_visitor_c {
+  private:
+    /* a pointer to the array_specification_c currently being analyzed */
+    symbol_c *array_specification;
+    /* used when called to iterate() for a parameter */
+    symbol_c *current_array_dimension;
+
+  private:
+    void* iterate_list(list_c *list);
+
+  public:
+    /* start off at the first dimension once again... */
+    void reset(void);
+
+    /* initialize the iterator object.
+     * We must be given a reference to a case_list_c that will be analyzed...
+     */
+    array_dimension_iterator_c(symbol_c *symbol);
+
+    /* Skip to the next subrange. After object creation,
+     * the object references on subrange _before_ the first, so
+     * this function must be called once to get the object to
+     * reference the first subrange...
+     *
+     * Returns the subrange symbol!
+     */
+    symbol_c *next(void);
+
+    private:
+    
+    /********************************/
+    /* B 1.3.3 - Derived data types */
+    /********************************/
+    /*  signed_integer DOTDOT signed_integer */
+    void *visit(subrange_c *symbol);
+    
+    /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+    void *visit(array_specification_c *symbol);
+
+    /* array_subrange_list ',' subrange */
+    void *visit(array_subrange_list_c *symbol);
+
+}; // function_param_iterator_c
+
+
+
+
+
+
+
--- a/absyntax_utils/case_element_iterator.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/case_element_iterator.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -93,8 +93,8 @@
 }
 
 
-/* initialise the iterator object.
- * We must be given a reference to a case_list_c that will be analysed...
+/* initialize the iterator object.
+ * We must be given a reference to a case_list_c that will be analyzed...
  */
 case_element_iterator_c::case_element_iterator_c(symbol_c *list, case_element_t element_type) {
   /* do some consistency check... */
@@ -102,7 +102,7 @@
 
   if (NULL == case_list) ERROR;
 
-  /* OK. Now initialise this object... */
+  /* OK. Now initialize this object... */
   this->case_list = list;
   this->wanted_element_type = element_type;
   reset();
--- a/absyntax_utils/case_element_iterator.hh	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/case_element_iterator.hh	Wed Sep 14 22:58:39 2011 +0200
@@ -60,9 +60,7 @@
 
 
   private:
-    /* a pointer to the function_block_declaration_c
-     * or function_declaration_c currently being analysed.
-     */
+    /* a pointer to the case_list_c currently being analyzed */
     symbol_c *case_list;
     /* used when called to iterate() for a parameter */
     symbol_c *current_case_element;
@@ -79,8 +77,8 @@
     /* start off at the first case element once again... */
     void reset(void);
 
-    /* initialise the iterator object.
-     * We must be given a reference to a case_list_c that will be analysed...
+    /* initialize the iterator object.
+     * We must be given a reference to a case_list_c that will be analyzed...
      */
     case_element_iterator_c(symbol_c *list, case_element_t element_type);
 
--- a/absyntax_utils/search_base_type.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/search_base_type.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -227,7 +227,8 @@
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 void *search_base_type_c::visit(array_specification_c *symbol)	{
-  if (NULL == this->current_type_name) ERROR;
+  if (NULL == this->current_type_name)
+	this->current_type_name = symbol->non_generic_type_name;
   return symbol->non_generic_type_name->accept(*this);
 }
 
--- a/absyntax_utils/search_base_type.hh	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/search_base_type.hh	Wed Sep 14 22:58:39 2011 +0200
@@ -52,6 +52,7 @@
 
   private:
     symbol_c *current_type_name;
+    bool is_array;
     bool is_subrange;
     bool is_enumerated;
 
--- a/absyntax_utils/search_varfb_instance_type.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/absyntax_utils/search_varfb_instance_type.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -269,20 +269,19 @@
 
 /*  identifier ':' array_spec_init */
 void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) {
-  this->is_complex = true;
   return symbol->array_spec_init->accept(*this);
 }
     
 /* array_specification [ASSIGN array_initialization] */
 /* array_initialization may be NULL ! */
 void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) {
-  this->is_complex = true;
   return symbol->array_specification->accept(*this);
 }
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 void *search_varfb_instance_type_c::visit(array_specification_c *symbol) {
   this->is_complex = true;
+  this->current_typeid = symbol;
   return symbol->non_generic_type_name->accept(*this);
 }
 
--- a/lib/accessor.h	Fri Sep 09 12:03:15 2011 +0200
+++ b/lib/accessor.h	Wed Sep 14 22:58:39 2011 +0200
@@ -1,6 +1,7 @@
 #ifndef __ACCESSOR_H
 #define __ACCESSOR_H
 
+#define __INITIAL_VALUE(...) __VA_ARGS__
 
 // variable declaration macros
 #define __DECLARE_VAR(type, name)\
@@ -45,9 +46,12 @@
 #define __INIT_VAR(name, initial, retained)\
 	name.value = initial;\
 	__INIT_RETAIN(name, retained)
-#define __INIT_GLOBAL(name, initial, retained)\
-	__INIT_GLOBAL_##name(initial);\
-	__INIT_RETAIN((*GLOBAL__##name), retained)
+#define __INIT_GLOBAL(type, name, initial, retained)\
+    {\
+	    static const type temp = initial;\
+	    __INIT_GLOBAL_##name(temp);\
+	    __INIT_RETAIN((*GLOBAL__##name), retained)\
+    }
 #define __INIT_GLOBAL_LOCATED(resource, name, location, retained)\
 	resource##__##name.value = location;\
 	__INIT_RETAIN(resource##__##name, retained)
--- a/stage1_2/iec_bison.yy	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage1_2/iec_bison.yy	Wed Sep 14 22:58:39 2011 +0200
@@ -3004,6 +3004,7 @@
 array_initial_elements:
   array_initial_element
 | integer '(' ')'
+	{$$ = new array_initial_elements_c($1, NULL, locloc(@$));}
 | integer '(' array_initial_element ')'
 	{$$ = new array_initial_elements_c($1, $3, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
--- a/stage4/generate_c/generate_c.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_c.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -27,6 +27,8 @@
 #include <sstream>
 #include <typeinfo>
 #include <list>
+#include <map>
+#include <sstream>
 #include <strings.h>
 
 #include "../../util/symtable.hh"
@@ -111,7 +113,6 @@
 #define INIT_LOCATED "__INIT_LOCATED"
 #define INIT_LOCATED_VALUE "__INIT_LOCATED_VALUE"
 
-
 /* Variable getter symbol for accessor macros */
 #define GET_VAR "__GET_VAR"
 #define GET_EXTERNAL "__GET_EXTERNAL"
@@ -581,6 +582,370 @@
 /***********************************************************************/
 
 
+class generate_c_datatypes_c: public generate_c_typedecl_c {
+  public:
+    typedef enum {
+      none_im,
+      arrayname_im,
+      arraydeclaration_im,
+    } inlinearray_mode_t;
+
+  private:
+    stage4out_c *s4o_ptr;
+    std::map<std::string, int> inline_array_defined;
+    std::string current_array_name;
+    inlinearray_mode_t current_mode;
+
+  public:
+    generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr)
+      : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) {
+      generate_c_datatypes_c::s4o_ptr = s4o_ptr;
+      current_mode = none_im;
+    };
+    virtual ~generate_c_datatypes_c(void) {
+      while (!inline_array_defined.empty()) {
+    	inline_array_defined.erase(inline_array_defined.begin());
+      }
+    }
+
+    /*************************/
+    /* B.1 - Common elements */
+    /*************************/
+    /*******************************************/
+    /* B 1.1 - Letters, digits and identifiers */
+    /*******************************************/
+    void *visit(identifier_c *symbol) {
+      switch (current_mode) {
+        case arrayname_im:
+          current_array_name += symbol->value;
+          break;
+        case arraydeclaration_im:
+          s4o_incl.print(symbol->value);
+          break;
+        default:
+          return generate_c_base_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
+
+    /**********************/
+    /* B.1.3 - Data types */
+    /**********************/
+    /***********************************/
+    /* B 1.3.1 - Elementary Data Types */
+    /***********************************/
+
+    #define HANDLE_ELEMENTARY_DATA_TYPE(datatype_symbol, datatype_name)\
+    void *visit(datatype_symbol *symbol) {\
+	  switch (current_mode) {\
+		case arrayname_im:\
+		  current_array_name += datatype_name;\
+		  break;\
+        case arraydeclaration_im:\
+          s4o_incl.print(datatype_name);\
+          break;\
+		default:\
+		  return generate_c_base_c::visit(symbol);\
+		  break;\
+	  }\
+	  return NULL;\
+	}
+
+    HANDLE_ELEMENTARY_DATA_TYPE(time_type_name_c, "TIME")
+    HANDLE_ELEMENTARY_DATA_TYPE(bool_type_name_c, "BOOL")
+    HANDLE_ELEMENTARY_DATA_TYPE(sint_type_name_c, "SINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(int_type_name_c, "INT")
+    HANDLE_ELEMENTARY_DATA_TYPE(dint_type_name_c, "DINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(lint_type_name_c, "LINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(usint_type_name_c, "USINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(uint_type_name_c, "UINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(udint_type_name_c, "UDINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(ulint_type_name_c, "ULINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(real_type_name_c, "REAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(lreal_type_name_c, "LREAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(date_type_name_c, "DATE")
+    HANDLE_ELEMENTARY_DATA_TYPE(tod_type_name_c, "TOD")
+    HANDLE_ELEMENTARY_DATA_TYPE(dt_type_name_c, "DT")
+    HANDLE_ELEMENTARY_DATA_TYPE(byte_type_name_c, "BYTE")
+    HANDLE_ELEMENTARY_DATA_TYPE(word_type_name_c, "WORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(dword_type_name_c, "DWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(lword_type_name_c, "LWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(string_type_name_c, "STRING")
+    HANDLE_ELEMENTARY_DATA_TYPE(wstring_type_name_c, "WSTRING")
+
+    HANDLE_ELEMENTARY_DATA_TYPE(safetime_type_name_c, "TIME")
+	HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
+	HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
+	HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
+	HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
+	HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
+	HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
+	HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
+	HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
+	HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
+	HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
+	HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
+	HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
+
+    /******************************************/
+    /* B 1.4.3 - Declaration & Initialization */
+    /******************************************/
+
+    void *visit(input_declarations_c *symbol) {
+      symbol->input_declaration_list->accept(*this);
+      return NULL;
+    }
+
+    void *visit(edge_declaration_c *symbol) {
+      return NULL;
+    }
+
+    void *visit(en_param_declaration_c *symbol) {
+      return NULL;
+    }
+
+    void *visit(eno_param_declaration_c *symbol) {
+      return NULL;
+    }
+
+    void *visit(var1_init_decl_c *symbol) {
+      return NULL;
+    }
+
+    /*  var1_list ':' array_spec_init */
+    // SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)
+    void *visit(array_var_init_decl_c *symbol) {
+      current_mode = arrayname_im;
+      symbol->array_spec_init->accept(*this);
+      current_mode = none_im;
+      return NULL;
+    }
+
+    /* array_specification [ASSIGN array_initialization] */
+    /* array_initialization may be NULL ! */
+    void *visit(array_spec_init_c *symbol) {
+      switch (current_mode) {
+    	case arrayname_im:
+    	  {
+    	    array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
+            if (specification != NULL)
+              symbol->array_specification->accept(*this);
+          }
+          break;
+    	default:
+    	  return generate_c_typedecl_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
+
+    /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+    void *visit(array_specification_c *symbol) {
+      switch (current_mode) {
+        case arrayname_im:
+          {
+            std::map<std::string,int>::iterator definition;
+            current_array_name = "__";
+            symbol->non_generic_type_name->accept(*this);
+            symbol->array_subrange_list->accept(*this);
+
+            definition = inline_array_defined.find(current_array_name);
+            if (definition == inline_array_defined.end()) {
+              current_mode = arraydeclaration_im;
+
+              s4o_incl.print("__DECLARE_ARRAY_TYPE(");
+              s4o_incl.print(current_array_name);
+              s4o_incl.print(",");
+              symbol->non_generic_type_name->accept(*this);
+              s4o_incl.print(",");
+              symbol->array_subrange_list->accept(*this);
+              s4o_incl.print(")\n\n");
+
+              inline_array_defined[current_array_name] = 0;
+            }
+          }
+          break;
+        default:
+          return generate_c_typedecl_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
+
+    /*  signed_integer DOTDOT signed_integer */
+    //SYM_REF2(subrange_c, lower_limit, upper_limit)
+    void *visit(subrange_c *symbol) {
+      int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
+      switch (current_mode) {
+        case arrayname_im:
+          current_array_name += "_";
+          {
+            std::stringstream ss;
+            ss << dimension;
+            current_array_name += ss.str();
+          }
+          break;
+        case arraydeclaration_im:
+          s4o_incl.print("[");
+          s4o_incl.print_integer(dimension);
+          s4o_incl.print("]");
+        default:
+          generate_c_typedecl_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
+
+    /*  var1_list ':' initialized_structure */
+    // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
+    void *visit(structured_var_init_decl_c *symbol) {
+      return NULL;
+    }
+
+    /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
+    /* structure_initialization -> may be NULL ! */
+    void *visit(fb_name_decl_c *symbol) {
+      return NULL;
+    }
+
+    /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
+    /* option -> may be NULL ! */
+    void *visit(output_declarations_c *symbol) {
+      symbol->var_init_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*  VAR_IN_OUT var_declaration_list END_VAR */
+    void *visit(input_output_declarations_c *symbol) {
+      symbol->var_declaration_list->accept(*this);
+      return NULL;
+    }
+
+    /*  var1_list ':' array_specification */
+    //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
+    void *visit(array_var_declaration_c *symbol) {
+      array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
+	  if (specification != NULL) {
+        current_mode = arrayname_im;
+        symbol->array_specification->accept(*this);
+        current_mode = none_im;
+      }
+      return NULL;
+    }
+
+    /* VAR [CONSTANT] var_init_decl_list END_VAR */
+    /* option -> may be NULL ! */
+    /* helper symbol for input_declarations */
+    void *visit(var_declarations_c *symbol) {
+      symbol->var_init_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*  VAR RETAIN var_init_decl_list END_VAR */
+    void *visit(retentive_var_declarations_c *symbol) {
+      symbol->var_init_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
+    /* option -> may be NULL ! */
+    //SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
+    void *visit(located_var_declarations_c *symbol) {
+      symbol->located_var_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*  [variable_name] location ':' located_var_spec_init */
+    /* variable_name -> may be NULL ! */
+    //SYM_REF4(located_var_decl_c, variable_name, location, located_var_spec_init, unused)
+    void *visit(located_var_decl_c *symbol) {
+      symbol->located_var_spec_init->accept(*this);
+      return NULL;
+    }
+
+    /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
+    /* option -> may be NULL ! */
+    //SYM_REF2(external_var_declarations_c, option, external_declaration_list)
+    void *visit(external_var_declarations_c *symbol) {
+      symbol->external_declaration_list->accept(*this);
+      return NULL;
+    }
+
+    /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
+    //SYM_REF2(external_declaration_c, global_var_name, specification)
+    void *visit(external_declaration_c *symbol) {
+      array_specification_c* array_specification = dynamic_cast<array_specification_c*>(symbol->specification);
+      if (array_specification != NULL) {
+        current_mode = arrayname_im;
+        symbol->specification->accept(*this);
+        current_mode = none_im;
+      }
+      return NULL;
+    }
+
+    /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */
+    /* option -> may be NULL ! */
+    // SYM_REF2(global_var_declarations_c, option, global_var_decl_list)
+    void *visit(global_var_declarations_c *symbol) {
+      symbol->global_var_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
+    /* type_specification ->may be NULL ! */
+    // SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
+    void *visit(global_var_decl_c *symbol) {
+      array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->type_specification);
+      if (array_spec_init != NULL) {
+        current_mode = arrayname_im;
+        symbol->type_specification->accept(*this);
+        current_mode = none_im;
+      }
+      return NULL;
+    }
+
+    void *visit(function_var_decls_c *symbol) {
+      symbol->decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*****************************/
+    /* B 1.5.2 - Function Blocks */
+    /*****************************/
+
+    /*  VAR_TEMP temp_var_decl_list END_VAR */
+    void *visit(temp_var_decls_c *symbol) {
+      symbol->var_decl_list->accept(*this);
+      return NULL;
+    }
+
+    /*  VAR NON_RETAIN var_init_decl_list END_VAR */
+    void *visit(non_retentive_var_decls_c *symbol) {
+      symbol->var_decl_list->accept(*this);
+      return NULL;
+    }
+
+};
+
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+
 class generate_c_pous_c: public generate_c_typedecl_c {
   private:
     stage4out_c *s4o_ptr;
@@ -772,15 +1137,15 @@
           structure_initialization->init_structure_values(default_value);
           delete structure_initialization;
         }
-    	break;
+        break;
       case initialization_analyzer_c::array_it:
         {
-    	  generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
-    	  array_initialization->init_array_size(symbol->type_name);
-    	  array_initialization->init_array_values(default_value);
-    	  delete array_initialization;
+          generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+          array_initialization->init_array_size(symbol->type_name);
+          array_initialization->init_array_values(default_value);
+          delete array_initialization;
         }
-    	break;
+        break;
       default:
         default_value->accept(*this);
         break;
@@ -1195,7 +1560,7 @@
       : generate_c_typedecl_c(s4o_ptr) {
       generate_c_config_c::s4o_ptr = s4o_ptr;
     };
-	
+
     virtual ~generate_c_config_c(void) {}
 
     typedef enum {
@@ -1240,6 +1605,7 @@
   s4o.print("/*******************************************/\n\n");
   s4o.print("#include \"iec_std_lib.h\"\n\n");
   s4o.print("#include \"accessor.h\"\n\n"); 
+  s4o.print("#include \"POUS.h\"\n\n");
 
   /* (A) configuration declaration... */
   /* (A.1) configuration name in comment */
@@ -1435,17 +1801,17 @@
     unsigned int current_varqualifier;
 
     void *print_retain(void) {
-	  s4o.print(",");
+      s4o.print(",");
       switch (current_varqualifier) {
-		case retain_vq:
+        case retain_vq:
           s4o.print("1");
           break;
         case non_retain_vq:
           s4o.print("0");
           break;
-		default:
-		  s4o.print("retain");
-		  break;
+        default:
+          s4o.print("retain");
+          break;
       }
       return NULL;
     }
@@ -1631,7 +1997,7 @@
           break;
         case init_dt:
           if (symbol->retain_option != NULL)
-        	symbol->retain_option->accept(*this);
+            symbol->retain_option->accept(*this);
           s4o.print(s4o.indent_spaces);
           symbol->program_type_name->accept(*this);
           s4o.print(FB_INIT_SUFFIX);
@@ -1876,12 +2242,20 @@
 /***********************************************************************/
 
 class generate_c_c: public iterator_visitor_c {
+  public:
+    typedef enum {
+      none_gm,
+      datatypes_gm,
+      pous_gm,
+    } generate_mode_t;
+
   protected:
     stage4out_c &s4o;
     stage4out_c pous_s4o;
     stage4out_c pous_incl_s4o;
     stage4out_c located_variables_s4o;
     stage4out_c variables_s4o;
+    generate_c_datatypes_c generate_c_datatypes;
     generate_c_pous_c generate_c_pous;
     
     symbol_c *current_configuration;
@@ -1891,6 +2265,8 @@
 
     unsigned long long common_ticktime;
 
+    generate_mode_t current_mode;
+
   public:
     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
             s4o(*s4o_ptr),
@@ -1898,9 +2274,11 @@
             pous_incl_s4o(builddir, "POUS", "h"),
             located_variables_s4o(builddir, "LOCATED_VARIABLES","h"),
             variables_s4o(builddir, "VARIABLES","csv"),
+            generate_c_datatypes(&pous_s4o, &pous_incl_s4o),
             generate_c_pous(&pous_s4o, &pous_incl_s4o) {
       current_builddir = builddir;
       current_configuration = NULL;
+      current_mode = none_gm;
     }
             
     ~generate_c_c(void) {}
@@ -1934,9 +2312,17 @@
 /***************************/
     void *visit(library_c *symbol) {
       pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n#include \"accessor.h\"\n\n");
+
+      current_mode = datatypes_gm;
       for(int i = 0; i < symbol->n; i++) {
         symbol->elements[i]->accept(*this);
       }
+
+      current_mode = pous_gm;
+      for(int i = 0; i < symbol->n; i++) {
+        symbol->elements[i]->accept(*this);
+      }
+
       pous_incl_s4o.print("#endif //__POUS_H\n");
       
       generate_var_list_c generate_var_list(&variables_s4o, symbol);
@@ -1955,8 +2341,8 @@
 /* B 1.1 - Letters, digits and identifiers */
 /*******************************************/
     void *visit(identifier_c *symbol) {
-    	current_name = symbol->value;
-    	return NULL;
+        current_name = symbol->value;
+        return NULL;
     }
 
 /********************************/
@@ -1964,7 +2350,13 @@
 /********************************/
     /*  TYPE type_declaration_list END_TYPE */
     void *visit(data_type_declaration_c *symbol) {
-      symbol->accept(generate_c_pous);
+      switch (current_mode) {
+        case datatypes_gm:
+          symbol->accept(generate_c_datatypes);
+          break;
+        default:
+          break;
+      }
       return NULL;
     }
 
@@ -1975,24 +2367,51 @@
 /* B 1.5.1 - Functions */
 /***********************/
     void *visit(function_declaration_c *symbol) {
-    	symbol->accept(generate_c_pous);
-    	return NULL;
+      switch (current_mode) {
+        case datatypes_gm:
+          symbol->var_declarations_list->accept(generate_c_datatypes);
+          break;
+        case pous_gm:
+          symbol->accept(generate_c_pous);
+          break;
+        default:
+          break;
+      }
+      return NULL;
     }
     
 /*****************************/
 /* B 1.5.2 - Function Blocks */
 /*****************************/
     void *visit(function_block_declaration_c *symbol) {
-    	symbol->accept(generate_c_pous);
-    	return NULL;
+        switch (current_mode) {
+          case datatypes_gm:
+            symbol->var_declarations->accept(generate_c_datatypes);
+            break;
+          case pous_gm:
+            symbol->accept(generate_c_pous);
+            break;
+          default:
+            break;
+        }
+        return NULL;
     }
     
 /**********************/
 /* B 1.5.3 - Programs */
 /**********************/    
     void *visit(program_declaration_c *symbol) {
-    	symbol->accept(generate_c_pous);
-    	return NULL;
+        switch (current_mode) {
+          case datatypes_gm:
+            symbol->var_declarations->accept(generate_c_datatypes);
+            break;
+          case pous_gm:
+            symbol->accept(generate_c_pous);
+            break;
+          default:
+            break;
+        }
+        return NULL;
     }
     
 
@@ -2000,54 +2419,88 @@
 /* B 1.7 Configuration elements */
 /********************************/
     void *visit(configuration_declaration_c *symbol) {
-  	  static int configuration_count = 0;
-  
-      if (configuration_count++) {
-        /* the first configuration is the one we will use!! */
-        ERROR;
+      switch (current_mode) {
+        case datatypes_gm:
+          if (symbol->global_var_declarations != NULL)
+            symbol->global_var_declarations->accept(generate_c_datatypes);
+          break;
+
+        case pous_gm:
+          static int configuration_count = 0;
+
+          if (configuration_count++) {
+            /* the first configuration is the one we will use!! */
+            ERROR;
+          }
+
+          current_configuration = symbol;
+
+          {
+            calculate_common_ticktime_c calculate_common_ticktime;
+            symbol->accept(calculate_common_ticktime);
+            common_ticktime = calculate_common_ticktime.get_common_ticktime();
+            if (common_ticktime == 0) {
+              fprintf(stderr, "\nYou must at least define a periodic task to set cycle period!");
+              ERROR;
+            }
+
+            symbol->configuration_name->accept(*this);
+
+            stage4out_c config_s4o(current_builddir, current_name, "c");
+            generate_c_config_c generate_c_config(&config_s4o);
+            symbol->accept(generate_c_config);
+
+            config_s4o.print("unsigned long long common_ticktime__ = ");
+            config_s4o.print_long_long_integer(common_ticktime);
+            config_s4o.print("; /*ns*/\n");
+            config_s4o.print("unsigned long greatest_tick_count__ = ");
+            config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count());
+            config_s4o.print("; /*tick*/\n");
+          }
+
+          symbol->resource_declarations->accept(*this);
+
+          current_configuration = NULL;
+          break;
+
+        default:
+          break;
       }
-      
-      current_configuration = symbol;
-      
-      calculate_common_ticktime_c calculate_common_ticktime;
-      symbol->accept(calculate_common_ticktime);
-      common_ticktime = calculate_common_ticktime.get_common_ticktime();
-      if (common_ticktime == 0) {
-        fprintf(stderr, "\nYou must at least define a periodic task to set cycle period!");
-        ERROR;
+      return NULL;
+    }
+
+    void *visit(resource_declaration_c *symbol) {
+      switch (current_mode) {
+        case datatypes_gm:
+          if (symbol->global_var_declarations != NULL)
+            symbol->global_var_declarations->accept(generate_c_datatypes);
+          break;
+        case pous_gm:
+          symbol->resource_name->accept(*this);
+          {
+            stage4out_c resources_s4o(current_builddir, current_name, "c");
+            generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
+            symbol->accept(generate_c_resources);
+          }
+          break;
+        default:
+          break;
       }
-      
-      symbol->configuration_name->accept(*this);
-      stage4out_c config_s4o(current_builddir, current_name, "c");
-      generate_c_config_c generate_c_config(&config_s4o);
-      symbol->accept(generate_c_config);
-        
-      config_s4o.print("unsigned long long common_ticktime__ = ");
-      config_s4o.print_long_long_integer(common_ticktime);
-      config_s4o.print("; /*ns*/\n");
-      config_s4o.print("unsigned long greatest_tick_count__ = ");
-      config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count());
-      config_s4o.print("; /*tick*/\n");
-      
-      symbol->resource_declarations->accept(*this);
-
-      current_configuration = NULL;
-      
-      return NULL;
-    }
-
-    void *visit(resource_declaration_c *symbol) {
-      symbol->resource_name->accept(*this);
-      stage4out_c resources_s4o(current_builddir, current_name, "c");
-      generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
-      symbol->accept(generate_c_resources);
       return NULL;
     }
 
     void *visit(single_resource_declaration_c *symbol) {
-      stage4out_c resources_s4o(current_builddir, "RESOURCE", "c");
-      generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
-      symbol->accept(generate_c_resources);
+      switch (current_mode) {
+        case pous_gm:
+          {
+            stage4out_c resources_s4o(current_builddir, "RESOURCE", "c");
+            generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
+            symbol->accept(generate_c_resources);
+          }
+          break;
+        default:
+          break;
+      }
       return NULL;
     }
     
--- a/stage4/generate_c/generate_c_il.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_c_il.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -548,6 +548,16 @@
 #endif
 
 
+/********************************/
+/* B 1.3.3 - Derived data types */
+/********************************/
+
+/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+void *visit(array_specification_c *symbol) {
+  symbol->non_generic_type_name->accept(*this);
+  return NULL;
+}
+
 /*********************/
 /* B 1.4 - Variables */
 /*********************/
@@ -676,15 +686,18 @@
 
 /* subscript_list ',' subscript */
 void *visit(subscript_list_c *symbol) {
+  array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
-    s4o.print("[__");
-    current_array_type->accept(*this);
-    s4o.print("_TRANSIDX(");
-    print_integer(i);
-    s4o.print(",");
+    symbol_c* dimension = array_dimension_iterator->next();
+	if (dimension == NULL) ERROR;
+
+	s4o.print("[(");
     symbol->elements[i]->accept(*this);
+    s4o.print(") - (");
+    dimension->accept(*this);
     s4o.print(")]");
   }
+  delete array_dimension_iterator;
   return NULL;
 }
 
--- a/stage4/generate_c/generate_c_st.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_c_st.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -223,6 +223,7 @@
 /********************************/
 /* B 1.3.3 - Derived data types */
 /********************************/
+
 /*  signed_integer DOTDOT signed_integer */
 void *visit(subrange_c *symbol) {
   switch (wanted_casegeneration) {
@@ -233,11 +234,18 @@
       symbol->upper_limit->accept(*this);
       break;
     default:
+      symbol->lower_limit->accept(*this);
       break;
   }
   return NULL;
 }
 
+/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+void *visit(array_specification_c *symbol) {
+  symbol->non_generic_type_name->accept(*this);
+  return NULL;
+}
+
 /*********************/
 /* B 1.4 - Variables */
 /*********************/
@@ -367,15 +375,18 @@
 
 /* subscript_list ',' subscript */
 void *visit(subscript_list_c *symbol) {
+  array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
-    s4o.print("[__");
-    current_array_type->accept(*this);
-    s4o.print("_TRANSIDX(");
-    print_integer(i);
-    s4o.print(",");
+    symbol_c* dimension = array_dimension_iterator->next();
+	if (dimension == NULL) ERROR;
+
+	s4o.print("[(");
     symbol->elements[i]->accept(*this);
+    s4o.print(") - (");
+    dimension->accept(*this);
     s4o.print(")]");
   }
+  delete array_dimension_iterator;
   return NULL;
 }
 
--- a/stage4/generate_c/generate_c_typedecl.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_c_typedecl.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -70,10 +70,9 @@
       arrayderiveddeclaration_bd,
       arraybasetype_bd,
       arraybasetypeincl_bd,
-      arraysubrange_bd,
-      arraytranslateindex_bd
+      arraysubrange_bd
     } basetypedeclaration_t;
-    
+
     basetypedeclaration_t current_basetypedeclaration;
 
     void print_integer(unsigned int integer) {
@@ -373,21 +372,6 @@
   }
   s4o_incl.print(")\n");
 
-  if (search_base_type.type_is_subrange(symbol->identifier)) {
-	s4o.print("#define __CHECK_");
-	current_type_name->accept(*this);
-	s4o.print(" __CHECK_");
-	current_basetypedeclaration = arraybasetype_bd;
-	symbol->array_spec_init->accept(*this);
-	current_basetypedeclaration = none_bd;
-	s4o.print("\n");
-  }
-
-  current_basetypedeclaration = arraytranslateindex_bd;
-  symbol->array_spec_init->accept(*this);
-  current_basetypedeclaration = none_bd;
-  s4o.print("\n");
-
   current_type_name = NULL;
   current_typedefinition = none_td;
 
@@ -404,18 +388,6 @@
 	  case arrayderiveddeclaration_bd:
 	    array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
 	    break;
-	  case arraytranslateindex_bd:
-	    if (!array_is_derived)
-		  symbol->array_specification->accept(*this);
-	    s4o.print("#define __");
-	    current_type_name->accept(*this);
-	    s4o.print("_TRANSIDX(row, index) __");
-	    if (array_is_derived)
-		   symbol->array_specification->accept(*this);
-	    else
-		   current_type_name->accept(*this);
-	    s4o.print("_TRANSIDX##row(index)");
-	    break;
 	  default:
 	    if (array_is_derived)
 		  symbol->array_specification->accept(*basedecl);
@@ -440,7 +412,6 @@
       symbol->non_generic_type_name->accept(*basedecl);
       break;
     case arraysubrange_bd:
-    case arraytranslateindex_bd:
       symbol->array_subrange_list->accept(*this);
       break;
     default:
@@ -452,19 +423,7 @@
 /* helper symbol for array_specification */
 /* array_subrange_list ',' subrange */
 void *visit(array_subrange_list_c *symbol) {
-  if (current_basetypedeclaration == arraytranslateindex_bd) {
-    for (int i = 0; i < symbol->n; i++) {
-      s4o.print("#define __");
-      current_type_name->accept(*this);
-      s4o.print("_TRANSIDX");
-      print_integer(i);
-      s4o.print("(index) (index) - ");
-      symbol->elements[i]->accept(*this);
-      s4o.print("\n");
-    }
-  }
-  else
-    print_list(symbol);
+  print_list(symbol);
   return NULL;
 }
 
@@ -491,6 +450,15 @@
   s4o_incl.print(",");
   symbol->simple_spec_init->accept(*this);
   s4o_incl.print(")\n");
+
+  if (search_base_type.type_is_subrange(symbol->simple_type_name)) {
+	s4o.print("#define __CHECK_");
+	current_type_name->accept(*this);
+	s4o.print(" __CHECK_");
+	symbol->simple_spec_init->accept(*this);
+	s4o.print("\n");
+  }
+
   return NULL;
 }
 
--- a/stage4/generate_c/generate_c_vardecl.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_c_vardecl.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -105,7 +105,6 @@
 
       current_mode = typedecl_am;
       array_specification->accept(*this);
-
       s4o.print(" temp = ");
 
       init_array_values(array_initialization);
@@ -188,14 +187,21 @@
     
     /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
     void *visit(array_specification_c *symbol) {
-      symbol->array_subrange_list->accept(*this);
+      identifier_c* type_name;
       switch (current_mode) {
         case arraysize_am:
+          symbol->array_subrange_list->accept(*this);
           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;
           break;
+        case typedecl_am:
+          s4o.print("__");
+          symbol->non_generic_type_name->accept(*this);
+          symbol->array_subrange_list->accept(*this);
+          break;
         default:
+          symbol->array_subrange_list->accept(*this);
           break;
       } 
       return NULL;
@@ -204,9 +210,14 @@
     /*  signed_integer DOTDOT signed_integer */
     //SYM_REF2(subrange_c, lower_limit, upper_limit)
     void *visit(subrange_c *symbol) {
+      int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
       switch (current_mode) {
         case arraysize_am:
-          array_size *= extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
+          array_size *= dimension;
+          break;
+        case typedecl_am:
+          s4o.print("_");
+          s4o.print_integer(dimension);
           break;
         default:
           break;
@@ -1379,6 +1390,23 @@
   return NULL;
 }
 
+/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+void *visit(array_specification_c *symbol) {
+  s4o.print("__");
+  symbol->non_generic_type_name->accept(*this);
+  symbol->array_subrange_list->accept(*this);
+  return NULL;
+}
+
+/*  signed_integer DOTDOT signed_integer */
+//SYM_REF2(subrange_c, lower_limit, upper_limit)
+void *visit(subrange_c *symbol) {
+  int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
+  s4o.print("_");
+  print_integer(dimension);
+  return NULL;
+}
+
 /*  var1_list ':' initialized_structure */
 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
 void *visit(structured_var_init_decl_c *symbol) {
@@ -1521,7 +1549,7 @@
 }
 
 void *visit(array_initial_elements_list_c *symbol) {
-  if (wanted_varformat == localinit_vf) {
+  if (wanted_varformat == localinit_vf || wanted_varformat == constructorinit_vf) {
 	generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
 	array_initialization->init_array_size(this->current_var_type_symbol);
 	array_initialization->init_array_values(this->current_var_init_symbol);
@@ -1952,12 +1980,15 @@
 	    s4o.print(nv->get());
 	    s4o.print(INIT_GLOBAL);
 	    s4o.print("(");
+	    this->current_var_type_symbol->accept(*this);
+	    s4o.print(",");
 	    if (symbol->global_var_name != NULL)
 		  symbol->global_var_name->accept(*this);
 	    else
 		  symbol->location->accept(*this);
-	    s4o.print(",");
+	    s4o.print(",__INITIAL_VALUE(");
 	    this->current_var_init_symbol->accept(*this);
+	    s4o.print(")");
 	    print_retain();
 	    s4o.print(")");
       }
@@ -2013,9 +2044,12 @@
 
           s4o.print(INIT_GLOBAL);
           s4o.print("(");
+          this->current_var_type_symbol->accept(*this);
+          s4o.print(",");
           list->elements[i]->accept(*this);
-          s4o.print(",");
+          s4o.print(",__INITIAL_VALUE(");
           this->current_var_init_symbol->accept(*this);
+          s4o.print(")");
           print_retain();
           s4o.print(")");
 #if 0
--- a/stage4/generate_c/generate_var_list.cc	Fri Sep 09 12:03:15 2011 +0200
+++ b/stage4/generate_c/generate_var_list.cc	Wed Sep 14 22:58:39 2011 +0200
@@ -25,66 +25,157 @@
  *
  */
 
-typedef struct
-{
-  symbol_c *symbol;
-} SYMBOL;
-
-typedef enum {
-  none_lt,
-  input_lt,
-  output_lt,
-  memory_lt
-} locationtype_t;
-
-
-/***********************************************************************/
-/***********************************************************************/
-/***********************************************************************/
-/***********************************************************************/
-
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
 
 class search_location_type_c: public iterator_visitor_c {
 
   public:
+    typedef enum {
+      none_lt,
+      input_lt,
+      output_lt,
+      memory_lt
+    } locationtype_t;
+
     locationtype_t current_location_type;
 
   public:
-	search_location_type_c(void) {}
-
-	virtual ~search_location_type_c(void) {}
-
-	locationtype_t get_location_type(symbol_c *symbol) {
+    search_location_type_c(void) {}
+
+    virtual ~search_location_type_c(void) {}
+
+    locationtype_t get_location_type(symbol_c *symbol) {
       current_location_type = none_lt;
       symbol->accept(*this);
       if (current_location_type == none_lt) ERROR;
       return current_location_type;
-	}
+    }
 
   private:
 
-	void *visit(incompl_location_c* symbol) {
+    void *visit(incompl_location_c* symbol) {
       if (symbol->value[1] == 'I')
         current_location_type = input_lt;
-	  else if (symbol->value[1] == 'Q')
+     else if (symbol->value[1] == 'Q')
         current_location_type = output_lt;
-	  else if (symbol->value[1] == 'M')
+     else if (symbol->value[1] == 'M')
         current_location_type = memory_lt;
       return NULL;
-	}
-
-	void *visit(direct_variable_c *symbol) {
+    }
+
+    void *visit(direct_variable_c *symbol) {
       if (symbol->value[1] == 'I')
         current_location_type = input_lt;
-	  else if (symbol->value[1] == 'Q')
+     else if (symbol->value[1] == 'Q')
         current_location_type = output_lt;
-	  else if (symbol->value[1] == 'M')
+     else if (symbol->value[1] == 'M')
         current_location_type = memory_lt;
       return NULL;
-	}
+    }
 };
 
 
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+
+class search_type_symbol_c: public iterator_visitor_c {
+
+  public:
+    typedef enum {
+      none_vtc,
+      variable_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;
+    search_base_type_c search_base_type;
+    search_fb_typedecl_c *search_fb_typedecl;
+
+  public:
+    search_type_symbol_c(symbol_c *scope) {
+      search_fb_typedecl = new search_fb_typedecl_c(scope);
+    }
+
+    virtual ~search_type_symbol_c(void) {
+      delete search_fb_typedecl;
+    }
+
+    symbol_c *get_type_symbol(symbol_c* symbol) {
+      this->current_var_type_category = variable_vtc;
+      this->current_var_type_symbol = NULL;
+      this->current_var_type_name = NULL;
+
+      symbol_c* var_type_symbol = spec_init_sperator_c::get_spec(symbol);
+      if (var_type_symbol == NULL) {
+        var_type_symbol = symbol;
+      }
+
+      var_type_symbol->accept(*this);
+
+      if (this->current_var_type_symbol == NULL)
+    	this->current_var_type_symbol = var_type_symbol;
+
+      return (this->current_var_type_symbol);
+    }
+
+    symbol_c *get_current_type_name(void) {
+      if (this->current_var_type_name == NULL)
+    	return (this->current_var_type_symbol);
+
+      return (this->current_var_type_name);
+    }
+
+    void *visit(identifier_c* symbol) {
+      if (this->current_var_type_name == NULL) {
+        this->current_var_type_name = symbol;
+
+        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));
+          this->current_var_type_symbol->accept(*this);
+        }
+      }
+      return NULL;
+    }
+
+    void *visit(array_specification_c* symbol) {
+      this->current_var_type_category = array_vtc;
+
+      if (this->current_var_type_name == NULL)
+        this->current_var_type_name = symbol->non_generic_type_name;
+
+      return NULL;
+    }
+
+    void *visit(structure_element_declaration_list_c* symbol) {
+      this->current_var_type_category = structure_vtc;
+      return NULL;
+    }
+
+};
+
 /***********************************************************************/
 /***********************************************************************/
 /***********************************************************************/
@@ -97,6 +188,11 @@
 class generate_var_list_c: protected generate_c_typedecl_c {
   
   public:
+    typedef struct
+    {
+      symbol_c *symbol;
+    } SYMBOL;
+
     typedef enum {
       none_dt,
       programs_dt,
@@ -106,18 +202,14 @@
     declarationtype_t current_declarationtype;
     
     typedef enum {
-      none_vtc,
-      variable_vtc,
-      external_vtc,
-      located_input_vtc,
-      located_memory_vtc,
-      located_output_vtc,
-      array_vtc,
-      structure_vtc,
-      function_block_vtc
-    } vartypecategory_t;
-    
-    vartypecategory_t current_var_type_category;
+      none_vcc,
+      external_vcc,
+      located_input_vcc,
+      located_memory_vcc,
+      located_output_vcc,
+    } varclasscategory_t;
+
+    varclasscategory_t current_var_class_category;
     
   private:
     symbol_c *current_var_type_symbol;
@@ -128,49 +220,26 @@
     unsigned int action_number;
     bool configuration_defined;
     std::list<SYMBOL> current_symbol_list;
-    search_base_type_c search_base_type;
-    search_fb_typedecl_c *search_fb_typedecl;
+    search_type_symbol_c *search_type_symbol;
     
   public:
     generate_var_list_c(stage4out_c *s4o_ptr, symbol_c *scope)
     : generate_c_typedecl_c(s4o_ptr) {
-      search_fb_typedecl = new search_fb_typedecl_c(scope);
+      search_type_symbol = new search_type_symbol_c(scope);
       current_var_number = 0;
-      current_var_type_symbol = current_var_type_name = NULL;
+      current_var_type_symbol = NULL;
+      current_var_type_name = NULL;
       current_declarationtype = none_dt;
-      current_var_type_category = none_vtc;
+      current_var_class_category = none_vcc;
     }
     
     ~generate_var_list_c(void) {
-      delete search_fb_typedecl;
+      delete search_type_symbol;
     }
     
     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) {
-        std::list<SYMBOL>::iterator pt;
-        for(pt = current_symbol_list.begin(); pt != current_symbol_list.end(); pt++) {
-          fprintf(stderr, "%s.", ((identifier_c*)(pt->symbol))->value);
-        }
-        ERROR;
-      }
-      
-      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;
+      this->current_var_type_symbol = search_type_symbol->get_type_symbol(symbol);
+      this->current_var_type_name = search_type_symbol->get_current_type_name();
     }
 
     void reset_var_type_symbol(void) {
@@ -209,39 +278,43 @@
     
     void declare_variable(symbol_c *symbol) {
       // Arrays and structures are not supported in debugging
-      switch (this->current_var_type_category) {
-      	case array_vtc:
-      	case structure_vtc:
+      switch (search_type_symbol->current_var_type_category) {
+          case search_type_symbol_c::array_vtc:
+          case search_type_symbol_c::structure_vtc:
           return;
-      	default:
-      	  break;
+          default:
+           break;
       }
       print_var_number();
       s4o.print(";");
-      switch (this->current_var_type_category) {
-        case external_vtc:
-          s4o.print("EXT");
-          break;
-        case located_input_vtc:
-          s4o.print("IN");
-          break;
-        case located_memory_vtc:
-          s4o.print("MEM");
-          break;
-        case located_output_vtc:
-          s4o.print("OUT");
-          break;
-        case array_vtc:
+      switch (search_type_symbol->current_var_type_category) {
+        case search_type_symbol_c::array_vtc:
           s4o.print("ARRAY");
           break;
-        case structure_vtc:
+        case search_type_symbol_c::structure_vtc:
           s4o.print("STRUCT");
           break;
-        case function_block_vtc:
+        case search_type_symbol_c::function_block_vtc:
           s4o.print("FB");
           break;
         default:
-          s4o.print("VAR");
+          switch (this->current_var_class_category) {
+            case external_vcc:
+             s4o.print("EXT");
+             break;
+            case located_input_vcc:
+             s4o.print("IN");
+             break;
+            case located_memory_vcc:
+             s4o.print("MEM");
+             break;
+            case located_output_vcc:
+             s4o.print("OUT");
+             break;
+            default:
+             s4o.print("VAR");
+             break;
+          }
           break;
       }
       s4o.print(";");
@@ -251,9 +324,9 @@
       print_symbol_list();
       symbol->accept(*this);
       s4o.print(";");
-      switch (this->current_var_type_category) {
-        case structure_vtc:
-        case function_block_vtc:
+      switch (search_type_symbol->current_var_type_category) {
+        case search_type_symbol_c::structure_vtc:
+        case search_type_symbol_c::function_block_vtc:
           this->current_var_type_name->accept(*this);
           s4o.print(";\n");
           SYMBOL *current_name;
@@ -263,7 +336,7 @@
           this->current_var_type_symbol->accept(*this);
           current_symbol_list.pop_back();
           break;
-        case array_vtc:
+        case search_type_symbol_c::array_vtc:
           this->current_var_type_name->accept(*this);
           s4o.print(";\n");
           break;
@@ -321,20 +394,33 @@
         update_var_type_symbol(symbol->located_var_spec_init);
         
         search_location_type_c search_location_type;
-        locationtype_t location_type = search_location_type.get_location_type(symbol->location);
-        if (location_type == input_lt)
-          this->current_var_type_category = located_input_vtc;
-        else if (location_type == memory_lt)
-          this->current_var_type_category = located_memory_vtc;
-        else if (location_type == output_lt)
-          this->current_var_type_category = located_output_vtc;
+        switch (search_location_type.get_location_type(symbol->location)) {
+          case search_location_type_c::input_lt:
+            this->current_var_class_category = located_input_vcc;
+            break;
+          case search_location_type_c::memory_lt:
+            this->current_var_class_category = located_memory_vcc;
+            break;
+          case search_location_type_c::output_lt:
+              this->current_var_class_category = located_output_vcc;
+              break;
+          default:
+            ERROR;
+            break;
+        }
 
         if (symbol->variable_name != NULL)
           declare_variable(symbol->variable_name);
         else
           declare_variable(symbol->location);
         
-        current_var_type_symbol = NULL;
+        this->current_var_class_category = none_vcc;
+
+        /* 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;
     }
 
@@ -348,20 +434,33 @@
         update_var_type_symbol(symbol->var_spec);
 
         search_location_type_c search_location_type;
-        locationtype_t location_type = search_location_type.get_location_type(symbol->incompl_location);
-        if (location_type == input_lt)
-          this->current_var_type_category = located_input_vtc;
-        else if (location_type == memory_lt)
-          this->current_var_type_category = located_memory_vtc;
-        else if (location_type == output_lt)
-          this->current_var_type_category = located_output_vtc;
+        switch (search_location_type.get_location_type(symbol->incompl_location)) {
+          case search_location_type_c::input_lt:
+            this->current_var_class_category = located_input_vcc;
+            break;
+          case search_location_type_c::memory_lt:
+            this->current_var_class_category = located_memory_vcc;
+            break;
+          case search_location_type_c::output_lt:
+            this->current_var_class_category = located_output_vcc;
+            break;
+          default:
+            ERROR;
+            break;
+        }
 
         if (symbol->variable_name != NULL)
           declare_variable(symbol->variable_name);
         else
           declare_variable(symbol->incompl_location);
 
-        current_var_type_symbol = NULL;
+        this->current_var_class_category = none_vcc;
+
+        /* 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;
     }
     
@@ -374,7 +473,6 @@
        */
       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.
@@ -400,7 +498,6 @@
       update_var_type_symbol(symbol->initialized_structure);
     
       /* now to produce the c equivalent... */
-      this->current_var_type_category = structure_vtc;
       declare_variables(symbol->var1_list);
     
       /* Values no longer in scope, and therefore no longer used.
@@ -450,16 +547,18 @@
        */
       update_var_type_symbol(symbol->specification);
       
+      this->current_var_class_category = external_vcc;
+
       /* now to produce the c equivalent... */
-      this->current_var_type_category = external_vtc;
       declare_variable(symbol->global_var_name);
       
+      this->current_var_class_category = none_vcc;
+
       /* 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;
     }
 
@@ -498,18 +597,28 @@
     // SYM_REF2(global_var_spec_c, global_var_name, location)
     void *visit(global_var_spec_c *symbol) {
       search_location_type_c search_location_type;
-	  locationtype_t location_type = search_location_type.get_location_type(symbol->location);
-	  if (location_type == input_lt)
-        this->current_var_type_category = located_input_vtc;
-      else if (location_type == memory_lt)
-        this->current_var_type_category = located_memory_vtc;
-      else if (location_type == output_lt)
-        this->current_var_type_category = located_output_vtc;
+	  switch (search_location_type.get_location_type(symbol->location)) {
+		case search_location_type_c::input_lt:
+		  this->current_var_class_category = located_input_vcc;
+		  break;
+		case search_location_type_c::memory_lt:
+		  this->current_var_class_category = located_memory_vcc;
+		  break;
+		case search_location_type_c::output_lt:
+		  this->current_var_class_category = located_output_vcc;
+		  break;
+		default:
+		  ERROR;
+	      break;
+	  }
 
       if (symbol->global_var_name != NULL)
         declare_variable(symbol->global_var_name);
       else
         declare_variable(symbol->location);
+
+      this->current_var_class_category = none_vcc;
+
       return NULL;
     }
     
@@ -539,7 +648,7 @@
       /* Start off by setting the current_var_type_symbol and
        * current_var_init_symbol private variables...
        */
-      this->current_var_type_symbol = symbol->type;
+      update_var_type_symbol(symbol->type);
 
       /* now to produce the c equivalent... */
       declare_variable(symbol->name);
@@ -559,7 +668,7 @@
       /* Start off by setting the current_var_type_symbol and
        * current_var_init_symbol private variables...
        */
-      this->current_var_type_symbol = symbol->type;
+      update_var_type_symbol(symbol->type);
 
       /* now to produce the c equivalent... */
       declare_variable(symbol->name);