Add support for de-referencing of REF_TO datatypes (Note: dereferencing of arrays and structs not yet supported!)
authormjsousa
Sun, 28 Sep 2014 16:35:44 +0100
changeset 933 76324f461aed
parent 932 061824c45a5b
child 934 2a42a68f4b59
Add support for de-referencing of REF_TO datatypes (Note: dereferencing of arrays and structs not yet supported!)
absyntax/absyntax.def
lib/C/accessor.h
main.cc
stage1_2/iec_bison.yy
stage1_2/iec_flex.ll
stage3/fill_candidate_datatypes.cc
stage3/fill_candidate_datatypes.hh
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
stage3/print_datatypes_error.cc
stage3/print_datatypes_error.hh
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_iec/generate_iec.cc
--- a/absyntax/absyntax.def	Sat Sep 27 20:09:19 2014 +0100
+++ b/absyntax/absyntax.def	Sun Sep 28 16:35:44 2014 +0100
@@ -1139,16 +1139,17 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
-SYM_REF1(ref_expression_c, exp)  /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
-SYM_REF2(or_expression_c, l_exp, r_exp)
+SYM_REF1(  ref_expression_c, exp)  /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+SYM_REF1(deref_expression_c, exp)  /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Dereferences an address!        */
+SYM_REF2( or_expression_c, l_exp, r_exp)
 SYM_REF2(xor_expression_c, l_exp, r_exp)
 SYM_REF2(and_expression_c, l_exp, r_exp)
 SYM_REF2(equ_expression_c, l_exp, r_exp)
 SYM_REF2(notequ_expression_c, l_exp, r_exp)
-SYM_REF2(lt_expression_c, l_exp, r_exp)
-SYM_REF2(gt_expression_c, l_exp, r_exp)
-SYM_REF2(le_expression_c, l_exp, r_exp)
-SYM_REF2(ge_expression_c, l_exp, r_exp)
+SYM_REF2( lt_expression_c, l_exp, r_exp)
+SYM_REF2( gt_expression_c, l_exp, r_exp)
+SYM_REF2( le_expression_c, l_exp, r_exp)
+SYM_REF2( ge_expression_c, l_exp, r_exp)
 SYM_REF2(add_expression_c, l_exp, r_exp, bool deprecated_operation;)
 SYM_REF2(sub_expression_c, l_exp, r_exp, bool deprecated_operation;)
 SYM_REF2(mul_expression_c, l_exp, r_exp, bool deprecated_operation;)
--- a/lib/C/accessor.h	Sat Sep 27 20:09:19 2014 +0100
+++ b/lib/C/accessor.h	Sun Sep 28 16:35:44 2014 +0100
@@ -111,6 +111,15 @@
 #define __GET_LOCATED_REF(name, ...)\
 	(&((*(name.value)) __VA_ARGS__))
 
+#define __GET_VAR_DREF(name, ...)\
+	(*(name.value __VA_ARGS__))
+#define __GET_EXTERNAL_DREF(name, ...)\
+	(*((*(name.value)) __VA_ARGS__))
+#define __GET_EXTERNAL_FB_DREF(name, ...)\
+	(*(__GET_VAR(((*name) __VA_ARGS__))))
+#define __GET_LOCATED_DREF(name, ...)\
+	(*((*(name.value)) __VA_ARGS__))
+
 
 // variable setting macros
 #define __SET_VAR(prefix, name, suffix, new_value)\
--- a/main.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/main.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -122,7 +122,7 @@
       /******************************************************/
   printf(" -s : allow use of safe datatypes (SAFEBOOL, etc.)   (defined in PLCOpen Safety)\n");
   printf(" -n : allow use of nested comments                   (an IEC 61131-3 v3 feature)\n");
-  printf(" -r : allow use of references (REF_TO, REF, NULL)    (an IEC 61131-3 v3 feature)\n");
+  printf(" -r : allow use of references (REF_TO, REF, ^, NULL) (an IEC 61131-3 v3 feature)\n");
   printf(" -R : allow use of REF_TO ANY datatypes              (a non-standard extension!)\n");
   printf("        as well as REF_TO in ARRAYs and STRUCTs      (a non-standard extension!)\n");
   printf(" -c : create conversion functions for enumerated data types\n");
--- a/stage1_2/iec_bison.yy	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage1_2/iec_bison.yy	Sun Sep 28 16:35:44 2014 +0100
@@ -416,6 +416,7 @@
 
 /* Keywords in IEC 61131-3 v3 */
 %token	REF
+%token	DREF
 %token	REF_TO
 %token	NULL_token  /* cannot use simply 'NULL', as it conflicts with the NULL keyword in C++ */
 
