More changes for support of semantic verification of il_expressions
authorMario de Sousa <msousa@fe.up.pt>
Tue, 21 Feb 2012 17:39:57 +0000
changeset 453 4733f662362a
parent 452 79ac274d1cc4
child 454 099aa5d655de
More changes for support of semantic verification of il_expressions
absyntax/absyntax.def
stage1_2/iec_bison.yy
stage3/fill_candidate_datatypes.cc
stage3/fill_candidate_datatypes.hh
stage3/flow_control_analysis.cc
stage3/flow_control_analysis.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_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_iec/generate_iec.cc
--- a/absyntax/absyntax.def	Mon Feb 20 19:44:40 2012 +0000
+++ b/absyntax/absyntax.def	Tue Feb 21 17:39:57 2012 +0000
@@ -958,6 +958,15 @@
 /* | simple_instr_list il_simple_instruction */
 SYM_LIST(simple_instr_list_c)
 
+
+/* il_simple_instruction:
+ *   il_simple_operation eol_list
+ * | il_expression eol_list
+ * | il_formal_funct_call eol_list
+ */
+/* NOTE: The parameter 'prev_il_instruction' is used to point to all previous il instructions that may be executed imedaitely before this instruction. */
+SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+
 /* | il_initial_param_list il_param_instruction */
 SYM_LIST(il_param_list_c)
 
--- a/stage1_2/iec_bison.yy	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage1_2/iec_bison.yy	Tue Feb 21 17:39:57 2012 +0000
@@ -6637,8 +6637,11 @@
 
 il_simple_instruction:
   il_simple_operation eol_list
+	{$$ = new il_simple_instruction_c($1, locloc(@$));}
 | il_expression eol_list
+	{$$ = new il_simple_instruction_c($1, locloc(@$));}
 | il_formal_funct_call eol_list
+	{$$ = new il_simple_instruction_c($1, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | il_expression error
   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "EOL missing after expression IL instruction."); yyerrok;}
--- a/stage3/fill_candidate_datatypes.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -45,7 +45,7 @@
 #include <strings.h>
 
 /* set to 1 to see debug info during execution */
-static int debug = 0;
+static int debug = 1;
 
 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) {
 }
