134 if (NULL != fcall_data.formal_operand_list) { |
134 if (NULL != fcall_data.formal_operand_list) { |
135 fcall_data.formal_operand_list->accept(*this); |
135 fcall_data.formal_operand_list->accept(*this); |
136 if (NULL != f_decl) { |
136 if (NULL != f_decl) { |
137 function_param_iterator_c fp_iterator(f_decl); |
137 function_param_iterator_c fp_iterator(f_decl); |
138 while ((param_name = fcp_iterator.next_f()) != NULL) { |
138 while ((param_name = fcp_iterator.next_f()) != NULL) { |
|
139 #if 0 |
|
140 /* TODO: check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */ |
|
141 |
|
142 |
|
143 /* TODO: Check if there are duplicat parameter values */ |
|
144 verify_duplicate_param = fcp_iterator.search_f(call_param_name); |
|
145 if(verify_duplicate_param != call_param_value) |
|
146 return false; |
|
147 #endif |
139 param_value = fcp_iterator.get_current_value(); |
148 param_value = fcp_iterator.get_current_value(); |
140 /* Find the corresponding parameter in function declaration */ |
149 /* Find the corresponding parameter in function declaration */ |
141 if (NULL == fp_iterator.search(param_name)) { |
150 if (NULL == fp_iterator.search(param_name)) { |
142 STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); |
151 STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); |
143 } else if (NULL == param_value->datatype) { |
152 } else if (NULL == param_value->datatype) { |
164 } |
173 } |
165 |
174 |
166 return; |
175 return; |
167 } |
176 } |
168 |
177 |
169 |
178 void print_datatypes_error_c::handle_implicit_il_fb_invocation(symbol_c *il_operator, const char *param_name, symbol_c *called_fb_declaration) { |
170 |
179 if (NULL == il_operand) { |
|
180 STAGE3_ERROR(0, il_operator, il_operator, "Missing operand for FB call operator '%s'.", param_name); |
|
181 return; |
|
182 } |
|
183 if (NULL == called_fb_declaration) { |
|
184 STAGE3_ERROR(0, il_operand, il_operand, "Operand of FB call operator '%s' is not a FB variable.", param_name); |
|
185 return; |
|
186 } |
|
187 if (NULL == prev_il_instruction) { |
|
188 STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name); |
|
189 return; |
|
190 } |
|
191 /* Find the corresponding parameter in function declaration */ |
|
192 function_param_iterator_c fp_iterator(called_fb_declaration); |
|
193 if (NULL == fp_iterator.search(param_name)) { |
|
194 /* TODO: must also check whther it is an IN parameter!! */ |
|
195 STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name); |
|
196 return; |
|
197 } |
|
198 if (NULL == prev_il_instruction->datatype) { |
|
199 STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed, when invoking FB.", param_name); |
|
200 return; |
|
201 } |
|
202 |
|
203 return; |
|
204 } |
171 |
205 |
172 |
206 |
173 /*********************/ |
207 /*********************/ |
174 /* B 1.2 - Constants */ |
208 /* B 1.2 - Constants */ |
175 /*********************/ |
209 /*********************/ |
430 * so it does not make sense to recursively visit all the field_selectors to print out error messages. |
464 * so it does not make sense to recursively visit all the field_selectors to print out error messages. |
431 * Maybe in the future, if we find the need to print out more detailed error messages, we might do it that way. For now, we don't! |
465 * Maybe in the future, if we find the need to print out more detailed error messages, we might do it that way. For now, we don't! |
432 */ |
466 */ |
433 void *print_datatypes_error_c::visit(structured_variable_c *symbol) { |
467 void *print_datatypes_error_c::visit(structured_variable_c *symbol) { |
434 if (symbol->candidate_datatypes.size() == 0) |
468 if (symbol->candidate_datatypes.size() == 0) |
435 STAGE3_ERROR(0, symbol, symbol, "Structure variable not declared in this scope."); |
469 STAGE3_ERROR(0, symbol, symbol, "Undeclared structured/FB variable."); |
436 return NULL; |
470 return NULL; |
437 } |
471 } |
438 |
472 |
439 /************************************/ |
473 /************************************/ |
440 /* B 1.5 Program organization units */ |
474 /* B 1.5 Program organization units */ |
536 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
570 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
537 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
571 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
538 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
572 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
539 }; |
573 }; |
540 |
574 |
|
575 /* TODO: check what error message (if any) the compiler will give out if this function invocation |
|
576 * is not preceded by a LD operator (or another equivalent operator or list of operators). |
|
577 * I.e. if it is preceded by an operator or operator list that will set the 'current value'. |
|
578 * I.e. if the prev_il_operand == NULL; |
|
579 */ |
541 handle_function_invocation(symbol, fcall_param); |
580 handle_function_invocation(symbol, fcall_param); |
542 |
581 |
543 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
582 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
544 * In order to be able to handle this without coding special cases, we will simply prepend that symbol |
583 * In order to be able to handle this without coding special cases, we simply prepend that symbol |
545 * to the il_operand_list. This is done in fill_candidate_datatypes_c. |
584 * to the il_operand_list. This was done in fill_candidate_datatypes_c. |
546 * We now undo those changes! |
585 * We now undo those changes! |
547 */ |
586 */ |
548 ((list_c *)symbol->il_operand_list)->remove_element(0); |
587 ((list_c *)symbol->il_operand_list)->remove_element(0); |
549 if (((list_c *)symbol->il_operand_list)->n == 0) { |
588 if (((list_c *)symbol->il_operand_list)->n == 0) { |
550 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
589 /* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */ |
660 prev_il_instruction = symbol; |
699 prev_il_instruction = symbol; |
661 return NULL; |
700 return NULL; |
662 } |
701 } |
663 |
702 |
664 void *print_datatypes_error_c::visit(S_operator_c *symbol) { |
703 void *print_datatypes_error_c::visit(S_operator_c *symbol) { |
|
704 /* TODO: what if this is a FB call ?? */ |
665 il_operand->accept(*this); |
705 il_operand->accept(*this); |
666 if ((symbol->candidate_datatypes.size() == 0) && |
706 if ((symbol->candidate_datatypes.size() == 0) && |
667 (il_operand->candidate_datatypes.size() > 0)) |
707 (il_operand->candidate_datatypes.size() > 0)) |
668 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S' operator."); |
708 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S' operator."); |
669 prev_il_instruction = symbol; |
709 prev_il_instruction = symbol; |
670 return NULL; |
710 return NULL; |
671 } |
711 } |
672 |
712 |
673 void *print_datatypes_error_c::visit(R_operator_c *symbol) { |
713 void *print_datatypes_error_c::visit(R_operator_c *symbol) { |
|
714 /* TODO: what if this is a FB call ?? */ |
674 il_operand->accept(*this); |
715 il_operand->accept(*this); |
675 if ((symbol->candidate_datatypes.size() == 0) && |
716 if ((symbol->candidate_datatypes.size() == 0) && |
676 (il_operand->candidate_datatypes.size() > 0)) |
717 (il_operand->candidate_datatypes.size() > 0)) |
677 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R' operator."); |
718 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R' operator."); |
678 prev_il_instruction = symbol; |
719 prev_il_instruction = symbol; |
679 return NULL; |
720 return NULL; |
680 } |
721 } |
681 |
722 |
682 void *print_datatypes_error_c::visit(S1_operator_c *symbol) { |
723 void *print_datatypes_error_c::visit(S1_operator_c *symbol) { |
683 il_operand->accept(*this); |
724 handle_implicit_il_fb_invocation(symbol, "S1", symbol->called_fb_declaration); |
684 if ((symbol->candidate_datatypes.size() == 0) && |
|
685 (il_operand->candidate_datatypes.size() > 0)) |
|
686 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S1' operator."); |
|
687 prev_il_instruction = symbol; |
|
688 return NULL; |
725 return NULL; |
689 } |
726 } |
690 |
727 |
691 void *print_datatypes_error_c::visit(R1_operator_c *symbol) { |
728 void *print_datatypes_error_c::visit(R1_operator_c *symbol) { |
692 il_operand->accept(*this); |
729 handle_implicit_il_fb_invocation(symbol, "R1", symbol->called_fb_declaration); |
693 if ((symbol->candidate_datatypes.size() == 0) && |
|
694 (il_operand->candidate_datatypes.size() > 0)) |
|
695 STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R1' operator."); |
|
696 prev_il_instruction = symbol; |
|
697 return NULL; |
730 return NULL; |
698 } |
731 } |
699 |
732 |
700 void *print_datatypes_error_c::visit(CLK_operator_c *symbol) { |
733 void *print_datatypes_error_c::visit(CLK_operator_c *symbol) { |
701 prev_il_instruction = symbol; |
734 handle_implicit_il_fb_invocation(symbol, "CLK", symbol->called_fb_declaration); |
702 return NULL; |
735 return NULL; |
703 } |
736 } |
704 |
737 |
705 void *print_datatypes_error_c::visit(CU_operator_c *symbol) { |
738 void *print_datatypes_error_c::visit(CU_operator_c *symbol) { |
706 prev_il_instruction = symbol; |
739 handle_implicit_il_fb_invocation(symbol, "CU", symbol->called_fb_declaration); |
707 return NULL; |
740 return NULL; |
708 } |
741 } |
709 |
742 |
710 void *print_datatypes_error_c::visit(CD_operator_c *symbol) { |
743 void *print_datatypes_error_c::visit(CD_operator_c *symbol) { |
711 prev_il_instruction = symbol; |
744 handle_implicit_il_fb_invocation(symbol, "CD", symbol->called_fb_declaration); |
712 return NULL; |
745 return NULL; |
713 } |
746 } |
714 |
747 |
715 void *print_datatypes_error_c::visit(PV_operator_c *symbol) { |
748 void *print_datatypes_error_c::visit(PV_operator_c *symbol) { |
716 prev_il_instruction = symbol; |
749 handle_implicit_il_fb_invocation(symbol, "PV", symbol->called_fb_declaration); |
717 return NULL; |
750 return NULL; |
718 } |
751 } |
719 |
752 |
720 void *print_datatypes_error_c::visit(IN_operator_c *symbol) { |
753 void *print_datatypes_error_c::visit(IN_operator_c *symbol) { |
721 prev_il_instruction = symbol; |
754 handle_implicit_il_fb_invocation(symbol, "IN", symbol->called_fb_declaration); |
722 return NULL; |
755 return NULL; |
723 } |
756 } |
724 |
757 |
725 void *print_datatypes_error_c::visit(PT_operator_c *symbol) { |
758 void *print_datatypes_error_c::visit(PT_operator_c *symbol) { |
726 prev_il_instruction = symbol; |
759 handle_implicit_il_fb_invocation(symbol, "PT", symbol->called_fb_declaration); |
727 return NULL; |
760 return NULL; |
728 } |
761 } |
729 |
762 |
730 void *print_datatypes_error_c::visit(AND_operator_c *symbol) { |
763 void *print_datatypes_error_c::visit(AND_operator_c *symbol) { |
731 il_operand->accept(*this); |
764 il_operand->accept(*this); |