Adding support for EN/ENO params in function and function blocks (standard function not supported yet)
authorlbessard
Fri, 26 Sep 2008 14:42:05 +0200
changeset 146 eef5e62048c7
parent 145 72ae82e65dbc
child 147 f34f9084a20e
Adding support for EN/ENO params in function and function blocks (standard function not supported yet)
absyntax/absyntax.def
stage1_2/iec.y
stage4/generate_c/function_call_param_iterator.cc
stage4/generate_c/function_param_iterator.cc
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_base.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_c_vardecl.cc
stage4/generate_iec/generate_iec.cc
--- a/absyntax/absyntax.def	Thu Sep 25 10:26:10 2008 +0200
+++ b/absyntax/absyntax.def	Fri Sep 26 14:42:05 2008 +0200
@@ -365,6 +365,8 @@
 /* edge -> The F_EDGE or R_EDGE directive */
 SYM_REF2(edge_declaration_c, edge, var1_list)
 
+SYM_REF0(en_param_declaration_c)
+
 SYM_REF0(raising_edge_option_c)
 SYM_REF0(falling_edge_option_c)
 
@@ -395,6 +397,8 @@
 /* option -> may be NULL ! */
 SYM_REF2(output_declarations_c, option, var_init_decl_list)
 
+SYM_REF0(eno_param_declaration_c)
+
 /*  VAR_IN_OUT var_declaration_list END_VAR */
 SYM_REF1(input_output_declarations_c, var_declaration_list)
 
--- a/stage1_2/iec.y	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage1_2/iec.y	Fri Sep 26 14:42:05 2008 +0200
@@ -656,6 +656,7 @@
 %type  <list>	input_declaration_list
 %type  <leaf>	input_declaration
 %type  <leaf>	edge_declaration
+%type  <leaf>	en_param_declaration
 %type  <leaf>	var_init_decl
 %type  <leaf>	var1_init_decl
 %type  <list>	var1_list
@@ -669,6 +670,9 @@
 // %type  <list>	fb_name_list
 // %type  <leaf>	fb_name
 %type  <leaf>	output_declarations
+%type  <leaf>	var_output_init_decl
+%type  <list>	var_output_init_decl_list
+%type  <leaf>	en_param_declaration
 %type  <leaf>	input_output_declarations
 /* helper symbol for input_output_declarations */
 %type  <list>	var_declaration_list
@@ -711,7 +715,7 @@
 %type  <leaf>	string_spec
 /* intermediate helper symbol for:
  *  - non_retentive_var_decls
- *  - output_declarations
+ *  - var_declarations
  */
 %type  <list>	var_init_decl_list
 
@@ -2964,6 +2968,7 @@
 variable:
   symbolic_variable
 | direct_variable
+| eno_param
 ;
 
 
@@ -3160,6 +3165,7 @@
 input_declaration:
   var_init_decl
 | edge_declaration
+| en_param_declaration
 ;
 
 
@@ -3170,9 +3176,9 @@
 	{$$ = new edge_declaration_c(new falling_edge_option_c(locloc(@3)), $1, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | var1_list BOOL R_EDGE
-	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification."); yynerrs++;}
+	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
 | var1_list BOOL F_EDGE
-	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification."); yynerrs++;}
+	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;}
 | var1_list ':' BOOL R_EDGE F_EDGE
 	{$$ = NULL; print_err_msg(locf(@5), locl(@5), "'R_EDGE' and 'F_EDGE' can't be present at the same time in edge declaration."); yynerrs++;}
 | var1_list ':' R_EDGE
@@ -3182,6 +3188,28 @@
 /* ERROR_CHECK_END */
 ;
 
+en_param_declaration:
+  en_param ':' BOOL ASSIGN boolean_literal
+  {$$ = new en_param_declaration_c(locloc(@$));}
+| en_param ':' BOOL ASSIGN integer
+  {$$ = new en_param_declaration_c(locloc(@$));}
+/* ERROR_CHECK_BEGIN */
+| en_param BOOL ASSIGN boolean_literal
+	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
+| en_param BOOL ASSIGN integer
+	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
+| en_param ':' ASSIGN boolean_literal
+  {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
+| en_param ':' ASSIGN integer
+	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;}
+| en_param ':' BOOL ASSIGN error
+	{$$ = NULL;
+	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in EN declaration.");}
+	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in EN declaration."); yyclearin;}
+	 yyerrok;
+	}
+/* ERROR_CHECK_END */
+;
 
 var_init_decl:
   var1_init_decl
@@ -3341,11 +3369,11 @@
 
 
 output_declarations:
-  VAR_OUTPUT var_init_decl_list END_VAR
+  VAR_OUTPUT var_output_init_decl_list END_VAR
 	{$$ = new output_declarations_c(NULL, $2, locloc(@$));}
-| VAR_OUTPUT RETAIN var_init_decl_list END_VAR
+| VAR_OUTPUT RETAIN var_output_init_decl_list END_VAR
 	{$$ = new output_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));}