@@ -904,25 +904,17 @@
 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
 void *fill_candidate_datatypes_c::visit(il_expression_c *symbol) {
+  symbol_c *prev_il_instruction_backup = prev_il_instruction;
+  il_parenthesis_level++;
+  
   if (NULL != symbol->il_operand)
     symbol->il_operand->accept(*this);
-  
-  il_parenthesis_level++;
-
-  /* Note that prev_il_instruction will actually be used to get the current value store in the il_default_variable */
-  /* If a symbol->il_operand is provided, then that will be the result before executing the simple_instr_list.
-   * If this symbol is NULL, then the current result is also NULL, which is correct for what we want to do!
-   */
-  symbol_c *prev_il_instruction_backup = prev_il_instruction;
-  prev_il_instruction = symbol->il_operand;
-  
-  if(symbol->simple_instr_list != NULL) {
+
+  if(symbol->simple_instr_list != NULL)
     symbol->simple_instr_list->accept(*this);
-  }
 
   il_parenthesis_level--;
   if (il_parenthesis_level < 0) ERROR;
-
   
   /* Now check the if the data type semantics of operation are correct,  */
   il_operand = symbol->simple_instr_list;
@@ -1006,18 +998,33 @@
 /* | simple_instr_list il_simple_instruction */
 /* This object is referenced by il_expression_c objects */
 void *fill_candidate_datatypes_c::visit(simple_instr_list_c *symbol) {
-  int i;
-  for(i = 0; i < symbol->n; i++)    
+std::cout << "simple_instr_list_c [filling starting]\n";
+  if (symbol->n <= 0)
+    return NULL;  /* List is empty! Nothing to do. */
+    
+  for(int i = 0; i < symbol->n; i++)
     symbol->elements[i]->accept(*this);
-  /* This object has (inherits) the same candidate datatypes as the last il_instruction (if it exists!) */
-  if (i > 0)  
-    copy_candidate_datatype_list(symbol->elements[i-1] /*from*/, symbol /*to*/);	
+
+  /* This object has (inherits) the same candidate datatypes as the last il_instruction */
+  copy_candidate_datatype_list(symbol->elements[symbol->n-1] /*from*/, symbol /*to*/);	
   
   if (debug) std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n";
 std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n";
   return NULL;
 }
 
+// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+void *fill_candidate_datatypes_c::visit(il_simple_instruction_c *symbol) {
+  prev_il_instruction = symbol->prev_il_instruction;
+  symbol->il_simple_instruction->accept(*this);
+  prev_il_instruction = NULL;
+
+  /* This object has (inherits) the same candidate datatypes as the il_simple_instruction it points to */
+  copy_candidate_datatype_list(symbol->il_simple_instruction /*from*/, symbol /*to*/);	
+  return NULL;
+}
+
+
 /*
     void *visit(il_param_list_c *symbol);
     void *visit(il_param_assignment_c *symbol);
@@ -1171,6 +1178,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "AND [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
@@ -1187,6 +1195,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "OR [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
@@ -1203,6 +1212,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "XOR [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
@@ -1219,6 +1229,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "ANDN [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
@@ -1235,6 +1246,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "ORN [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
@@ -1251,6 +1263,7 @@
 				symbol->candidate_datatypes.push_back(prev_instruction_type);
 		}
 	}
+	if (debug) std::cout <<  "XORN [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
 	return NULL;
 }
 
--- a/stage3/fill_candidate_datatypes.hh	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/fill_candidate_datatypes.hh	Tue Feb 21 17:39:57 2012 +0000
@@ -204,6 +204,7 @@
     void *visit(il_formal_funct_call_c *symbol);
 //  void *visit(il_operand_list_c *symbol);
     void *visit(simple_instr_list_c *symbol);
+    void *visit(il_simple_instruction_c*symbol);
 //  void *visit(il_param_list_c *symbol);
 //  void *visit(il_param_assignment_c *symbol);
 //  void *visit(il_param_out_assignment_c *symbol);
--- a/stage3/flow_control_analysis.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/flow_control_analysis.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -37,6 +37,72 @@
  *  This class will annotate the abstract syntax tree, by filling in the
  *  prev_il_instruction variable in the il_instruction_c, so it points to
  *  the previous il_instruction_c object in the instruction list instruction_list_c.
+ *
+ *  The result will essentially be a linked list of il_instruction_c objects, each 
+ *  pointing to the previous il_instruction_c object.
+ *
+ *  The reality is we will get several independent and isolated linked lists
+ *  (actually, once we process labels correctly, this will become a graph):
+ *  one for each block of IL code (e.g. inside a Function, FB or Program).
+ *  Additionally, when the IL code has an expression (expression_c object), we will actually
+ *  have one more isolated linked list for the IL code inside that expression.
+ *
+ *  e.g.
+ *       line_1:   LD 1
+ *       line_2:   ADD (42
+ *       line_3:        ADD B
+ *       line_4:        ADD C 
+ *       line_5:       )
+ *       line_6:   ADD D
+ *       line_7:   ST  E
+ * 
+ *     will result in two independent linked lists:
+ *       main list:  line_7 -> line_6 -> line2 -> line_1
+ *       expr list:  lin4_4 -> line_3 -> (operand of line_2, i.e. '42')
+ * 
+ * 
+ *     In the main list, each:
+ *        line_x: IL_operation IL_operand
+ *      is encoded as
+ *          il_instruction_c(label, il_incomplete_instruction)
+ *      these il_instruction_c objects will point back to the previous il_instruction_c object.
+ *
+ *     In the expr list, each 
+ *        line_x:        IL_operation IL_operand
+ *      is encoded as
+ *          il_simple_instruction_c(il_simple_instruction)
+ *      these il_simple_instruction_c objects will point back to the previous il_simple_instruction_c object,
+ *      except the for the first il_simple_instruction_c object in the list, which will point back to
+ *      the first il_operand (in the above example, '42'), or NULL is it does not exist.
+ *          
+ *
+ * label:
+ *   identifier_c  
+ *   
+ * il_incomplete_instruction:
+ *   il_simple_operation   (il_simple_operation_c, il_function_call_c)
+ * | il_expression         (il_expression_c)
+ * | il_jump_operation     (il_jump_operation_c)
+ * | il_fb_call            (il_fb_call_c)
+ * | il_formal_funct_call  (il_formal_funct_call_c)
+ * | il_return_operator    (RET_operator_c, RETC_operator_c, RETCN_operator_c)
+ *  
+ * 
+ * il_expression_c(il_expr_operator, il_operand, simple_instr_list)
+ * 
+ * il_operand:
+ *   variable            (symbolic_variable_c, direct_variable_c, array_variable_c, structured_variable_c)  
+ * | enumerated_value    (enumerated_value_c)
+ * | constant            (lots of literal classes _c)
+ * 
+ * simple_instr_list:
+ *   list of il_simple_instruction
+ * 
+ * il_simple_instruction:
+ *   il_simple_operation       (il_simple_operation_c)
+ * | il_expression             (il_expression_c)
+ * | il_formal_funct_call      (il_formal_funct_call_c)
+ * 
  */
 
 #include "flow_control_analysis.hh"
