Adding support for POU struct definition in POUS.h
authorlbessard
Mon, 19 May 2008 14:07:31 +0200
changeset 121 9e8ce092e169
parent 120 74640e3c7f53
child 122 9e57c6d79398
Adding support for POU struct definition in POUS.h
Adding program instanciated in configuration definition into VARIABLE.h
stage1_2/iec.y
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_sfc.cc
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_var_list.cc
--- a/stage1_2/iec.y	Wed Apr 16 09:49:28 2008 +0200
+++ b/stage1_2/iec.y	Mon May 19 14:07:31 2008 +0200
@@ -2285,6 +2285,7 @@
 
 enumerated_value:
   identifier 
+  {$$ = new enumerated_value_c(NULL, $1, locloc(@$));}
 | prev_declared_enumerated_type_name '#' any_identifier
 	{$$ = new enumerated_value_c($1, $3, locloc(@$));}
 ;
--- a/stage4/generate_c/generate_c.cc	Wed Apr 16 09:49:28 2008 +0200
+++ b/stage4/generate_c/generate_c.cc	Mon May 19 14:07:31 2008 +0200
@@ -454,8 +454,8 @@
 class generate_c_pous_c: public generate_c_typedecl_c {
 
   public:
-    generate_c_pous_c(stage4out_c *s4o_ptr)
-      : generate_c_typedecl_c(s4o_ptr) {};
+    generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr)
+      : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) {};
     virtual ~generate_c_pous_c(void) {}
 
 
