71 * All parameters being passed to the called function MUST be in the parameter list to which f_call points to! |
71 * All parameters being passed to the called function MUST be in the parameter list to which f_call points to! |
72 * This means that, for non formal function calls in IL, de current (default value) must be artificially added to the |
72 * This means that, for non formal function calls in IL, de current (default value) must be artificially added to the |
73 * beginning of the parameter list BEFORE calling handle_function_call(). |
73 * beginning of the parameter list BEFORE calling handle_function_call(). |
74 */ |
74 */ |
75 bool fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl) { |
75 bool fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl) { |
76 symbol_c *call_param_value, *param_type; |
76 symbol_c *call_param_value, *param_datatype; |
77 identifier_c *param_name; |
77 identifier_c *param_name; |
78 function_param_iterator_c fp_iterator(f_decl); |
78 function_param_iterator_c fp_iterator(f_decl); |
79 function_call_param_iterator_c fcp_iterator(f_call); |
79 function_call_param_iterator_c fcp_iterator(f_call); |
80 int extensible_parameter_highest_index = -1; |
80 int extensible_parameter_highest_index = -1; |
81 unsigned int i; |
81 unsigned int i; |
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 /* Get the parameter type */ |
94 /* Get the parameter type */ |
95 param_type = base_type(fp_iterator.param_type()); |
95 param_datatype = base_type(fp_iterator.param_type()); |
96 |
96 |
97 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
97 /* 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_type, call_param_value->candidate_datatypes) < 0) |
98 if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0) |
99 return false; /* return false if param_type not in the list! */ |
99 return false; /* return false if param_type not in the list! */ |
100 } |
100 } |
101 /* call is compatible! */ |
101 /* call is compatible! */ |
102 return true; |
102 return true; |
103 } |
103 } |
105 |
105 |
106 |
106 |
107 /* returns true if compatible function/FB invocation, otherwise returns false */ |
107 /* 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 */ |
108 /* 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) { |
109 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl) { |
110 symbol_c *call_param_value, *call_param_name, *param_type; |
110 symbol_c *call_param_value, *call_param_name, *param_datatype; |
111 symbol_c *verify_duplicate_param; |
111 symbol_c *verify_duplicate_param; |
112 identifier_c *param_name; |
112 identifier_c *param_name; |
113 function_param_iterator_c fp_iterator(f_decl); |
113 function_param_iterator_c fp_iterator(f_decl); |
114 function_call_param_iterator_c fcp_iterator(f_call); |
114 function_call_param_iterator_c fcp_iterator(f_call); |
115 int extensible_parameter_highest_index = -1; |
115 int extensible_parameter_highest_index = -1; |
116 identifier_c *extensible_parameter_name; |
116 identifier_c *extensible_parameter_name; |
117 unsigned int i; |
117 unsigned int i; |
118 |
118 |
119 /* Iterating through the formal parameters of the function call */ |
119 /* Iterating through the formal parameters of the function call */ |
120 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
120 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
121 /* TODO: check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */ |
|
122 /* Obtaining the value being passed in the function call */ |
121 /* Obtaining the value being passed in the function call */ |
123 call_param_value = fcp_iterator.get_current_value(); |
122 call_param_value = fcp_iterator.get_current_value(); |
124 /* the following should never occur. If it does, then we have a bug in our code... */ |
123 /* the following should never occur. If it does, then we have a bug in our code... */ |
125 if (NULL == call_param_value) ERROR; |
124 if (NULL == call_param_value) ERROR; |
126 |
125 |
|
126 /* Obtaining the assignment direction: := (assign_in) or => (assign_out) */ |
|
127 function_call_param_iterator_c::assign_direction_t call_param_dir = fcp_iterator.get_assign_direction(); |
|
128 |
127 /* Checking if there are duplicated parameter values */ |
129 /* Checking if there are duplicated parameter values */ |
128 verify_duplicate_param = fcp_iterator.search_f(call_param_name); |
130 verify_duplicate_param = fcp_iterator.search_f(call_param_name); |
129 if(verify_duplicate_param != call_param_value) |
131 if(verify_duplicate_param != call_param_value) |
130 return false; |
132 return false; |
131 |
133 |
133 std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes; |
135 std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes; |
134 |
136 |
135 /* Find the corresponding parameter in function declaration */ |
137 /* Find the corresponding parameter in function declaration */ |
136 param_name = fp_iterator.search(call_param_name); |
138 param_name = fp_iterator.search(call_param_name); |
137 if(param_name == NULL) return false; |
139 if(param_name == NULL) return false; |
138 /* Get the parameter type */ |
140 /* Get the parameter data type */ |
139 param_type = base_type(fp_iterator.param_type()); |
141 param_datatype = base_type(fp_iterator.param_type()); |
|
142 /* Get the parameter direction: IN, OUT, IN_OUT */ |
|
143 function_param_iterator_c::param_direction_t param_dir = fp_iterator.param_direction(); |
|
144 |
|
145 /* check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */ |
|
146 if (function_call_param_iterator_c::assign_in == call_param_dir) { |
|
147 if ((function_param_iterator_c::direction_in != param_dir) && |
|
148 (function_param_iterator_c::direction_inout != param_dir)) |
|
149 return false; |
|
150 } else if (function_call_param_iterator_c::assign_out == call_param_dir) { |
|
151 if ((function_param_iterator_c::direction_out != param_dir)) |
|
152 return false; |
|
153 } else ERROR; |
|
154 |
140 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
155 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
141 if (search_in_candidate_datatype_list(param_type, call_param_types) < 0) |
156 if (search_in_candidate_datatype_list(param_datatype, call_param_types) < 0) |
142 return false; /* return false if param_type not in the list! */ |
157 return false; /* return false if param_type not in the list! */ |
143 } |
158 } |
144 /* call is compatible! */ |
159 /* call is compatible! */ |
145 return true; |
160 return true; |
146 } |
161 } |