65 /* function defined in main.cc */ |
68 /* function defined in main.cc */ |
66 extern void error_exit(const char *file_name, int line_no); |
69 extern void error_exit(const char *file_name, int line_no); |
67 |
70 |
68 |
71 |
69 |
72 |
|
73 /* compare the name of two __extensible__ function parameters. |
|
74 * The usual use case is to have one of the parameters as used |
|
75 * in the function declaration, and another as used in a formal function call. |
|
76 * |
|
77 * Will return: |
|
78 * < 0 : if two parameters are not compatible, or one is invalid |
|
79 * >= 0 : if both parameters .......... |
|
80 */ |
|
81 /* |
|
82 * ("in", "i0") -> returns error (<0) |
|
83 * ("in1", "in") -> returns error (<0) |
|
84 * ("in", "in") -> returns error (<0) |
|
85 * ("in", "inw") -> returns error (<0) |
|
86 * ("in", "in10.4") -> returns error (<0) |
|
87 * ("in", "in10e") -> returns error (<0) |
|
88 * ("in", "") -> returns error (<0) |
|
89 * ("", "in10e") -> returns error (<0) |
|
90 * ("in", "in0") -> returns 0 |
|
91 * ("in", "in9") -> returns 9 |
|
92 * ("in", "in42") -> returns 42 |
|
93 * ("in", "in-42") -> returns -42 (error!) |
|
94 */ |
|
95 int function_param_iterator_c::cmp_extparam_names(const char* s1, const char* s2) { |
|
96 int res; |
|
97 char *endptr; |
|
98 int len; |
|
99 |
|
100 if ((s1 == NULL) || (s2 == NULL) || (*s1 == '\0') || (*s2 == '\0')) return -1; |
|
101 |
|
102 len = strlen(s1); |
|
103 if (strncasecmp(s1, s2, len)) return -2; |
|
104 |
|
105 s1 = &s2[len]; |
|
106 if (*s1 == '\0') return -3; |
|
107 |
|
108 res = strtol(s1, &endptr, 10); |
|
109 if (*endptr != '\0') return -4; |
|
110 |
|
111 return res; |
|
112 } |
|
113 |
|
114 |
|
115 |
70 void* function_param_iterator_c::handle_param_list(list_c *list) { |
116 void* function_param_iterator_c::handle_param_list(list_c *list) { |
71 switch (current_operation) { |
117 switch (current_operation) { |
72 case iterate_op: |
118 case iterate_op: |
73 if (next_param <= param_count + list->n) |
119 if (next_param <= param_count + list->n) |
74 return list->elements[next_param - param_count - 1]; |
120 return list->elements[next_param - param_count - 1]; |
77 param_count += list->n; |
123 param_count += list->n; |
78 break; |
124 break; |
79 |
125 |
80 case search_op: |
126 case search_op: |
81 for(int i = 0; i < list->n; i++) { |
127 for(int i = 0; i < list->n; i++) { |
82 identifier_c *variable_name = dynamic_cast<identifier_c *>(list->elements[i]); |
128 symbol_c *sym = list->elements[i]; |
|
129 extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym); |
|
130 if (extensible_parameter != NULL) { |
|
131 sym = extensible_parameter->var_name; |
|
132 current_param_is_extensible = true; |
|
133 _first_extensible_param_index = extract_integer(extensible_parameter->first_index); |
|
134 } |
|
135 identifier_c *variable_name = dynamic_cast<identifier_c *>(sym); |
83 if (variable_name == NULL) ERROR; |
136 if (variable_name == NULL) ERROR; |
84 |
137 |
85 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
138 if (!current_param_is_extensible) |
86 /* FOUND! This is the same parameter!! */ |
139 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
87 return (void *)variable_name; |
140 /* FOUND! This is the same parameter!! */ |
|
141 return (void *)variable_name; |
|
142 |
|
143 if (current_param_is_extensible) { |
|
144 current_extensible_param_index = cmp_extparam_names(variable_name->value, search_param_name->value); |
|
145 if (current_extensible_param_index >= 0) |
|
146 /* FOUND! This is a compatible extensible parameter!! */ |
|
147 return (void *)variable_name; |
|
148 } |
88 } |
149 } |
89 break; |
150 break; |
90 } /* switch */ |
151 } /* switch */ |
91 |
152 |
92 /* Not found! */ |
153 /* Not found! */ |
100 if (next_param == param_count) |
161 if (next_param == param_count) |
101 return var_name; |
162 return var_name; |
102 break; |
163 break; |
103 |
164 |
104 case search_op: |
165 case search_op: |
|
166 extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(var_name); |
|
167 if (extensible_parameter != NULL) { |
|
168 var_name = extensible_parameter->var_name; |
|
169 current_param_is_extensible = true; |
|
170 _first_extensible_param_index = extract_integer(extensible_parameter->first_index); |
|
171 } |
105 identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name); |
172 identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name); |
106 if (variable_name == NULL) ERROR; |
173 if (variable_name == NULL) ERROR; |
107 |
174 |
108 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
175 if (!current_param_is_extensible) |
109 /* FOUND! This is the same parameter!! */ |
176 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
110 return (void *)variable_name; |
177 /* FOUND! This is the same parameter!! */ |
|
178 return (void *)variable_name; |
|
179 |
|
180 if (current_param_is_extensible) { |
|
181 current_extensible_param_index = cmp_extparam_names(variable_name->value, search_param_name->value); |
|
182 if (current_extensible_param_index >= 0) |
|
183 /* FOUND! This is a compatible extensible parameter!! */ |
|
184 return (void *)variable_name; |
|
185 } |
111 break; |
186 break; |
112 } /* switch */ |
187 } /* switch */ |
113 |
188 |
114 /* Not found! */ |
189 /* Not found! */ |
115 return NULL; |
190 return NULL; |
126 } |
201 } |
127 |
202 |
128 /* start off at the first parameter once again... */ |
203 /* start off at the first parameter once again... */ |
129 void function_param_iterator_c::reset(void) { |
204 void function_param_iterator_c::reset(void) { |
130 next_param = param_count = 0; |
205 next_param = param_count = 0; |
|
206 _first_extensible_param_index = -1; |
|
207 current_param_is_extensible = false; |
131 current_param_name = NULL; |
208 current_param_name = NULL; |
132 current_param_type = current_param_default_value = NULL; |
209 current_param_type = current_param_default_value = NULL; |
133 } |
210 } |
134 |
211 |
135 |
212 |
164 */ |
241 */ |
165 identifier_c *function_param_iterator_c::next(void) { |
242 identifier_c *function_param_iterator_c::next(void) { |
166 void *res; |
243 void *res; |
167 identifier_c *identifier; |
244 identifier_c *identifier; |
168 |
245 |
|
246 if (current_param_is_extensible) { |
|
247 current_extensible_param_index++; |
|
248 return current_param_name; |
|
249 } |
|
250 |
169 param_count = 0; |
251 param_count = 0; |
170 en_eno_param_implicit = false; |
252 en_eno_param_implicit = false; |
171 next_param++; |
253 next_param++; |
172 current_operation = function_param_iterator_c::iterate_op; |
254 current_operation = function_param_iterator_c::iterate_op; |
173 res = f_decl->accept(*this); |
255 res = f_decl->accept(*this); |
174 if (res == NULL) |
256 if (res == NULL) |
175 return NULL; |
257 return NULL; |
176 |
258 |
177 symbol_c *sym = (symbol_c *)res; |
259 symbol_c *sym = (symbol_c *)res; |
|
260 extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym); |
|
261 if (extensible_parameter != NULL) { |
|
262 sym = extensible_parameter->var_name; |
|
263 current_param_is_extensible = true; |
|
264 _first_extensible_param_index = extract_integer(extensible_parameter->first_index); |
|
265 current_extensible_param_index = _first_extensible_param_index; |
|
266 } |
178 identifier = dynamic_cast<identifier_c *>(sym); |
267 identifier = dynamic_cast<identifier_c *>(sym); |
179 if (identifier == NULL) |
268 if (identifier == NULL) |
180 ERROR; |
269 ERROR; |
181 current_param_name = identifier; |
270 current_param_name = identifier; |
182 return current_param_name; |
271 return current_param_name; |
185 /* Search for the value passed to the parameter named <param_name>... */ |
274 /* Search for the value passed to the parameter named <param_name>... */ |
186 identifier_c *function_param_iterator_c::search(symbol_c *param_name) { |
275 identifier_c *function_param_iterator_c::search(symbol_c *param_name) { |
187 if (NULL == param_name) ERROR; |
276 if (NULL == param_name) ERROR; |
188 search_param_name = dynamic_cast<identifier_c *>(param_name); |
277 search_param_name = dynamic_cast<identifier_c *>(param_name); |
189 if (NULL == search_param_name) ERROR; |
278 if (NULL == search_param_name) ERROR; |
|
279 en_eno_param_implicit = false; |
|
280 current_param_is_extensible = false; |
190 current_operation = function_param_iterator_c::search_op; |
281 current_operation = function_param_iterator_c::search_op; |
191 void *res = f_decl->accept(*this); |
282 void *res = f_decl->accept(*this); |
192 identifier_c *res_param_name = dynamic_cast<identifier_c *>((symbol_c *)res); |
283 identifier_c *res_param_name = dynamic_cast<identifier_c *>((symbol_c *)res); |
193 return res_param_name; |
284 return res_param_name; |
194 } |
285 } |
208 /* Returns if currently referenced parameter is an implicit defined EN/ENO parameter. */ |
299 /* Returns if currently referenced parameter is an implicit defined EN/ENO parameter. */ |
209 bool function_param_iterator_c::is_en_eno_param_implicit(void) { |
300 bool function_param_iterator_c::is_en_eno_param_implicit(void) { |
210 return en_eno_param_implicit; |
301 return en_eno_param_implicit; |
211 } |
302 } |
212 |
303 |
|
304 /* Returns if currently referenced parameter is an extensible parameter. */ |
|
305 /* extensible paramters only occur in some standard functions, e.g. AND(word#34, word#44, word#65); */ |
|
306 bool function_param_iterator_c::is_extensible_param(void) { |
|
307 return current_param_is_extensible; |
|
308 } |
|
309 |
|
310 /* Returns the index of the current extensible parameter. */ |
|
311 /* If the current parameter is not an extensible paramter, returns -1 */ |
|
312 int function_param_iterator_c::extensible_param_index(void) { |
|
313 return (current_param_is_extensible? current_extensible_param_index : -1); |
|
314 } |
|
315 |
|
316 /* Returns the index of the first extensible parameter, or -1 if no extensible parameter found. */ |
|
317 /* WARNING: Will only return the correct value _after_ an extensible parameter has been found! */ |
|
318 int function_param_iterator_c::first_extensible_param_index(void) { |
|
319 return _first_extensible_param_index; |
|
320 } |
|
321 |
213 /* Returns the currently referenced parameter's data passing direction. |
322 /* Returns the currently referenced parameter's data passing direction. |
214 * i.e. VAR_INPUT, VAR_OUTPUT or VAR_INOUT |
323 * i.e. VAR_INPUT, VAR_OUTPUT or VAR_INOUT |
215 */ |
324 */ |
216 function_param_iterator_c::param_direction_t function_param_iterator_c::param_direction(void) { |
325 function_param_iterator_c::param_direction_t function_param_iterator_c::param_direction(void) { |
217 return current_param_direction; |
326 return current_param_direction; |
218 } |
327 } |
219 |
328 |
220 void *function_param_iterator_c::visit(implicit_definition_c *symbol) { |
329 void *function_param_iterator_c::visit(implicit_definition_c *symbol) { |
221 en_eno_param_implicit = current_operation == function_param_iterator_c::iterate_op; |
330 en_eno_param_implicit = true; |
222 return NULL; |
331 return NULL; |
223 } |
332 } |
224 |
333 |
225 /****************************************/ |
334 /****************************************/ |
226 /* 1.4.3 - Declaration & Initialisation */ |
335 /* 1.4.3 - Declaration & Initialisation */ |
241 * variables, because if the desired parameter is not in the |
350 * variables, because if the desired parameter is not in the |
242 * variable list we will be analysing, the current_param_XXXX |
351 * variable list we will be analysing, the current_param_XXXX |
243 * variables will get overwritten when we visit the next |
352 * variables will get overwritten when we visit the next |
244 * var1_init_decl_c list! |
353 * var1_init_decl_c list! |
245 */ |
354 */ |
246 symbol->method->accept(*this); |
|
247 |
|
248 current_param_default_value = symbol->value; |
355 current_param_default_value = symbol->value; |
249 current_param_type = symbol->type; |
356 current_param_type = symbol->type; |
250 |
357 |
251 return handle_single_param(symbol->name); |
358 void *res = handle_single_param(symbol->name); |
|
359 |
|
360 /* If we have found the parameter we will be returning, we set the en_eno_param_implicit to TRUE if implicitly defined */ |
|
361 if (res != NULL) symbol->method->accept(*this); |
|
362 |
|
363 return res; |
252 } |
364 } |
253 |
365 |
254 /* var1_list ':' array_spec_init */ |
366 /* var1_list ':' array_spec_init */ |
255 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
367 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
256 void *function_param_iterator_c::visit(array_var_init_decl_c *symbol) { |
368 void *function_param_iterator_c::visit(array_var_init_decl_c *symbol) { |
276 void *function_param_iterator_c::visit(output_declarations_c *symbol) { |
388 void *function_param_iterator_c::visit(output_declarations_c *symbol) { |
277 TRACE("output_declarations_c"); |
389 TRACE("output_declarations_c"); |
278 current_param_direction = direction_out; |
390 current_param_direction = direction_out; |
279 return symbol->var_init_decl_list->accept(*this); |
391 return symbol->var_init_decl_list->accept(*this); |
280 } |
392 } |
|
393 |
281 void *function_param_iterator_c::visit(eno_param_declaration_c *symbol) { |
394 void *function_param_iterator_c::visit(eno_param_declaration_c *symbol) { |
282 TRACE("eno_param_declaration_c"); |
395 TRACE("eno_param_declaration_c"); |
283 /* It is OK to store these values in the current_param_XXX |
396 /* It is OK to store these values in the current_param_XXX |
284 * variables, because if the desired parameter is not in the |
397 * variables, because if the desired parameter is not in the |
285 * variable list we will be analysing, the current_param_XXXX |
398 * variable list we will be analysing, the current_param_XXXX |
286 * variables will get overwritten when we visit the next |
399 * variables will get overwritten when we visit the next |
287 * var1_init_decl_c list! |
400 * var1_init_decl_c list! |
288 */ |
401 */ |
289 symbol->method->accept(*this); |
|
290 |
|
291 current_param_default_value = NULL; |
402 current_param_default_value = NULL; |
292 current_param_type = symbol->type; |
403 current_param_type = symbol->type; |
293 |
404 |
294 return handle_single_param(symbol->name); |
405 void *res = handle_single_param(symbol->name); |
295 } |
406 |
|
407 /* If we have found the parameter we will be returning, we set the en_eno_param_implicit to TRUE if implicitly defined */ |
|
408 if (res != NULL) symbol->method->accept(*this); |
|
409 |
|
410 return res; |
|
411 } |
|
412 |
296 void *function_param_iterator_c::visit(input_output_declarations_c *symbol) { |
413 void *function_param_iterator_c::visit(input_output_declarations_c *symbol) { |
297 TRACE("input_output_declarations_c"); |
414 TRACE("input_output_declarations_c"); |
298 current_param_direction = direction_inout; |
415 current_param_direction = direction_inout; |
299 return symbol->var_declaration_list->accept(*this); |
416 return symbol->var_declaration_list->accept(*this); |
300 } |
417 } |
|
418 |
301 void *function_param_iterator_c::visit(var_declaration_list_c *symbol) {TRACE("var_declaration_list_c"); return iterate_list(symbol);} |
419 void *function_param_iterator_c::visit(var_declaration_list_c *symbol) {TRACE("var_declaration_list_c"); return iterate_list(symbol);} |
302 |
420 |
303 /* var1_list ':' array_specification */ |
421 /* var1_list ':' array_specification */ |
304 //SYM_REF2(array_var_declaration_c, var1_list, array_specification) |
422 //SYM_REF2(array_var_declaration_c, var1_list, array_specification) |
305 void *function_param_iterator_c::visit(array_var_declaration_c *symbol) { |
423 void *function_param_iterator_c::visit(array_var_declaration_c *symbol) { |
423 |
541 |
424 return symbol->var1_list->accept(*this); |
542 return symbol->var1_list->accept(*this); |
425 } |
543 } |
426 |
544 |
427 |
545 |
428 |
|
429 void *function_param_iterator_c::visit(var1_list_c *symbol) { |
546 void *function_param_iterator_c::visit(var1_list_c *symbol) { |
430 TRACE("var1_list_c"); |
547 TRACE("var1_list_c"); |
431 return handle_param_list(symbol); |
548 return handle_param_list(symbol); |
432 } |
549 } |
|
550 |
433 |
551 |
434 void *function_param_iterator_c::visit(var_init_decl_list_c *symbol) {TRACE("var_init_decl_list_c"); return iterate_list(symbol);} |
552 void *function_param_iterator_c::visit(var_init_decl_list_c *symbol) {TRACE("var_init_decl_list_c"); return iterate_list(symbol);} |
435 |
553 |
436 |
554 |
437 /***********************/ |
555 /***********************/ |