-| VAR_OUTPUT NON_RETAIN var_init_decl_list END_VAR
+| VAR_OUTPUT NON_RETAIN var_output_init_decl_list END_VAR
 	{$$ = new output_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | VAR_OUTPUT END_VAR
@@ -3354,17 +3382,17 @@
 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive output variable(s) declaration."); yynerrs++;}
 | VAR_OUTPUT NON_RETAIN END_VAR
 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive output variable(s) declaration."); yynerrs++;}
-| VAR_OUTPUT error var_init_decl_list END_VAR
+| VAR_OUTPUT error var_output_init_decl_list END_VAR
 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_OUPUT' in output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT RETAIN error var_init_decl_list END_VAR
+| VAR_OUTPUT RETAIN error var_output_init_decl_list END_VAR
 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT NON_RETAIN error var_init_decl_list END_VAR
+| VAR_OUTPUT NON_RETAIN error var_output_init_decl_list END_VAR
 	{$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT var_init_decl_list error END_OF_INPUT
+| VAR_OUTPUT var_output_init_decl_list error END_OF_INPUT
 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT RETAIN var_init_decl_list error END_OF_INPUT
+| VAR_OUTPUT RETAIN var_output_init_decl_list error END_OF_INPUT
 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive output variable(s) declaration."); yyerrok;}
-| VAR_OUTPUT NON_RETAIN var_init_decl_list error END_OF_INPUT
+| VAR_OUTPUT NON_RETAIN var_output_init_decl_list error END_OF_INPUT
 	{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive output variable(s) declaration."); yyerrok;}
 | VAR_OUTPUT error END_VAR
 	{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in output variable(s) declaration."); yyerrok;}
@@ -3375,6 +3403,38 @@
 /* ERROR_CHECK_END */
 ;
 
+var_output_init_decl:
+  var_init_decl
+| eno_param_declaration
+;
+
+var_output_init_decl_list:
+  var_output_init_decl ';'
+	{$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);}
+| var_output_init_decl_list var_output_init_decl ';'
+	{$$ = $1; $$->add_element($2);}
+/* ERROR_CHECK_BEGIN */
+| var_output_init_decl_list var_output_init_decl error
+	{$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;}
+| var_output_init_decl_list error ';'
+	{$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;}
+/* ERROR_CHECK_END */
+;
+
+eno_param_declaration:
+  eno_param ':' BOOL
+  {$$ = new eno_param_declaration_c(locloc(@$));}
+/* ERROR_CHECK_BEGIN */
+| en_param BOOL
+	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN0 declaration."); yynerrs++;}
+| en_param ':' error
+	{$$ = NULL;
+	 if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in ENO declaration.");}
+	 else {print_err_msg(locf(@3), locl(@3), "invalid specification in ENO declaration."); yyclearin;}
+	 yyerrok;
+	}
+/* ERROR_CHECK_END */
+;
 
 
 input_output_declarations:
@@ -4063,7 +4123,6 @@
 
 /* intermediate helper symbol for:
  *  - non_retentive_var_decls
- *  - output_declarations
  *  - var_declarations
  */
 var_init_decl_list:
--- a/stage4/generate_c/function_call_param_iterator.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/function_call_param_iterator.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -127,7 +127,21 @@
 
         case search_op:
           identifier_c *variable_name2 = dynamic_cast<identifier_c *>(variable_name);
+          
+          if (variable_name2 == NULL) {
+            en_param_c *en_param = dynamic_cast<en_param_c *>(variable_name);
+            if (en_param != NULL)
+              variable_name2 = new identifier_c("EN");
+          }
+          
+          if (variable_name2 == NULL) {
+            eno_param_c *eno_param = dynamic_cast<eno_param_c *>(variable_name);
+            if (eno_param != NULL)
+              variable_name2 = new identifier_c("ENO");
+          }
+          
           if (variable_name2 == NULL) ERROR;
+          
           if (strcasecmp(search_param_name->value, variable_name2->value) == 0)
             /* FOUND! This is the same parameter!! */
             return (void *)expression;
--- a/stage4/generate_c/function_param_iterator.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/function_param_iterator.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -90,6 +90,8 @@
     symbol_c *current_param_type;
     symbol_c *current_param_default_value;
     param_direction_t current_param_direction;
+    bool en_declared;
+    bool eno_declared;
 
   private:
     void* handle_param_list(list_c *list) {
@@ -114,8 +116,8 @@
       void *res;
       for (int i = 0; i < list->n; i++) {
         res = list->elements[i]->accept(*this);
-	if (res != NULL)
-	  return res;
+        if (res != NULL)
+	        return res;
       }
       return NULL;
    }
@@ -127,6 +129,8 @@
       next_param = param_count = 0;
       current_param_name = NULL;
       current_param_type = current_param_default_value = NULL;
+      en_declared = false;
+      eno_declared = false;
     }
 
     /* initialise the iterator object.
@@ -165,21 +169,47 @@
      */
     identifier_c *next(void) {
       void *res;
+      identifier_c *identifier;
       param_count = 0;
       next_param++;
       res = f_decl->accept(*this);
-      if (res == NULL)
+      if (res != NULL) {
+        symbol_c *sym = (symbol_c *)res;
+        identifier = dynamic_cast<identifier_c *>(sym);
+        if (identifier == NULL)
+          ERROR;
+      }
+      else if (!en_declared) {
+        current_param_direction = direction_in;
+        identifier = declare_en_param();
+      }
+      else if (!eno_declared) {
+        current_param_direction = direction_out;
+        identifier = declare_eno_param();
+      }
+      else
         return NULL;
-
-      symbol_c *sym = (symbol_c *)res;
-      identifier_c *identifier = dynamic_cast<identifier_c *>(sym);
-      if (identifier == NULL)
-        ERROR;
-
+      
       current_param_name = identifier;
       return current_param_name;
     }
 
+    identifier_c *declare_en_param(void) {
+      en_declared = true;
+      identifier_c *identifier = new identifier_c("EN");
+      current_param_type = (symbol_c*)(new bool_type_name_c());
+      current_param_default_value = (symbol_c*)(new boolean_literal_c(current_param_type, new boolean_true_c()));
+      return identifier;
+    }
+
+    identifier_c *declare_eno_param(void) {
+      eno_declared = true;
+      identifier_c *identifier = new identifier_c("ENO");
+      current_param_type = (symbol_c*)(new bool_type_name_c());
+      current_param_default_value = NULL;
+      return identifier;
+    }
+
     /* Returns the currently referenced parameter's default value,
      * or NULL if none is specified in the function declrataion itself.
      */
@@ -209,7 +239,11 @@
     }
     void *visit(input_declaration_list_c *symbol) {TRACE("input_declaration_list_c"); return iterate_list(symbol);}
     void *visit(edge_declaration_c *symbol) {TRACE("edge_declaration_c"); return symbol->var1_list->accept(*this);}
-
+    void *visit(en_param_declaration_c *symbol) {
+      TRACE("en_param_declaration_c");
+      if (en_declared) ERROR;
+      return (void *)declare_en_param();
+    }
 #if 0
 /* var1_list ':' array_spec_init */
 SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)
