106 */ |
106 */ |
107 void print_datatypes_error_c::handle_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) { |
107 void print_datatypes_error_c::handle_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) { |
108 symbol_c *param_value, *param_name; |
108 symbol_c *param_value, *param_name; |
109 function_call_param_iterator_c fcp_iterator(fcall); |
109 function_call_param_iterator_c fcp_iterator(fcall); |
110 bool function_invocation_error = false; |
110 bool function_invocation_error = false; |
|
111 const char *POU_str = NULL; |
|
112 |
|
113 if (generic_function_call_t::POU_FB == fcall_data.POU_type) POU_str = "FB"; |
|
114 if (generic_function_call_t::POU_function == fcall_data.POU_type) POU_str = "function"; |
|
115 if (NULL == POU_str) ERROR; |
111 |
116 |
112 if ((NULL != fcall_data.formal_operand_list) && (NULL != fcall_data.nonformal_operand_list)) |
117 if ((NULL != fcall_data.formal_operand_list) && (NULL != fcall_data.nonformal_operand_list)) |
113 ERROR; |
118 ERROR; |
114 |
119 |
115 symbol_c *f_decl = fcall_data.called_function_declaration; |
120 symbol_c *f_decl = fcall_data.called_function_declaration; |
|
121 if ((NULL == f_decl) && (generic_function_call_t::POU_FB ==fcall_data.POU_type)) { |
|
122 /* Due to the way the syntax analysis is buit (i.e. stage 2), this should never occur. */ |
|
123 /* I.e., a FB invocation using an undefined FB variable is not possible in the current implementation of stage 2. */ |
|
124 ERROR; |
|
125 } |
116 if (NULL == f_decl) { |
126 if (NULL == f_decl) { |
117 STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded function '%s' is being invoked.", ((identifier_c *)fcall_data.function_name)->value); |
127 STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value); |
118 /* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */ |
128 /* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */ |
119 function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name); |
129 function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name); |
120 if (lower == function_symtable.end()) ERROR; |
130 if (lower == function_symtable.end()) ERROR; |
121 f_decl = function_symtable.get_value(lower); |
131 f_decl = function_symtable.get_value(lower); |
122 } |
132 } |
127 function_param_iterator_c fp_iterator(f_decl); |
137 function_param_iterator_c fp_iterator(f_decl); |
128 while ((param_name = fcp_iterator.next_f()) != NULL) { |
138 while ((param_name = fcp_iterator.next_f()) != NULL) { |
129 param_value = fcp_iterator.get_current_value(); |
139 param_value = fcp_iterator.get_current_value(); |
130 /* Find the corresponding parameter in function declaration */ |
140 /* Find the corresponding parameter in function declaration */ |
131 if (NULL == fp_iterator.search(param_name)) { |
141 if (NULL == fp_iterator.search(param_name)) { |
132 STAGE3_ERROR(0, fcall, fcall, "Invalid parameter '%s' when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)fcall_data.function_name)->value); |
142 STAGE3_ERROR(0, fcall, fcall, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); |
133 } else if (NULL == param_value->datatype) { |
143 } else if (NULL == param_value->datatype) { |
134 function_invocation_error = true; |
144 function_invocation_error = true; |
135 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between parameter '%s' and value being passed, when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)fcall_data.function_name)->value); |
145 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); |
136 } |
146 } |
137 } |
147 } |
138 } |
148 } |
139 } |
149 } |
140 if (NULL != fcall_data.nonformal_operand_list) { |
150 if (NULL != fcall_data.nonformal_operand_list) { |
141 fcall_data.nonformal_operand_list->accept(*this); |
151 fcall_data.nonformal_operand_list->accept(*this); |
142 if (f_decl) |
152 if (f_decl) |
143 for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) { |
153 for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) { |
144 if (NULL == param_value->datatype) { |
154 if (NULL == param_value->datatype) { |
145 function_invocation_error = true; |
155 function_invocation_error = true; |
146 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed in position %d when invoking function '%s'", i, ((identifier_c *)fcall_data.function_name)->value); |
156 STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value); |
147 } |
157 } |
148 } |
158 } |
149 } |
159 } |
150 |
160 |
151 if (function_invocation_error) { |
161 if (function_invocation_error) { |
152 /* No compatible function exists */ |
162 /* No compatible function exists */ |
153 STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking function '%s'", ((identifier_c *)fcall_data.function_name)->value); |
163 STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value); |
154 } |
164 } |
155 |
165 |
156 return; |
166 return; |
157 } |
167 } |
158 |
168 |
517 /* | function_name [il_operand_list] */ |
527 /* | function_name [il_operand_list] */ |
518 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
528 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
519 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
529 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
520 void *print_datatypes_error_c::visit(il_function_call_c *symbol) { |
530 void *print_datatypes_error_c::visit(il_function_call_c *symbol) { |
521 generic_function_call_t fcall_param = { |
531 generic_function_call_t fcall_param = { |
522 /* fcall_param.function_name = */ symbol->function_name, |
532 /* fcall_param.function_name = */ symbol->function_name, |
523 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
533 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
524 /* fcall_param.formal_operand_list = */ NULL, |
534 /* fcall_param.formal_operand_list = */ NULL, |
525 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
535 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_function, |
526 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
536 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
527 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
537 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
538 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
528 }; |
539 }; |
529 |
540 |
530 handle_function_invocation(symbol, fcall_param); |
541 handle_function_invocation(symbol, fcall_param); |
531 |
542 |
532 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
543 /* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction) |
546 |
557 |
547 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
558 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
548 return NULL; |
559 return NULL; |
549 } |
560 } |
550 |
561 |
|
562 /* il_call_operator prev_declared_fb_name |
|
563 * | il_call_operator prev_declared_fb_name '(' ')' |
|
564 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
|
565 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
|
566 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
|
567 */ |
|
568 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
|
569 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
551 void *print_datatypes_error_c::visit(il_fb_call_c *symbol) { |
570 void *print_datatypes_error_c::visit(il_fb_call_c *symbol) { |
|
571 int extensible_param_count; /* unused vairable! Needed for compilation only! */ |
|
572 std::vector <symbol_c *> candidate_functions; /* unused vairable! Needed for compilation only! */ |
|
573 generic_function_call_t fcall_param = { |
|
574 /* fcall_param.function_name = */ symbol->fb_name, |
|
575 /* fcall_param.nonformal_operand_list = */ symbol->il_operand_list, |
|
576 /* fcall_param.formal_operand_list = */ symbol->il_param_list, |
|
577 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_FB, |
|
578 /* fcall_param.candidate_functions = */ candidate_functions, /* will not be used, but must provide a reference to be able to compile */ |
|
579 /* fcall_param.called_function_declaration = */ symbol->called_fb_declaration, |
|
580 /* fcall_param.extensible_param_count = */ extensible_param_count /* will not be used, but must provide a reference to be able to compile */ |
|
581 }; |
|
582 |
|
583 handle_function_invocation(symbol, fcall_param); |
552 return NULL; |
584 return NULL; |
553 } |
585 } |
554 |
586 |
555 /* | function_name '(' eol_list [il_param_list] ')' */ |
587 /* | function_name '(' eol_list [il_param_list] ')' */ |
556 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
588 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
557 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
589 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
558 void *print_datatypes_error_c::visit(il_formal_funct_call_c *symbol) { |
590 void *print_datatypes_error_c::visit(il_formal_funct_call_c *symbol) { |
559 generic_function_call_t fcall_param = { |
591 generic_function_call_t fcall_param = { |
560 /* fcall_param.function_name = */ symbol->function_name, |
592 /* fcall_param.function_name = */ symbol->function_name, |
561 /* fcall_param.nonformal_operand_list = */ NULL, |
593 /* fcall_param.nonformal_operand_list = */ NULL, |
562 /* fcall_param.formal_operand_list = */ symbol->il_param_list, |
594 /* fcall_param.formal_operand_list = */ symbol->il_param_list, |
563 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
595 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_function, |
564 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
596 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
565 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
597 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
|
598 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
566 }; |
599 }; |
567 |
600 |
568 handle_function_invocation(symbol, fcall_param); |
601 handle_function_invocation(symbol, fcall_param); |
569 return NULL; |
602 return NULL; |
570 } |
603 } |
1060 (symbol->exp->candidate_datatypes.size() > 0)) |
1093 (symbol->exp->candidate_datatypes.size() > 0)) |
1061 STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'NOT' expression."); |
1094 STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'NOT' expression."); |
1062 return NULL; |
1095 return NULL; |
1063 } |
1096 } |
1064 |
1097 |
1065 |
1098 /* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4. */ |
|
1099 /* formal_param_list -> may be NULL ! */ |
|
1100 /* nonformal_param_list -> may be NULL ! */ |
|
1101 // SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;) |
1066 void *print_datatypes_error_c::visit(function_invocation_c *symbol) { |
1102 void *print_datatypes_error_c::visit(function_invocation_c *symbol) { |
1067 symbol_c *param_value, *param_name; |
1103 generic_function_call_t fcall_param = { |
1068 function_call_param_iterator_c fcp_iterator(symbol); |
1104 /* fcall_param.function_name = */ symbol->function_name, |
1069 bool function_invocation_error = false; |
1105 /* fcall_param.nonformal_operand_list = */ symbol->nonformal_param_list, |
1070 |
1106 /* fcall_param.formal_operand_list = */ symbol->formal_param_list, |
1071 if ((NULL != symbol->formal_param_list) && (NULL != symbol->nonformal_param_list)) |
1107 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_function, |
1072 ERROR; |
1108 /* fcall_param.candidate_functions = */ symbol->candidate_functions, |
1073 |
1109 /* fcall_param.called_function_declaration = */ symbol->called_function_declaration, |
1074 symbol_c *f_decl = symbol->called_function_declaration; |
1110 /* fcall_param.extensible_param_count = */ symbol->extensible_param_count |
1075 if (NULL == f_decl) { |
1111 }; |
1076 STAGE3_ERROR(0, symbol, symbol, "Unable to resolve which overloaded function '%s' is being invoked.", ((identifier_c *)symbol->function_name)->value); |
1112 |
1077 /* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */ |
1113 handle_function_invocation(symbol, fcall_param); |
1078 function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); |
1114 return NULL; |
1079 if (lower == function_symtable.end()) ERROR; |
1115 } |
1080 f_decl = function_symtable.get_value(lower); |
1116 |
1081 } |
1117 |
1082 |
|
1083 if (NULL != symbol->formal_param_list) { |
|
1084 symbol->formal_param_list->accept(*this); |
|
1085 if (NULL != f_decl) { |
|
1086 function_param_iterator_c fp_iterator(f_decl); |
|
1087 while ((param_name = fcp_iterator.next_f()) != NULL) { |
|
1088 param_value = fcp_iterator.get_current_value(); |
|
1089 /* Find the corresponding parameter in function declaration */ |
|
1090 if (NULL == fp_iterator.search(param_name)) { |
|
1091 STAGE3_ERROR(0, symbol, symbol, "Invalid parameter '%s' when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)symbol->function_name)->value); |
|
1092 } else if (NULL == param_value->datatype) { |
|
1093 function_invocation_error = true; |
|
1094 STAGE3_ERROR(0, symbol, symbol, "Data type incompatibility between parameter '%s' and value being passed, when invoking function '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)symbol->function_name)->value); |
|
1095 } |
|
1096 } |
|
1097 } |
|
1098 } |
|
1099 if (NULL != symbol->nonformal_param_list) { |
|
1100 symbol->nonformal_param_list->accept(*this); |
|
1101 if (f_decl) |
|
1102 for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) { |
|
1103 if (NULL == param_value->datatype) { |
|
1104 function_invocation_error = true; |
|
1105 STAGE3_ERROR(0, symbol, symbol, "Data type incompatibility for value passed in position %d when invoking function '%s'", i, ((identifier_c *)symbol->function_name)->value); |
|
1106 } |
|
1107 } |
|
1108 } |
|
1109 |
|
1110 if (function_invocation_error) { |
|
1111 /* No compatible function exists */ |
|
1112 STAGE3_ERROR(2, symbol, symbol, "Invalid parameters when invoking function '%s'", ((identifier_c *)symbol->function_name)->value); |
|
1113 } |
|
1114 |
|
1115 return NULL; |
|
1116 } |
|
1117 |
1118 |
1118 /********************/ |
1119 /********************/ |
1119 /* B 3.2 Statements */ |
1120 /* B 3.2 Statements */ |
1120 /********************/ |
1121 /********************/ |
1121 |
1122 |
1141 /* formal_param_list -> may be NULL ! */ |
1142 /* formal_param_list -> may be NULL ! */ |
1142 /* nonformal_param_list -> may be NULL ! */ |
1143 /* nonformal_param_list -> may be NULL ! */ |
1143 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
1144 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
1144 // SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;) |
1145 // SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;) |
1145 void *print_datatypes_error_c::visit(fb_invocation_c *symbol) { |
1146 void *print_datatypes_error_c::visit(fb_invocation_c *symbol) { |
1146 symbol_c *param_value, *param_name; |
1147 int extensible_param_count; /* unused vairable! Needed for compilation only! */ |
1147 function_call_param_iterator_c fcp_iterator(symbol); |
1148 std::vector <symbol_c *> candidate_functions; /* unused vairable! Needed for compilation only! */ |
1148 bool function_invocation_error = false; |
1149 generic_function_call_t fcall_param = { |
1149 |
1150 /* fcall_param.function_name = */ symbol->fb_name, |
1150 if ((NULL != symbol->formal_param_list) && (NULL != symbol->nonformal_param_list)) |
1151 /* fcall_param.nonformal_operand_list = */ symbol->nonformal_param_list, |
1151 ERROR; |
1152 /* fcall_param.formal_operand_list = */ symbol->formal_param_list, |
1152 |
1153 /* enum {POU_FB, POU_function} POU_type = */ generic_function_call_t::POU_FB, |
1153 symbol_c *f_decl = symbol->called_fb_declaration; |
1154 /* fcall_param.candidate_functions = */ candidate_functions, /* will not be used, but must provide a reference to be able to compile */ |
1154 if (NULL == f_decl) { |
1155 /* fcall_param.called_function_declaration = */ symbol->called_fb_declaration, |
1155 /* Due to the way the syntax analysis is buit (i.e. stage 2), this should never occur. |
1156 /* fcall_param.extensible_param_count = */ extensible_param_count /* will not be used, but must provide a reference to be able to compile */ |
1156 * I.e., a FB invocation using an undefined FB variable is not possible in the current implementation of stage 2. |
1157 }; |
1157 */ |
1158 |
1158 ERROR; |
1159 handle_function_invocation(symbol, fcall_param); |
1159 // STAGE3_ERROR(0, symbol, symbol, "Undefined FB variable '%s'", ((identifier_c *)symbol->fb_name)->value); |
|
1160 } |
|
1161 |
|
1162 if (NULL != symbol->formal_param_list) { |
|
1163 symbol->formal_param_list->accept(*this); |
|
1164 function_param_iterator_c fp_iterator(f_decl); |
|
1165 while ((param_name = fcp_iterator.next_f()) != NULL) { |
|
1166 param_value = fcp_iterator.get_current_value(); |
|
1167 /* Find the corresponding parameter in function declaration */ |
|
1168 if (NULL == fp_iterator.search(param_name)) { |
|
1169 STAGE3_ERROR(0, symbol, symbol, "Invalid parameter '%s' when invoking FB '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)symbol->fb_name)->value); |
|
1170 } else if (NULL == param_value->datatype) { |
|
1171 function_invocation_error = true; |
|
1172 STAGE3_ERROR(0, symbol, symbol, "Data type incompatibility between parameter '%s' and value being passed, when invoking FB '%s'", ((identifier_c *)param_name)->value, ((identifier_c *)symbol->fb_name)->value); |
|
1173 } |
|
1174 } |
|
1175 } |
|
1176 if (NULL != symbol->nonformal_param_list) { |
|
1177 symbol->nonformal_param_list->accept(*this); |
|
1178 for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) { |
|
1179 if (NULL == param_value->datatype) { |
|
1180 function_invocation_error = true; |
|
1181 STAGE3_ERROR(0, symbol, symbol, "Invalid parameter (position %d) in FB invocation: %s", i, ((identifier_c *)symbol->fb_name)->value); |
|
1182 } |
|
1183 } |
|
1184 } |
|
1185 |
|
1186 if (function_invocation_error) { |
|
1187 /* Invalid parameters for FB call! */ |
|
1188 STAGE3_ERROR(2, symbol, symbol, "Invalid parameters in FB invocation: %s", ((identifier_c *)symbol->fb_name)->value); |
|
1189 } |
|
1190 |
|
1191 return NULL; |
1160 return NULL; |
1192 } |
1161 } |
1193 |
1162 |
1194 |
1163 |
1195 /********************************/ |
1164 /********************************/ |