58 extern void error_exit(const char *file_name, int line_no); |
58 extern void error_exit(const char *file_name, int line_no); |
59 |
59 |
60 |
60 |
61 |
61 |
62 void* function_param_iterator_c::handle_param_list(list_c *list) { |
62 void* function_param_iterator_c::handle_param_list(list_c *list) { |
63 if (next_param <= param_count + list->n) |
63 switch (current_operation) { |
64 return list->elements[next_param - param_count - 1]; |
64 case iterate_op: |
65 |
65 if (next_param <= param_count + list->n) |
66 /* the desired param is not on this list... */ |
66 return list->elements[next_param - param_count - 1]; |
67 param_count += list->n; |
67 |
68 return NULL; |
68 /* the desired param is not on this list... */ |
|
69 param_count += list->n; |
|
70 break; |
|
71 |
|
72 case search_op: |
|
73 for(int i = 0; i < list->n; i++) { |
|
74 identifier_c *variable_name = dynamic_cast<identifier_c *>(list->elements[i]); |
|
75 if (variable_name == NULL) ERROR; |
|
76 |
|
77 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
|
78 /* FOUND! This is the same parameter!! */ |
|
79 return (void *)variable_name; |
|
80 } |
|
81 break; |
|
82 } /* switch */ |
|
83 |
|
84 /* Not found! */ |
|
85 return NULL; |
69 } |
86 } |
70 |
87 |
71 void* function_param_iterator_c::handle_single_param(symbol_c *var_name) { |
88 void* function_param_iterator_c::handle_single_param(symbol_c *var_name) { |
72 param_count++; |
89 switch (current_operation) { |
73 if (next_param == param_count) |
90 case iterate_op: |
74 return var_name; |
91 param_count++; |
75 |
92 if (next_param == param_count) |
76 /* not yet the desired param... */ |
93 return var_name; |
77 return NULL; |
94 break; |
|
95 |
|
96 case search_op: |
|
97 identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name); |
|
98 if (variable_name == NULL) ERROR; |
|
99 |
|
100 if (strcasecmp(search_param_name->value, variable_name->value) == 0) |
|
101 /* FOUND! This is the same parameter!! */ |
|
102 return (void *)variable_name; |
|
103 break; |
|
104 } /* switch */ |
|
105 |
|
106 /* Not found! */ |
|
107 return NULL; |
78 } |
108 } |
79 |
109 |
80 void* function_param_iterator_c::iterate_list(list_c *list) { |
110 void* function_param_iterator_c::iterate_list(list_c *list) { |
81 void *res; |
111 void *res; |
82 for (int i = 0; i < list->n; i++) { |
112 for (int i = 0; i < list->n; i++) { |
90 /* start off at the first parameter once again... */ |
120 /* start off at the first parameter once again... */ |
91 void function_param_iterator_c::reset(void) { |
121 void function_param_iterator_c::reset(void) { |
92 next_param = param_count = 0; |
122 next_param = param_count = 0; |
93 current_param_name = NULL; |
123 current_param_name = NULL; |
94 current_param_type = current_param_default_value = NULL; |
124 current_param_type = current_param_default_value = NULL; |
95 en_declared = false; |
125 } |
96 eno_declared = false; |
126 |
97 } |
|
98 |
127 |
99 /* initialise the iterator object. |
128 /* initialise the iterator object. |
100 * We must be given a reference to the function declaration |
129 * We must be given a reference to one of the following |
|
130 * - function_declaration_c |
|
131 * - function_block_declaration_c |
|
132 * - program_declaration_c |
101 * that will be analysed... |
133 * that will be analysed... |
102 */ |
134 */ |
103 function_param_iterator_c::function_param_iterator_c(function_declaration_c *f_decl) { |
135 function_param_iterator_c::function_param_iterator_c(symbol_c *pou_decl) { |
104 this->f_decl = f_decl; |
136 /* do some consistency checks... */ |
|
137 function_declaration_c * f_decl = dynamic_cast<function_declaration_c *>(pou_decl); |
|
138 function_block_declaration_c *fb_decl = dynamic_cast<function_block_declaration_c *>(pou_decl); |
|
139 program_declaration_c * p_decl = dynamic_cast<program_declaration_c *>(pou_decl); |
|
140 |
|
141 if ((NULL == f_decl) && (NULL == fb_decl) && (NULL == p_decl)) ERROR; |
|
142 |
|
143 /* OK. Now initialise this object... */ |
|
144 this->f_decl = pou_decl; |
105 reset(); |
145 reset(); |
106 } |
146 } |
107 |
147 |
108 /* initialise the iterator object. |
148 |
109 * We must be given a reference to the function block declaration |
|
110 * that will be analysed... |
|
111 */ |
|
112 function_param_iterator_c::function_param_iterator_c(function_block_declaration_c *fb_decl) { |
|
113 this->f_decl = fb_decl; |
|
114 reset(); |
|
115 } |
|
116 |
|
117 /* initialise the iterator object. |
|
118 * We must be given a reference to the program declaration |
|
119 * that will be analysed... |
|
120 */ |
|
121 function_param_iterator_c::function_param_iterator_c(program_declaration_c *p_decl) { |
|
122 this->f_decl = p_decl; |
|
123 reset(); |
|
124 } |
|
125 |
149 |
126 /* Skip to the next parameter. After object creation, |
150 /* Skip to the next parameter. After object creation, |
127 * the object references on parameter _before_ the first, so |
151 * the object references on parameter _before_ the first, so |
128 * this function must be called once to get the object to |
152 * this function must be called once to get the object to |
129 * reference the first parameter... |
153 * reference the first parameter... |
131 * Returns the parameter's name! |
155 * Returns the parameter's name! |
132 */ |
156 */ |
133 identifier_c *function_param_iterator_c::next(void) { |
157 identifier_c *function_param_iterator_c::next(void) { |
134 void *res; |
158 void *res; |
135 identifier_c *identifier; |
159 identifier_c *identifier; |
|
160 |
136 param_count = 0; |
161 param_count = 0; |
137 next_param++; |
162 next_param++; |
|
163 current_operation = function_param_iterator_c::iterate_op; |
138 res = f_decl->accept(*this); |
164 res = f_decl->accept(*this); |
139 if (res != NULL) { |
165 if (res == NULL) |
140 symbol_c *sym = (symbol_c *)res; |
|
141 identifier = dynamic_cast<identifier_c *>(sym); |
|
142 if (identifier == NULL) |
|
143 ERROR; |
|
144 } |
|
145 else if (!en_declared) { |
|
146 current_param_direction = direction_in; |
|
147 identifier = declare_en_param(); |
|
148 } |
|
149 else if (!eno_declared) { |
|
150 current_param_direction = direction_out; |
|
151 identifier = declare_eno_param(); |
|
152 } |
|
153 else |
|
154 return NULL; |
166 return NULL; |
155 |
167 |
|
168 symbol_c *sym = (symbol_c *)res; |
|
169 identifier = dynamic_cast<identifier_c *>(sym); |
|
170 if (identifier == NULL) |
|
171 ERROR; |
156 current_param_name = identifier; |
172 current_param_name = identifier; |
157 return current_param_name; |
173 return current_param_name; |
158 } |
174 } |
159 |
175 |
160 identifier_c *function_param_iterator_c::declare_en_param(void) { |
176 /* Search for the value passed to the parameter named <param_name>... */ |
161 en_declared = true; |
177 identifier_c *function_param_iterator_c::search(symbol_c *param_name) { |
162 identifier_c *identifier = new identifier_c("EN"); |
178 if (NULL == param_name) ERROR; |
163 current_param_type = (symbol_c*)(new bool_type_name_c()); |
179 search_param_name = dynamic_cast<identifier_c *>(param_name); |
164 current_param_default_value = (symbol_c*)(new boolean_literal_c(current_param_type, new boolean_true_c())); |
180 if (NULL == search_param_name) ERROR; |
165 return identifier; |
181 current_operation = function_param_iterator_c::search_op; |
166 } |
182 void *res = f_decl->accept(*this); |
167 |
183 identifier_c *res_param_name = dynamic_cast<identifier_c *>((symbol_c *)res); |
168 identifier_c *function_param_iterator_c::declare_eno_param(void) { |
184 return res_param_name; |
169 eno_declared = true; |
|
170 identifier_c *identifier = new identifier_c("ENO"); |
|
171 current_param_type = (symbol_c*)(new bool_type_name_c()); |
|
172 current_param_default_value = NULL; |
|
173 return identifier; |
|
174 } |
185 } |
175 |
186 |
176 /* Returns the currently referenced parameter's default value, |
187 /* Returns the currently referenced parameter's default value, |
177 * or NULL if none is specified in the function declrataion itself. |
188 * or NULL if none is specified in the function declrataion itself. |
178 */ |
189 */ |
205 |
216 |
206 void *function_param_iterator_c::visit(edge_declaration_c *symbol) {TRACE("edge_declaration_c"); return symbol->var1_list->accept(*this);} |
217 void *function_param_iterator_c::visit(edge_declaration_c *symbol) {TRACE("edge_declaration_c"); return symbol->var1_list->accept(*this);} |
207 |
218 |
208 void *function_param_iterator_c::visit(en_param_declaration_c *symbol) { |
219 void *function_param_iterator_c::visit(en_param_declaration_c *symbol) { |
209 TRACE("en_param_declaration_c"); |
220 TRACE("en_param_declaration_c"); |
210 if (en_declared) ERROR; |
221 /* It is OK to store these values in the current_param_XXX |
211 return (void *)declare_en_param(); |
222 * variables, because if the desired parameter is not in the |
|
223 * variable list we will be analysing, the current_param_XXXX |
|
224 * variables will get overwritten when we visit the next |
|
225 * var1_init_decl_c list! |
|
226 */ |
|
227 current_param_default_value = symbol->value; |
|
228 current_param_type = symbol->type; |
|
229 |
|
230 return handle_single_param(symbol->name); |
212 } |
231 } |
213 |
232 |
214 /* var1_list ':' array_spec_init */ |
233 /* var1_list ':' array_spec_init */ |
215 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
234 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
216 void *function_param_iterator_c::visit(array_var_init_decl_c *symbol) {TRACE("array_var_init_decl_c"); return symbol->var1_list->accept(*this);} |
235 void *function_param_iterator_c::visit(array_var_init_decl_c *symbol) {TRACE("array_var_init_decl_c"); return symbol->var1_list->accept(*this);} |
224 current_param_direction = direction_out; |
243 current_param_direction = direction_out; |
225 return symbol->var_init_decl_list->accept(*this); |
244 return symbol->var_init_decl_list->accept(*this); |
226 } |
245 } |
227 void *function_param_iterator_c::visit(eno_param_declaration_c *symbol) { |
246 void *function_param_iterator_c::visit(eno_param_declaration_c *symbol) { |
228 TRACE("eno_param_declaration_c"); |
247 TRACE("eno_param_declaration_c"); |
|
248 /* It is OK to store these values in the current_param_XXX |
|
249 * variables, because if the desired parameter is not in the |
|
250 * variable list we will be analysing, the current_param_XXXX |
|
251 * variables will get overwritten when we visit the next |
|
252 * var1_init_decl_c list! |
|
253 */ |
|
254 current_param_default_value = NULL; |
|
255 current_param_type = symbol->type; |
|
256 |
|
257 return handle_single_param(symbol->name); |
|
258 #if 0 |
229 if (eno_declared) ERROR; |
259 if (eno_declared) ERROR; |
230 return (void *)declare_eno_param(); |
260 return (void *)declare_eno_param(); |
|
261 #endif |
231 } |
262 } |
232 void *function_param_iterator_c::visit(input_output_declarations_c *symbol) { |
263 void *function_param_iterator_c::visit(input_output_declarations_c *symbol) { |
233 TRACE("input_output_declarations_c"); |
264 TRACE("input_output_declarations_c"); |
234 current_param_direction = direction_inout; |
265 current_param_direction = direction_inout; |
235 return symbol->var_declaration_list->accept(*this); |
266 return symbol->var_declaration_list->accept(*this); |