@@ -1319,7 +1320,8 @@
  *      are not required. Their values are integrated
  *      directly into other rules...
  */
-%type  <leaf>	ref_expression  /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
+%type  <leaf>	  ref_expression  /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
+%type  <leaf>	deref_expression  /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
 %type  <leaf>	expression
 %type  <leaf>	xor_expression
 %type  <leaf>	and_expression
@@ -3399,7 +3401,27 @@
 | identifier
 	{$$ = new symbolic_variable_c($1, locloc(@$));}
 */
-;
+| symbolic_variable '^'     
+	/* Dereferencing operator defined in IEC 61131-3 v3. However, implemented here differently then how it is defined in the standard! See following note for explanation! */
+	{$$ = new deref_expression_c($1, locloc(@$));}
+;
+/*
+ * NOTE: The syntax defined in the v3 standard for the dereferencing operator '^' seems to me to be un-intentionally
+ *       limited. For example
+ *         ref_to_bool_var := REF(        array_of_bool [1] );   <---     Allowed!
+ *         ref_to_bool_var := REF( ref_to_array_of_bool^[1] );   <---     Allowed!
+ *         bool_var        := array_of_ref_to_bool[1]^;          <--- NOT Allowed!
+ *         ref_to_array_of_bool^[1] := FALSE;                    <---     Allowed!
+ *       I consider this a bug in the v3 standard!!
+ *       I have therefore opted to implement this by simply adding a rule to symbolic_variable 
+ *         symbolic_variable: 
+ *                ...
+ *           | symbolic_variable '^'
+ *       This simple rule should be able to cover all the needed dereferencing syntax!
+ *       I have also added a dereferencing expression for the DREF() operator.
+ *       Since both of them do the exact same operation, they will both be translated to the exact same
+ *       entry type in the abstract syntax tree (an deref_expression_c)
+ */
 
 
 /* NOTE: in section B 1.7, when configuring a program, symbolic_variable
@@ -7233,7 +7255,8 @@
 /***********************/
 expression:
   xor_expression
-| ref_expression  /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
+| ref_expression    /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
+| deref_expression  /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ 
 | expression OR xor_expression
 	{$$ = new or_expression_c($1, $3, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
@@ -7254,6 +7277,14 @@
 	{$$ = new ref_expression_c($3, locloc(@$));}
 ;
 
+/*  DREF(var_name) */
+/*  This is an extension to the IEC 61131-3 standard. It is actually defined in the IEC 61131-3 v3 standard */
+/*  The DREF() operator accesses the variable stored in the specified address. Basically, it dereferences a pointer to the variable */
+deref_expression:
+  DREF '(' symbolic_variable ')'
+	{$$ = new deref_expression_c($3, locloc(@$));}
+;
+
 xor_expression:
   and_expression
 | xor_expression XOR and_expression
--- a/stage1_2/iec_flex.ll	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage1_2/iec_flex.ll	Sun Sep 28 16:35:44 2014 +0100
@@ -1252,6 +1252,7 @@
 
 
 REF	{if (get_opt_ref_operator()) return REF;        else{REJECT;}}		/* Keyword in IEC 61131-3 v3 */
+DREF	{if (get_opt_ref_operator()) return DREF;       else{REJECT;}}		/* Keyword in IEC 61131-3 v3 */
 REF_TO	{if (get_opt_ref_operator()) return REF_TO;     else{REJECT;}}		/* Keyword in IEC 61131-3 v3 */
 NULL	{if (get_opt_ref_operator()) return NULL_token; else{REJECT;}}		/* Keyword in IEC 61131-3 v3 */
 
--- a/stage3/fill_candidate_datatypes.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/fill_candidate_datatypes.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -1889,9 +1889,26 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
+/* SYM_REF1(deref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+void *fill_candidate_datatypes_c::visit(deref_expression_c  *symbol) {
+  symbol->exp->accept(*this);
+
+  for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) {
+    /* Determine whether the datatype is a ref_spec_c, as this is the class used as the    */
+    /* canonical/base datatype of REF_TO types (see search_base_type_c ...)                */ 
+    ref_spec_c *ref_spec = dynamic_cast<ref_spec_c *>(symbol->exp->candidate_datatypes[i]);
+    
+    if (NULL != ref_spec)
+      add_datatype_to_candidate_list(symbol, ref_spec->type_name);
+  }
+  
+  return NULL;
+}
+
+
 /* SYM_REF1(ref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
 void *fill_candidate_datatypes_c::visit(  ref_expression_c  *symbol) {
-  /* We must first determine the datatype of the expression passe to the REF() operator, with no ambiguities! 
+  /* We must first determine the datatype of the expression passed to the REF() operator, with no ambiguities! 
    * To do this, we could use the complete standard fill/narrow algorithm for determining the datatype
    * of the expression. This is actually possible, as nothing stops us from directly calling the narrow_candidate_datatypes_c
    * from this method inside fill_candidate_datatypes_c, to complete the fill/narrow algorithm on this
@@ -1910,9 +1927,8 @@
   if (symbol->exp->candidate_datatypes.size() == 1)
     symbol->exp->datatype = symbol->exp->candidate_datatypes[0];
 
-  /* Create a new object of ref_spec_c, as this is the class used as the canonical/base datatype of REF_TO types 
-   * (see search_base_type_c ...)
-   */ 
+  /* Create a new object of ref_spec_c, as this is the class used as the  */
+  /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ 
   ref_spec_c *ref_spec = new ref_spec_c(symbol->exp->datatype);
   add_datatype_to_candidate_list(symbol, ref_spec);
   return NULL;
