stage3/print_datatypes_error.cc
changeset 441 e8de43eefcc5
parent 439 cf7d6862033d
child 443 ff4d26b7e51d
equal deleted inserted replaced
440:a745f7d38a5d 441:e8de43eefcc5
   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 /********************************/