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)) { |
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); |