22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 /* |
25 /* |
26 * Function call parameter iterator. |
26 * Function call parameter iterator. |
27 * It will iterate through the formal parameters of a function call |
27 * It will iterate through the non-formal parameters of a function call |
28 * (i.e. function calls using the foo(<param1>, <param2>, ...) syntax). |
28 * (i.e. function calls using the foo(<param1>, <param2>, ...) syntax). |
29 * and/or search through the non-formal parameters of a function call |
29 * and/or search through the formal parameters of a function call |
30 * (i.e. function calls using the foo(<name1> = <param1>, <name2> = <param2>, ...) syntax). |
30 * (i.e. function calls using the foo(<name1> = <param1>, <name2> = <param2>, ...) syntax). |
31 * |
31 * |
32 * Calls to function blocks and programs are also supported. |
32 * Calls to function blocks and programs are also supported. |
33 * |
33 * |
34 * Note that calls to next() will only iterate through formal parameters, |
34 * Note that calls to next_nf() will only iterate through non-formal parameters, |
35 * and calls to search() will only serach through non-formal parameters. |
35 * calls to next_f() will only iterate through formal parameters, |
|
36 * and calls to search_f() will only serach through formal parameters. |
36 */ |
37 */ |
37 |
38 |
38 |
39 |
39 |
40 |
40 #include "function_call_param_iterator.hh" |
41 #include "function_call_param_iterator.hh" |
56 |
57 |
57 |
58 |
58 |
59 |
59 void *function_call_param_iterator_c::search_list(list_c *list) { |
60 void *function_call_param_iterator_c::search_list(list_c *list) { |
60 switch (current_operation) { |
61 switch (current_operation) { |
61 case iterate_op: |
62 case iterate_nf_op: |
62 for(int i = 0; i < list->n; i++) { |
63 for(int i = 0; i < list->n; i++) { |
63 void *res = list->elements[i]->accept(*this); |
64 void *res = list->elements[i]->accept(*this); |
64 if (NULL != res) { |
65 if (NULL != res) { |
65 /* It went through the handle_parameter_assignment() function, |
66 /* It went through the handle_parameter_assignment() function, |
66 * and is therefore a parameter assignment (<param> = <value>), |
67 * and is therefore a parameter assignment (<param> = <value>), |
67 * and not a simple expression (<value>). |
68 * and not a simple expression (<value>). |
68 */ |
69 */ |
69 /* we do nothing... */ |
70 /* we do nothing... */ |
70 } else { |
71 } else { |
71 param_count++; |
72 param_count++; |
72 if (param_count == next_param) { |
73 if (param_count == iterate_nf_next_param) { |
73 return list->elements[i]; |
74 return list->elements[i]; |
74 } |
75 } |
75 } |
76 } |
76 } |
77 } |
77 return NULL; |
78 return NULL; |
78 break; |
79 break; |
79 |
80 |
80 case search_op: |
81 case iterate_f_op: |
|
82 for(int i = 0; i < list->n; i++) { |
|
83 void *res = list->elements[i]->accept(*this); |
|
84 if (NULL != res) { |
|
85 /* It went through the handle_parameter_assignment() function, |
|
86 * and is therefore a parameter assignment (<param> = <value>), |
|
87 * and not a simple expression (<value>). |
|
88 */ |
|
89 param_count++; |
|
90 if (param_count == iterate_f_next_param) { |
|
91 return res; |
|
92 } |
|
93 } else { |
|
94 /* we do nothing... */ |
|
95 } |
|
96 } |
|
97 return NULL; |
|
98 break; |
|
99 |
|
100 case search_f_op: |
81 for(int i = 0; i < list->n; i++) { |
101 for(int i = 0; i < list->n; i++) { |
82 void *res = list->elements[i]->accept(*this); |
102 void *res = list->elements[i]->accept(*this); |
83 if (res != NULL) |
103 if (res != NULL) |
84 return res; |
104 return res; |
85 } |
105 } |
91 |
111 |
92 |
112 |
93 |
113 |
94 void *function_call_param_iterator_c::handle_parameter_assignment(symbol_c *variable_name, symbol_c *expression) { |
114 void *function_call_param_iterator_c::handle_parameter_assignment(symbol_c *variable_name, symbol_c *expression) { |
95 switch (current_operation) { |
115 switch (current_operation) { |
96 case iterate_op: |
116 case iterate_nf_op: |
97 /* UGLY HACK -> this will be detected in the search_list() function */ |
117 /* UGLY HACK -> this will be detected in the search_list() function */ |
98 return (void *)this; /* anything, as long as it is not NULL!! */ |
118 return (void *)variable_name; /* anything, as long as it is not NULL!! */ |
99 break; |
119 break; |
100 |
120 |
101 case search_op: |
121 case iterate_f_op: |
|
122 current_value = expression; |
|
123 return (void *)variable_name; |
|
124 break; |
|
125 |
|
126 case search_f_op: |
102 identifier_c *variable_name2 = dynamic_cast<identifier_c *>(variable_name); |
127 identifier_c *variable_name2 = dynamic_cast<identifier_c *>(variable_name); |
103 |
128 |
104 if (variable_name2 == NULL) { |
|
105 en_param_c *en_param = dynamic_cast<en_param_c *>(variable_name); |
|
106 if (en_param != NULL) |
|
107 variable_name2 = new identifier_c("EN"); |
|
108 } |
|
109 |
|
110 if (variable_name2 == NULL) { |
|
111 eno_param_c *eno_param = dynamic_cast<eno_param_c *>(variable_name); |
|
112 if (eno_param != NULL) |
|
113 variable_name2 = new identifier_c("ENO"); |
|
114 } |
|
115 |
|
116 if (variable_name2 == NULL) ERROR; |
129 if (variable_name2 == NULL) ERROR; |
117 |
130 |
118 if (strcasecmp(search_param_name->value, variable_name2->value) == 0) |
131 if (strcasecmp(search_param_name->value, variable_name2->value) == 0) |
119 /* FOUND! This is the same parameter!! */ |
132 /* FOUND! This is the same parameter!! */ |
120 return (void *)expression; |
133 return (void *)expression; |
121 return NULL; |
134 return NULL; |
122 break; |
135 break; |
148 this->f_call = f_call; |
163 this->f_call = f_call; |
149 search_param_name = NULL; |
164 search_param_name = NULL; |
150 reset(); |
165 reset(); |
151 } |
166 } |
152 |
167 |
153 /* Skip to the next parameter. After object creation, |
168 /* Skip to the next formal parameter. After object creation, |
154 * the object references on parameter _before_ the first, so |
169 * the object references on parameter _before_ the first, so |
155 * this function must be called once to get the object to |
170 * this function must be called once to get the object to |
156 * reference the first parameter... |
171 * reference the first parameter... |
157 * |
172 * |
158 * Returns whatever is being passed to the parameter! |
173 * Returns the paramater name to which a value is being passed! |
159 */ |
174 * You can determine the value being passed by calling |
160 symbol_c *function_call_param_iterator_c::next(void) { |
175 * function_call_param_iterator_c::search_f() |
|
176 */ |
|
177 symbol_c *function_call_param_iterator_c::next_f(void) { |
|
178 current_value = NULL; |
161 param_count = 0; |
179 param_count = 0; |
162 next_param++; |
180 iterate_f_next_param++; |
163 current_operation = function_call_param_iterator_c::iterate_op; |
181 current_operation = function_call_param_iterator_c::iterate_f_op; |
164 void *res = f_call->accept(*this); |
182 void *res = f_call->accept(*this); |
165 return (symbol_c *)res; |
183 return (symbol_c *)res; |
166 } |
184 } |
167 |
185 |
|
186 |
|
187 /* Skip to the next non-formal parameter. After object creation, |
|
188 * the object references on parameter _before_ the first, so |
|
189 * this function must be called once to get the object to |
|
190 * reference the first parameter... |
|
191 * |
|
192 * Returns whatever is being passed to the parameter! |
|
193 */ |
|
194 symbol_c *function_call_param_iterator_c::next_nf(void) { |
|
195 current_value = NULL; |
|
196 param_count = 0; |
|
197 iterate_nf_next_param++; |
|
198 current_operation = function_call_param_iterator_c::iterate_nf_op; |
|
199 void *res = f_call->accept(*this); |
|
200 current_value = (symbol_c *)res; |
|
201 return (symbol_c *)res; |
|
202 } |
|
203 |
168 /* Search for the value passed to the parameter named <param_name>... */ |
204 /* Search for the value passed to the parameter named <param_name>... */ |
169 symbol_c *function_call_param_iterator_c::search(symbol_c *param_name) { |
205 symbol_c *function_call_param_iterator_c::search_f(symbol_c *param_name) { |
|
206 current_value = NULL; |
170 if (NULL == param_name) ERROR; |
207 if (NULL == param_name) ERROR; |
171 search_param_name = dynamic_cast<identifier_c *>(param_name); |
208 search_param_name = dynamic_cast<identifier_c *>(param_name); |
172 if (NULL == search_param_name) ERROR; |
209 if (NULL == search_param_name) ERROR; |
173 current_operation = function_call_param_iterator_c::search_op; |
210 current_operation = function_call_param_iterator_c::search_f_op; |
174 void *res = f_call->accept(*this); |
211 void *res = f_call->accept(*this); |
|
212 current_value = (symbol_c *)res; |
175 return (symbol_c *)res; |
213 return (symbol_c *)res; |
176 } |
214 } |
177 |
215 |
178 |
216 /* Returns the value being passed to the current parameter. */ |
|
217 symbol_c *function_call_param_iterator_c::get_current_value(void) { |
|
218 return current_value; |
|
219 } |
179 |
220 |
180 /********************************/ |
221 /********************************/ |
181 /* B 1.7 Configuration elements */ |
222 /* B 1.7 Configuration elements */ |
182 /********************************/ |
223 /********************************/ |
183 |
224 |
401 |
442 |
402 // TODO : We do not yet handle a instruction list passed as parameter !!! |
443 // TODO : We do not yet handle a instruction list passed as parameter !!! |
403 // since we do not yet support it, it is best to simply stop than to fail silently... |
444 // since we do not yet support it, it is best to simply stop than to fail silently... |
404 if (NULL != symbol->simple_instr_list) ERROR; |
445 if (NULL != symbol->simple_instr_list) ERROR; |
405 |
446 |
406 return handle_parameter_assignment(symbol->il_assign_operator, symbol->il_operand); |
447 return handle_parameter_assignment((symbol_c *)symbol->il_assign_operator->accept(*this), symbol->il_operand); |
407 } |
448 } |
408 |
449 |
409 /* il_assign_out_operator variable */ |
450 /* il_assign_out_operator variable */ |
410 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable); |
451 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable); |
411 void *function_call_param_iterator_c::visit(il_param_out_assignment_c *symbol) { |
452 void *function_call_param_iterator_c::visit(il_param_out_assignment_c *symbol) { |
415 |
456 |
416 |
457 |
417 /*******************/ |
458 /*******************/ |
418 /* B 2.2 Operators */ |
459 /* B 2.2 Operators */ |
419 /*******************/ |
460 /*******************/ |
|
461 /* any_identifier ASSIGN */ |
|
462 // SYM_REF1(il_assign_operator_c, variable_name) |
|
463 void *function_call_param_iterator_c::visit(il_assign_operator_c *symbol) { |
|
464 TRACE("il_assign_operator_c"); |
|
465 return (void *)symbol->variable_name; |
|
466 } |
|
467 |
420 /*| [NOT] any_identifier SENDTO */ |
468 /*| [NOT] any_identifier SENDTO */ |
421 // SYM_REF2(il_assign_out_operator_c, option, variable_name) |
469 // SYM_REF2(il_assign_out_operator_c, option, variable_name) |
422 void *function_call_param_iterator_c::visit(il_assign_out_operator_c *symbol) { |
470 void *function_call_param_iterator_c::visit(il_assign_out_operator_c *symbol) { |
423 TRACE("il_assign_out_operator_c"); |
471 TRACE("il_assign_out_operator_c"); |
424 |
472 |
425 // TODO : Handle not_param !!! |
473 // TODO : Handle not_param !!! |
426 // we do not yet support it, so it is best to simply stop than to fail silently... |
474 // we do not yet support it, so it is best to simply stop than to fail silently... |
427 if (NULL != symbol->option) ERROR; |
475 // if (NULL != symbol->option) ERROR; |
428 |
476 |
429 return (void *)symbol->variable_name; |
477 return (void *)symbol->variable_name; |
430 } |
478 } |
431 |
479 |
432 |
480 |
442 /* |
490 /* |
443 SYM_REF2(function_invocation_c, function_name, parameter_assignment_list) |
491 SYM_REF2(function_invocation_c, function_name, parameter_assignment_list) |
444 */ |
492 */ |
445 void *function_call_param_iterator_c::visit(function_invocation_c *symbol) { |
493 void *function_call_param_iterator_c::visit(function_invocation_c *symbol) { |
446 TRACE("function_invocation_c"); |
494 TRACE("function_invocation_c"); |
447 if ((symbol_c *)symbol == f_call && symbol->parameter_assignment_list != NULL) |
495 /* If the syntax parser is working correctly, exactly one of the |
448 return symbol->parameter_assignment_list->accept(*this); |
496 * following two symbols will be NULL, while the other is != NULL. |
449 else |
497 */ |
450 return NULL; |
498 if (symbol-> formal_param_list != NULL) return symbol-> formal_param_list->accept(*this); |
|
499 if (symbol->nonformal_param_list != NULL) return symbol->nonformal_param_list->accept(*this); |
|
500 |
|
501 return NULL; |
451 } |
502 } |
452 |
503 |
453 |
504 |
454 /********************/ |
505 /********************/ |
455 /* B 3.2 Statements */ |
506 /* B 3.2 Statements */ |
472 /* fb_name '(' [param_assignment_list] ')' */ |
523 /* fb_name '(' [param_assignment_list] ')' */ |
473 /* param_assignment_list -> may be NULL ! */ |
524 /* param_assignment_list -> may be NULL ! */ |
474 // SYM_REF2(fb_invocation_c, fb_name, param_assignment_list) |
525 // SYM_REF2(fb_invocation_c, fb_name, param_assignment_list) |
475 void *function_call_param_iterator_c::visit(fb_invocation_c *symbol) { |
526 void *function_call_param_iterator_c::visit(fb_invocation_c *symbol) { |
476 TRACE("fb_invocation_c"); |
527 TRACE("fb_invocation_c"); |
477 if (symbol->param_assignment_list != NULL) |
528 /* If the syntax parser is working correctly, only one of the |
478 return symbol->param_assignment_list->accept(*this); |
529 * following two symbols will be != NULL. |
479 else |
530 * However, both may be NULL simultaneously! |
480 return NULL; |
531 */ |
|
532 if (symbol-> formal_param_list != NULL) return symbol-> formal_param_list->accept(*this); |
|
533 if (symbol->nonformal_param_list != NULL) return symbol->nonformal_param_list->accept(*this); |
|
534 |
|
535 return NULL; |
481 } |
536 } |
482 |
537 |
483 /* helper symbol for fb_invocation */ |
538 /* helper symbol for fb_invocation */ |
484 /* param_assignment_list ',' param_assignment */ |
539 /* param_assignment_list ',' param_assignment */ |
485 // SYM_LIST(param_assignment_list_c) |
540 // SYM_LIST(param_assignment_list_c) |