Finish support for semantic verification of IL paranthesised expressions.
authorMario de Sousa <msousa@fe.up.pt>
Thu, 23 Feb 2012 13:25:49 +0000
changeset 454 099aa5d655de
parent 453 4733f662362a
child 455 933c0dccc82f
Finish support for semantic verification of IL paranthesised expressions.
stage3/fill_candidate_datatypes.cc
stage3/flow_control_analysis.cc
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
stage3/print_datatypes_error.cc
stage3/print_datatypes_error.hh
--- a/stage3/fill_candidate_datatypes.cc	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Thu Feb 23 13:25:49 2012 +0000
@@ -45,7 +45,7 @@
 #include <strings.h>
 
 /* set to 1 to see debug info during execution */
-static int debug = 1;
+static int debug = 0;
 
 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) {
 }
@@ -921,6 +921,9 @@
   prev_il_instruction = prev_il_instruction_backup;
   symbol->il_expr_operator->accept(*this);
   il_operand = NULL;
+  
+  /* This object has the same candidate datatypes as the il_expr_operator. */
+  copy_candidate_datatype_list(symbol->il_expr_operator/*from*/, symbol/*to*/);
   return NULL;
 }
 
@@ -998,7 +1001,6 @@
 /* | 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) {
-std::cout << "simple_instr_list_c [filling starting]\n";
   if (symbol->n <= 0)
     return NULL;  /* List is empty! Nothing to do. */
     
@@ -1009,7 +1011,6 @@
   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;
 }
 
--- a/stage3/flow_control_analysis.cc	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/flow_control_analysis.cc	Thu Feb 23 13:25:49 2012 +0000
@@ -99,7 +99,7 @@
  *   list of il_simple_instruction
  * 
  * il_simple_instruction:
- *   il_simple_operation       (il_simple_operation_c)
+ *   il_simple_operation       (il_simple_operation_c, il_function_call_c)
  * | il_expression             (il_expression_c)
  * | il_formal_funct_call      (il_formal_funct_call_c)
  * 
@@ -257,8 +257,7 @@
 
 //  void *visit(il_operand_list_c *symbol);
 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
-	/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
-	for(int i = 1; i < symbol->n; i++) {
+	for(int i = 0; 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);
--- a/stage3/narrow_candidate_datatypes.cc	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.cc	Thu Feb 23 13:25:49 2012 +0000
@@ -572,10 +572,11 @@
 void *narrow_candidate_datatypes_c::visit(il_expression_c *symbol) {
   /* 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;
+  il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */
   symbol->il_expr_operator->accept(*this);
 
   /* now give the parenthesised IL list a chance to narrow the datatypes */
+  /* The datatype that is must return was set by the call symbol->il_expr_operator->accept(*this) */
   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;
@@ -679,11 +680,26 @@
 	if (NULL == symbol->datatype)
 		/* next IL instructions were unable to determine the datatype this instruction should produce */
 		return NULL;
+	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
+	 * e.g.  LD 33
+	 *       AND ( 45
+	 *            OR 56
+	 *            )
+	 *       When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c.
+	 *       In this case, when we call il_operand->accept(*this);, the prev_il_instruction pointer will be overwritten!
+	 *
+	 *       We must therefore set the prev_il_instruction->datatype = symbol->datatype;
+	 *       __before__ calling il_operand->accept(*this) !!
+	 *
+	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
+	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
+	 *         (or simple_instr_list_c), which iterates backwards.
+	 */
+	/* set the desired datatype of the previous il instruction */
+	prev_il_instruction->datatype = symbol->datatype;
 	/* set the datatype for the operand */
 	il_operand->datatype = symbol->datatype;
 	il_operand->accept(*this);
-	/* set the desired datatype of the previous il instruction */
-	prev_il_instruction->datatype = symbol->datatype;
 	return NULL;
 }
 
@@ -735,7 +751,6 @@
 }
 
 void *narrow_candidate_datatypes_c::visit(NOT_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
--- a/stage3/narrow_candidate_datatypes.hh	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.hh	Thu Feb 23 13:25:49 2012 +0000
@@ -77,7 +77,6 @@
     /* B 1.4.2 - Multi-element variables */
     /*************************************/
     void *visit(array_variable_c *symbol);
-    void *visit(il_instruction_c *symbol);
     void *visit(subscript_list_c *symbol);
 
     /**************************************/
@@ -109,6 +108,7 @@
     /* B 2.1 Instructions and Operands */
     /***********************************/
     void *visit(instruction_list_c *symbol);
+    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);
--- a/stage3/print_datatypes_error.cc	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/print_datatypes_error.cc	Thu Feb 23 13:25:49 2012 +0000
@@ -475,10 +475,7 @@
 /* subscript_list ',' subscript */
 // SYM_LIST(subscript_list_c)
 /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */
-#if 0
-void *print_datatypes_error_c::visit(subscript_list_c *symbol) {
-}
-#endif
+// void *print_datatypes_error_c::visit(subscript_list_c *symbol)
 
 
 /*  record_variable '.' field_selector */