@@ -230,6 +264,11 @@
       current_param_direction = direction_out;
       return symbol->var_init_decl_list->accept(*this);
     }
+    void *visit(eno_param_declaration_c *symbol) {
+      TRACE("eno_param_declaration_c");
+      if (eno_declared) ERROR;
+      return (void *)declare_eno_param();
+    }
     void *visit(input_output_declarations_c *symbol) {
       TRACE("input_output_declarations_c");
       current_param_direction = direction_inout;
--- a/stage4/generate_c/generate_c.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/generate_c.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -570,28 +570,34 @@
   				      generate_c_vardecl_c::finterface_vf,
   				      generate_c_vardecl_c::input_vt |
 				        generate_c_vardecl_c::output_vt |
-				        generate_c_vardecl_c::inoutput_vt);
+				        generate_c_vardecl_c::inoutput_vt |
+                generate_c_vardecl_c::eneno_vt);
+  vardecl->print(symbol->var_declarations_list);
+  if (!vardecl->is_en_declared()) {
+    s4o.print(",\n" + s4o.indent_spaces + "BOOL EN");
+  }
+  if (!vardecl->is_eno_declared()) {
+    s4o.print(",\n" + s4o.indent_spaces + "BOOL *ENO");
+  }
+  delete vardecl;
+  
+  s4o.indent_left();
+  
+  s4o.print(")\n" + s4o.indent_spaces + "{\n");
+
+  /* (B) Function local variable declaration */
+  /* (B.1) Variables declared in ST source code */
+  s4o.indent_right();
+  
+  vardecl = new generate_c_vardecl_c(&s4o, 
+                generate_c_vardecl_c::localinit_vf, 
+                generate_c_vardecl_c::output_vt |
+                generate_c_vardecl_c::inoutput_vt |
+                generate_c_vardecl_c::private_vt);
   vardecl->print(symbol->var_declarations_list);
   delete vardecl;