--- a/stage3/fill_candidate_datatypes.hh	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/fill_candidate_datatypes.hh	Sun Sep 28 16:35:44 2014 +0100
@@ -337,24 +337,25 @@
     /***********************/
     /* B 3.1 - Expressions */
     /***********************/
-    void *visit(ref_expression_c *symbol);
-    void *visit(or_expression_c *symbol);
-    void *visit(xor_expression_c *symbol);
-    void *visit(and_expression_c *symbol);
-    void *visit(equ_expression_c *symbol);
-    void *visit(notequ_expression_c *symbol);
-    void *visit(lt_expression_c *symbol);
-    void *visit(gt_expression_c *symbol);
-    void *visit(le_expression_c *symbol);
-    void *visit(ge_expression_c *symbol);
-    void *visit(add_expression_c *symbol);
-    void *visit(sub_expression_c *symbol);
-    void *visit(mul_expression_c *symbol);
-    void *visit(div_expression_c *symbol);
-    void *visit(mod_expression_c *symbol);
-    void *visit(power_expression_c *symbol);
-    void *visit(neg_expression_c *symbol);
-    void *visit(not_expression_c *symbol);
+    void *visit(   deref_expression_c *symbol);
+    void *visit(     ref_expression_c *symbol);
+    void *visit(      or_expression_c *symbol);
+    void *visit(     xor_expression_c *symbol);
+    void *visit(     and_expression_c *symbol);
+    void *visit(     equ_expression_c *symbol);
+    void *visit(  notequ_expression_c *symbol);
+    void *visit(      lt_expression_c *symbol);
+    void *visit(      gt_expression_c *symbol);
+    void *visit(      le_expression_c *symbol);
+    void *visit(      ge_expression_c *symbol);
+    void *visit(     add_expression_c *symbol);
+    void *visit(     sub_expression_c *symbol);
+    void *visit(     mul_expression_c *symbol);
+    void *visit(     div_expression_c *symbol);
+    void *visit(     mod_expression_c *symbol);
+    void *visit(   power_expression_c *symbol);
+    void *visit(     neg_expression_c *symbol);
+    void *visit(     not_expression_c *symbol);
     void *visit(function_invocation_c *symbol);
 
     /*********************************/
--- a/stage3/narrow_candidate_datatypes.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/narrow_candidate_datatypes.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -1378,6 +1378,23 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
+/* SYM_REF1(deref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+void *narrow_candidate_datatypes_c::visit(deref_expression_c  *symbol) {
+  for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) {
+    /* Determine whether the datatype is a ref_spec_c, as this is the class used as the    */
+    /* canonical/base datatype of REF_TO types (see search_base_type_c ...)                */ 
+    ref_spec_c *ref_spec = dynamic_cast<ref_spec_c *>(symbol->exp->candidate_datatypes[i]);
+    
+    if ((NULL != ref_spec) && get_datatype_info_c::is_type_equal(ref_spec->type_name, symbol->datatype))
+      /* if it points to the required datatype for symbol, then that is the required datatype for symbol->exp */
+      symbol->exp->datatype = ref_spec;
+  }
+  
+  symbol->exp->accept(*this);
+  return NULL;
+}
+
+
 /* SYM_REF1(ref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
 void *narrow_candidate_datatypes_c::visit(  ref_expression_c  *symbol) {
   if (symbol->exp->candidate_datatypes.size() > 0) {
--- a/stage3/narrow_candidate_datatypes.hh	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/narrow_candidate_datatypes.hh	Sun Sep 28 16:35:44 2014 +0100
@@ -308,25 +308,25 @@
     /***********************/
     /* B 3.1 - Expressions */
     /***********************/
