291 * However, we do not place that object directly in the fake il_param_list_c that we will be |
291 * However, we do not place that object directly in the fake il_param_list_c that we will be |
292 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list. |
292 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list. |
293 * The il_prev_intruction object has already been visited. We DO NOT want to visit it again. |
293 * The il_prev_intruction object has already been visited. We DO NOT want to visit it again. |
294 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object! |
294 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object! |
295 */ |
295 */ |
296 symbol_c param_value; |
296 symbol_c param_value = *prev_il_instruction; |
297 copy_candidate_datatype_list(prev_il_instruction/*from*/, ¶m_value/*to*/); |
|
298 |
297 |
299 identifier_c variable_name(param_name); |
298 identifier_c variable_name(param_name); |
300 // SYM_REF1(il_assign_operator_c, variable_name) |
299 // SYM_REF1(il_assign_operator_c, variable_name) |
301 il_assign_operator_c il_assign_operator(&variable_name); |
300 il_assign_operator_c il_assign_operator(&variable_name); |
302 // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
301 // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
859 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
858 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
860 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
859 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
861 void *fill_candidate_datatypes_c::visit(il_function_call_c *symbol) { |
860 void *fill_candidate_datatypes_c::visit(il_function_call_c *symbol) { |
862 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
861 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
863 * In order to be able to handle this without coding special cases, we will simply prepend that symbol |
862 * In order to be able to handle this without coding special cases, we will simply prepend that symbol |
864 * to the il_operand_list, and remove it later (in the print_datatypes_error_c). |
863 * to the il_operand_list, and remove it after calling handle_function_call(). |
865 * |
864 * |
866 * However, if no further paramters are given, then il_operand_list will be NULL, and we will |
865 * However, if no further paramters are given, then il_operand_list will be NULL, and we will |
867 * need to create a new object to hold the pointer to prev_il_instruction. |
866 * need to create a new object to hold the pointer to prev_il_instruction. |
868 * This change will also be undone later in print_datatypes_error_c. |
867 * This change will also be undone later in print_datatypes_error_c. |
869 */ |
868 */ |
870 if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c; |
869 if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c; |
871 if (NULL == symbol->il_operand_list) ERROR; |
870 if (NULL == symbol->il_operand_list) ERROR; |
872 |
871 |
873 symbol->il_operand_list->accept(*this); |
872 symbol->il_operand_list->accept(*this); |
874 |
873 |
875 if (NULL == prev_il_instruction) return NULL; |
874 if (NULL != prev_il_instruction) { |
876 ((list_c *)symbol->il_operand_list)->insert_element(prev_il_instruction, 0); |
875 ((list_c *)symbol->il_operand_list)->insert_element(prev_il_instruction, 0); |
877 |
876 |
878 generic_function_call_t fcall_param = { |
877 generic_function_call_t fcall_param = { |
879 /* fcall_param.function_name = */ symbol->function_name, |
878 /* fcall_param.function_name = */ symbol->function_name, |
880 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
879 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
881 /* fcall_param.formal_operand_list = */ NULL, |
880 /* fcall_param.formal_operand_list = */ NULL, |
882 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_function, |
881 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_function, |
883 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
882 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
884 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
883 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
885 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
884 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
886 }; |
885 }; |
887 handle_function_call(symbol, fcall_param); |
886 handle_function_call(symbol, fcall_param); |
888 |
887 |
|
888 /* Undo the changes to the abstract syntax tree we made above... */ |
|
889 ((list_c *)symbol->il_operand_list)->remove_element(0); |
|
890 } |
|
891 |
|
892 /* Undo the changes to the abstract syntax tree we made above... */ |
|
893 if (((list_c *)symbol->il_operand_list)->n == 0) { |
|
894 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
|
895 delete symbol->il_operand_list; |
|
896 symbol->il_operand_list = NULL; |
|
897 } |
|
898 |
889 if (debug) std::cout << "il_function_call_c [" << symbol->candidate_datatypes.size() << "] result.\n"; |
899 if (debug) std::cout << "il_function_call_c [" << symbol->candidate_datatypes.size() << "] result.\n"; |
890 return NULL; |
900 return NULL; |
891 } |
901 } |
892 |
902 |
893 |
903 |