-  s4o.indent_left();
-
-  s4o.print(")\n" + s4o.indent_spaces + "{\n");
-
-  /* (B) Function local variable declaration */
-    /* (B.1) Variables declared in ST source code */
-  s4o.indent_right();
-  vardecl = new generate_c_vardecl_c(&s4o,
-                generate_c_vardecl_c::foutputdecl_vf,
-                generate_c_vardecl_c::output_vt |
-                generate_c_vardecl_c::inoutput_vt);
-  vardecl->print(symbol->var_declarations_list);
-  delete vardecl;
-  
-  vardecl = new generate_c_vardecl_c(&s4o, generate_c_vardecl_c::localinit_vf, generate_c_vardecl_c::private_vt);
-  vardecl->print(symbol->var_declarations_list);
-  delete vardecl;
-
-    /* (B.2) Temporary variable for function's return value */
+
+  /* (B.2) Temporary variable for function's return value */
   /* It will have the same name as the function itself! */
   s4o.print(s4o.indent_spaces);
   symbol->type_name->accept(*this); /* return type */
@@ -605,7 +611,30 @@
     default_value->accept(*this);
   }
   s4o.print(";\n\n");
-
+  
+  s4o.print(s4o.indent_spaces + "// Control execution\n");
+  s4o.print(s4o.indent_spaces + "if (!EN) {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces + "if (ENO != NULL) {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces + "*ENO = __BOOL_LITERAL(FALSE);\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+  s4o.print(s4o.indent_spaces + "return ");
+  symbol->derived_function_name->accept(*this);
+  s4o.print(";\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+  s4o.print(s4o.indent_spaces + "else {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces + "if (ENO != NULL) {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces + "*ENO = __BOOL_LITERAL(TRUE);\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+  
   /* (C) Function body */
   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol);
   symbol->function_body->accept(generate_c_code);
@@ -663,8 +692,15 @@
   				      generate_c_vardecl_c::local_vf,
   				      generate_c_vardecl_c::input_vt |
   				      generate_c_vardecl_c::output_vt |
-  				      generate_c_vardecl_c::inoutput_vt);
+  				      generate_c_vardecl_c::inoutput_vt |
+                generate_c_vardecl_c::eneno_vt);
   vardecl->print(symbol->var_declarations);
+  if (!vardecl->is_en_declared()) {
+    s4o_incl.print(s4o_incl.indent_spaces + "BOOL EN;\n");
+  }
+  if (!vardecl->is_eno_declared()) {
+    s4o_incl.print(s4o_incl.indent_spaces + "BOOL ENO;\n");
+  }
   delete vardecl;
   s4o_incl.print("\n");
   /* (A.3) Private internal variables */
@@ -677,6 +713,7 @@
   				      generate_c_vardecl_c::external_vt);
   vardecl->print(symbol->var_declarations);
   delete vardecl;
