89 param_name = fp_iterator.next(); |
89 param_name = fp_iterator.next(); |
90 /* If there is no other parameter declared, then we are passing too many parameters... */ |
90 /* If there is no other parameter declared, then we are passing too many parameters... */ |
91 if(param_name == NULL) return false; |
91 if(param_name == NULL) return false; |
92 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
92 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
93 |
93 |
|
94 /* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */ |
94 /* Get the parameter type */ |
95 /* Get the parameter type */ |
95 param_datatype = base_type(fp_iterator.param_type()); |
96 param_datatype = base_type(fp_iterator.param_type()); |
96 |
97 |
97 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
98 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
98 if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0) |
99 if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0) |
104 |
105 |
105 |
106 |
106 |
107 |
107 /* returns true if compatible function/FB invocation, otherwise returns false */ |
108 /* returns true if compatible function/FB invocation, otherwise returns false */ |
108 /* Assumes that the candidate_datatype lists of all the parameters being passed haved already been filled in */ |
109 /* Assumes that the candidate_datatype lists of all the parameters being passed haved already been filled in */ |
109 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl) { |
110 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl, symbol_c **first_param_datatype) { |
110 symbol_c *call_param_value, *call_param_name, *param_datatype; |
111 symbol_c *call_param_value, *call_param_name, *param_datatype; |
111 symbol_c *verify_duplicate_param; |
112 symbol_c *verify_duplicate_param; |
112 identifier_c *param_name; |
113 identifier_c *param_name; |
113 function_param_iterator_c fp_iterator(f_decl); |
114 function_param_iterator_c fp_iterator(f_decl); |
114 function_call_param_iterator_c fcp_iterator(f_call); |
115 function_call_param_iterator_c fcp_iterator(f_call); |
115 int extensible_parameter_highest_index = -1; |
116 int extensible_parameter_highest_index = -1; |
116 identifier_c *extensible_parameter_name; |
117 identifier_c *extensible_parameter_name; |
117 unsigned int i; |
118 unsigned int i; |
|
119 bool is_first_param = true; |
118 |
120 |
119 /* Iterating through the formal parameters of the function call */ |
121 /* Iterating through the formal parameters of the function call */ |
120 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
122 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
121 /* Obtaining the value being passed in the function call */ |
123 /* Obtaining the value being passed in the function call */ |
122 call_param_value = fcp_iterator.get_current_value(); |
124 call_param_value = fcp_iterator.get_current_value(); |
253 |
261 |
254 |
262 |
255 /* handle implicit FB call in IL. |
263 /* handle implicit FB call in IL. |
256 * e.g. CLK ton_var |
264 * e.g. CLK ton_var |
257 * CU counter_var |
265 * CU counter_var |
258 * |
|
259 * The algorithm will be to build a fake il_fb_call_c equivalent to the implicit IL FB call, and let |
|
260 * the visit(il_fb_call_c *) method handle it! |
|
261 */ |
266 */ |
262 void fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) { |
267 void fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) { |
263 if (NULL == il_operand) |
|
264 /* No FB to call was specified. There is nothing we can do... */ |
|
265 return; |
|
266 |
|
267 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand); |
268 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand); |
268 /* This is a call to a non-declared FB/Variable is a semantic error (which is currently caught by stage 2, so this should never occur) |
269 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
269 * or no operand was given (il_operand == NULL). In this case, we just give up! |
270 if (NULL == fb_type_id) ERROR; |
270 */ |
|
271 if (NULL == fb_type_id) |
|
272 return; |
|
273 |
271 |
274 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
272 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
275 if (function_block_type_symtable.end_value() == fb_decl) |
273 if (function_block_type_symtable.end_value() == fb_decl) |
276 /* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type. |
274 /* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type. |
277 * this is a smeantic error, so there is no way we can evaluate the rest of the code. We simply give up, and leave |
275 * this is a semantic error. |
278 * the candidate_datatype_list empty, and the called_fb_declaration pointing to NULL |
|
279 */ |
276 */ |
280 return; |
277 fb_decl = NULL; |
281 |
278 |
282 if (NULL == prev_il_instruction) { |
279 /* The narrow_candidate_datatypes_c does not rely on this called_fb_declaration pointer being == NULL to conclude that |
283 /* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction |
280 * we have a datatype incompatibility error, so we set it to fb_decl to allow the print_datatype_error_c to print out |
284 * (or list of instructions) that will set the IL current/default value. |
281 * more informative error messages! |
285 * We cannot proceed verifying type compatibility of something that does not ecist. |
|
286 */ |
|
287 return; |
|
288 } |
|
289 |
|
290 /* The value being passed to the 'param_name' parameter is actually the prev_il_instruction. |
|
291 * However, we do not place that object directly in the fake il_param_list_c that we will be |
|
292 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list. |
|
293 * The il_prev_intruction object has already been visited. We DO NOT want to visit it again. |
|
294 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object! |
|
295 */ |
282 */ |
296 symbol_c param_value = *prev_il_instruction; |
283 called_fb_declaration = fb_decl; |
297 |
284 |
298 identifier_c variable_name(param_name); |
285 /* This implicit FB call does not change the value stored in the current/default IL variable */ |
299 // SYM_REF1(il_assign_operator_c, variable_name) |
286 if (NULL != prev_il_instruction) |
300 il_assign_operator_c il_assign_operator(&variable_name); |
287 copy_candidate_datatype_list(prev_il_instruction/*from*/, il_instruction/*to*/); |
301 // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
288 |
302 il_param_assignment_c il_param_assignment(&il_assign_operator, ¶m_value/*il_operand*/, NULL); |
289 if (debug) std::cout << "handle_implicit_il_fb_call() [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << il_instruction->candidate_datatypes.size() << " result.\n"; |
303 il_param_list_c il_param_list; |
|
304 il_param_list.add_element(&il_param_assignment); |
|
305 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
|
306 il_fb_call_c il_fb_call(NULL, il_operand, NULL, &il_param_list); |
|
307 |
|
308 il_fb_call.accept(*this); |
|
309 copy_candidate_datatype_list(&il_fb_call/*from*/, il_instruction/*to*/); |
|
310 called_fb_declaration = il_fb_call.called_fb_declaration; |
|
311 } |
290 } |
312 |
291 |
313 |
292 |
314 /* a helper function... */ |
293 /* a helper function... */ |
315 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
294 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
721 |
700 |
722 |
701 |
723 /* subscript_list ',' subscript */ |
702 /* subscript_list ',' subscript */ |
724 // SYM_LIST(subscript_list_c) |
703 // SYM_LIST(subscript_list_c) |
725 /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */ |
704 /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */ |
726 #if 0 |
705 // void *fill_candidate_datatypes_c::visit(subscript_list_c *symbol) |
727 void *fill_candidate_datatypes_c::visit(subscript_list_c *symbol) { |
|
728 } |
|
729 #endif |
|
730 |
706 |
731 |
707 |
732 /* record_variable '.' field_selector */ |
708 /* record_variable '.' field_selector */ |
733 /* WARNING: input and/or output variables of function blocks |
709 /* WARNING: input and/or output variables of function blocks |
734 * may be accessed as fields of a structured variable! |
710 * may be accessed as fields of a structured variable! |
943 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
917 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
944 */ |
918 */ |
945 /* 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 */ |
919 /* 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 */ |
946 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
920 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
947 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
921 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
948 bool compatible = false; |
922 /* We do not call |
949 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
923 * fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
|
924 * because we want to make sure it is a FB instance, and not some other data type... |
|
925 */ |
|
926 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name); |
|
927 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
|
928 if (NULL == fb_type_id) ERROR; |
|
929 |
|
930 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
|
931 if (function_block_type_symtable.end_value() == fb_decl) |
|
932 /* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */ |
|
933 fb_decl = NULL; |
|
934 |
950 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
935 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
951 if (NULL == fb_decl) ERROR; |
936 if (NULL == fb_decl) ERROR; |
952 |
937 |
953 if (symbol-> il_param_list != NULL) { |
938 if (symbol-> il_param_list != NULL) symbol->il_param_list->accept(*this); |
954 symbol->il_param_list->accept(*this); |
939 if (symbol->il_operand_list != NULL) symbol->il_operand_list->accept(*this); |
955 compatible = match_formal_call(symbol, fb_decl); |
|
956 } |
|
957 if (symbol->il_operand_list != NULL) { |
|
958 symbol->il_operand_list->accept(*this); |
|
959 compatible = match_nonformal_call(symbol, fb_decl); |
|
960 } |
|
961 |
940 |
962 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |
941 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |
963 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe, |
942 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe, |
964 * as the compiler will never reach the compilation stage! |
943 * as the compiler will never reach the compilation stage! |
965 */ |
944 */ |
966 symbol->called_fb_declaration = fb_decl; |
945 symbol->called_fb_declaration = fb_decl; |
967 |
946 |
968 /* This object has the same candidate datatypes as the prev_il_instruction, since it does not change the value stored in the current/default IL variable. */ |
947 /* Let the il_call_operator (CAL, CALC, or CALCN) determine the candidate datatypes of the il_fb_call_c... */ |
969 copy_candidate_datatype_list(prev_il_instruction/*from*/, symbol/*to*/); |
948 /* NOTE: We ignore whether the call is 'compatible' or not when filling in the candidate datatypes list. |
|
949 * Even if it is not compatible, we fill in the candidate datatypes list correctly so that the following |
|
950 * IL instructions may be handled correctly and debuged. |
|
951 * Doing this is actually safe, as the parameter_list will still contain errors that will be found by |
|
952 * print_datatypes_error_c, so the code will never reach stage 4! |
|
953 */ |
|
954 symbol->il_call_operator->accept(*this); |
|
955 copy_candidate_datatype_list(symbol->il_call_operator/*from*/, symbol/*to*/); |
970 |
956 |
971 if (debug) std::cout << "FB [] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
957 if (debug) std::cout << "FB [] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
972 return NULL; |
958 return NULL; |
973 } |
959 } |
974 |
960 |
2000 |
1986 |
2001 /*****************************************/ |
1987 /*****************************************/ |
2002 /* B 3.2.2 Subprogram Control Statements */ |
1988 /* B 3.2.2 Subprogram Control Statements */ |
2003 /*****************************************/ |
1989 /*****************************************/ |
2004 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
1990 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
2005 bool compatible = false; |
1991 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name); |
2006 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1992 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
|
1993 if (NULL == fb_type_id) ERROR; |
|
1994 |
|
1995 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
|
1996 if (function_block_type_symtable.end_value() == fb_decl) |
|
1997 /* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */ |
|
1998 fb_decl = NULL; |
|
1999 |
2007 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
2000 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
2008 if (NULL == fb_decl) ERROR; |
2001 if (NULL == fb_decl) ERROR; |
2009 |
2002 |
2010 if (symbol-> formal_param_list != NULL) { |
2003 if (symbol-> formal_param_list != NULL) symbol->formal_param_list->accept(*this); |
2011 symbol->formal_param_list->accept(*this); |
2004 if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this); |
2012 compatible = match_formal_call(symbol, fb_decl); |
|
2013 } |
|
2014 if (symbol->nonformal_param_list != NULL) { |
|
2015 symbol->nonformal_param_list->accept(*this); |
|
2016 compatible = match_nonformal_call(symbol, fb_decl); |
|
2017 } |
|
2018 |
2005 |
2019 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |
2006 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |
2020 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe, |
2007 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe, |
2021 * as the compiler will never reach the compilation stage! |
2008 * as the compiler will never reach the compilation stage! |
2022 */ |
2009 */ |