stage3/print_datatypes_error.cc
changeset 455 933c0dccc82f
parent 454 099aa5d655de
child 457 67d8b07bac22
equal deleted inserted replaced
454:099aa5d655de 455:933c0dccc82f
   181 	}
   181 	}
   182 	if (NULL != fcall_data.nonformal_operand_list) {
   182 	if (NULL != fcall_data.nonformal_operand_list) {
   183 		fcall_data.nonformal_operand_list->accept(*this);
   183 		fcall_data.nonformal_operand_list->accept(*this);
   184 		if (f_decl)
   184 		if (f_decl)
   185 			for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) {
   185 			for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) {
       
   186 		  		/* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */
       
   187 
   186 				if (NULL == param_value->datatype) {
   188 				if (NULL == param_value->datatype) {
   187 					function_invocation_error = true;
   189 					function_invocation_error = true;
   188 					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);
   190 					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);
   189 				}
   191 				}
   190 			}
   192 			}
   201 	} 
   203 	} 
   202 
   204 
   203 	return;
   205 	return;
   204 }
   206 }
   205 
   207 
       
   208 
       
   209 
   206 void print_datatypes_error_c::handle_implicit_il_fb_invocation(symbol_c *il_operator, const char *param_name, symbol_c *called_fb_declaration) {
   210 void print_datatypes_error_c::handle_implicit_il_fb_invocation(symbol_c *il_operator, const char *param_name, symbol_c *called_fb_declaration) {
   207 	if (NULL == il_operand) {
   211 	if (NULL == il_operand) {
   208 		STAGE3_ERROR(0, il_operator, il_operator, "Missing operand for FB call operator '%s'.", param_name);
   212 		STAGE3_ERROR(0, il_operator, il_operator, "Missing operand for FB call operator '%s'.", param_name);
   209 		return;
   213 		return;
   210 	}
   214 	}
       
   215 	il_operand->accept(*this);
       
   216 	
   211 	if (NULL == called_fb_declaration) {
   217 	if (NULL == called_fb_declaration) {
   212 		STAGE3_ERROR(0, il_operand, il_operand, "Operand of FB call operator '%s' is not a FB variable.", param_name);
   218 		STAGE3_ERROR(0, il_operator, il_operand, "Invalid FB call: operand is not a FB instance.");
   213 		return;
   219 		return;
   214 	}
   220 	}
       
   221 
   215 	if (NULL == prev_il_instruction) {
   222 	if (NULL == prev_il_instruction) {
   216 		STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);	
   223 		STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);	
   217 		return;
   224 		return;
   218 	}
   225 	}
       
   226 
   219 	/* Find the corresponding parameter in function declaration */
   227 	/* Find the corresponding parameter in function declaration */
   220 	function_param_iterator_c fp_iterator(called_fb_declaration);
   228 	function_param_iterator_c fp_iterator(called_fb_declaration);
   221 	if (NULL == fp_iterator.search(param_name)) {
   229 	if (NULL == fp_iterator.search(param_name)) {
   222 /* TODO: must also check whther it is an IN parameter!! */
   230 		/* TODO: must also check whther it is an IN parameter!! */
       
   231 		/* NOTE: although all standard FBs have the implicit FB calls defined as input parameters
       
   232 		*        (i.e., for all standard FBs, CLK, PT, IN, CU, CD, S1, R1, etc... is always an input parameter)
       
   233 		*        if a non-standard (i.e. a FB not defined in the standard library) FB is being called, then
       
   234 		*        this (CLK, PT, IN, CU, ...) parameter may just have been defined as OUT or INOUT,
       
   235 		*        which will not work for an implicit FB call!
       
   236 		*/
   223 		STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);	
   237 		STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);	
   224 		return;
   238 		return;
   225 	}
   239 	}
   226 	if (NULL == prev_il_instruction->datatype) {
   240 	if (NULL == prev_il_instruction->datatype) {
   227 		STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed, when invoking FB.", param_name);
   241 		STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name);
   228 		return;
   242 		return;
   229 	}
   243 	}
   230 
   244 	
       
   245 
       
   246 	/* NOTE: The error_level currently being used for errors in variables/constants etc... is rather high.
       
   247 	 *       However, in the case of an implicit FB call, if the datatype of the operand == NULL, this may be
       
   248 	 *       the __only__ indication of an error! So we test it here again, to make sure thtis error will really
       
   249 	 *       be printed out!
       
   250 	 */
       
   251 	if (NULL == il_operand->datatype) {
       
   252 		/* Note: the case of (NULL == fb_declaration) was already caught above! */
       
   253 // 		if (NULL != fb_declaration) {
       
   254 			STAGE3_ERROR(0, il_operator, il_operator, "Invalid FB call: Datatype incompatibility between the FB's '%s' parameter and value being passed, or paramater '%s' is not a 'VAR_INPUT' parameter.", param_name, param_name);
       
   255 			return;
       
   256 // 		}
       
   257 	}
       
   258 // 
   231 	return;
   259 	return;
   232 }
   260 }
   233 
   261 
   234 
   262 
   235 /*********************/
   263 /*********************/
   550 
   578 
   551 /********************************/
   579 /********************************/
   552 /* B 1.7 Configuration elements */
   580 /* B 1.7 Configuration elements */
   553 /********************************/
   581 /********************************/
   554 void *print_datatypes_error_c::visit(configuration_declaration_c *symbol) {
   582 void *print_datatypes_error_c::visit(configuration_declaration_c *symbol) {
   555 #if 0
       
   556 	// TODO !!!
   583 	// TODO !!!
   557 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
   584 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
   558 #endif
       
   559 	return NULL;
   585 	return NULL;
   560 }
   586 }
   561 
   587 
   562 /****************************************/
   588 /****************************************/
   563 /* B.2 - Language IL (Instruction List) */
   589 /* B.2 - Language IL (Instruction List) */
   679 		/* fcall_param.called_function_declaration = */ symbol->called_fb_declaration,
   705 		/* fcall_param.called_function_declaration = */ symbol->called_fb_declaration,
   680 		/* fcall_param.extensible_param_count      = */ extensible_param_count           /* will not be used, but must provide a reference to be able to compile */
   706 		/* fcall_param.extensible_param_count      = */ extensible_param_count           /* will not be used, but must provide a reference to be able to compile */
   681 	};
   707 	};
   682   
   708   
   683 	handle_function_invocation(symbol, fcall_param);
   709 	handle_function_invocation(symbol, fcall_param);
       
   710 	/* check the semantics of the CALC, CALCN operators! */
       
   711 	symbol->il_call_operator->accept(*this);
   684 	return NULL;
   712 	return NULL;
   685 }
   713 }
   686 
   714 
   687 /* | function_name '(' eol_list [il_param_list] ')' */
   715 /* | function_name '(' eol_list [il_param_list] ')' */
   688 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
   716 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
   920 
   948 
   921 void *print_datatypes_error_c::visit(CAL_operator_c *symbol) {
   949 void *print_datatypes_error_c::visit(CAL_operator_c *symbol) {
   922 	return NULL;
   950 	return NULL;
   923 }
   951 }
   924 
   952 
       
   953 
       
   954 void *print_datatypes_error_c::handle_conditional_flow_control_IL_instruction(symbol_c *symbol, const char *oper) {
       
   955 	if (NULL == symbol->datatype)
       
   956 		STAGE3_ERROR(0, symbol, symbol, "%s operator must be preceded by an IL instruction producing a BOOL value.", oper);
       
   957 	return NULL;
       
   958 }
       
   959 
   925 void *print_datatypes_error_c::visit(CALC_operator_c *symbol) {
   960 void *print_datatypes_error_c::visit(CALC_operator_c *symbol) {
   926 	return NULL;
   961 	return handle_conditional_flow_control_IL_instruction(symbol, "CALC");
   927 }
   962 }
   928 
   963 
   929 void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) {
   964 void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) {
   930 	return NULL;
   965 	return handle_conditional_flow_control_IL_instruction(symbol, "CALCN");
   931 }
   966 }
   932 
   967 
   933 void *print_datatypes_error_c::visit(RET_operator_c *symbol) {
   968 void *print_datatypes_error_c::visit(RET_operator_c *symbol) {
   934 	return NULL;
   969 	return NULL;
   935 }
   970 }
   936 
   971 
   937 void *print_datatypes_error_c::visit(RETC_operator_c *symbol) {
   972 void *print_datatypes_error_c::visit(RETC_operator_c *symbol) {
   938 	return NULL;
   973 	return handle_conditional_flow_control_IL_instruction(symbol, "RETC");
   939 }
   974 }
   940 
   975 
   941 void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) {
   976 void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) {
   942 	return NULL;
   977 	return handle_conditional_flow_control_IL_instruction(symbol, "RETCN");
   943 }
   978 }
   944 
   979 
   945 void *print_datatypes_error_c::visit(JMP_operator_c *symbol) {
   980 void *print_datatypes_error_c::visit(JMP_operator_c *symbol) {
   946 	return NULL;
   981 	return NULL;
   947 }
   982 }
   948 
   983 
   949 void *print_datatypes_error_c::visit(JMPC_operator_c *symbol) {
   984 void *print_datatypes_error_c::visit(JMPC_operator_c *symbol) {
   950 	return NULL;
   985 	return handle_conditional_flow_control_IL_instruction(symbol, "JMPC");
   951 }
   986 }
   952 
   987 
   953 void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) {
   988 void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) {
   954 	return NULL;
   989 	return handle_conditional_flow_control_IL_instruction(symbol, "JMPCN");
   955 }
   990 }
   956 
   991 
   957 /* Symbol class handled together with function call checks */
   992 /* Symbol class handled together with function call checks */
   958 // void *visit(il_assign_operator_c *symbol, variable_name);
   993 // void *visit(il_assign_operator_c *symbol, variable_name);
   959 /* Symbol class handled together with function call checks */
   994 /* Symbol class handled together with function call checks */