Fix bug in parser while trying to use IL operator like S1, R1, etc... as standard function block interface variable in structured_variable syntax and bug in code generator while generating code for assignment of function block interface variable using structured_variable syntax
authorlaurent
Tue, 11 Oct 2011 12:30:49 +0200
changeset 382 ac6dfec701c9
parent 381 2fd934b91ffd
child 383 0b81b59f333b
Fix bug in parser while trying to use IL operator like S1, R1, etc... as standard function block interface variable in structured_variable syntax and bug in code generator while generating code for assignment of function block interface variable using structured_variable syntax
absyntax_utils/decompose_var_instance_name.cc
absyntax_utils/decompose_var_instance_name.hh
absyntax_utils/search_varfb_instance_type.cc
stage1_2/iec_bison.yy
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_st.cc
--- a/absyntax_utils/decompose_var_instance_name.cc	Sun Oct 09 20:18:55 2011 +0200
+++ b/absyntax_utils/decompose_var_instance_name.cc	Tue Oct 11 12:30:49 2011 +0200
@@ -128,17 +128,38 @@
 
   /* The correct code, is therefore more complex... */
   if (next_variable_name == symbol) {
-    /* NOTE: field_selector is always an identifier_c,
-     * so we do not have to recursevily visit it again...
-     * return (void *)symbol->field_selector->accept(*this);  -> NOT REQUIRED!!
-     */
-	 return (void *)symbol->field_selector;
+    return (void *)symbol->field_selector->accept(*this);
   }
 
   current_recursive_variable_name = symbol;
   return symbol->record_variable->accept(*this);
 }
 
+/********************************/
+/* B 2.2 - Operators */
+/********************************/
+void *decompose_var_instance_name_c::visit(LD_operator_c *symbol) {return (void *)&LD_operator_name;}
+void *decompose_var_instance_name_c::visit(S_operator_c *symbol) {return (void *)&S_operator_name;}
+void *decompose_var_instance_name_c::visit(R_operator_c *symbol) {return (void *)&R_operator_name;}
+void *decompose_var_instance_name_c::visit(S1_operator_c *symbol) {return (void *)&S1_operator_name;}
+void *decompose_var_instance_name_c::visit(R1_operator_c *symbol) {return (void *)&R1_operator_name;}
+void *decompose_var_instance_name_c::visit(CLK_operator_c *symbol) {return (void *)&CLK_operator_name;}
+void *decompose_var_instance_name_c::visit(CU_operator_c *symbol) {return (void *)&CU_operator_name;}
+void *decompose_var_instance_name_c::visit(CD_operator_c *symbol) {return (void *)&CD_operator_name;}
+void *decompose_var_instance_name_c::visit(PV_operator_c *symbol) {return (void *)&PV_operator_name;}
+void *decompose_var_instance_name_c::visit(IN_operator_c *symbol) {return (void *)&IN_operator_name;}
+void *decompose_var_instance_name_c::visit(PT_operator_c *symbol) {return (void *)&PT_operator_name;}
+
+identifier_c     decompose_var_instance_name_c::LD_operator_name("LD");
+identifier_c     decompose_var_instance_name_c::S_operator_name("S");
+identifier_c     decompose_var_instance_name_c::R_operator_name("R");
+identifier_c     decompose_var_instance_name_c::S1_operator_name("S1");
+identifier_c     decompose_var_instance_name_c::R1_operator_name("R1");
+identifier_c     decompose_var_instance_name_c::CLK_operator_name("CLK");
+identifier_c     decompose_var_instance_name_c::CU_operator_name("CU");
+identifier_c     decompose_var_instance_name_c::CD_operator_name("CD");
+identifier_c     decompose_var_instance_name_c::PV_operator_name("PV");
+identifier_c     decompose_var_instance_name_c::IN_operator_name("IN");
+identifier_c     decompose_var_instance_name_c::PT_operator_name("PT");
 
 
-
--- a/absyntax_utils/decompose_var_instance_name.hh	Sun Oct 09 20:18:55 2011 +0200
+++ b/absyntax_utils/decompose_var_instance_name.hh	Tue Oct 11 12:30:49 2011 +0200
@@ -52,6 +52,23 @@
 
 class decompose_var_instance_name_c: null_visitor_c {
 
+  public:
+    /***********************************/
+    /* B 1.2 - Operators               */
+    /***********************************/
+    static identifier_c     LD_operator_name;
+    static identifier_c     S_operator_name;
+    static identifier_c     R_operator_name;
+    static identifier_c     S1_operator_name;
+    static identifier_c     R1_operator_name;
+    static identifier_c     CLK_operator_name;
+    static identifier_c     CU_operator_name;
+    static identifier_c     CD_operator_name;
+    static identifier_c     PV_operator_name;
+    static identifier_c     IN_operator_name;
+    static identifier_c     PT_operator_name;
+
+
   private:
     symbol_c *variable_name;
     symbol_c *next_variable_name;
@@ -98,6 +115,21 @@
   //SYM_REF2(structured_variable_c, record_variable, field_selector)
     void *visit(structured_variable_c *symbol);
 
+    /********************************/
+    /* B 2.2 - Operators            */
+    /********************************/
+    void *visit(LD_operator_c *symbol);
+    void *visit(S_operator_c *symbol);
+    void *visit(R_operator_c *symbol);
+    void *visit(S1_operator_c *symbol);
+    void *visit(R1_operator_c *symbol);
+    void *visit(CLK_operator_c *symbol);
+    void *visit(CU_operator_c *symbol);
+    void *visit(CD_operator_c *symbol);
+    void *visit(PV_operator_c *symbol);
+    void *visit(IN_operator_c *symbol);
+    void *visit(PT_operator_c *symbol);
+
 }; // decompose_var_instance_name_c
 
 