@@ -511,9 +508,7 @@
 	if (debug) printf("Print error data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
 	il_parenthesis_level = 0;
 	il_error = false;
-	prev_il_instruction = NULL;
 	symbol->function_body->accept(*this);
-	prev_il_instruction = NULL;
 	delete search_varfb_instance_type;
 	search_varfb_instance_type = NULL;
 	return NULL;
@@ -529,9 +524,7 @@
 	if (debug) printf("Print error data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
 	il_parenthesis_level = 0;
 	il_error = false;
-	prev_il_instruction = NULL;
 	symbol->fblock_body->accept(*this);
-	prev_il_instruction = NULL;
 	delete search_varfb_instance_type;
 	search_varfb_instance_type = NULL;
 	return NULL;
@@ -547,9 +540,7 @@
 	if (debug) printf("Print error data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
 	il_parenthesis_level = 0;
 	il_error = false;
-	prev_il_instruction = NULL;
 	symbol->function_block_body->accept(*this);
-	prev_il_instruction = NULL;
 	delete search_varfb_instance_type;
 	search_varfb_instance_type = NULL;
 	return NULL;
@@ -574,7 +565,23 @@
 /***********************************/
 /* B 2.1 Instructions and Operands */
 /***********************************/
+
 // void *visit(instruction_list_c *symbol);
+
+/* | label ':' [il_incomplete_instruction] eol_list */
+// SYM_REF2(il_instruction_c, label, il_instruction)
+void *print_datatypes_error_c::visit(il_instruction_c *symbol) {
+	if (NULL != symbol->il_instruction) {
+		prev_il_instruction = symbol->prev_il_instruction;
+		symbol->il_instruction->accept(*this);
+		prev_il_instruction = NULL;
+	}
+
+	return NULL;
+}
+
+
+
 void *print_datatypes_error_c::visit(il_simple_operation_c *symbol) {
 	il_operand = symbol->il_operand;
 	if (NULL != symbol->il_operand) {
@@ -635,10 +642,22 @@
 	return NULL;
 }
 
+
+/* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
+// SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
 void *print_datatypes_error_c::visit(il_expression_c *symbol) {
-  /* TODO */
-	return NULL;
-}
+  /* first give the parenthesised IL list a chance to print errors */
+  symbol_c *save_prev_il_instruction = prev_il_instruction;
+  symbol->simple_instr_list->accept(*this);
+  prev_il_instruction = save_prev_il_instruction;
+
+  /* Now handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */
+  il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */
+  symbol->il_expr_operator->accept(*this);
+
+return NULL;
+}
+
 
 /*   il_call_operator prev_declared_fb_name
  * | il_call_operator prev_declared_fb_name '(' ')'
@@ -685,22 +704,17 @@
 
 
 //     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;
-}
+//     void *visit(simple_instr_list_c *symbol);
 
 // 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 *print_datatypes_error_c::visit(il_simple_instruction_c *symbol)	{
+  prev_il_instruction = symbol->prev_il_instruction;
+  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);
@@ -709,16 +723,13 @@
 /* B 2.2 Operators */
 /*******************/
 void *print_datatypes_error_c::visit(LD_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(LDN_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'LDN' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
@@ -728,11 +739,9 @@
 	 * we can't use a ST like first instruction.
 	 * What do you think?
 	 */
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ST' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
@@ -742,36 +751,29 @@
 	 * we can't use a ST like first instruction.
 	 * What do you think?
 	 */
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'STN' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(NOT_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(S_operator_c *symbol) {
   /* TODO: what if this is a FB call ?? */
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(R_operator_c *symbol) {
   /* TODO: what if this is a FB call ?? */
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
@@ -816,176 +818,139 @@
 }
 
 void *print_datatypes_error_c::visit(AND_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'AND' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(OR_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'OR' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(XOR_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'XOR' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(ANDN_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ANDN' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(ORN_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ORN' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(XORN_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ORN' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(ADD_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ADD' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(SUB_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'SUB' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(MUL_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'MUL' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(DIV_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'DIV' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(MOD_operator_c *symbol) {
-	il_operand->accept(*this);
 	if ((symbol->candidate_datatypes.size() == 0) 		&&
 		(il_operand->candidate_datatypes.size() > 0))
 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'MOD' operator.");
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(GT_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(GE_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(EQ_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(LT_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(LE_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(NE_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(CAL_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(CALC_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(RET_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(RETC_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(JMP_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(JMPC_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
 void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) {
-	prev_il_instruction = symbol;
 	return NULL;
 }
 
--- a/stage3/print_datatypes_error.hh	Tue Feb 21 17:39:57 2012 +0000
+++ b/stage3/print_datatypes_error.hh	Thu Feb 23 13:25:49 2012 +0000
@@ -42,7 +42,7 @@
   private:
     /* The level of detail that the user wants us to display error messages. */
 //     #define error_level_default (1)
-    #define error_level_default (1)
+    #define error_level_default (4)
     #define error_level_nagging (4)
     unsigned int current_display_error_level;
     
@@ -187,14 +187,15 @@
     /***********************************/
     /* B 2.1 Instructions and Operands */
     /***********************************/
-    // void *visit(instruction_list_c *symbol);
+//  void *visit(instruction_list_c *symbol);
+    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_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(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);