+  
   /* (A.4) Generate private internal variables for SFC */
   sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd);
   sfcdecl->print(symbol->fblock_body);
@@ -713,8 +750,19 @@
   				      generate_c_vardecl_c::inoutput_vt |
   				      generate_c_vardecl_c::private_vt |
 				        generate_c_vardecl_c::located_vt |
-				        generate_c_vardecl_c::external_vt);
+				        generate_c_vardecl_c::external_vt |
+                generate_c_vardecl_c::eneno_vt);
   vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
+  if (!vardecl->is_en_declared()) {
+    s4o.print("\n" + s4o.indent_spaces);
+    s4o.print(FB_FUNCTION_PARAM);
+    s4o.print("->EN = __BOOL_LITERAL(TRUE);");
+  }
+  if (!vardecl->is_eno_declared()) {
+    s4o.print("\n" + s4o.indent_spaces);
+    s4o.print(FB_FUNCTION_PARAM);
+    s4o.print("->ENO = __BOOL_LITERAL(TRUE);");
+  }
   delete vardecl;
   s4o.print("\n");
   /* (B.3) Generate private internal variables for SFC */
@@ -750,6 +798,25 @@
   s4o.print(") {\n");
   s4o.indent_right();
 
+  s4o.print(s4o.indent_spaces + "// Control execution\n");
+  s4o.print(s4o.indent_spaces + "if (!");
+  s4o.print(FB_FUNCTION_PARAM);
+  s4o.print("->EN) {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces);
+  s4o.print(FB_FUNCTION_PARAM);
+  s4o.print("->ENO = __BOOL_LITERAL(FALSE);\n");
+  s4o.print(s4o.indent_spaces + "return;\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+  s4o.print(s4o.indent_spaces + "else {\n");
+  s4o.indent_right();
+  s4o.print(s4o.indent_spaces);
+  s4o.print(FB_FUNCTION_PARAM);
+  s4o.print("->ENO = __BOOL_LITERAL(TRUE);\n");
+  s4o.indent_left();
+  s4o.print(s4o.indent_spaces + "}\n");
+
   /* (C.4) Initialize TEMP variables */
   /* function body */
   s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n");
--- a/stage4/generate_c/generate_c_base.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/generate_c_base.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -78,6 +78,7 @@
     ~generate_c_base_c(void) {}
 
     void set_variable_prefix(const char *variable_prefix) {variable_prefix_ = variable_prefix;}
+    bool is_variable_prefix_null(void) {return variable_prefix_ == NULL;}
     void print_variable_prefix(void) {
       if (variable_prefix_ != NULL)
         s4o.print(variable_prefix_);
--- a/stage4/generate_c/generate_c_il.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/generate_c_il.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -295,6 +295,8 @@
 
     search_base_type_c search_base_type;
 
+    bool current_param_is_pointer;
+
   public:
     generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
     : generate_c_typedecl_c(s4o_ptr),
@@ -308,6 +310,7 @@
       current_operand = NULL;
       current_operand_type = NULL;
       il_default_variable_init_value = NULL;
+      current_param_is_pointer = false;
       this->set_variable_prefix(variable_prefix);
     }
 
@@ -458,6 +461,38 @@
 
 private:
 
+void *visit(eno_param_c *symbol) {
+  if (this->is_variable_prefix_null()) {
+    s4o.print("*");
+  }
+  else {
+    this->print_variable_prefix();
+  }
+  s4o.print("ENO");
+  return NULL;
+}
+
+/*********************/
+/* B 1.4 - Variables */
+/*********************/
+void *visit(symbolic_variable_c *symbol) {
+  unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
+  if (!current_param_is_pointer && (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt)) {
+    s4o.print("*(");
+    generate_c_base_c::visit(symbol);
+    s4o.print(")");
+  }
+  else if (current_param_is_pointer && vartype != search_var_instance_decl_c::external_vt && vartype != search_var_instance_decl_c::located_vt) {
+    s4o.print("&(");
+    generate_c_base_c::visit(symbol);
+    s4o.print(")");
+  }
+  else {
+    generate_c_base_c::visit(symbol);
+  }
+  return NULL;
+}
+
 /********************************************/
 /* B.1.4.1   Directly Represented Variables */
 /********************************************/
@@ -466,10 +501,14 @@
   TRACE("direct_variable_c");
   /* Do not use print_token() as it will change everything into uppercase */
   if (strlen(symbol->value) == 0) ERROR;
-  s4o.print("*(");
+  if (!current_param_is_pointer) {
+    s4o.print("*(");
+  }
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
-  s4o.print(")");
+  if (!current_param_is_pointer) {
+    s4o.print(")");
+  }
   return NULL;
 }
 
@@ -583,44 +622,7 @@
     if (symbol->il_operand_list != NULL)
       nb_param += ((list_c *)symbol->il_operand_list)->n;
 
-#include "il_code_gen.c"
-
-#if 0
-    for(int current_param = 0; current_param < nb_param; current_param++) {
-      symbol_c *param_value;
-      if (current_param == 0)
-        param_value = &this->default_variable_name;
-      else {
-        symbol_c *param_name = NULL;
-        switch (current_function_type) {
-          default: ERROR;
-        }
-        
-         
-        /* Get the value from a foo(<param_name> = <param_value>) style call */
-        param_value = function_call_param_iterator.search(param_name);
-        delete param_name;
-        
-        /* Get the value from a foo(<param_value>) style call */
-        if (param_value == NULL)
-          param_value = function_call_param_iterator.next();
-        
-        if (param_value == NULL) ERROR;
-      }
-      
-      switch (current_function_type) {
-        case (function_sqrt):
-          if (current_param == 0) {
-            s4o.print("sqrt(");
-            param_value->accept(*this);
-            s4o.print(")");
-          }
-          else ERROR;
-          break;
-        default: ERROR;
-      }
-    } /* for(...) */
-#endif
+    #include "il_code_gen.c"
 
     /* the data type returned by the function, and stored in the il default variable... */
     default_variable_name.current_type = return_data_type;
@@ -696,14 +698,13 @@
           break;
         case function_param_iterator_c::direction_out:
         case function_param_iterator_c::direction_inout:
+          current_param_is_pointer = true;
           if (param_value == NULL) {
-  	  /* no parameter value given, so we pass a previously declared temporary variable. */
-            std::string *temp_var_name = temp_var_name_factory.new_name();
-            s4o.print(*temp_var_name);
-            delete temp_var_name;
+            s4o.print("NULL");
           } else {
             param_value->accept(*this);
           }
+          current_param_is_pointer = false;
           break;
         case function_param_iterator_c::direction_extref:
           /* TODO! */
--- a/stage4/generate_c/generate_c_st.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/generate_c_st.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -134,6 +134,17 @@
 
   private:
 
+void *visit(eno_param_c *symbol) {
+  if (this->is_variable_prefix_null()) {
+    s4o.print("*");
+  }
+  else {
+    this->print_variable_prefix();
+  }
+  s4o.print("ENO");
+  return NULL;
+}
+
 /*********************/
 /* B 1.4 - Variables */
 /*********************/
@@ -447,114 +458,8 @@
     
     int nb_param = ((list_c *)symbol->parameter_assignment_list)->n;
 
-#include "st_code_gen.c"
-
-#if 0
-    for(int current_param = 0; current_param < nb_param; current_param++) {
-      symbol_c *param_name = NULL;
-      switch (current_function_type) {
-        case function_add:
-        case function_and:
-        case function_or:
-          param_name = generate_param_name("IN%d", current_param + 1);
-          break;
-        case function_sub:
-          if (current_param < 2)
-            param_name = generate_param_name("IN%d", current_param + 1);
-          else
-            ERROR;
-          break;
-        default: ERROR;
-      }
-      
-      /* Get the value from a foo(<param_name> = <param_value>) style call */
-      symbol_c *param_value = function_call_param_iterator.search(param_name);
-      delete param_name;
-      
-      /* Get the value from a foo(<param_value>) style call */
-      if (param_value == NULL)
-        param_value = function_call_param_iterator.next();
-      
-      if (param_value == NULL) ERROR;
-      
-      switch (current_function_type) {
-        case function_add:
-          if (search_expression_type->is_time_type(function_return_type)) {
-            if (current_param == 0) {
-              s4o.print("__time_add(");
-              param_value->accept(*this);
-            }
-            else if (current_param == 1) {
-              s4o.print(", ");
-              param_value->accept(*this);
-              s4o.print(")");
-            }
-            else ERROR;
-          }
-          else {
-            if (current_param == 0)
-              s4o.print("(");
-            else
-              s4o.print(" + ");
-            param_value->accept(*this);
-            if (current_param == nb_param - 1)
-              s4o.print(")");
-          }
-          break;
-        case function_sub:
-          if (search_expression_type->is_time_type(function_return_type)) {
-            if (current_param == 0) {
-              s4o.print("__time_sub(");
-              param_value->accept(*this);
-            }
-            else if (current_param == 1) {
-              s4o.print(", ");
-              param_value->accept(*this);
-              s4o.print(")");
-            }
-            else ERROR;
-          }
-          else {
-            if (current_param == 0) {
-              s4o.print("(");
-              param_value->accept(*this);
-            }
-            else if (current_param == 1) {
-              s4o.print(" - ");
-              param_value->accept(*this);
-              s4o.print(")");
-            }
-            else ERROR;
-          }
-          break;
-        case function_and:
-          if (current_param == 0)
-            s4o.print("(");
-          else
-            if (search_expression_type->is_bool_type(function_return_type))
-              s4o.print(" && ");
-            else
-              s4o.print(" & ");
-          param_value->accept(*this);
-          if (current_param == nb_param - 1)
-            s4o.print(")");
-          break;
-        case function_or:
-          if (current_param == 0)
-            s4o.print("(");
-          else
-            if (search_expression_type->is_bool_type(function_return_type))
-              s4o.print(" || ");
-            else
-              s4o.print(" | ");
-          param_value->accept(*this);
-          if (current_param == nb_param - 1)
-            s4o.print(")");
-          break;
-        default: ERROR;
-      }
-    } /* for(...) */
-#endif
+    #include "st_code_gen.c"
+
   }
   else {
     /* loop through each function parameter, find the value we should pass
@@ -609,10 +514,7 @@
         case function_param_iterator_c::direction_inout:
           current_param_is_pointer = true;
           if (param_value == NULL) {
-            /* no parameter value given, so we pass a previously declared temporary variable. */
-            std::string *temp_var_name = temp_var_name_factory.new_name();
-            s4o.print(*temp_var_name);
-            delete temp_var_name;
+            s4o.print("NULL");
           } else {
             param_value->accept(*this);
           }
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_c/generate_c_vardecl.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -345,6 +345,8 @@
 						     //    Programs declared inside a resource will not be declared
 						     //    unless program_vt is acompanied by resource_vt
 
+    static const unsigned int eneno_vt  = 0x0200;  // EN/ENO declaration
+    
     static const unsigned int resource_vt = 0x8000;  // RESOURCE (inside a configuration!)
                                                      //    This, just of itself, will not print out any declarations!!
 						     //    It must be acompanied by either program_vt and/or global_vt
@@ -401,7 +403,6 @@
      *                __plc_pt_c<INT, 8*sizeof(INT)> START_P::loc = __plc_pt_c<INT, 8*sizeof(INT)>("I2");
      */
     typedef enum {finterface_vf,
-                  foutputdecl_vf,
                   foutputassign_vf,
                   local_vf,
 		              localinit_vf,
@@ -436,6 +437,10 @@
      * specific global variable declaration (with #define...)*/
     symbol_c *resource_name;
 
+    /* Store if En and ENO parameters have been defined by user */
+    bool en_declared;
+    bool eno_declared;
+
     /* Holds the references to the type and initial value
      * of the variables currently being declared.
      * Please read the comment under var1_init_decl_c for further
@@ -529,18 +534,6 @@
         }
       }
 
-      if (wanted_varformat == foutputdecl_vf) {
-        for(int i = 0; i < list->n; i++) {
-          if ((current_vartype & (output_vt | inoutput_vt)) != 0) {
-            s4o.print(s4o.indent_spaces);
-            this->current_var_type_symbol->accept(*this);
-            s4o.print(" ");
-            list->elements[i]->accept(*this);
-            s4o.print(";\n");
-          }
-        }
-      }
-
       if (wanted_varformat == foutputassign_vf) {
         for(int i = 0; i < list->n; i++) {
           if ((current_vartype & (output_vt | inoutput_vt)) != 0) {
@@ -599,12 +592,21 @@
       globalnamespace         = NULL;
       nv = NULL;
       resource_name = res_name;
+      en_declared = false;
+      eno_declared = false;
     }
 
     ~generate_c_vardecl_c(void) {
       delete generate_c_array_initialization;
     }
 
+    bool is_en_declared(void) {
+      return en_declared;
+    }
+    
+    bool is_eno_declared(void) {
+      return eno_declared;
+    }
 
     void print(symbol_c *symbol, symbol_c *scope = NULL, const char *variable_prefix = NULL) {
       this->set_variable_prefix(variable_prefix);
@@ -750,6 +752,27 @@
   return NULL;
 }
 
+void *visit(en_param_declaration_c *symbol) {
+  TRACE("en_declaration_c");
+  if (en_declared) ERROR;
+  if (wanted_varformat == finterface_vf) {
+    finterface_var_count++;
+  }  
+  if ((current_vartype & eneno_vt) != 0) {
+    if (wanted_varformat == finterface_vf) {
+      s4o.print(nv->get());
+      s4o.print("\n" + s4o.indent_spaces + "BOOL EN");
+    }
+    if (wanted_varformat == constructorinit_vf) {
+      s4o.print(nv->get());
+      this->print_variable_prefix();
+      s4o.print("ENO = __BOOL_LITERAL(TRUE);");
+    }
+  }
+  en_declared = true;
+  return NULL;
+}
+
 void *visit(raising_edge_option_c *symbol) {
   // TO DO ...
   s4o.print("R_EDGE");
@@ -861,6 +884,27 @@
   return NULL;
 }
 
+void *visit(eno_param_declaration_c *symbol) {
+  TRACE("eno_declaration_c");
+  if (eno_declared) ERROR;
+  if (wanted_varformat == finterface_vf) {
+    finterface_var_count++;
+  }
+  if ((current_vartype & eneno_vt) != 0) {
+    if (wanted_varformat == finterface_vf) {
+      s4o.print(nv->get());
+      s4o.print("\n" + s4o.indent_spaces + "BOOL *EN0");
+    }
+    if (wanted_varformat == constructorinit_vf) {
+      s4o.print(nv->get());
+      this->print_variable_prefix();
+      s4o.print("ENO = __BOOL_LITERAL(TRUE);");
+    }
+  }
+  eno_declared = true;
+  return NULL;
+}
+
 /*  VAR_IN_OUT var_declaration_list END_VAR */
 void *visit(input_output_declarations_c *symbol) {
   TRACE("input_output_declarations_c");
--- a/stage4/generate_iec/generate_iec.cc	Thu Sep 25 10:26:10 2008 +0200
+++ b/stage4/generate_iec/generate_iec.cc	Fri Sep 26 14:42:05 2008 +0200
@@ -606,6 +606,10 @@
   return NULL;
 }
 
+void *visit(en_param_declaration_c *symbol) {
+  s4o.print("EN : BOOL := 1");
+  return NULL;
+}
 
 void *visit(raising_edge_option_c *symbol) {
   s4o.print("R_EDGE");
@@ -681,6 +685,11 @@
   return NULL;
 }
 
+void *visit(eno_param_declaration_c *symbol) {
+  s4o.print("EN0 : BOOL");
+  return NULL;
+}
+
 /*  VAR_IN_OUT  END_VAR */
 void *visit(input_output_declarations_c *symbol) {
   s4o.print(s4o.indent_spaces); s4o.print("VAR_IN_OUT ");