-    void *visit(ref_expression_c *symbol);
-    void *visit(or_expression_c *symbol);
-    void *visit(xor_expression_c *symbol);
-    void *visit(and_expression_c *symbol);
-    void *visit(equ_expression_c *symbol);
-    void *visit(notequ_expression_c *symbol);
-    void *visit(lt_expression_c *symbol);
-    void *visit(gt_expression_c *symbol);
-    void *visit(le_expression_c *symbol);
-    void *visit(ge_expression_c *symbol);
-    void *visit(add_expression_c *symbol);
-    void *visit(sub_expression_c *symbol);
-    void *visit(mul_expression_c *symbol);
-    void *visit(div_expression_c *symbol);
-    void *visit(mod_expression_c *symbol);
-    void *visit(power_expression_c *symbol);
-    void *visit(neg_expression_c *symbol);
-    void *visit(not_expression_c *symbol);
-
+    void *visit(   deref_expression_c *symbol);
+    void *visit(     ref_expression_c *symbol);
+    void *visit(      or_expression_c *symbol);
+    void *visit(     xor_expression_c *symbol);
+    void *visit(     and_expression_c *symbol);
+    void *visit(     equ_expression_c *symbol);
+    void *visit(  notequ_expression_c *symbol);
+    void *visit(      lt_expression_c *symbol);
+    void *visit(      gt_expression_c *symbol);
+    void *visit(      le_expression_c *symbol);
+    void *visit(      ge_expression_c *symbol);
+    void *visit(     add_expression_c *symbol);
+    void *visit(     sub_expression_c *symbol);
+    void *visit(     mul_expression_c *symbol);
+    void *visit(     div_expression_c *symbol);
+    void *visit(     mod_expression_c *symbol);
+    void *visit(   power_expression_c *symbol);
+    void *visit(     neg_expression_c *symbol);
+    void *visit(     not_expression_c *symbol);
     void *visit(function_invocation_c *symbol);
 
     /*********************************/
--- a/stage3/print_datatypes_error.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/print_datatypes_error.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -1044,6 +1044,15 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
+/* SYM_REF1(deref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+void *print_datatypes_error_c::visit(deref_expression_c  *symbol) {
+	symbol->exp->accept(*this);
+	/* we should really check whether the expression is merely a variable. For now, leave it for the future! */
+	if ((symbol->candidate_datatypes.size() == 0) && (symbol->exp->candidate_datatypes.size() > 0))
+		STAGE3_ERROR(0, symbol, symbol, "DREF operator must be used with a value of type REF_TO.");
+	return NULL;
+}
+
 /* SYM_REF1(ref_expression_c, exp)  --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
 void *print_datatypes_error_c::visit(  ref_expression_c  *symbol) {
 	symbol->exp->accept(*this);
--- a/stage3/print_datatypes_error.hh	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage3/print_datatypes_error.hh	Sun Sep 28 16:35:44 2014 +0100
@@ -288,24 +288,25 @@
     /***********************/
     /* B 3.1 - Expressions */
     /***********************/
-    void *visit(ref_expression_c *symbol);
-    void *visit(or_expression_c *symbol);
-    void *visit(xor_expression_c *symbol);
-    void *visit(and_expression_c *symbol);
-    void *visit(equ_expression_c *symbol);
-    void *visit(notequ_expression_c *symbol);
-    void *visit(lt_expression_c *symbol);
-    void *visit(gt_expression_c *symbol);
-    void *visit(le_expression_c *symbol);
-    void *visit(ge_expression_c *symbol);
-    void *visit(add_expression_c *symbol);
-    void *visit(sub_expression_c *symbol);
-    void *visit(mul_expression_c *symbol);
-    void *visit(div_expression_c *symbol);
-    void *visit(mod_expression_c *symbol);
-    void *visit(power_expression_c *symbol);
-    void *visit(neg_expression_c *symbol);
-    void *visit(not_expression_c *symbol);
+    void *visit(   deref_expression_c *symbol);
+    void *visit(     ref_expression_c *symbol);
+    void *visit(      or_expression_c *symbol);
+    void *visit(     xor_expression_c *symbol);
+    void *visit(     and_expression_c *symbol);
+    void *visit(     equ_expression_c *symbol);
+    void *visit(  notequ_expression_c *symbol);
+    void *visit(      lt_expression_c *symbol);
+    void *visit(      gt_expression_c *symbol);
+    void *visit(      le_expression_c *symbol);
+    void *visit(      ge_expression_c *symbol);
+    void *visit(     add_expression_c *symbol);
+    void *visit(     sub_expression_c *symbol);
+    void *visit(     mul_expression_c *symbol);
+    void *visit(     div_expression_c *symbol);
+    void *visit(     mod_expression_c *symbol);
+    void *visit(   power_expression_c *symbol);
+    void *visit(     neg_expression_c *symbol);
+    void *visit(     not_expression_c *symbol);
     void *visit(function_invocation_c *symbol);
 
     /*********************************/