--- a/absyntax_utils/search_varfb_instance_type.cc	Sun Oct 09 20:18:55 2011 +0200
+++ b/absyntax_utils/search_varfb_instance_type.cc	Tue Oct 11 12:30:49 2011 +0200
@@ -309,7 +309,72 @@
   this->is_complex = true;
   if (NULL != current_structelement_name) ERROR;
   
-  /* make sure that we have decomposed all strcuture elements of the variable name */
+  /* make sure that we have decomposed all structure elements of the variable name */
+  symbol_c *var_name = decompose_var_instance_name->next_part();
+  if (NULL == var_name) {
+    /* this is it... !
+     * No need to look any further...
+     * Note also that, unlike for the struct types, a function block may
+     * not be defined based on another (i.e. no inheritance is allowed),
+     * so this function block is already the most base type.
+     * We simply return it.
+     */
+    return (void *)symbol;
+  }
+
+  /* reset current_type_id because of new structure element part */
+  this->current_typeid = NULL;
+
+  /* look for the var_name in the structure declaration */
+  current_structelement_name = var_name;
+
+  /* recursively find out the data type of current_structelement_name... */
+  return symbol->structure_type_name->accept(*this);
+}
+
+/* helper symbol for structure_declaration */
+/* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
+/* structure_element_declaration_list structure_element_declaration ';' */
+void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol)	{
+  if (NULL == current_structelement_name) ERROR;
+  /* now search the structure declaration */
+  return visit_list(symbol);
+}
+
+/*  structure_element_name ':' spec_init */
+void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) {
+  if (NULL == current_structelement_name) ERROR;
+
+  if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) {
+    current_structelement_name = NULL;
+    /* found the type of the element we were looking for! */
+    return symbol->spec_init->accept(*this);
+  }  
+
+  /* Did not find the type of the element we were looking for! */
+  /* Will keep looking... */
+  return NULL;
+}
+
+/* helper symbol for structure_initialization */
+/* structure_initialization: '(' structure_element_initialization_list ')' */
+/* structure_element_initialization_list ',' structure_element_initialization */
+void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */
+/*  structure_element_name ASSIGN value */
+void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */
+
+
+
+/**************************************/
+/* B.1.5 - Program organization units */
+/**************************************/
+/*****************************/
+/* B 1.5.2 - Function Blocks */
+/*****************************/
+/*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
+// SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
+void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) {
+  /* make sure that we have decomposed all structure elements of the variable name */
   symbol_c *var_name = decompose_var_instance_name->next_part();
   if (NULL == var_name) {
     /* this is it... !
@@ -322,67 +387,8 @@
     return (void *)symbol;
    }
 
-  /* look for the var_name in the structure declaration */
-  current_structelement_name = var_name;
-
-  /* recursively find out the data type of current_structelement_name... */
-  return symbol->structure_type_name->accept(*this);
-}
-
-/* helper symbol for structure_declaration */
-/* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
-/* structure_element_declaration_list structure_element_declaration ';' */
-void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol)	{
-  if (NULL == current_structelement_name) ERROR;
-  /* now search the structure declaration */
-  return visit_list(symbol);
-}
-
-/*  structure_element_name ':' spec_init */
-void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) {
-  if (NULL == current_structelement_name) ERROR;
-
-  if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) {
-    current_structelement_name = NULL;
-    /* found the type of the element we were looking for! */
-    return symbol->spec_init->accept(*this);
-  }  
-
-  /* Did not find the type of the element we were looking for! */
-  /* Will keep looking... */
-  return NULL;
-}
-
-/* helper symbol for structure_initialization */
-/* structure_initialization: '(' structure_element_initialization_list ')' */
-/* structure_element_initialization_list ',' structure_element_initialization */
-void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */
-/*  structure_element_name ASSIGN value */
-void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */
-
-
-
-/**************************************/
-/* B.1.5 - Program organization units */
-/**************************************/
-/*****************************/
-/* B 1.5.2 - Function Blocks */
-/*****************************/
-/*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
-// SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
-void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) {
-  /* make sure that we have decomposed all strcuture elements of the variable name */
-  symbol_c *var_name = decompose_var_instance_name->next_part();
-  if (NULL == var_name) {
-    /* this is it... !
-     * No need to look any further...
-     * Note also that, unlike for the struct types, a function block may
-     * not be defined based on another (i.e. no inheritance is allowed),
-     * so this function block is already the most base type.
-     * We simply return it.
-     */
-    return (void *)symbol;
-   }
+   /* reset current_type_id because of new structure element part */
+   this->current_typeid = NULL;
 
    /* now search the function block declaration for the variable... */
    search_var_instance_decl_c search_decl(symbol);