@@ -128,14 +194,19 @@
 	/* TODO: handle labels correctly!
 	 *
 	 *      Don't forget to handle multiple consecutive lables too!
-	 * 	  label2:
+	 *        label2:
 	 *        label3:
 	 *        label4:
 	 *                LD I
 	 */
+	/* NOTE: the following recursive call will mess up the value in the
+	 *       this->prev_il_instruction variable, so be sure not to use it
+	 *       after the return of symbol->il_instruction->accept(*this);
+	 */
+	/* check if it is an il_expression_c, and if so, handle it correctly */
 	if (NULL != symbol->il_instruction)
 		symbol->il_instruction->accept(*this);
-return NULL;
+	return NULL;
 }
 
 
@@ -146,13 +217,22 @@
 void *flow_control_analysis_c::visit(il_function_call_c *symbol) {
 	return NULL;
 }
+#endif
 
 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
 void *flow_control_analysis_c::visit(il_expression_c *symbol) {
-return NULL;
-}
-
+	if(NULL == symbol->simple_instr_list) 
+		/* nothing to do... */
+		return NULL;
+  
+	prev_il_instruction = symbol->il_operand;
+	symbol->simple_instr_list->accept(*this);
+	return NULL;
+}
+
+
+#if 0
 /*   il_call_operator prev_declared_fb_name
  * | il_call_operator prev_declared_fb_name '(' ')'
  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
@@ -176,16 +256,24 @@
 
 
 //  void *visit(il_operand_list_c *symbol);
-
 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
-	for(int i = 0; i < symbol->n; i++) {
-		prev_il_instruction = NULL;
-		if (i > 0) prev_il_instruction = symbol->elements[i-1];
+	/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
+	for(int i = 1; i < symbol->n; i++) {
+		/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
+		if (i>0) prev_il_instruction = symbol->elements[i-1];
 		symbol->elements[i]->accept(*this);
 	}
 	return NULL;
 }
 
+
+// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
+	symbol->prev_il_instruction = prev_il_instruction;
+	return NULL;
+}
+
+
 /*
     void *visit(il_param_list_c *symbol);
     void *visit(il_param_assignment_c *symbol);
--- a/stage3/flow_control_analysis.hh	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/flow_control_analysis.hh	Tue Feb 21 17:39:57 2012 +0000
@@ -88,11 +88,12 @@
     void *visit(il_instruction_c *symbol);
 //     void *visit(il_simple_operation_c *symbol);
 //     void *visit(il_function_call_c *symbol);
-//     void *visit(il_expression_c *symbol);
+    void *visit(il_expression_c *symbol);
 //     void *visit(il_fb_call_c *symbol);
 //     void *visit(il_formal_funct_call_c *symbol);
 //     void *visit(il_operand_list_c *symbol);
        void *visit(simple_instr_list_c *symbol);
+       void *visit(il_simple_instruction_c*symbol);
 //     void *visit(il_param_list_c *symbol);
 //     void *visit(il_param_assignment_c *symbol);
 //     void *visit(il_param_out_assignment_c *symbol);
--- a/stage3/narrow_candidate_datatypes.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -570,14 +570,15 @@
 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
 void *narrow_candidate_datatypes_c::visit(il_expression_c *symbol) {
-  symbol_c *save_prev_il_instruction = prev_il_instruction;
-  
-  symbol->simple_instr_list->datatype = symbol->datatype;
+  /* first handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */
+  symbol->il_expr_operator->datatype = symbol->datatype;
+  il_operand = symbol->il_operand;
+  symbol->il_expr_operator->accept(*this);
+
+  /* now give the parenthesised IL list a chance to narrow the datatypes */
+  symbol_c *save_prev_il_instruction = prev_il_instruction; /*this is not really necessary, but lets play it safe */
   symbol->simple_instr_list->accept(*this);
-
   prev_il_instruction = save_prev_il_instruction;
-
-  /* TODO: finish this */
 return NULL;
 }
 
@@ -641,6 +642,10 @@
 
 
 //     void *visit(il_operand_list_c *symbol);
+
+
+/* | simple_instr_list il_simple_instruction */
+/* This object is referenced by il_expression_c objects */
 void *narrow_candidate_datatypes_c::visit(simple_instr_list_c *symbol) {
 	if (symbol->n > 0)
 		symbol->elements[symbol->n - 1]->datatype = symbol->datatype;
@@ -651,6 +656,16 @@
 	return NULL;
 }
 
+
+// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+void *narrow_candidate_datatypes_c::visit(il_simple_instruction_c *symbol)	{
+  prev_il_instruction = symbol->prev_il_instruction;
+  symbol->il_simple_instruction->datatype = symbol->datatype;
+  symbol->il_simple_instruction->accept(*this);
+  prev_il_instruction = NULL;
+  return NULL;
+}
+
 //     void *visit(il_param_list_c *symbol);
 //     void *visit(il_param_assignment_c *symbol);
 //     void *visit(il_param_out_assignment_c *symbol);