--- a/stage4/generate_c/generate_c.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage4/generate_c/generate_c.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -138,6 +138,11 @@
 #define GET_EXTERNAL_FB_REF "__GET_EXTERNAL_FB_REF"
 #define GET_LOCATED_REF "__GET_LOCATED_REF"
 
+#define GET_VAR_DREF "__GET_VAR_DREF"
+#define GET_EXTERNAL_DREF "__GET_EXTERNAL_DREF"
+#define GET_EXTERNAL_FB_DREF "__GET_EXTERNAL_FB_DREF"
+#define GET_LOCATED_DREF "__GET_LOCATED_DREF"
+
 #define GET_VAR_BY_REF "__GET_VAR_BY_REF"
 #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF"
 #define GET_EXTERNAL_FB_BY_REF "__GET_EXTERNAL_FB_BY_REF"
--- a/stage4/generate_c/generate_c_st.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -463,6 +463,48 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
+void *visit(deref_expression_c *symbol) {
+  s4o.print("(");  
+  if (this->is_variable_prefix_null()) {  
+    /* For code in FUNCTIONs */
+    s4o.print("*");  
+    symbol->exp->accept(*this);    
+    s4o.print("");  
+  } else {
+    /* For code in FBs, and PROGRAMS... */
+    s4o.print("(");  
+    unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol->exp, scope_);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (!get_datatype_info_c::is_type_valid    (symbol->exp->datatype)) ERROR;
+      if ( get_datatype_info_c::is_function_block(symbol->exp->datatype))
+        s4o.print(GET_EXTERNAL_FB_DREF);
+      else
+        s4o.print(GET_EXTERNAL_DREF);
+    }
+    else if (vartype == search_var_instance_decl_c::located_vt)
+      s4o.print(GET_LOCATED_DREF);
+    else
+      s4o.print(GET_VAR_DREF);
+    
+    variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration; 
+    s4o.print("(");
+    wanted_variablegeneration = complextype_base_vg;
+    print_variable_prefix();
+    symbol->exp->accept(*this);
+    s4o.print(",");
+    wanted_variablegeneration = complextype_suffix_vg;
+    symbol->exp->accept(*this);
+    s4o.print(")");
+    wanted_variablegeneration = old_wanted_variablegeneration;
+    
+    s4o.print(")");  
+  }
+  s4o.print(")");  
+
+  return NULL;
+}
+
+
 void *visit(ref_expression_c *symbol) {
   s4o.print("(");  
   if (this->is_variable_prefix_null()) {  
--- a/stage4/generate_iec/generate_iec.cc	Sat Sep 27 20:09:19 2014 +0100
+++ b/stage4/generate_iec/generate_iec.cc	Sun Sep 28 16:35:44 2014 +0100
@@ -1917,24 +1917,25 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
-void *visit(ref_expression_c *symbol) {return  s4o.print("REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
-void *visit(or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");}
-void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");}
-void *visit(and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");}
-void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");}
+void *visit(   ref_expression_c *symbol) {return  s4o.print( "REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+void *visit( deref_expression_c *symbol) {return  s4o.print("DREF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */
+void *visit(    or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");}
+void *visit(   xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");}
+void *visit(   and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");}
+void *visit(   equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");}
 void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <> ");}
-void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");}
-void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");}
-void *visit(le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");}
-void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");}
-void *visit(add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");}
-void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");}
-void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");}
-void *visit(div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");}
-void *visit(mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");}
-void *visit(power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");}
-void *visit(neg_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "-");}
-void *visit(not_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "NOT ");}
+void *visit(    lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");}
+void *visit(    gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");}
+void *visit(    le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");}
+void *visit(    ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");}
+void *visit(   add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");}
+void *visit(   sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");}
+void *visit(   mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");}
+void *visit(   div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");}
+void *visit(   mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");}
+void *visit( power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");}
+void *visit(   neg_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "-");}
+void *visit(   not_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "NOT ");}
 
 void *visit(function_invocation_c *symbol) {
   symbol->function_name->accept(*this);