Add MOD widening table, and some code clean-ups.
authorMario de Sousa <msousa@fe.up.pt>
Tue, 13 Mar 2012 19:04:07 +0000
changeset 480 8a58d7b8b26c
parent 479 a174d61f2087
child 481 16f943328696
Add MOD widening table, and some code clean-ups.
stage3/datatype_functions.cc
stage3/datatype_functions.hh
stage3/fill_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
--- a/stage3/datatype_functions.cc	Tue Mar 13 18:29:34 2012 +0000
+++ b/stage3/datatype_functions.cc	Tue Mar 13 19:04:07 2012 +0000
@@ -238,7 +238,7 @@
     { &search_constant_type_c::safetime_type_name,      &search_constant_type_c::TYPE##_type_name,          &search_constant_type_c::time_type_name,     widen_entry::deprecated }, \
     { &search_constant_type_c::time_type_name,          &search_constant_type_c::safe##TYPE##_type_name,    &search_constant_type_c::time_type_name,     widen_entry::deprecated }, \
     { &search_constant_type_c::safetime_type_name,      &search_constant_type_c::safe##TYPE##_type_name,    &search_constant_type_c::safetime_type_name, widen_entry::deprecated }, \
-    /* NOTE: the standard des not explicitly support the following semantics. However, since 'multiplication' is supposed to be commutative, we add it anyway... */ \
+    /* NOTE: the standard des not explicitly support the following semantics. However, since 'multiplication' is supposed to be commutative, we add it anyway... */                 \
     { &search_constant_type_c::TYPE##_type_name,        &search_constant_type_c::time_type_name,            &search_constant_type_c::time_type_name,     widen_entry::deprecated }, \
     { &search_constant_type_c::safe##TYPE##_type_name,  &search_constant_type_c::time_type_name,            &search_constant_type_c::time_type_name,     widen_entry::deprecated }, \
     { &search_constant_type_c::TYPE##_type_name,        &search_constant_type_c::safetime_type_name,        &search_constant_type_c::time_type_name,     widen_entry::deprecated }, \
@@ -279,6 +279,22 @@
  };
 
  
+
+
+const struct widen_entry widen_MOD_table[] = {
+#define __mod(TYPE)       \
+    { &search_constant_type_c::TYPE##_type_name,        &search_constant_type_c::TYPE##_type_name,          &search_constant_type_c::TYPE##_type_name,       widen_entry::ok     }, \
+    { &search_constant_type_c::safe##TYPE##_type_name,  &search_constant_type_c::TYPE##_type_name,          &search_constant_type_c::TYPE##_type_name,       widen_entry::ok     }, \
+    { &search_constant_type_c::TYPE##_type_name,        &search_constant_type_c::safe##TYPE##_type_name,    &search_constant_type_c::TYPE##_type_name,       widen_entry::ok     }, \
+    { &search_constant_type_c::safe##TYPE##_type_name,  &search_constant_type_c::safe##TYPE##_type_name,    &search_constant_type_c::safe##TYPE##_type_name, widen_entry::ok     },
+    __ANY_NUM(__mod)
+#undef __mod
+
+    { NULL, NULL, NULL, widen_entry::ok },
+};
+ 
+ 
+ 
  
 /* Search for a datatype inside a candidate_datatypes list.
  * Returns: position of datatype in the list, or -1 if not found.
--- a/stage3/datatype_functions.hh	Tue Mar 13 18:29:34 2012 +0000
+++ b/stage3/datatype_functions.hh	Tue Mar 13 19:04:07 2012 +0000
@@ -132,6 +132,7 @@
 extern const struct widen_entry widen_SUB_table[];
 extern const struct widen_entry widen_MUL_table[];
 extern const struct widen_entry widen_DIV_table[];
+extern const struct widen_entry widen_MOD_table[];
 
 /* Search for a datatype inside a candidate_datatypes list.
  * Returns: position of datatype in the list, or -1 if not found.
--- a/stage3/fill_candidate_datatypes.cc	Tue Mar 13 18:29:34 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Tue Mar 13 19:04:07 2012 +0000
@@ -1213,24 +1213,9 @@
 void *fill_candidate_datatypes_c::visit(SUB_operator_c *symbol) {return handle_binary_operator(widen_SUB_table, symbol, prev_il_instruction, il_operand);}
 void *fill_candidate_datatypes_c::visit(MUL_operator_c *symbol) {return handle_binary_operator(widen_MUL_table, symbol, prev_il_instruction, il_operand);}
 void *fill_candidate_datatypes_c::visit(DIV_operator_c *symbol) {return handle_binary_operator(widen_DIV_table, symbol, prev_il_instruction, il_operand);}
-
-
-void *fill_candidate_datatypes_c::visit(MOD_operator_c *symbol) {
-	symbol_c *prev_instruction_type, *operand_type;
-
-	if (NULL == prev_il_instruction) return NULL;
-	for(unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
-			prev_instruction_type = prev_il_instruction->candidate_datatypes[i];
-			operand_type = il_operand->candidate_datatypes[j];
-			if (is_type_equal(prev_instruction_type, operand_type) &&
-					is_ANY_INT_compatible(prev_instruction_type))
-				add_datatype_to_candidate_list(symbol, prev_instruction_type);
-		}
-	}
-	if (debug) std::cout <<  "MOD [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
-	return NULL;
-}
+void *fill_candidate_datatypes_c::visit(MOD_operator_c *symbol) {return handle_binary_operator(widen_MOD_table, symbol, prev_il_instruction, il_operand);}
+
+
 
 void *fill_candidate_datatypes_c::visit(GT_operator_c *symbol) {
 	bool found = false;
@@ -1619,24 +1604,7 @@
 void *fill_candidate_datatypes_c::visit(sub_expression_c *symbol) {return handle_binary_expression(widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp);}
 void *fill_candidate_datatypes_c::visit(mul_expression_c *symbol) {return handle_binary_expression(widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp);}
 void *fill_candidate_datatypes_c::visit(div_expression_c *symbol) {return handle_binary_expression(widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp);}
-
-
-void *fill_candidate_datatypes_c::visit(mod_expression_c *symbol) {
-	symbol_c *left_type, *right_type;
-
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->accept(*this);
-	for (unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
-			left_type = symbol->l_exp->candidate_datatypes[i];
-			right_type = symbol->r_exp->candidate_datatypes[j];
-			if (is_type_equal(left_type, right_type) && is_ANY_INT_compatible(left_type))
-				add_datatype_to_candidate_list(symbol, left_type);
-		}
-	}
-	if (debug) std::cout << "mod [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
-	return NULL;
-}
+void *fill_candidate_datatypes_c::visit(mod_expression_c *symbol) {return handle_binary_expression(widen_MOD_table, symbol, symbol->l_exp, symbol->r_exp);}
 
 
 void *fill_candidate_datatypes_c::visit(power_expression_c *symbol) {
--- a/stage3/narrow_candidate_datatypes.cc	Tue Mar 13 18:29:34 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.cc	Tue Mar 13 19:04:07 2012 +0000
@@ -95,12 +95,13 @@
 
 
 
-bool narrow_candidate_datatypes_c::is_widening_compatible(const struct widen_entry widen_table[], symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, bool &deprecated_status) {
+bool narrow_candidate_datatypes_c::is_widening_compatible(const struct widen_entry widen_table[], symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, bool *deprecated_status) {
 	for (int k = 0; NULL != widen_table[k].left;  k++) {
 		if        ((typeid(*left_type)   == typeid(*widen_table[k].left))
 		        && (typeid(*right_type)  == typeid(*widen_table[k].right))
 			&& (typeid(*result_type) == typeid(*widen_table[k].result))) {
-			deprecated_status = (widen_table[k].status == widen_entry::deprecated);
+			if (NULL != deprecated_status)
+				*deprecated_status = (widen_table[k].status == widen_entry::deprecated);
 			return true;
 		}
 	}
@@ -750,15 +751,17 @@
 /*******************/
 /* B 2.2 Operators */
 /*******************/
-void *narrow_candidate_datatypes_c::handle_il_instruction_widen(symbol_c *symbol, bool &deprecated_operation, const struct widen_entry widen_table[]) {
+void *narrow_candidate_datatypes_c::narrow_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, bool *deprecated_operation) {
 	symbol_c *prev_instruction_type, *operand_type;
 	int count = 0;
-	bool deprecated_status;
 
 	if (NULL == symbol->datatype)
 		/* next IL instructions were unable to determine the datatype this instruction should produce */
 		return NULL;
 
+        if (NULL != deprecated_operation)
+		*deprecated_operation = false;
+
 	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
 	 * e.g.  LD 33
 	 *       AND ( 45
@@ -774,7 +777,6 @@
 	 *         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.
 	 */
-        deprecated_operation = false;
 	for(unsigned int i = 0; i < fake_prev_il_instruction->candidate_datatypes.size(); i++) {
 		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
 			prev_instruction_type = fake_prev_il_instruction->candidate_datatypes[i];
@@ -789,7 +791,6 @@
 			}
 		}
 	}
-
 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
 
@@ -799,6 +800,8 @@
 
 
 
+
+
 void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) {
 	if (NULL == symbol->datatype)
 		/* next IL instructions were unable to determine the datatype this instruction should produce */
@@ -914,11 +917,11 @@
 void *narrow_candidate_datatypes_c::visit(ANDN_operator_c *symbol)  {return handle_il_instruction(symbol);}
 void *narrow_candidate_datatypes_c::visit( ORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
 void *narrow_candidate_datatypes_c::visit(XORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
-void *narrow_candidate_datatypes_c::visit( ADD_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_ADD_table);}
-void *narrow_candidate_datatypes_c::visit( SUB_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_SUB_table);}
-void *narrow_candidate_datatypes_c::visit( MUL_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_MUL_table);}
-void *narrow_candidate_datatypes_c::visit( DIV_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_DIV_table);}
-void *narrow_candidate_datatypes_c::visit( MOD_operator_c *symbol)  {return handle_il_instruction(symbol);}
+void *narrow_candidate_datatypes_c::visit( ADD_operator_c *symbol)  {return narrow_binary_operator(widen_ADD_table, symbol, &(symbol->deprecated_operation));}
+void *narrow_candidate_datatypes_c::visit( SUB_operator_c *symbol)  {return narrow_binary_operator(widen_SUB_table, symbol, &(symbol->deprecated_operation));}
+void *narrow_candidate_datatypes_c::visit( MUL_operator_c *symbol)  {return narrow_binary_operator(widen_MUL_table, symbol, &(symbol->deprecated_operation));}
+void *narrow_candidate_datatypes_c::visit( DIV_operator_c *symbol)  {return narrow_binary_operator(widen_DIV_table, symbol, &(symbol->deprecated_operation));}
+void *narrow_candidate_datatypes_c::visit( MOD_operator_c *symbol)  {return narrow_binary_operator(widen_MOD_table, symbol);}
 void *narrow_candidate_datatypes_c::visit(  GT_operator_c *symbol)  {return handle_il_instruction(symbol);}
 void *narrow_candidate_datatypes_c::visit(  GE_operator_c *symbol)  {return handle_il_instruction(symbol);}
 void *narrow_candidate_datatypes_c::visit(  EQ_operator_c *symbol)  {return handle_il_instruction(symbol);}
@@ -1005,6 +1008,33 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
+void *narrow_candidate_datatypes_c::narrow_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation) {
+	symbol_c *l_type, *r_type;
+	int count = 0;
+
+        if (NULL != deprecated_operation)
+		*deprecated_operation = false;
+
+	for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) {
+		for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) {
+			/* test widening compatibility */
+			l_type = l_expr->candidate_datatypes[i];
+			r_type = r_expr->candidate_datatypes[j];
+			if (is_widening_compatible(widen_table, l_type, r_type, symbol->datatype, deprecated_operation)) {
+				l_expr->datatype = l_type;
+				r_expr->datatype = r_type;
+				count ++;
+			}
+		}
+	}
+// 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
+	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
+	
+	l_expr->accept(*this);
+	r_expr->accept(*this);
+	return NULL;
+}
+
 
 void *narrow_candidate_datatypes_c::visit(or_expression_c *symbol) {
 	symbol_c * selected_type = NULL;
@@ -1229,127 +1259,13 @@
 	return NULL;
 }
 
-void *narrow_candidate_datatypes_c::visit(add_expression_c *symbol) {
-	symbol_c *left_type, *right_type;
-	int count = 0;
-	bool deprecated_status;
-
-	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
-			/* test widening compatibility */
-			left_type  = symbol->l_exp->candidate_datatypes[i];
-			right_type = symbol->r_exp->candidate_datatypes[j];
-			if (is_widening_compatible(widen_ADD_table, left_type, right_type, symbol->datatype, deprecated_status)) {
-				symbol->l_exp->datatype = left_type;
-				symbol->r_exp->datatype = right_type;
-				symbol->deprecated_operation = deprecated_status;
-				count ++;
-			}
-		}
-	}
-// 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
-	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
-	
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->accept(*this);
-	return NULL;
-}
-
-
-
-void *narrow_candidate_datatypes_c::visit(sub_expression_c *symbol) {
-	symbol_c *left_type, *right_type;
-	int count = 0;
-	bool deprecated_status;
-
-	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
-			/* test widening compatibility */
-			left_type  = symbol->l_exp->candidate_datatypes[i];
-			right_type = symbol->r_exp->candidate_datatypes[j];
-			if (is_widening_compatible(widen_SUB_table, left_type, right_type, symbol->datatype, deprecated_status)) {
-				symbol->l_exp->datatype = left_type;
-				symbol->r_exp->datatype = right_type;
-				symbol->deprecated_operation = deprecated_status;
-				count ++;
-			}
-		}
-	}
-// 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
-	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
-	
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->accept(*this);
-	return NULL;
-}
-
-
-
-void *narrow_candidate_datatypes_c::visit(mul_expression_c *symbol) {
-	symbol_c *left_type, *right_type;
-	int count = 0;
-	bool deprecated_status;
-
-	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
-			/* test widening compatibility */
-			left_type  = symbol->l_exp->candidate_datatypes[i];
-			right_type = symbol->r_exp->candidate_datatypes[j];
-			if (is_widening_compatible(widen_MUL_table, left_type, right_type, symbol->datatype, deprecated_status)) {
-				symbol->l_exp->datatype = left_type;
-				symbol->r_exp->datatype = right_type;
-				symbol->deprecated_operation = deprecated_status;
-				count ++;
-			}
-		}
-	}
-// 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
-	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
-	
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->accept(*this);
-	return NULL;
-}
-
-
-
-
-void *narrow_candidate_datatypes_c::visit(div_expression_c *symbol) {
-	symbol_c *left_type, *right_type;
-	int count = 0;
-	bool deprecated_status;
-
-	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
-		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
-			/* test widening compatibility */
-			left_type  = symbol->l_exp->candidate_datatypes[i];
-			right_type = symbol->r_exp->candidate_datatypes[j];
-			if (is_widening_compatible(widen_DIV_table, left_type, right_type, symbol->datatype, deprecated_status)) {
-				symbol->l_exp->datatype = left_type;
-				symbol->r_exp->datatype = right_type;
-				symbol->deprecated_operation = deprecated_status;
-				count ++;
-			}
-		}
-	}
-// 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
-	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
-	
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->accept(*this);
-	return NULL;
-}
-
-
-
-
-void *narrow_candidate_datatypes_c::visit(mod_expression_c *symbol) {
-	symbol->l_exp->datatype = symbol->datatype;
-	symbol->l_exp->accept(*this);
-	symbol->r_exp->datatype = symbol->datatype;
-	symbol->r_exp->accept(*this);
-	return NULL;
-}
+void *narrow_candidate_datatypes_c::visit(add_expression_c *symbol) {return narrow_binary_expression(widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(sub_expression_c *symbol) {return narrow_binary_expression(widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(mul_expression_c *symbol) {return narrow_binary_expression(widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(div_expression_c *symbol) {return narrow_binary_expression(widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(mod_expression_c *symbol) {return narrow_binary_expression(widen_MOD_table, symbol, symbol->l_exp, symbol->r_exp);}
+
+
 
 
 void *narrow_candidate_datatypes_c::visit(power_expression_c *symbol) {
--- a/stage3/narrow_candidate_datatypes.hh	Tue Mar 13 18:29:34 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.hh	Tue Mar 13 19:04:07 2012 +0000
@@ -46,7 +46,7 @@
     std::vector <symbol_c *> *prev_il_instructions;
     std::vector <symbol_c *> *prev_il_instructions_intersected_datatypes;
 
-    bool is_widening_compatible(const struct widen_entry widen_table[], symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, bool &deprecated_status);
+    bool is_widening_compatible(const struct widen_entry widen_table[], symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, bool *deprecated_status = NULL);
 
     void  narrow_function_invocation(symbol_c *f_call, generic_function_call_t fcall_data);
     void  narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count = NULL);
@@ -54,7 +54,8 @@
     void *narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration);
 
     void *handle_il_instruction(symbol_c *symbol);
-    void *handle_il_instruction_widen(symbol_c *symbol, bool &deprecated_operation, const struct widen_entry widen_table[]);
+    void *narrow_binary_operator  (const struct widen_entry widen_table[], symbol_c *symbol,                                     bool *deprecated_operation = NULL);
+    void *narrow_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL);
 
     void *narrow_conditional_flow_control_IL_instruction(symbol_c *symbol);