--- a/stage3/narrow_candidate_datatypes.hh	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.hh	Tue Feb 21 17:39:57 2012 +0000
@@ -116,6 +116,7 @@
     void *visit(il_formal_funct_call_c *symbol);
 //  void *visit(il_operand_list_c *symbol);
     void *visit(simple_instr_list_c *symbol);
+    void *visit(il_simple_instruction_c*symbol);
 //  void *visit(il_param_list_c *symbol);
 //  void *visit(il_param_assignment_c *symbol);
 //  void *visit(il_param_out_assignment_c *symbol);
--- a/stage3/print_datatypes_error.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/print_datatypes_error.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -636,6 +636,7 @@
 }
 
 void *print_datatypes_error_c::visit(il_expression_c *symbol) {
+  /* TODO */
 	return NULL;
 }
 
@@ -683,13 +684,26 @@
 }
 
 
-/*
-    void *visit(il_operand_list_c *symbol);
-    void *visit(simple_instr_list_c *symbol);
-    void *visit(il_param_list_c *symbol);
-    void *visit(il_param_assignment_c *symbol);
-    void *visit(il_param_out_assignment_c *symbol);
- */
+//     void *visit(il_operand_list_c *symbol);
+
+
+/* | simple_instr_list il_simple_instruction */
+/* This object is referenced by il_expression_c objects */
+void *print_datatypes_error_c::visit(simple_instr_list_c *symbol) {
+  /* TODO */
+	return NULL;
+}
+
+// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol) {
+  /* TODO */
+	return NULL;
+}
+
+//     void *visit(simple_instr_list_c *symbol);
+//     void *visit(il_param_list_c *symbol);
+//     void *visit(il_param_assignment_c *symbol);
+//     void *visit(il_param_out_assignment_c *symbol);
 
 /*******************/
 /* B 2.2 Operators */
--- a/stage3/print_datatypes_error.hh	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage3/print_datatypes_error.hh	Tue Feb 21 17:39:57 2012 +0000
@@ -193,13 +193,12 @@
     void *visit(il_expression_c *symbol);
     void *visit(il_fb_call_c *symbol);
     void *visit(il_formal_funct_call_c *symbol);
-    /*
-        void *visit(il_operand_list_c *symbol);
-        void *visit(simple_instr_list_c *symbol);
-        void *visit(il_param_list_c *symbol);
-        void *visit(il_param_assignment_c *symbol);
-        void *visit(il_param_out_assignment_c *symbol);
-     */
+//  void *visit(il_operand_list_c *symbol);
+    void *visit(simple_instr_list_c *symbol);
+    void *visit(il_simple_instruction_c*symbol);
+//  void *visit(il_param_list_c *symbol);
+//  void *visit(il_param_assignment_c *symbol);
+//  void *visit(il_param_out_assignment_c *symbol);
 
     /*******************/
     /* B 2.2 Operators */
--- a/stage4/generate_c/generate_c_il.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage4/generate_c/generate_c_il.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -1556,6 +1556,12 @@
   return NULL;
 }
 
+// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+void *visit(il_simple_instruction_c *symbol)	{
+  return symbol->il_simple_instruction->accept(*this);
+}
+
+
 /* | il_initial_param_list il_param_instruction */
 // SYM_LIST(il_param_list_c)
 void *visit(il_param_list_c *symbol) {ERROR; return NULL;} // should never get called!
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -826,6 +826,11 @@
 	  this->default_variable_back_name.current_type = this->default_variable_name.current_type;
 	  return NULL;
     }
+    
+    // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
+    void *visit(il_simple_instruction_c *symbol)	{
+      return symbol->il_simple_instruction->accept(*this);
+    }
 
     void *visit(LD_operator_c *symbol)	{
       /* the data type resulting from this operation... */
--- a/stage4/generate_iec/generate_iec.cc	Mon Feb 20 19:44:40 2012 +0000
+++ b/stage4/generate_iec/generate_iec.cc	Tue Feb 21 17:39:57 2012 +0000
@@ -1670,6 +1670,17 @@
   return print_list(symbol,  s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n");
 }
 
+
+/* il_simple_instruction:
+ *   il_simple_operation eol_list
+ * | il_expression eol_list
+ * | il_formal_funct_call eol_list
+ */
+void *visit(il_simple_instruction_c *symbol)	{
+  return symbol->il_simple_instruction->accept(*this);
+}
+
+
 /* | il_initial_param_list il_param_instruction */
 void *visit(il_param_list_c *symbol) {
 // return print_list(symbol);