@@ -625,6 +625,7 @@
 void *visit(function_block_declaration_c *symbol) {
   generate_c_vardecl_c *vardecl;
   generate_c_sfcdecl_c *sfcdecl;
+  generate_c_typedecl_c *typedecl;
   TRACE("function_block_declaration_c");
 
   /* start off by adding this declaration to the global
@@ -633,25 +634,26 @@
   function_block_type_symtable.insert(symbol->fblock_name, symbol);
   
   /* (A) Function Block data structure declaration... */
+  typedecl = new generate_c_typedecl_c(&s4o_incl);
   /* (A.1) Data structure declaration */
-  s4o.print("// FUNCTION_BLOCK ");
-  symbol->fblock_name->accept(*this);
-  s4o.print("\n// Data part\n");
-  s4o.print("typedef struct {\n");
-  s4o.indent_right();
+  s4o_incl.print("// FUNCTION_BLOCK ");
+  symbol->fblock_name->accept(*typedecl);
+  s4o_incl.print("\n// Data part\n");
+  s4o_incl.print("typedef struct {\n");
+  s4o_incl.indent_right();
   /* (A.2) Public variables: i.e. the function parameters... */
-  s4o.print(s4o.indent_spaces + "// FB Interface - IN, OUT, IN_OUT variables\n");
-  vardecl = new generate_c_vardecl_c(&s4o,
+  s4o_incl.print(s4o_incl.indent_spaces + "// FB Interface - IN, OUT, IN_OUT variables\n");
+  vardecl = new generate_c_vardecl_c(&s4o_incl,
   				      generate_c_vardecl_c::local_vf,
   				      generate_c_vardecl_c::input_vt |
   				      generate_c_vardecl_c::output_vt |
   				      generate_c_vardecl_c::inoutput_vt);
   vardecl->print(symbol->var_declarations);
   delete vardecl;
-  s4o.print("\n");
+  s4o_incl.print("\n");
   /* (A.3) Private internal variables */
-  s4o.print(s4o.indent_spaces + "// FB private variables - TEMP, private and located variables\n");
-  vardecl = new generate_c_vardecl_c(&s4o,
+  s4o_incl.print(s4o_incl.indent_spaces + "// FB private variables - TEMP, private and located variables\n");
+  vardecl = new generate_c_vardecl_c(&s4o_incl,
   				      generate_c_vardecl_c::local_vf,
 				        generate_c_vardecl_c::temp_vt |
   				      generate_c_vardecl_c::private_vt |
@@ -660,17 +662,17 @@
   vardecl->print(symbol->var_declarations);
   delete vardecl;
   /* (A.4) Generate private internal variables for SFC */
-  sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::sfcdecl_sd);
+  sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd);
   sfcdecl->print(symbol->fblock_body);
   delete sfcdecl;
-  s4o.print("\n");
-
+  s4o_incl.print("\n");
+  
   /* (A.5) Function Block data structure type name. */
-  s4o.indent_left();
-  s4o.print("} ");
-  symbol->fblock_name->accept(*this);
-  s4o.print(";\n\n");
-
+  s4o_incl.indent_left();
+  s4o_incl.print("} ");
+  symbol->fblock_name->accept(*typedecl);
+  s4o_incl.print(";\n\n");
+  delete typedecl;
 
   /* (B) Constructor */
   /* (B.1) Constructor name... */
@@ -785,6 +787,7 @@
 void *visit(program_declaration_c *symbol) {
   generate_c_vardecl_c *vardecl;
   generate_c_sfcdecl_c *sfcdecl;
+  generate_c_typedecl_c *typedecl;
   TRACE("program_declaration_c");
 
   /* start off by adding this declaration to the global
@@ -793,26 +796,27 @@
   program_type_symtable.insert(symbol->program_type_name, symbol);
 
   /* (A) Program data structure declaration... */
+  typedecl = new generate_c_typedecl_c(&s4o_incl);
   /* (A.1) Data structure declaration */
-  s4o.print("// PROGRAM ");
-  symbol->program_type_name->accept(*this);
-  s4o.print("\n// Data part\n");
-  s4o.print("typedef struct {\n");
-  s4o.indent_right();
+  s4o_incl.print("// PROGRAM ");
+  symbol->program_type_name->accept(*typedecl);
+  s4o_incl.print("\n// Data part\n");
+  s4o_incl.print("typedef struct {\n");
+  s4o_incl.indent_right();
 
   /* (A.2) Public variables: i.e. the program parameters... */
-  s4o.print(s4o.indent_spaces + "// PROGRAM Interface - IN, OUT, IN_OUT variables\n");
-  vardecl = new generate_c_vardecl_c(&s4o,
+  s4o_incl.print(s4o_incl.indent_spaces + "// PROGRAM Interface - IN, OUT, IN_OUT variables\n");
+  vardecl = new generate_c_vardecl_c(&s4o_incl,
   				      generate_c_vardecl_c::local_vf,
   				      generate_c_vardecl_c::input_vt |
   				      generate_c_vardecl_c::output_vt |
   				      generate_c_vardecl_c::inoutput_vt);
   vardecl->print(symbol->var_declarations);
   delete vardecl;
-  s4o.print("\n");
+  s4o_incl.print("\n");
   /* (A.3) Private internal variables */
-  s4o.print(s4o.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n");
-  vardecl = new generate_c_vardecl_c(&s4o,
+  s4o_incl.print(s4o_incl.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n");
+  vardecl = new generate_c_vardecl_c(&s4o_incl,
                 generate_c_vardecl_c::local_vf,
                 generate_c_vardecl_c::temp_vt |
                 generate_c_vardecl_c::private_vt |
@@ -821,15 +825,16 @@
   vardecl->print(symbol->var_declarations);
   delete vardecl;
   /* (A.4) Generate private internal variables for SFC */
-  sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::sfcdecl_sd);
+  sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd);
   sfcdecl->print(symbol->function_block_body);
   delete sfcdecl;
   
   /* (A.5) Program data structure type name. */
-  s4o.indent_left();
-  s4o.print("} ");
-  symbol->program_type_name->accept(*this);
-  s4o.print(";\n\n");
+  s4o_incl.indent_left();
+  s4o_incl.print("} ");
+  symbol->program_type_name->accept(*typedecl);
+  s4o_incl.print(";\n\n");
+  delete typedecl;
 
   /* (B) Constructor */
   /* (B.1) Constructor name... */
@@ -1211,6 +1216,7 @@
       }
       
       /* (A.3) POUs inclusion */
+      s4o.print("#include \"POUS.h\"\n\n");
       s4o.print("#include \"POUS.c\"\n\n");
       
       /* (A.4) Resource programs declaration... */
@@ -1436,10 +1442,10 @@
   protected:
     stage4out_c &s4o;
     stage4out_c pous_s4o;
+    stage4out_c pous_incl_s4o;
     stage4out_c located_variables_s4o;
     stage4out_c variables_s4o;
     generate_c_pous_c generate_c_pous;
-    generate_var_list_c *generate_var_list;
     
     symbol_c *current_configuration;
 
@@ -1452,9 +1458,10 @@
     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
             s4o(*s4o_ptr),
             pous_s4o(builddir, "POUS", "c"),
+            pous_incl_s4o(builddir, "POUS", "h"),
             located_variables_s4o(builddir, "LOCATED_VARIABLES","h"),
             variables_s4o(builddir, "VARIABLES","csv"),
-            generate_c_pous(&pous_s4o) {
+            generate_c_pous(&pous_s4o, &pous_incl_s4o) {
       current_builddir = builddir;
       current_configuration = NULL;
     }
@@ -1465,13 +1472,15 @@
 /* B 0 - Programming Model */
 /***************************/
     void *visit(library_c *symbol) {
-      generate_var_list = new generate_var_list_c(&variables_s4o, symbol);
-      
+      pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n");
       for(int i = 0; i < symbol->n; i++) {
         symbol->elements[i]->accept(*this);
       }
-      
-      delete generate_var_list;
+      pous_incl_s4o.print("#endif //__POUS_H\n");
+      
+      generate_var_list_c generate_var_list(&variables_s4o, symbol);
+      generate_var_list.generate_programs(symbol);
+      generate_var_list.generate_variables(symbol);
       
       generate_location_list_c generate_location_list(&located_variables_s4o);
       symbol->accept(generate_location_list);
@@ -1556,8 +1565,6 @@
 
       current_configuration = NULL;
       
-      symbol->accept(*generate_var_list);
-      
       return NULL;
     }
 
--- a/stage4/generate_c/generate_c_sfc.cc	Wed Apr 16 09:49:28 2008 +0200
+++ b/stage4/generate_c/generate_c_sfc.cc	Mon May 19 14:07:31 2008 +0200
@@ -355,7 +355,7 @@
           s4o.print("action_list[");
           s4o.print(SFC_STEP_ACTION_PREFIX);
           symbol->action_name->accept(*this);
-          s4o.print("].state) {");
+          s4o.print("].state) {\n");
           s4o.indent_right();
           
           // generate action code
--- a/stage4/generate_c/generate_c_typedecl.cc	Wed Apr 16 09:49:28 2008 +0200
+++ b/stage4/generate_c/generate_c_typedecl.cc	Mon May 19 14:07:31 2008 +0200
@@ -48,16 +48,29 @@
 
 class generate_c_typedecl_c: public generate_c_base_c {
 
+  protected:
+    stage4out_c &s4o_incl;
+
   private:
     symbol_c* current_type_name;
     search_base_type_c search_base_type;
 
+    generate_c_base_c *basedecl;
+
   public:
-    generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr) {
+    generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) {
       current_typedefinition = none_td;
       current_basetypedeclaration = none_bd;
+      basedecl = new generate_c_base_c(&s4o_incl);
     }
-    ~generate_c_typedecl_c(void) {}
+    generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) {
+      current_typedefinition = none_td;
+      current_basetypedeclaration = none_bd;
+      basedecl = new generate_c_base_c(&s4o_incl);
+    }
+    ~generate_c_typedecl_c(void) {
+      delete basedecl;
+    }
 
     typedef enum {
       none_td,
@@ -73,6 +86,7 @@
       subrangebasetypeexploration_bd,
       subrangetest_bd,
       arraybasetype_bd,
+      arraybasetypeincl_bd,
       arraysubrange_bd,
       arraytranslateindex_bd
     } basetypedeclaration_t;
@@ -89,6 +103,38 @@
       s4o.print(str);
     }
 
+    void print_integer_incl(unsigned int integer) {
+      char str[10];
+      sprintf(str, "%d", integer);
+      s4o_incl.print(str);
+    }
+
+    void *print_list_incl(list_c *list,
+         std::string pre_elem_str = "",
+         std::string inter_elem_str = "",
+         std::string post_elem_str = "",
+         visitor_c *visitor = NULL) {
+      if (visitor == NULL) visitor = this;
+
+      if (list->n > 0) {
+//std::cout << "generate_c_base_c::print_list(n = " << list->n << ")   000\n";
+        s4o_incl.print(pre_elem_str);
+        list->elements[0]->accept(*visitor);
+      }
+
+      for(int i = 1; i < list->n; i++) {
+//std::cout << "generate_c_base_c::print_list   " << i << "\n";
+        s4o_incl.print(inter_elem_str);
+        list->elements[i]->accept(*visitor);
+      }
+
+      if (list->n > 0)
+        s4o_incl.print(post_elem_str);
+
+      return NULL;
+    }
+
+
 /***************************/
 /* B 0 - Programming Model */
 /***************************/
@@ -152,13 +198,13 @@
   /* add this type declaration to the type symbol table... */
   type_symtable.insert(symbol->subrange_type_name, symbol->subrange_spec_init);
   
-  s4o.print("typedef ");
+  s4o_incl.print("typedef ");
   current_basetypedeclaration = subrangebasetype_bd;
   symbol->subrange_spec_init->accept(*this);
   current_basetypedeclaration = none_bd;
-  s4o.print(" ");
-  symbol->subrange_type_name->accept(*this);
-  s4o.print(";\n\n");
+  s4o_incl.print(" ");
+  symbol->subrange_type_name->accept(*basedecl);
+  s4o_incl.print(";\n\n");
   
   current_basetypedeclaration = subrangebasetypeexploration_bd;
   symbol->subrange_spec_init->accept(*this);
@@ -186,7 +232,7 @@
 void *visit(subrange_specification_c *symbol) {
   switch (current_basetypedeclaration) {
     case subrangebasetype_bd:
-      symbol->integer_type_name->accept(*this);
+      symbol->integer_type_name->accept(*basedecl);
       break;
     case subrangebasetypeexploration_bd:
       search_base_type.explore_type(symbol->integer_type_name);
@@ -232,10 +278,10 @@
   switch (current_typedefinition) {
     case array_td:
       if (current_basetypedeclaration == arraysubrange_bd) {
-        s4o.print("[");
+        s4o_incl.print("[");
         dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1;
-        print_integer(dimension);
-        s4o.print("]");
+        print_integer_incl(dimension);
+        s4o_incl.print("]");
       }
       else
         symbol->lower_limit->accept(*this);
@@ -273,13 +319,13 @@
   /* add this type declaration to the type symbol table... */
   type_symtable.insert(symbol->enumerated_type_name, symbol->enumerated_spec_init);
   
-  s4o.print("typedef enum {\n");
-  s4o.indent_right();
+  s4o_incl.print("typedef enum {\n");
+  s4o_incl.indent_right();
   symbol->enumerated_spec_init->accept(*this);
-  s4o.indent_left();
-  s4o.print("} ");
-  symbol->enumerated_type_name->accept(*this);
-  s4o.print(";\n");
+  s4o_incl.indent_left();
+  s4o_incl.print("} ");
+  symbol->enumerated_type_name->accept(*basedecl);
+  s4o_incl.print(";\n");
   return NULL;
 }
 
@@ -292,13 +338,13 @@
 /* helper symbol for enumerated_specification->enumerated_spec_init */
 /* enumerated_value_list ',' enumerated_value */
 void *visit(enumerated_value_list_c *symbol) {
-  print_list(symbol, s4o.indent_spaces, ",\n"+s4o.indent_spaces, "\n");
+  print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n");
   return NULL;
 }
 
 /* enumerated_type_name '#' identifier */
 void *visit(enumerated_value_c *symbol) {
-  symbol->value->accept(*this);
+  symbol->value->accept(*basedecl);
   return NULL;
 }
 
@@ -308,16 +354,16 @@
   /* add this type declaration to the type symbol table... */
   type_symtable.insert(symbol->identifier, symbol->array_spec_init);
   
-  s4o.print("typedef ");
-  current_basetypedeclaration = arraybasetype_bd;
+  s4o_incl.print("typedef ");
+  current_basetypedeclaration = arraybasetypeincl_bd;
   symbol->array_spec_init->accept(*this);
   current_basetypedeclaration = none_bd;
-  s4o.print(" ");
-  symbol->identifier->accept(*this);
+  s4o_incl.print(" ");
+  symbol->identifier->accept(*basedecl);
   current_basetypedeclaration = arraysubrange_bd;
   symbol->array_spec_init->accept(*this);
   current_basetypedeclaration = none_bd;
-  s4o.print(";\n");
+  s4o_incl.print(";\n");
   
   search_base_type.explore_type(symbol->array_spec_init);
   if (search_base_type.base_is_subrange()) {
@@ -355,6 +401,9 @@
     case arraybasetype_bd:
       symbol->non_generic_type_name->accept(*this);
       break;
+    case arraybasetypeincl_bd:
+      symbol->non_generic_type_name->accept(*basedecl);
+      break;
     case arraysubrange_bd:
     case arraytranslateindex_bd:
       symbol->array_subrange_list->accept(*this);
@@ -404,11 +453,11 @@
   /* add this type declaration to the type symbol table... */
   type_symtable.insert(symbol->simple_type_name, symbol->simple_spec_init);
 
-  s4o.print("typedef ");
+  s4o_incl.print("typedef ");
   symbol->simple_spec_init->accept(*this);
-  s4o.print(" ");
-  symbol->simple_type_name->accept(*this);
-  s4o.print(";\n");
+  s4o_incl.print(" ");
+  symbol->simple_type_name->accept(*basedecl);
+  s4o_incl.print(";\n");
   return NULL;
 }
 
@@ -417,7 +466,7 @@
 // <constant> may be NULL
 void *visit(simple_spec_init_c *symbol) {
   TRACE("simple_spec_init_c");
-  symbol->simple_specification->accept(*this);
+  symbol->simple_specification->accept(*basedecl);
   return NULL;
 }
 
@@ -478,11 +527,11 @@
   /* add this type declaration to the type symbol table... */
   type_symtable.insert(symbol->structure_type_name, symbol->structure_specification);
 
-  s4o.print("typedef ");
+  s4o_incl.print("typedef ");
   symbol->structure_specification->accept(*this);
-  s4o.print(" ");
-  symbol->structure_type_name->accept(*this);
-  s4o.print(";\n");
+  s4o_incl.print(" ");
+  symbol->structure_type_name->accept(*basedecl);
+  s4o_incl.print(";\n");
   return NULL;
 }
 
--- a/stage4/generate_c/generate_var_list.cc	Wed Apr 16 09:49:28 2008 +0200
+++ b/stage4/generate_c/generate_var_list.cc	Mon May 19 14:07:31 2008 +0200
@@ -57,12 +57,22 @@
 
 class generate_var_list_c: protected generate_c_typedecl_c {
   
+  public:
+    typedef enum {
+      none_dt,
+      programs_dt,
+      variables_dt
+    } declarationtype_t;
+
+    declarationtype_t current_declarationtype;
+  
   private:
     symbol_c *current_var_type_symbol;
     unsigned int current_var_number;
     unsigned int step_number;
     unsigned int transition_number;
     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;
@@ -71,8 +81,9 @@
     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);
+      current_var_number = 0;
       current_var_type_symbol = NULL;
-      current_var_number = 0;
+      current_declarationtype = none_dt;
     }
     
     ~generate_var_list_c(void) {
@@ -80,6 +91,7 @@
     }
     
     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)
         ERROR;
@@ -96,6 +108,26 @@
       this->current_var_type_symbol = NULL;
     }
     
+    void generate_programs(symbol_c *symbol) {
+      s4o.print("// Programs\n");
+      current_var_number = 0;
+      configuration_defined = false;
+      current_declarationtype = programs_dt;
+      symbol->accept(*this);
+      current_declarationtype = none_dt;
+      s4o.print("\n");
+    }
+    
+    void generate_variables(symbol_c *symbol) {
+      s4o.print("// Variables\n");
+      current_var_number = 0;
+      configuration_defined = false;
+      current_declarationtype = variables_dt;
+      symbol->accept(*this);
+      current_declarationtype = none_dt;
+      s4o.print("\n");
+    }
+    
     void declare_variables(symbol_c *symbol, const char* type = "VAR") {
       list_c *list = dynamic_cast<list_c *>(symbol);
       /* should NEVER EVER occur!! */
@@ -163,10 +195,10 @@
         s4o.print(".");
       }
     }
-    
-    /********************************************/
-    /* B.1.4.3   Declaration and initilization  */
-    /********************************************/
+
+/********************************************/
+/* B.1.4.3 - Declaration and initialization */
+/********************************************/
     
     /*  [variable_name] location ':' located_var_spec_init */
     /* variable_name -> may be NULL ! */
@@ -342,16 +374,32 @@
       return NULL;
     }
 