@@ -404,7 +410,7 @@
   current_structelement_name = var_name;
   /* recursively find out the data type of var_name... */
   return symbol->var_declarations->accept(*this);
-#endif  
+#endif
   /* carry on recursively, in case the variable has more elements to be decomposed... */
   return var_decl->accept(*this);
 }
--- a/stage1_2/iec_bison.yy	Sun Oct 09 20:18:55 2011 +0200
+++ b/stage1_2/iec_bison.yy	Tue Oct 11 12:30:49 2011 +0200
@@ -1220,6 +1220,7 @@
 %type  <leaf>	il_simple_operator_clash
 %type  <leaf>	il_simple_operator_clash1
 %type  <leaf>	il_simple_operator_clash2
+%type  <leaf>	il_simple_operator_clash3
 %type  <leaf>	il_simple_operator_noclash
 
 //%type  <leaf>	il_expr_operator
@@ -3405,6 +3406,8 @@
 structured_variable:
   record_variable '.' field_selector
 	{$$ = new structured_variable_c($1, $3, locloc(@$));}
+| record_variable '.' il_simple_operator_clash3
+    {$$ = new structured_variable_c($1, $3, locloc(@$));}
 ;
 
 
@@ -3412,6 +3415,8 @@
 any_structured_variable:
   any_record_variable '.' field_selector
 	{$$ = new structured_variable_c($1, $3, locloc(@$));}
+| any_record_variable '.' il_simple_operator_clash3
+	{$$ = new structured_variable_c($1, $3, locloc(@$));}
 ;
 
 
@@ -6825,10 +6830,29 @@
 
 
 il_simple_operator_noclash:
-  LD_operator
-| LDN_operator
+  LDN_operator
 | ST_operator
 | STN_operator
+| il_expr_operator_noclash
+;
+
+
+il_simple_operator_clash:
+  il_simple_operator_clash1
+| il_simple_operator_clash2
+| il_simple_operator_clash3
+;
+
+il_simple_operator_clash1:
+  NOT_operator
+;
+
+il_simple_operator_clash2:
+  il_expr_operator_clash
+;
+
+il_simple_operator_clash3:
+  LD_operator
 | S_operator
 | R_operator
 | S1_operator
@@ -6839,23 +6863,7 @@
 | PV_operator
 | IN_operator
 | PT_operator
