stage3/print_datatypes_error.cc
changeset 958 7474d2cd1d6e
parent 936 0f7bcc160568
child 995 ce997a27c516
equal deleted inserted replaced
957:4489afa5b1c5 958:7474d2cd1d6e
   162 				param_value = fcp_iterator.get_current_value();
   162 				param_value = fcp_iterator.get_current_value();
   163 				
   163 				
   164 				/* Check if there are duplicate parameter values */
   164 				/* Check if there are duplicate parameter values */
   165 				if(fcp_iterator.search_f(param_name) != param_value) {
   165 				if(fcp_iterator.search_f(param_name) != param_value) {
   166 					function_invocation_error = true;
   166 					function_invocation_error = true;
   167 					STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   167 					STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value);
   168 					continue; /* jump to next parameter */
   168 					continue; /* jump to next parameter */
   169 				}
   169 				}
   170 
   170 
   171 				/* Find the corresponding parameter in function declaration */
   171 				/* Find the corresponding parameter in function declaration */
   172 				if (NULL == fp_iterator.search(param_name)) {
   172 				if (NULL == fp_iterator.search(param_name)) {
   173 					function_invocation_error = true;
   173 					function_invocation_error = true;
   174 					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);
   174 					STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value);
   175 					continue; /* jump to next parameter */
   175 					continue; /* jump to next parameter */
   176 				} 
   176 				} 
   177 
   177 
   178 				/* check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */
   178 				/* check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */
   179 				/* Obtaining the assignment direction:  := (assign_in) or => (assign_out) */
   179 				/* Obtaining the assignment direction:  := (assign_in) or => (assign_out) */
   182 				function_param_iterator_c::param_direction_t param_dir = fp_iterator.param_direction();
   182 				function_param_iterator_c::param_direction_t param_dir = fp_iterator.param_direction();
   183 				if          (function_call_param_iterator_c::assign_in  == call_param_dir) {
   183 				if          (function_call_param_iterator_c::assign_in  == call_param_dir) {
   184 					if ((function_param_iterator_c::direction_in    != param_dir) &&
   184 					if ((function_param_iterator_c::direction_in    != param_dir) &&
   185 					    (function_param_iterator_c::direction_inout != param_dir)) {
   185 					    (function_param_iterator_c::direction_inout != param_dir)) {
   186 						function_invocation_error = true;
   186 						function_invocation_error = true;
   187 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   187 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value);
   188 						continue; /* jump to next parameter */
   188 						continue; /* jump to next parameter */
   189 					}
   189 					}
   190 				} else if   (function_call_param_iterator_c::assign_out == call_param_dir) {
   190 				} else if   (function_call_param_iterator_c::assign_out == call_param_dir) {
   191 					if ((function_param_iterator_c::direction_out   != param_dir)) {
   191 					if ((function_param_iterator_c::direction_out   != param_dir)) {
   192 						function_invocation_error = true;
   192 						function_invocation_error = true;
   193 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   193 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value);
   194 						continue; /* jump to next parameter */
   194 						continue; /* jump to next parameter */
   195 					}
   195 					}
   196 				} else ERROR;
   196 				} else ERROR;
   197 
   197 
   198 				if (!get_datatype_info_c::is_type_valid(param_value->datatype)) {
   198 				if (!get_datatype_info_c::is_type_valid(param_value->datatype)) {
   199 					function_invocation_error = true;
   199 					function_invocation_error = true;
   200 					STAGE3_ERROR(0, param_value, param_value, "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);
   200 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value);
   201 					continue; /* jump to next parameter */
   201 					continue; /* jump to next parameter */
   202 				}
   202 				}
   203 			}
   203 			}
   204 		}
   204 		}
   205 	}
   205 	}
   221 					/* We are in a situation where an IL function call is passed the first parameter, which is actually the previous IL instruction */
   221 					/* We are in a situation where an IL function call is passed the first parameter, which is actually the previous IL instruction */
   222 					/* However, this is really a fake previous il instruction (see visit(il_instruction_c *) )
   222 					/* However, this is really a fake previous il instruction (see visit(il_instruction_c *) )
   223 					 * We will iterate through all the real previous IL instructions, and analyse each of them one by one */
   223 					 * We will iterate through all the real previous IL instructions, and analyse each of them one by one */
   224 					if (il_instruction_symbol->prev_il_instruction.size() == 0) {
   224 					if (il_instruction_symbol->prev_il_instruction.size() == 0) {
   225 						function_invocation_error = true;
   225 						function_invocation_error = true;
   226 						STAGE3_ERROR(0, fcall, fcall, "No available data to pass to first parameter of IL function %s. Missing a previous LD instruction?", ((identifier_c *)fcall_data.function_name)->value);
   226 						STAGE3_ERROR(0, fcall, fcall, "No available data to pass to first parameter of IL function %s. Missing a previous LD instruction?", ((token_c *)fcall_data.function_name)->value);
   227 					}
   227 					}
   228 #if 0
   228 #if 0
   229 					/* NOTE: We currently comment out this code...
   229 					/* NOTE: We currently comment out this code...
   230 					 * This does not currently work, since the narrow operation is currently done on the intersection 
   230 					 * This does not currently work, since the narrow operation is currently done on the intersection 
   231 					 * of all the previous IL instructions, so we currently either accept them all, or none at all.
   231 					 * of all the previous IL instructions, so we currently either accept them all, or none at all.
   235 					 */
   235 					 */
   236 					for (unsigned int p = 0; p < il_instruction_symbol->prev_il_instruction.size(); p++) {
   236 					for (unsigned int p = 0; p < il_instruction_symbol->prev_il_instruction.size(); p++) {
   237 						symbol_c *value = il_instruction_symbol->prev_il_instruction[p];  
   237 						symbol_c *value = il_instruction_symbol->prev_il_instruction[p];  
   238 						if (!get_datatype_info_c::is_type_valid(value->datatype)) {
   238 						if (!get_datatype_info_c::is_type_valid(value->datatype)) {
   239 							function_invocation_error = true;
   239 							function_invocation_error = true;
   240 							STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed to first parameter when invoking function '%s'", ((identifier_c *)fcall_data.function_name)->value);
   240 							STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed to first parameter when invoking function '%s'", ((token_c *)fcall_data.function_name)->value);
   241 							STAGE3_ERROR(0, value, value, "This is the IL instruction producing the incompatible data type to first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value);
   241 							STAGE3_ERROR(0, value, value, "This is the IL instruction producing the incompatible data type to first parameter of function '%s'", ((token_c *)fcall_data.function_name)->value);
   242 						}
   242 						}
   243 					}
   243 					}
   244 #else
   244 #else
   245 					if (!get_datatype_info_c::is_type_valid(il_instruction_symbol->datatype)) {
   245 					if (!get_datatype_info_c::is_type_valid(il_instruction_symbol->datatype)) {
   246 						function_invocation_error = true;
   246 						function_invocation_error = true;
   247 						STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between value in IL 'accumulator' and first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value);
   247 						STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between value in IL 'accumulator' and first parameter of function '%s'", ((token_c *)fcall_data.function_name)->value);
   248 					}
   248 					}
   249 #endif
   249 #endif
   250 					if (function_invocation_error)
   250 					if (function_invocation_error)
   251 						/* when handling a IL function call, and an error is found in the first parameter, then we bug out and do not print out any more error messages. */
   251 						/* when handling a IL function call, and an error is found in the first parameter, then we bug out and do not print out any more error messages. */
   252 						return;
   252 						return;
   253 				} else {
   253 				} else {
   254 					if (!get_datatype_info_c::is_type_valid(param_value->datatype)) {
   254 					if (!get_datatype_info_c::is_type_valid(param_value->datatype)) {
   255 						function_invocation_error = true;
   255 						function_invocation_error = true;
   256 						STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value);
   256 						STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((token_c *)fcall_data.function_name)->value);
   257 					}
   257 					}
   258 					param_value->accept(*this);
   258 					param_value->accept(*this);
   259 				}
   259 				}
   260 			}
   260 			}
   261 	}
   261 	}
   262 
   262 
   263 	if (NULL == fcall_data.called_function_declaration) {
   263 	if (NULL == fcall_data.called_function_declaration) {
   264 		function_invocation_error = true;
   264 		function_invocation_error = true;
   265 		STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value);
   265 		STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((token_c *)fcall_data.function_name)->value);
   266 	}
   266 	}
   267 
   267 
   268 	if (function_invocation_error) {
   268 	if (function_invocation_error) {
   269 		/* No compatible function exists */
   269 		/* No compatible function exists */
   270 		STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value);
   270 		STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((token_c *)fcall_data.function_name)->value);
   271 	} 
   271 	} 
   272 
   272 
   273 	return;
   273 	return;
   274 }
   274 }
   275 
   275