+/********************************/
+/* B 1.3.3 - Derived data types */
+/********************************/
+    void *visit(data_type_declaration_c *symbol) {
+      return NULL;
+    }
+
 /**************************************/
 /* B.1.5 - Program organization units */
 /**************************************/
 
+/***********************/
+/* B 1.5.1 - Functions */
+/***********************/
+    void *visit(function_declaration_c *symbol) {
+      return NULL;
+    }
+
 /*****************************/
 /* B 1.5.2 - Function Blocks */
 /*****************************/
     void *visit(function_block_declaration_c *symbol) {
-      symbol->var_declarations->accept(*this);
-      symbol->fblock_body->accept(*this);
+      if (current_declarationtype == variables_dt && configuration_defined) {
+        symbol->var_declarations->accept(*this);
+        symbol->fblock_body->accept(*this);
+      }
       return NULL;
     }
 
@@ -359,8 +407,10 @@
 /* B 1.5.3 - Programs */
 /**********************/
     void *visit(program_declaration_c *symbol) {
-      symbol->var_declarations->accept(*this);
-      symbol->function_block_body->accept(*this);
+      if (current_declarationtype == variables_dt && configuration_defined) {
+        symbol->var_declarations->accept(*this);
+        symbol->function_block_body->accept(*this);
+      }
       return NULL;
     }
 
@@ -484,18 +534,34 @@
     //SYM_REF6(program_configuration_c, retain_option, program_name, task_name, program_type_name, prog_conf_elements, unused)
     void *visit(program_configuration_c *symbol) {
       
-      /* 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);
-      
-      declare_variable(symbol->program_name, "FB");
-      
-      /* 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();
+      switch (current_declarationtype) {
+        case programs_dt:
+          print_var_number();
+          s4o.print(";");
+          print_symbol_list();
+          symbol->program_name->accept(*this);
+          s4o.print(";");
+          symbol->program_type_name->accept(*this);
+          s4o.print(";\n");
+          break;
+        case variables_dt:
+          /* 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);
+          
+          declare_variable(symbol->program_name, "FB");
+          
+          /* 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();
+          
+          break;
+        default:
+          break;
+      }
       
       return NULL;
     }
@@ -513,8 +579,10 @@
       current_name = new SYMBOL;
       current_name->symbol = symbol->configuration_name;
       current_symbol_list.push_back(*current_name);
+      configuration_defined = true;
       symbol->resource_declarations->accept(*this);
       current_symbol_list.pop_back();
+      configuration_defined = false;
       return NULL;
     }