-| il_expr_operator_noclash
-;
-
-
-il_simple_operator_clash:
-  il_simple_operator_clash1
-| il_simple_operator_clash2
-;
-
-il_simple_operator_clash1:
-  NOT_operator
-;
-
-il_simple_operator_clash2:
-  il_expr_operator_clash
-;
-
+;
 
 /*
 il_expr_operator:
--- a/stage4/generate_c/generate_c_il.cc	Sun Oct 09 20:18:55 2011 +0200
+++ b/stage4/generate_c/generate_c_il.cc	Tue Oct 11 12:30:49 2011 +0200
@@ -324,6 +324,11 @@
 
     /* A helper function... */
     void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) {
+      if (wanted_variablegeneration != expression_vg) {
+        s4o.print(param_name);
+        return NULL;
+      }
+
       if (NULL == fb_name) ERROR;
       symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name);
       if (NULL == sv) ERROR;
@@ -462,6 +467,7 @@
     		symbol_c* fb_value = NULL,
     		bool negative = false) {
       unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
+      bool type_is_complex = search_varfb_instance_type->type_is_complex();
       if (vartype == search_var_instance_decl_c::external_vt) {
         symbolic_variable_c *variable = dynamic_cast<symbolic_variable_c *>(symbol);
         /* TODO Find a solution for forcing global complex variables */
@@ -489,8 +495,11 @@
         fb_symbol->accept(*this);
         s4o.print(".");
       }
+      else if (type_is_complex)
+        wanted_variablegeneration = complextype_base_vg;
       else
-        wanted_variablegeneration = complextype_base_vg;
+        wanted_variablegeneration = assignment_vg;
+
       symbol->accept(*this);
       s4o.print(",");
       if (negative) {
@@ -501,7 +510,7 @@
       }
       wanted_variablegeneration = expression_vg;
       print_check_function(type, value, fb_value);
-      if (search_varfb_instance_type->type_is_complex()) {
+      if (type_is_complex) {
         s4o.print(",");
         wanted_variablegeneration = complextype_suffix_vg;
         symbol->accept(*this);
@@ -552,6 +561,12 @@
 /* B 1.3.3 - Derived data types */
 /********************************/
 
+/*  signed_integer DOTDOT signed_integer */
+void *visit(subrange_c *symbol) {
+  symbol->lower_limit->accept(*this);
+  return NULL;
+}
+
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 void *visit(array_specification_c *symbol) {
   symbol->non_generic_type_name->accept(*this);
@@ -564,23 +579,29 @@
 
 void *visit(symbolic_variable_c *symbol) {
   unsigned int vartype;
-  if (wanted_variablegeneration == complextype_base_vg)
-	generate_c_base_c::visit(symbol);
-  else if (wanted_variablegeneration == complextype_suffix_vg)
-	return NULL;
-  else if (this->is_variable_prefix_null()) {
-	vartype = search_varfb_instance_type->get_vartype(symbol);
-    if (wanted_variablegeneration == fparam_output_vg) {
-      s4o.print("&(");
+  switch (wanted_variablegeneration) {
+    case complextype_base_vg:
+    case assignment_vg:
       generate_c_base_c::visit(symbol);
-      s4o.print(")");
-    }
-    else {
-      generate_c_base_c::visit(symbol);
-    }
-  }
-  else
-    print_getter(symbol);
+      break;
+    case complextype_suffix_vg:
+	  break;
+    default:
+      if (this->is_variable_prefix_null()) {
+	    vartype = search_varfb_instance_type->get_vartype(symbol);
+        if (wanted_variablegeneration == fparam_output_vg) {
+          s4o.print("&(");
+          generate_c_base_c::visit(symbol);
+          s4o.print(")");
+        }
+        else {
+          generate_c_base_c::visit(symbol);
+        }
+      }
+      else
+        print_getter(symbol);
+      break;
+  }
   return NULL;
 }
 
@@ -630,6 +651,7 @@
       symbol->record_variable->accept(*this);
       break;
     case complextype_suffix_vg:
+    case assignment_vg:
       symbol->record_variable->accept(*this);
       s4o.print(".");
       symbol->field_selector->accept(*this);
@@ -1554,6 +1576,11 @@
 /*******************/
 
 void *visit(LD_operator_c *symbol)	{
+  if (wanted_variablegeneration != expression_vg) {
+    s4o.print("LD");
+    return NULL;
+  }
+
   /* the data type resulting from this operation... */
   this->default_variable_name.current_type = this->current_operand_type;
   XXX_operator(&(this->default_variable_name), " = ", this->current_operand);
@@ -1617,6 +1644,11 @@
 }
 
 void *visit(S_operator_c *symbol)	{
+  if (wanted_variablegeneration != expression_vg) {
+    s4o.print("LD");
+    return NULL;
+  }
+
   if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR;
 
   C_modifier();
@@ -1635,6 +1667,11 @@
 }
 
 void *visit(R_operator_c *symbol)	{
+  if (wanted_variablegeneration != expression_vg) {
+    s4o.print("LD");
+    return NULL;
+  }
+
   if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR;
 
   C_modifier();
--- a/stage4/generate_c/generate_c_st.cc	Sun Oct 09 20:18:55 2011 +0200
+++ b/stage4/generate_c/generate_c_st.cc	Tue Oct 11 12:30:49 2011 +0200
@@ -170,6 +170,7 @@
 		symbol_c* fb_value = NULL) {
   
   unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
+  bool type_is_complex = search_varfb_instance_type->type_is_complex();
   if (vartype == search_var_instance_decl_c::external_vt) {
     symbolic_variable_c *variable = dynamic_cast<symbolic_variable_c *>(symbol);
     /* TODO Find a solution for forcing global complex variables */
@@ -197,20 +198,16 @@
     fb_symbol->accept(*this);
     s4o.print(".");
   }
+  else if (type_is_complex)
+    wanted_variablegeneration = complextype_base_vg;
   else
-    wanted_variablegeneration = complextype_base_vg;
+    wanted_variablegeneration = assignment_vg;
   
   symbol->accept(*this);
   s4o.print(",");
   wanted_variablegeneration = expression_vg;
   print_check_function(type, value, fb_value);
-  /* We need to call search_varfb_instance_type->get_vartype() again, as it may have been called
-   * again since we called it in the beginning of this print_setter() function.
-   * This make sure the call to search_varfb_instance_type->type_is_complex() will return
-   * the correct value regarding our 'symbol'.
-   */
-  search_varfb_instance_type->get_vartype(symbol);
-  if (search_varfb_instance_type->type_is_complex()) {
+  if (type_is_complex) {
     s4o.print(",");
     wanted_variablegeneration = complextype_suffix_vg;
     symbol->accept(*this);
@@ -251,23 +248,29 @@
 /*********************/
 void *visit(symbolic_variable_c *symbol) {
   unsigned int vartype;
-  if (wanted_variablegeneration == complextype_base_vg)
-         generate_c_base_c::visit(symbol);
-  else if (wanted_variablegeneration == complextype_suffix_vg)
-         return NULL;
-  else if (this->is_variable_prefix_null()) {
-         vartype = search_varfb_instance_type->get_vartype(symbol);
-         if (wanted_variablegeneration == fparam_output_vg) {
-           s4o.print("&(");
-           generate_c_base_c::visit(symbol);
-           s4o.print(")");
-         } 
-         else {
-           generate_c_base_c::visit(symbol);
-         }
-  }
-  else
-      print_getter(symbol);
+  switch (wanted_variablegeneration) {
+    case complextype_base_vg:
+    case assignment_vg:
+      generate_c_base_c::visit(symbol);
+      break;
+    case complextype_suffix_vg:
+      break;
+    default:
+      if (this->is_variable_prefix_null()) {
+        vartype = search_varfb_instance_type->get_vartype(symbol);
+        if (wanted_variablegeneration == fparam_output_vg) {
+          s4o.print("&(");
+          generate_c_base_c::visit(symbol);
+          s4o.print(")");
+        }
+        else {
+          generate_c_base_c::visit(symbol);
+        }
+      }
+      else
+        print_getter(symbol);
+      break;
+  }
   return NULL;
 }
 
@@ -317,6 +320,7 @@
       symbol->record_variable->accept(*this);
       break;
     case complextype_suffix_vg:
+    case assignment_vg:
       symbol->record_variable->accept(*this);
       s4o.print(".");
       symbol->field_selector->accept(*this);