stage3/narrow_candidate_datatypes.cc
changeset 480 8a58d7b8b26c
parent 478 b13feab3b918
child 481 16f943328696
equal deleted inserted replaced
479:a174d61f2087 480:8a58d7b8b26c
    93 		set_datatype(datatype, symbol->prev_il_instruction[i]);
    93 		set_datatype(datatype, symbol->prev_il_instruction[i]);
    94 }
    94 }
    95 
    95 
    96 
    96 
    97 
    97 
    98 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) {
    98 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) {
    99 	for (int k = 0; NULL != widen_table[k].left;  k++) {
    99 	for (int k = 0; NULL != widen_table[k].left;  k++) {
   100 		if        ((typeid(*left_type)   == typeid(*widen_table[k].left))
   100 		if        ((typeid(*left_type)   == typeid(*widen_table[k].left))
   101 		        && (typeid(*right_type)  == typeid(*widen_table[k].right))
   101 		        && (typeid(*right_type)  == typeid(*widen_table[k].right))
   102 			&& (typeid(*result_type) == typeid(*widen_table[k].result))) {
   102 			&& (typeid(*result_type) == typeid(*widen_table[k].result))) {
   103 			deprecated_status = (widen_table[k].status == widen_entry::deprecated);
   103 			if (NULL != deprecated_status)
       
   104 				*deprecated_status = (widen_table[k].status == widen_entry::deprecated);
   104 			return true;
   105 			return true;
   105 		}
   106 		}
   106 	}
   107 	}
   107 	return false;
   108 	return false;
   108 }
   109 }
   748 
   749 
   749 
   750 
   750 /*******************/
   751 /*******************/
   751 /* B 2.2 Operators */
   752 /* B 2.2 Operators */
   752 /*******************/
   753 /*******************/
   753 void *narrow_candidate_datatypes_c::handle_il_instruction_widen(symbol_c *symbol, bool &deprecated_operation, const struct widen_entry widen_table[]) {
   754 void *narrow_candidate_datatypes_c::narrow_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, bool *deprecated_operation) {
   754 	symbol_c *prev_instruction_type, *operand_type;
   755 	symbol_c *prev_instruction_type, *operand_type;
   755 	int count = 0;
   756 	int count = 0;
   756 	bool deprecated_status;
       
   757 
   757 
   758 	if (NULL == symbol->datatype)
   758 	if (NULL == symbol->datatype)
   759 		/* next IL instructions were unable to determine the datatype this instruction should produce */
   759 		/* next IL instructions were unable to determine the datatype this instruction should produce */
   760 		return NULL;
   760 		return NULL;
       
   761 
       
   762         if (NULL != deprecated_operation)
       
   763 		*deprecated_operation = false;
   761 
   764 
   762 	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
   765 	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
   763 	 * e.g.  LD 33
   766 	 * e.g.  LD 33
   764 	 *       AND ( 45
   767 	 *       AND ( 45
   765 	 *            OR 56
   768 	 *            OR 56
   772 	 *
   775 	 *
   773 	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
   776 	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
   774 	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
   777 	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
   775 	 *         (or simple_instr_list_c), which iterates backwards.
   778 	 *         (or simple_instr_list_c), which iterates backwards.
   776 	 */
   779 	 */
   777         deprecated_operation = false;
       
   778 	for(unsigned int i = 0; i < fake_prev_il_instruction->candidate_datatypes.size(); i++) {
   780 	for(unsigned int i = 0; i < fake_prev_il_instruction->candidate_datatypes.size(); i++) {
   779 		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
   781 		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
   780 			prev_instruction_type = fake_prev_il_instruction->candidate_datatypes[i];
   782 			prev_instruction_type = fake_prev_il_instruction->candidate_datatypes[i];
   781 			operand_type = il_operand->candidate_datatypes[j];
   783 			operand_type = il_operand->candidate_datatypes[j];
   782 			if (is_widening_compatible(widen_table, prev_instruction_type, operand_type, symbol->datatype, deprecated_operation)) {
   784 			if (is_widening_compatible(widen_table, prev_instruction_type, operand_type, symbol->datatype, deprecated_operation)) {
   787 				
   789 				
   788 				count ++;
   790 				count ++;
   789 			}
   791 			}
   790 		}
   792 		}
   791 	}
   793 	}
   792 
       
   793 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
   794 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
   794 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
   795 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
   795 
   796 
   796 	il_operand->accept(*this);
   797 	il_operand->accept(*this);
   797 	return NULL;
   798 	return NULL;
   798 }
   799 }
       
   800 
       
   801 
   799 
   802 
   800 
   803 
   801 
   804 
   802 void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) {
   805 void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) {
   803 	if (NULL == symbol->datatype)
   806 	if (NULL == symbol->datatype)
   912 void *narrow_candidate_datatypes_c::visit(  OR_operator_c *symbol)  {return handle_il_instruction(symbol);}
   915 void *narrow_candidate_datatypes_c::visit(  OR_operator_c *symbol)  {return handle_il_instruction(symbol);}
   913 void *narrow_candidate_datatypes_c::visit( XOR_operator_c *symbol)  {return handle_il_instruction(symbol);}
   916 void *narrow_candidate_datatypes_c::visit( XOR_operator_c *symbol)  {return handle_il_instruction(symbol);}
   914 void *narrow_candidate_datatypes_c::visit(ANDN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   917 void *narrow_candidate_datatypes_c::visit(ANDN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   915 void *narrow_candidate_datatypes_c::visit( ORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   918 void *narrow_candidate_datatypes_c::visit( ORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   916 void *narrow_candidate_datatypes_c::visit(XORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   919 void *narrow_candidate_datatypes_c::visit(XORN_operator_c *symbol)  {return handle_il_instruction(symbol);}
   917 void *narrow_candidate_datatypes_c::visit( ADD_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_ADD_table);}
   920 void *narrow_candidate_datatypes_c::visit( ADD_operator_c *symbol)  {return narrow_binary_operator(widen_ADD_table, symbol, &(symbol->deprecated_operation));}
   918 void *narrow_candidate_datatypes_c::visit( SUB_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_SUB_table);}
   921 void *narrow_candidate_datatypes_c::visit( SUB_operator_c *symbol)  {return narrow_binary_operator(widen_SUB_table, symbol, &(symbol->deprecated_operation));}
   919 void *narrow_candidate_datatypes_c::visit( MUL_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_MUL_table);}
   922 void *narrow_candidate_datatypes_c::visit( MUL_operator_c *symbol)  {return narrow_binary_operator(widen_MUL_table, symbol, &(symbol->deprecated_operation));}
   920 void *narrow_candidate_datatypes_c::visit( DIV_operator_c *symbol)  {return handle_il_instruction_widen(symbol, symbol->deprecated_operation, widen_DIV_table);}
   923 void *narrow_candidate_datatypes_c::visit( DIV_operator_c *symbol)  {return narrow_binary_operator(widen_DIV_table, symbol, &(symbol->deprecated_operation));}
   921 void *narrow_candidate_datatypes_c::visit( MOD_operator_c *symbol)  {return handle_il_instruction(symbol);}
   924 void *narrow_candidate_datatypes_c::visit( MOD_operator_c *symbol)  {return narrow_binary_operator(widen_MOD_table, symbol);}
   922 void *narrow_candidate_datatypes_c::visit(  GT_operator_c *symbol)  {return handle_il_instruction(symbol);}
   925 void *narrow_candidate_datatypes_c::visit(  GT_operator_c *symbol)  {return handle_il_instruction(symbol);}
   923 void *narrow_candidate_datatypes_c::visit(  GE_operator_c *symbol)  {return handle_il_instruction(symbol);}
   926 void *narrow_candidate_datatypes_c::visit(  GE_operator_c *symbol)  {return handle_il_instruction(symbol);}
   924 void *narrow_candidate_datatypes_c::visit(  EQ_operator_c *symbol)  {return handle_il_instruction(symbol);}
   927 void *narrow_candidate_datatypes_c::visit(  EQ_operator_c *symbol)  {return handle_il_instruction(symbol);}
   925 void *narrow_candidate_datatypes_c::visit(  LT_operator_c *symbol)  {return handle_il_instruction(symbol);}
   928 void *narrow_candidate_datatypes_c::visit(  LT_operator_c *symbol)  {return handle_il_instruction(symbol);}
   926 void *narrow_candidate_datatypes_c::visit(  LE_operator_c *symbol)  {return handle_il_instruction(symbol);}
   929 void *narrow_candidate_datatypes_c::visit(  LE_operator_c *symbol)  {return handle_il_instruction(symbol);}
  1003 /* B.3 - Language ST (Structured Text) */
  1006 /* B.3 - Language ST (Structured Text) */
  1004 /***************************************/
  1007 /***************************************/
  1005 /***********************/
  1008 /***********************/
  1006 /* B 3.1 - Expressions */
  1009 /* B 3.1 - Expressions */
  1007 /***********************/
  1010 /***********************/
       
  1011 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) {
       
  1012 	symbol_c *l_type, *r_type;
       
  1013 	int count = 0;
       
  1014 
       
  1015         if (NULL != deprecated_operation)
       
  1016 		*deprecated_operation = false;
       
  1017 
       
  1018 	for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) {
       
  1019 		for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) {
       
  1020 			/* test widening compatibility */
       
  1021 			l_type = l_expr->candidate_datatypes[i];
       
  1022 			r_type = r_expr->candidate_datatypes[j];
       
  1023 			if (is_widening_compatible(widen_table, l_type, r_type, symbol->datatype, deprecated_operation)) {
       
  1024 				l_expr->datatype = l_type;
       
  1025 				r_expr->datatype = r_type;
       
  1026 				count ++;
       
  1027 			}
       
  1028 		}
       
  1029 	}
       
  1030 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
       
  1031 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
       
  1032 	
       
  1033 	l_expr->accept(*this);
       
  1034 	r_expr->accept(*this);
       
  1035 	return NULL;
       
  1036 }
       
  1037 
  1008 
  1038 
  1009 void *narrow_candidate_datatypes_c::visit(or_expression_c *symbol) {
  1039 void *narrow_candidate_datatypes_c::visit(or_expression_c *symbol) {
  1010 	symbol_c * selected_type = NULL;
  1040 	symbol_c * selected_type = NULL;
  1011 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
  1041 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
  1012 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
  1042 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
  1227 	else
  1257 	else
  1228 		ERROR;
  1258 		ERROR;
  1229 	return NULL;
  1259 	return NULL;
  1230 }
  1260 }
  1231 
  1261 
  1232 void *narrow_candidate_datatypes_c::visit(add_expression_c *symbol) {
  1262 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);}
  1233 	symbol_c *left_type, *right_type;
  1263 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);}
  1234 	int count = 0;
  1264 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);}
  1235 	bool deprecated_status;
  1265 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);}
  1236 
  1266 void *narrow_candidate_datatypes_c::visit(mod_expression_c *symbol) {return narrow_binary_expression(widen_MOD_table, symbol, symbol->l_exp, symbol->r_exp);}
  1237 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
  1267 
  1238 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
  1268 
  1239 			/* test widening compatibility */
       
  1240 			left_type  = symbol->l_exp->candidate_datatypes[i];
       
  1241 			right_type = symbol->r_exp->candidate_datatypes[j];
       
  1242 			if (is_widening_compatible(widen_ADD_table, left_type, right_type, symbol->datatype, deprecated_status)) {
       
  1243 				symbol->l_exp->datatype = left_type;
       
  1244 				symbol->r_exp->datatype = right_type;
       
  1245 				symbol->deprecated_operation = deprecated_status;
       
  1246 				count ++;
       
  1247 			}
       
  1248 		}
       
  1249 	}
       
  1250 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
       
  1251 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
       
  1252 	
       
  1253 	symbol->l_exp->accept(*this);
       
  1254 	symbol->r_exp->accept(*this);
       
  1255 	return NULL;
       
  1256 }
       
  1257 
       
  1258 
       
  1259 
       
  1260 void *narrow_candidate_datatypes_c::visit(sub_expression_c *symbol) {
       
  1261 	symbol_c *left_type, *right_type;
       
  1262 	int count = 0;
       
  1263 	bool deprecated_status;
       
  1264 
       
  1265 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
       
  1266 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
       
  1267 			/* test widening compatibility */
       
  1268 			left_type  = symbol->l_exp->candidate_datatypes[i];
       
  1269 			right_type = symbol->r_exp->candidate_datatypes[j];
       
  1270 			if (is_widening_compatible(widen_SUB_table, left_type, right_type, symbol->datatype, deprecated_status)) {
       
  1271 				symbol->l_exp->datatype = left_type;
       
  1272 				symbol->r_exp->datatype = right_type;
       
  1273 				symbol->deprecated_operation = deprecated_status;
       
  1274 				count ++;
       
  1275 			}
       
  1276 		}
       
  1277 	}
       
  1278 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
       
  1279 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
       
  1280 	
       
  1281 	symbol->l_exp->accept(*this);
       
  1282 	symbol->r_exp->accept(*this);
       
  1283 	return NULL;
       
  1284 }
       
  1285 
       
  1286 
       
  1287 
       
  1288 void *narrow_candidate_datatypes_c::visit(mul_expression_c *symbol) {
       
  1289 	symbol_c *left_type, *right_type;
       
  1290 	int count = 0;
       
  1291 	bool deprecated_status;
       
  1292 
       
  1293 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
       
  1294 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
       
  1295 			/* test widening compatibility */
       
  1296 			left_type  = symbol->l_exp->candidate_datatypes[i];
       
  1297 			right_type = symbol->r_exp->candidate_datatypes[j];
       
  1298 			if (is_widening_compatible(widen_MUL_table, left_type, right_type, symbol->datatype, deprecated_status)) {
       
  1299 				symbol->l_exp->datatype = left_type;
       
  1300 				symbol->r_exp->datatype = right_type;
       
  1301 				symbol->deprecated_operation = deprecated_status;
       
  1302 				count ++;
       
  1303 			}
       
  1304 		}
       
  1305 	}
       
  1306 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
       
  1307 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
       
  1308 	
       
  1309 	symbol->l_exp->accept(*this);
       
  1310 	symbol->r_exp->accept(*this);
       
  1311 	return NULL;
       
  1312 }
       
  1313 
       
  1314 
       
  1315 
       
  1316 
       
  1317 void *narrow_candidate_datatypes_c::visit(div_expression_c *symbol) {
       
  1318 	symbol_c *left_type, *right_type;
       
  1319 	int count = 0;
       
  1320 	bool deprecated_status;
       
  1321 
       
  1322 	for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) {
       
  1323 		for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) {
       
  1324 			/* test widening compatibility */
       
  1325 			left_type  = symbol->l_exp->candidate_datatypes[i];
       
  1326 			right_type = symbol->r_exp->candidate_datatypes[j];
       
  1327 			if (is_widening_compatible(widen_DIV_table, left_type, right_type, symbol->datatype, deprecated_status)) {
       
  1328 				symbol->l_exp->datatype = left_type;
       
  1329 				symbol->r_exp->datatype = right_type;
       
  1330 				symbol->deprecated_operation = deprecated_status;
       
  1331 				count ++;
       
  1332 			}
       
  1333 		}
       
  1334 	}
       
  1335 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
       
  1336 	if (is_type_valid(symbol->datatype) && (count <= 0)) ERROR;
       
  1337 	
       
  1338 	symbol->l_exp->accept(*this);
       
  1339 	symbol->r_exp->accept(*this);
       
  1340 	return NULL;
       
  1341 }
       
  1342 
       
  1343 
       
  1344 
       
  1345 
       
  1346 void *narrow_candidate_datatypes_c::visit(mod_expression_c *symbol) {
       
  1347 	symbol->l_exp->datatype = symbol->datatype;
       
  1348 	symbol->l_exp->accept(*this);
       
  1349 	symbol->r_exp->datatype = symbol->datatype;
       
  1350 	symbol->r_exp->accept(*this);
       
  1351 	return NULL;
       
  1352 }
       
  1353 
  1269 
  1354 
  1270 
  1355 void *narrow_candidate_datatypes_c::visit(power_expression_c *symbol) {
  1271 void *narrow_candidate_datatypes_c::visit(power_expression_c *symbol) {
  1356 	symbol->l_exp->datatype = symbol->datatype;
  1272 	symbol->l_exp->datatype = symbol->datatype;
  1357 	symbol->l_exp->accept(*this);
  1273 	symbol->l_exp->accept(*this);