315 |
315 |
316 if (debug) std::cout << "handle_implicit_il_fb_call() [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << il_instruction->candidate_datatypes.size() << " result.\n"; |
316 if (debug) std::cout << "handle_implicit_il_fb_call() [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << il_instruction->candidate_datatypes.size() << " result.\n"; |
317 } |
317 } |
318 |
318 |
319 |
319 |
|
320 |
|
321 |
|
322 /* handle a binary IL operator, like ADD, SUB, etc... */ |
|
323 void *fill_candidate_datatypes_c::handle_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
|
324 if (NULL == l_expr) /* if no prev_il_instruction */ |
|
325 return NULL; |
|
326 |
|
327 for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) |
|
328 for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) |
|
329 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
330 add_datatype_to_candidate_list(symbol, widening_conversion(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j], widen_table)); |
|
331 |
|
332 if (debug) std::cout << "[" << l_expr->candidate_datatypes.size() << "," << r_expr->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
333 return NULL; |
|
334 } |
|
335 |
|
336 |
|
337 /* handle a binary ST expression, like '+', '-', etc... */ |
|
338 void *fill_candidate_datatypes_c::handle_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
|
339 l_expr->accept(*this); |
|
340 r_expr->accept(*this); |
|
341 return handle_binary_operator(widen_table, symbol, l_expr, r_expr); |
|
342 } |
|
343 |
|
344 |
|
345 |
|
346 |
320 /* a helper function... */ |
347 /* a helper function... */ |
321 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
348 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
322 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
349 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
323 * in the code. |
350 * in the code. |
324 */ |
351 */ |
529 } |
533 } |
530 |
534 |
531 /************************************/ |
535 /************************************/ |
532 /* B 1.2.3.2 - Time of day and Date */ |
536 /* B 1.2.3.2 - Time of day and Date */ |
533 /************************************/ |
537 /************************************/ |
534 void *fill_candidate_datatypes_c::visit(time_of_day_c *symbol) { |
538 void *fill_candidate_datatypes_c::visit(time_of_day_c *symbol) {add_datatype_to_candidate_list(symbol, symbol->type_name); return NULL;} |
535 add_datatype_to_candidate_list(symbol, symbol->type_name); |
539 void *fill_candidate_datatypes_c::visit(date_c *symbol) {add_datatype_to_candidate_list(symbol, symbol->type_name); return NULL;} |
536 return NULL; |
540 void *fill_candidate_datatypes_c::visit(date_and_time_c *symbol) {add_datatype_to_candidate_list(symbol, symbol->type_name); return NULL;} |
537 } |
|
538 |
|
539 void *fill_candidate_datatypes_c::visit(date_c *symbol) { |
|
540 add_datatype_to_candidate_list(symbol, symbol->type_name); |
|
541 return NULL; |
|
542 } |
|
543 |
|
544 void *fill_candidate_datatypes_c::visit(date_and_time_c *symbol) { |
|
545 add_datatype_to_candidate_list(symbol, symbol->type_name); |
|
546 return NULL; |
|
547 } |
|
548 |
541 |
549 /**********************/ |
542 /**********************/ |
550 /* B 1.3 - Data types */ |
543 /* B 1.3 - Data types */ |
551 /**********************/ |
544 /**********************/ |
552 /********************************/ |
545 /********************************/ |
618 /* if (symbol->value == NULL) ERROR; |
609 /* if (symbol->value == NULL) ERROR; |
619 * if (symbol->value[0] == '\0') ERROR; |
610 * if (symbol->value[0] == '\0') ERROR; |
620 * if (symbol->value[1] == '\0') ERROR; |
611 * if (symbol->value[1] == '\0') ERROR; |
621 */ |
612 */ |
622 switch (symbol->value[2]) { |
613 switch (symbol->value[2]) { |
623 case 'X': // bit - 1 bit |
614 case 'X': /* bit - 1 bit */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break; |
624 add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); |
615 case 'B': /* byte - 8 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); break; |
625 break; |
616 case 'W': /* word - 16 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); break; |
626 |
617 case 'D': /* dword - 32 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); break; |
627 case 'B': // byte - 8 bits |
618 case 'L': /* lword - 64 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); break; |
628 add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); |
619 /* if none of the above, then the empty string was used <=> boolean */ |
629 break; |
620 default: add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break; |
630 |
|
631 case 'W': // word - 16 bits |
|
632 add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); |
|
633 break; |
|
634 |
|
635 case 'D': // double word - 32 bits |
|
636 add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); |
|
637 break; |
|
638 |
|
639 case 'L': // long word - 64 bits |
|
640 add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); |
|
641 break; |
|
642 |
|
643 default: // if none of the above, then the empty string was used <=> boolean |
|
644 add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); |
|
645 break; |
|
646 } |
621 } |
647 return NULL; |
622 return NULL; |
648 } |
623 } |
649 |
624 |
650 /*************************************/ |
625 /*************************************/ |
683 // SYM_REF2(structured_variable_c, record_variable, field_selector) |
658 // SYM_REF2(structured_variable_c, record_variable, field_selector) |
684 /* NOTE: We do not need to recursively determine the data types of each field_selector, as the search_varfb_instance_type |
659 /* NOTE: We do not need to recursively determine the data types of each field_selector, as the search_varfb_instance_type |
685 * will do that for us. So we determine the candidate datatypes only for the full structured_variable. |
660 * will do that for us. So we determine the candidate datatypes only for the full structured_variable. |
686 */ |
661 */ |
687 void *fill_candidate_datatypes_c::visit(structured_variable_c *symbol) { |
662 void *fill_candidate_datatypes_c::visit(structured_variable_c *symbol) { |
688 symbol_c *result = search_varfb_instance_type->get_basetype_decl(symbol); |
663 add_datatype_to_candidate_list(symbol, search_varfb_instance_type->get_basetype_decl(symbol)); /* will only add if non NULL */ |
689 if (NULL != result) add_datatype_to_candidate_list(symbol, result); |
|
690 return NULL; |
664 return NULL; |
691 } |
665 } |
692 |
666 |
693 /************************************/ |
667 /************************************/ |
694 /* B 1.5 Program organization units */ |
668 /* B 1.5 Program organization units */ |
695 /************************************/ |
669 /************************************/ |
696 /*********************/ |
670 /*********************/ |
697 /* B 1.5.1 Functions */ |
671 /* B 1.5.1 Functions */ |
698 /*********************/ |
672 /*********************/ |
699 void *fill_candidate_datatypes_c::visit(function_declaration_c *symbol) { |
673 void *fill_candidate_datatypes_c::visit(function_declaration_c *symbol) { |
|
674 if (debug) printf("Filling candidate data types list of function %s\n", ((token_c *)(symbol->derived_function_name))->value); |
700 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
675 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
701 symbol->var_declarations_list->accept(*this); |
676 symbol->var_declarations_list->accept(*this); |
702 if (debug) printf("Filling candidate data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value); |
|
703 // il_parenthesis_level = 0; |
|
704 symbol->function_body->accept(*this); |
677 symbol->function_body->accept(*this); |
705 delete search_varfb_instance_type; |
678 delete search_varfb_instance_type; |
706 search_varfb_instance_type = NULL; |
679 search_varfb_instance_type = NULL; |
707 return NULL; |
680 return NULL; |
708 } |
681 } |
709 |
682 |
710 /***************************/ |
683 /***************************/ |
711 /* B 1.5.2 Function blocks */ |
684 /* B 1.5.2 Function blocks */ |
712 /***************************/ |
685 /***************************/ |
713 void *fill_candidate_datatypes_c::visit(function_block_declaration_c *symbol) { |
686 void *fill_candidate_datatypes_c::visit(function_block_declaration_c *symbol) { |
|
687 if (debug) printf("Filling candidate data types list of FB %s\n", ((token_c *)(symbol->fblock_name))->value); |
714 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
688 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
715 symbol->var_declarations->accept(*this); |
689 symbol->var_declarations->accept(*this); |
716 if (debug) printf("Filling candidate data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value); |
|
717 // il_parenthesis_level = 0; |
|
718 symbol->fblock_body->accept(*this); |
690 symbol->fblock_body->accept(*this); |
719 delete search_varfb_instance_type; |
691 delete search_varfb_instance_type; |
720 search_varfb_instance_type = NULL; |
692 search_varfb_instance_type = NULL; |
721 return NULL; |
693 return NULL; |
722 } |
694 } |
723 |
695 |
724 /**********************/ |
696 /**********************/ |
725 /* B 1.5.3 - Programs */ |
697 /* B 1.5.3 - Programs */ |
726 /**********************/ |
698 /**********************/ |
727 void *fill_candidate_datatypes_c::visit(program_declaration_c *symbol) { |
699 void *fill_candidate_datatypes_c::visit(program_declaration_c *symbol) { |
|
700 if (debug) printf("Filling candidate data types list in program %s\n", ((token_c *)(symbol->program_type_name))->value); |
728 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
701 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
729 symbol->var_declarations->accept(*this); |
702 symbol->var_declarations->accept(*this); |
730 if (debug) printf("Filling candidate data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value); |
|
731 // il_parenthesis_level = 0; |
|
732 symbol->function_block_body->accept(*this); |
703 symbol->function_block_body->accept(*this); |
733 delete search_varfb_instance_type; |
704 delete search_varfb_instance_type; |
734 search_varfb_instance_type = NULL; |
705 search_varfb_instance_type = NULL; |
735 return NULL; |
706 return NULL; |
736 } |
707 } |
869 |
840 |
870 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
841 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
871 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
842 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
872 void *fill_candidate_datatypes_c::visit(il_expression_c *symbol) { |
843 void *fill_candidate_datatypes_c::visit(il_expression_c *symbol) { |
873 symbol_c *prev_il_instruction_backup = prev_il_instruction; |
844 symbol_c *prev_il_instruction_backup = prev_il_instruction; |
874 // il_parenthesis_level++; |
|
875 |
845 |
876 if (NULL != symbol->il_operand) |
846 if (NULL != symbol->il_operand) |
877 symbol->il_operand->accept(*this); |
847 symbol->il_operand->accept(*this); |
878 |
848 |
879 if(symbol->simple_instr_list != NULL) |
849 if(symbol->simple_instr_list != NULL) |
880 symbol->simple_instr_list->accept(*this); |
850 symbol->simple_instr_list->accept(*this); |
881 |
851 |
882 // il_parenthesis_level--; |
|
883 // if (il_parenthesis_level < 0) ERROR; |
|
884 |
|
885 /* Now check the if the data type semantics of operation are correct, */ |
852 /* Now check the if the data type semantics of operation are correct, */ |
886 il_operand = symbol->simple_instr_list; |
853 il_operand = symbol->simple_instr_list; |
887 prev_il_instruction = prev_il_instruction_backup; |
854 prev_il_instruction = prev_il_instruction_backup; |
888 symbol->il_expr_operator->accept(*this); |
855 symbol->il_expr_operator->accept(*this); |
889 il_operand = NULL; |
856 il_operand = NULL; |
1128 if (debug) std::cout << "R [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1095 if (debug) std::cout << "R [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1129 return NULL; |
1096 return NULL; |
1130 } |
1097 } |
1131 |
1098 |
1132 |
1099 |
1133 void *fill_candidate_datatypes_c::visit(S1_operator_c *symbol) { |
1100 void *fill_candidate_datatypes_c::visit(S1_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration); return NULL;} |
1134 handle_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration); |
1101 void *fill_candidate_datatypes_c::visit(R1_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration); return NULL;} |
1135 return NULL; |
1102 void *fill_candidate_datatypes_c::visit(CLK_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration); return NULL;} |
1136 } |
1103 void *fill_candidate_datatypes_c::visit(CU_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration); return NULL;} |
1137 |
1104 void *fill_candidate_datatypes_c::visit(CD_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "CD", symbol->called_fb_declaration); return NULL;} |
1138 void *fill_candidate_datatypes_c::visit(R1_operator_c *symbol) { |
1105 void *fill_candidate_datatypes_c::visit(PV_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "PV", symbol->called_fb_declaration); return NULL;} |
1139 handle_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration); |
1106 void *fill_candidate_datatypes_c::visit(IN_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "IN", symbol->called_fb_declaration); return NULL;} |
1140 return NULL; |
1107 void *fill_candidate_datatypes_c::visit(PT_operator_c *symbol) {handle_implicit_il_fb_call(symbol, "PT", symbol->called_fb_declaration); return NULL;} |
1141 } |
|
1142 |
|
1143 void *fill_candidate_datatypes_c::visit(CLK_operator_c *symbol) { |
|
1144 handle_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration); |
|
1145 return NULL; |
|
1146 } |
|
1147 |
|
1148 void *fill_candidate_datatypes_c::visit(CU_operator_c *symbol) { |
|
1149 handle_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration); |
|
1150 return NULL; |
|
1151 } |
|
1152 |
|
1153 void *fill_candidate_datatypes_c::visit(CD_operator_c *symbol) { |
|
1154 handle_implicit_il_fb_call(symbol, "CD", symbol->called_fb_declaration); |
|
1155 return NULL; |
|
1156 } |
|
1157 |
|
1158 void *fill_candidate_datatypes_c::visit(PV_operator_c *symbol) { |
|
1159 handle_implicit_il_fb_call(symbol, "PV", symbol->called_fb_declaration); |
|
1160 return NULL; |
|
1161 } |
|
1162 |
|
1163 void *fill_candidate_datatypes_c::visit(IN_operator_c *symbol) { |
|
1164 handle_implicit_il_fb_call(symbol, "IN", symbol->called_fb_declaration); |
|
1165 return NULL; |
|
1166 } |
|
1167 |
|
1168 void *fill_candidate_datatypes_c::visit(PT_operator_c *symbol) { |
|
1169 handle_implicit_il_fb_call(symbol, "PT", symbol->called_fb_declaration); |
|
1170 return NULL; |
|
1171 } |
|
1172 |
1108 |
1173 |
1109 |
1174 void *fill_candidate_datatypes_c::visit(AND_operator_c *symbol) { |
1110 void *fill_candidate_datatypes_c::visit(AND_operator_c *symbol) { |
1175 symbol_c *prev_instruction_type, *operand_type; |
1111 symbol_c *prev_instruction_type, *operand_type; |
1176 |
1112 |
1271 } |
1207 } |
1272 if (debug) std::cout << "XORN [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1208 if (debug) std::cout << "XORN [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1273 return NULL; |
1209 return NULL; |
1274 } |
1210 } |
1275 |
1211 |
1276 void *fill_candidate_datatypes_c::visit(ADD_operator_c *symbol) { |
1212 void *fill_candidate_datatypes_c::visit(ADD_operator_c *symbol) {return handle_binary_operator(widen_ADD_table, symbol, prev_il_instruction, il_operand);} |
1277 symbol_c *prev_instruction_type, *operand_type; |
1213 void *fill_candidate_datatypes_c::visit(SUB_operator_c *symbol) {return handle_binary_operator(widen_SUB_table, symbol, prev_il_instruction, il_operand);} |
1278 |
1214 void *fill_candidate_datatypes_c::visit(MUL_operator_c *symbol) {return handle_binary_operator(widen_MUL_table, symbol, prev_il_instruction, il_operand);} |
1279 symbol->deprecated_operation = false; |
1215 void *fill_candidate_datatypes_c::visit(DIV_operator_c *symbol) {return handle_binary_operator(widen_DIV_table, symbol, prev_il_instruction, il_operand);} |
1280 if (NULL == prev_il_instruction) return NULL; |
1216 |
1281 for(unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1282 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1283 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1284 operand_type = il_operand->candidate_datatypes[j]; |
|
1285 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1286 add_datatype_to_candidate_list(symbol, widening_conversion(prev_instruction_type, operand_type, widen_ADD_table)); |
|
1287 } |
|
1288 } |
|
1289 if (debug) std::cout << "ADD [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1290 return NULL; |
|
1291 } |
|
1292 |
|
1293 void *fill_candidate_datatypes_c::visit(SUB_operator_c *symbol) { |
|
1294 symbol_c *prev_instruction_type, *operand_type; |
|
1295 |
|
1296 symbol->deprecated_operation = false; |
|
1297 if (NULL == prev_il_instruction) return NULL; |
|
1298 for(unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1299 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1300 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1301 operand_type = il_operand->candidate_datatypes[j]; |
|
1302 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1303 add_datatype_to_candidate_list(symbol, widening_conversion(prev_instruction_type, operand_type, widen_SUB_table)); |
|
1304 } |
|
1305 } |
|
1306 if (debug) std::cout << "SUB [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1307 return NULL; |
|
1308 } |
|
1309 |
|
1310 void *fill_candidate_datatypes_c::visit(MUL_operator_c *symbol) { |
|
1311 symbol_c *prev_instruction_type, *operand_type; |
|
1312 |
|
1313 symbol->deprecated_operation = false; |
|
1314 if (NULL == prev_il_instruction) return NULL; |
|
1315 for(unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1316 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1317 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1318 operand_type = il_operand->candidate_datatypes[j]; |
|
1319 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1320 add_datatype_to_candidate_list(symbol, widening_conversion(prev_instruction_type, operand_type, widen_MUL_table)); |
|
1321 } |
|
1322 } |
|
1323 if (debug) std::cout << "MUL [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1324 return NULL; |
|
1325 } |
|
1326 |
|
1327 void *fill_candidate_datatypes_c::visit(DIV_operator_c *symbol) { |
|
1328 symbol_c *prev_instruction_type, *operand_type; |
|
1329 |
|
1330 symbol->deprecated_operation = false; |
|
1331 if (NULL == prev_il_instruction) return NULL; |
|
1332 for(unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1333 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1334 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1335 operand_type = il_operand->candidate_datatypes[j]; |
|
1336 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1337 add_datatype_to_candidate_list(symbol, widening_conversion(prev_instruction_type, operand_type, widen_DIV_table)); |
|
1338 } |
|
1339 } |
|
1340 if (debug) std::cout << "DIV [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1341 return NULL; |
|
1342 } |
|
1343 |
1217 |
1344 void *fill_candidate_datatypes_c::visit(MOD_operator_c *symbol) { |
1218 void *fill_candidate_datatypes_c::visit(MOD_operator_c *symbol) { |
1345 symbol_c *prev_instruction_type, *operand_type; |
1219 symbol_c *prev_instruction_type, *operand_type; |
1346 |
1220 |
1347 if (NULL == prev_il_instruction) return NULL; |
1221 if (NULL == prev_il_instruction) return NULL; |
1717 if (found) |
1591 if (found) |
1718 add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); |
1592 add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); |
1719 return NULL; |
1593 return NULL; |
1720 } |
1594 } |
1721 |
1595 |
1722 void *fill_candidate_datatypes_c::visit(add_expression_c *symbol) { |
1596 |
1723 /* The following code is correct when handling the addition of 2 symbolic_variables |
1597 /* The following code is correct when handling the addition of 2 symbolic_variables |
1724 * In this case, adding two variables (e.g. USINT_var1 + USINT_var2) will always yield |
1598 * In this case, adding two variables (e.g. USINT_var1 + USINT_var2) will always yield |
1725 * the same data type, even if the result of the adition could not fit inside the same |
1599 * the same data type, even if the result of the adition could not fit inside the same |
1726 * data type (due to overflowing) |
1600 * data type (due to overflowing) |
1727 * |
1601 * |
1728 * However, when adding two literals (e.g. USINT#42 + USINT#3) |
1602 * However, when adding two literals (e.g. USINT#42 + USINT#3) |
1729 * we should be able to detect overflows of the result, and therefore not consider |
1603 * we should be able to detect overflows of the result, and therefore not consider |
1730 * that the result may be of type USINT. |
1604 * that the result may be of type USINT. |
1731 * Currently we do not yet detect these overflows, and allow handling the sum of two USINTs |
1605 * Currently we do not yet detect these overflows, and allow handling the sum of two USINTs |
1732 * as always resulting in an USINT, even in the following expression |
1606 * as always resulting in an USINT, even in the following expression |
1733 * (USINT#65535 + USINT#2). |
1607 * (USINT#65535 + USINT#2). |
1734 * |
1608 * |
1735 * In the future we can add some code to reduce |
1609 * In the future we can add some code to reduce |
1736 * all the expressions that are based on literals into the resulting literal |
1610 * all the expressions that are based on literals into the resulting literal |
1737 * value (maybe some visitor class that will run before or after data type |
1611 * value (maybe some visitor class that will run before or after data type |
1738 * checking). Since this class will have to be very careful to make sure it implements the same mathematical |
1612 * checking). Since this class will have to be very careful to make sure it implements the same mathematical |
1739 * details (e.g. how to round and truncate numbers) as defined in IEC 61131-3, we will leave this to the future. |
1613 * details (e.g. how to round and truncate numbers) as defined in IEC 61131-3, we will leave this to the future. |
1740 * Also, the question will arise if we should also replace calls to standard |
1614 * Also, the question will arise if we should also replace calls to standard |
1741 * functions if the input parameters are all literals (e.g. ADD(42, 42)). This |
1615 * functions if the input parameters are all literals (e.g. ADD(42, 42)). This |
1742 * means this class will be more difficult than it appears at first. |
1616 * means this class will be more difficult than it appears at first. |
1743 */ |
1617 */ |
1744 symbol_c *left_type, *right_type; |
1618 void *fill_candidate_datatypes_c::visit(add_expression_c *symbol) {return handle_binary_expression(widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp);} |
1745 |
1619 void *fill_candidate_datatypes_c::visit(sub_expression_c *symbol) {return handle_binary_expression(widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp);} |
1746 symbol->deprecated_operation = false; |
1620 void *fill_candidate_datatypes_c::visit(mul_expression_c *symbol) {return handle_binary_expression(widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp);} |
1747 symbol->l_exp->accept(*this); |
1621 void *fill_candidate_datatypes_c::visit(div_expression_c *symbol) {return handle_binary_expression(widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp);} |
1748 symbol->r_exp->accept(*this); |
|
1749 for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
|
1750 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
|
1751 left_type = symbol->l_exp->candidate_datatypes[i]; |
|
1752 right_type = symbol->r_exp->candidate_datatypes[j]; |
|
1753 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1754 add_datatype_to_candidate_list(symbol, widening_conversion(left_type, right_type, widen_ADD_table)); |
|
1755 } |
|
1756 } |
|
1757 if (debug) std::cout << "+ [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1758 return NULL; |
|
1759 } |
|
1760 |
|
1761 |
|
1762 void *fill_candidate_datatypes_c::visit(sub_expression_c *symbol) { |
|
1763 symbol_c *left_type, *right_type; |
|
1764 |
|
1765 symbol->deprecated_operation = false; |
|
1766 symbol->l_exp->accept(*this); |
|
1767 symbol->r_exp->accept(*this); |
|
1768 for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
|
1769 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
|
1770 left_type = symbol->l_exp->candidate_datatypes[i]; |
|
1771 right_type = symbol->r_exp->candidate_datatypes[j]; |
|
1772 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1773 add_datatype_to_candidate_list(symbol, widening_conversion(left_type, right_type, widen_SUB_table)); |
|
1774 } |
|
1775 } |
|
1776 if (debug) std::cout << "- [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1777 return NULL; |
|
1778 } |
|
1779 |
|
1780 |
|
1781 void *fill_candidate_datatypes_c::visit(mul_expression_c *symbol) { |
|
1782 symbol_c *left_type, *right_type; |
|
1783 |
|
1784 symbol->deprecated_operation = false; |
|
1785 symbol->l_exp->accept(*this); |
|
1786 symbol->r_exp->accept(*this); |
|
1787 for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
|
1788 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
|
1789 left_type = symbol->l_exp->candidate_datatypes[i]; |
|
1790 right_type = symbol->r_exp->candidate_datatypes[j]; |
|
1791 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1792 add_datatype_to_candidate_list(symbol, widening_conversion(left_type, right_type, widen_MUL_table)); |
|
1793 } |
|
1794 } |
|
1795 if (debug) std::cout << "* [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1796 |
|
1797 return NULL; |
|
1798 } |
|
1799 |
|
1800 void *fill_candidate_datatypes_c::visit(div_expression_c *symbol) { |
|
1801 symbol_c *left_type, *right_type; |
|
1802 |
|
1803 symbol->deprecated_operation = false; |
|
1804 symbol->l_exp->accept(*this); |
|
1805 symbol->r_exp->accept(*this); |
|
1806 for(unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
|
1807 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
|
1808 left_type = symbol->l_exp->candidate_datatypes[i]; |
|
1809 right_type = symbol->r_exp->candidate_datatypes[j]; |
|
1810 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
|
1811 add_datatype_to_candidate_list(symbol, widening_conversion(left_type, right_type, widen_DIV_table)); |
|
1812 } |
|
1813 } |
|
1814 if (debug) std::cout << "/ [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1815 return NULL; |
|
1816 } |
|
1817 |
1622 |
1818 |
1623 |
1819 void *fill_candidate_datatypes_c::visit(mod_expression_c *symbol) { |
1624 void *fill_candidate_datatypes_c::visit(mod_expression_c *symbol) { |
1820 symbol_c *left_type, *right_type; |
1625 symbol_c *left_type, *right_type; |
1821 |
1626 |