73 * option (2) will return INT |
73 * option (2) will return INT |
74 * |
74 * |
75 * |
75 * |
76 * Member functions: |
76 * Member functions: |
77 * ================ |
77 * ================ |
|
78 * get_basetype_id() ---> returns 2A (implemented, although currently it is not needed! ) |
78 * get_basetype_decl() ---> returns 2B |
79 * get_basetype_decl() ---> returns 2B |
79 * get_type_id() ---> returns 1A |
80 * get_type_id() ---> returns 1A |
80 * |
81 * |
81 * Since we haven't yet needed them, we don't yet implement |
82 * Since we haven't yet needed it, we don't yet implement |
82 * get_basetype_id() ----> would return 2A |
83 * get_type_decl() ---> returns 1B |
83 * get_type_decl() ----> would return 1B |
|
84 */ |
84 */ |
85 |
85 |
86 |
86 |
87 /* |
87 |
88 * TODO: this code has a memory leak... |
|
89 * We call 'new' in several locations, but bever get to 'delete' the object instances... |
|
90 */ |
|
91 #include "absyntax_utils.hh" |
88 #include "absyntax_utils.hh" |
92 |
89 |
93 |
90 |
|
91 void search_varfb_instance_type_c::init(void) { |
|
92 this->current_type_id = NULL; |
|
93 this->current_basetype_id = NULL; |
|
94 this->current_basetype_decl = NULL; |
|
95 this->current_field_selector = NULL; |
|
96 } |
|
97 |
|
98 |
94 search_varfb_instance_type_c::search_varfb_instance_type_c(symbol_c *search_scope): search_var_instance_decl(search_scope) { |
99 search_varfb_instance_type_c::search_varfb_instance_type_c(symbol_c *search_scope): search_var_instance_decl(search_scope) { |
95 this->decompose_var_instance_name = NULL; |
100 this->init(); |
96 this->current_structelement_name = NULL; |
101 } |
97 this->current_typeid = NULL; |
102 |
98 this->current_basetypeid = NULL; |
103 |
99 } |
104 /* We expect to be passed a symbolic_variable_c */ |
100 |
105 symbol_c *search_varfb_instance_type_c::get_type_id(symbol_c *variable_name) { |
101 symbol_c *search_varfb_instance_type_c::get_type_decl(symbol_c *variable_name) { |
106 this->init(); |
102 this->current_structelement_name = NULL; |
107 variable_name->accept(*this); |
103 this->current_typeid = NULL; |
108 return current_type_id; |
104 this->current_basetypeid = NULL; |
109 } |
105 this->decompose_var_instance_name = new decompose_var_instance_name_c(variable_name); |
110 |
106 if (NULL == decompose_var_instance_name) ERROR; |
111 |
107 |
112 symbol_c *search_varfb_instance_type_c::get_basetype_id(symbol_c *variable_name) { |
108 /* find the part of the variable name that will appear in the |
113 this->init(); |
109 * variable declaration, for e.g., in window.point.x, this would be |
114 variable_name->accept(*this); |
110 * window! |
115 return current_basetype_id; |
|
116 } |
|
117 |
|
118 |
|
119 symbol_c *search_varfb_instance_type_c::get_basetype_decl(symbol_c *variable_name) { |
|
120 this->init(); |
|
121 variable_name->accept(*this); |
|
122 return current_basetype_decl; |
|
123 } |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 /*************************/ |
|
129 /* B.1 - Common elements */ |
|
130 /*************************/ |
|
131 /*******************************************/ |
|
132 /* B 1.1 - Letters, digits and identifiers */ |
|
133 /*******************************************/ |
|
134 // SYM_TOKEN(identifier_c) |
|
135 void *search_varfb_instance_type_c::visit(identifier_c *variable_name) { |
|
136 /* symbol should be a variable name!! */ |
|
137 /* Note: although the method is called get_decl(), it is getting the declaration of the variable, which for us is the type_id of that variable! */ |
|
138 current_type_id = search_var_instance_decl.get_decl (variable_name); |
|
139 current_basetype_decl = search_base_type.get_basetype_decl(current_type_id); |
|
140 current_basetype_id = search_base_type.get_basetype_id (current_type_id); |
|
141 |
|
142 /* What if the variable has not been declared? Then this should not be a compiler error! |
|
143 * However, currently stage 2 of the compiler already detects when variables have not been delcared, |
|
144 * so if the variable's declaration is not found, then that means that we have an internal compiler error! |
|
145 * |
|
146 * Actually, the above is not true anymore. See the use of the any_symbolic_variable in iec_bison.yy |
|
147 * - when defining the delay of a delayed action association in SFC |
|
148 * - in program connections inside configurations (will this search_varfb_instance_type_c class be called to handle this??) |
111 */ |
149 */ |
112 symbol_c *var_name_part = decompose_var_instance_name->next_part(); |
150 // if (NULL == current_type_id) ERROR; |
113 if (NULL == var_name_part) ERROR; |
151 |
114 |
152 return NULL; |
115 /* Now we try to find the variable instance declaration, to determine its type... */ |
153 } |
116 symbol_c *var_decl = search_var_instance_decl.get_decl(var_name_part); |
154 |
117 if (NULL == var_decl) ERROR; |
155 |
118 |
156 |
119 /* if it is a struct or function block, we must search the type |
157 |
120 * of the struct or function block member. |
|
121 * This is done by this class visiting the var_decl. |
|
122 * This class, while visiting, will recursively call |
|
123 * decompose_var_instance_name->get_next() when and if required... |
|
124 */ |
|
125 symbol_c *res = (symbol_c *)var_decl->accept(*this); |
|
126 /* NOTE: A Null result is not really an internal compiler error, but rather an error in |
|
127 * the IEC 61131-3 source code being compiled. This means we cannot just abort the compiler with ERROR. |
|
128 * // if (NULL == res) ERROR; |
|
129 */ |
|
130 if (NULL == res) return NULL; |
|
131 |
|
132 /* make sure that we have decomposed all structure elements of the variable name */ |
|
133 symbol_c *var_name = decompose_var_instance_name->next_part(); |
|
134 /* NOTE: A non-NULL result is not really an internal compiler error, but rather an error in |
|
135 * the IEC 61131-3 source code being compiled. |
|
136 * (for example, 'int_var.struct_elem' in the source code, when 'int_var' is a simple integer, |
|
137 * and not a structure, will result in this result being non-NULL!) |
|
138 * This means we cannot just abort the compiler with ERROR. |
|
139 * // if (NULL != var_name) ERROR; |
|
140 */ |
|
141 if (NULL != var_name) return NULL; |
|
142 |
|
143 return res; |
|
144 } |
|
145 |
|
146 |
|
147 symbol_c *search_varfb_instance_type_c::get_basetype_decl(symbol_c *variable_name) { |
|
148 symbol_c *res = get_type_decl(variable_name); |
|
149 if (NULL == res) return NULL; |
|
150 return (symbol_c *)base_type(res); |
|
151 } |
|
152 |
|
153 |
|
154 unsigned int search_varfb_instance_type_c::get_vartype(symbol_c *variable_name) { |
|
155 this->current_structelement_name = NULL; |
|
156 this->current_typeid = NULL; |
|
157 this->current_basetypeid = NULL; |
|
158 this->is_complex = false; |
|
159 this->decompose_var_instance_name = new decompose_var_instance_name_c(variable_name); |
|
160 if (NULL == decompose_var_instance_name) ERROR; |
|
161 |
|
162 /* find the part of the variable name that will appear in the |
|
163 * variable declaration, for e.g., in window.point.x, this would be |
|
164 * window! |
|
165 */ |
|
166 symbol_c *var_name_part = decompose_var_instance_name->next_part(); |
|
167 if (NULL == var_name_part) ERROR; |
|
168 |
|
169 /* Now we try to find the variable instance declaration, to determine its type... */ |
|
170 symbol_c *var_decl = search_var_instance_decl.get_decl(var_name_part); |
|
171 if (NULL == var_decl) { |
|
172 /* variable instance declaration not found! */ |
|
173 return 0; |
|
174 } |
|
175 |
|
176 /* if it is a struct or function block, we must search the type |
|
177 * of the struct or function block member. |
|
178 * This is done by this class visiting the var_decl. |
|
179 * This class, while visiting, will recursively call |
|
180 * decompose_var_instance_name->get_next() when and if required... |
|
181 */ |
|
182 var_decl->accept(*this); |
|
183 unsigned int res = search_var_instance_decl.get_vartype(); |
|
184 |
|
185 /* make sure that we have decomposed all structure elements of the variable name */ |
|
186 symbol_c *var_name = decompose_var_instance_name->next_part(); |
|
187 if (NULL != var_name) ERROR; |
|
188 |
|
189 return res; |
|
190 } |
|
191 |
|
192 symbol_c *search_varfb_instance_type_c::get_type_id(symbol_c *variable_name) { |
|
193 this->current_typeid = NULL; |
|
194 symbol_c *vartype = this->get_type_decl(variable_name); |
|
195 if (this->current_typeid != NULL) |
|
196 return this->current_typeid; |
|
197 else |
|
198 return vartype; |
|
199 } |
|
200 |
|
201 bool search_varfb_instance_type_c::type_is_complex(void) { |
|
202 return this->is_complex; |
|
203 } |
|
204 |
|
205 /* a helper function... */ |
|
206 void *search_varfb_instance_type_c::visit_list(list_c *list) { |
|
207 if (NULL == current_structelement_name) ERROR; |
|
208 |
|
209 for(int i = 0; i < list->n; i++) { |
|
210 void *res = list->elements[i]->accept(*this); |
|
211 if (res != NULL) |
|
212 return res; |
|
213 } |
|
214 /* not found! */ |
|
215 return NULL; |
|
216 } |
|
217 |
|
218 /* a helper function... */ |
|
219 void *search_varfb_instance_type_c::base_type(symbol_c *symbol) { |
|
220 search_base_type_c search_base_type; |
|
221 return symbol->accept(search_base_type); |
|
222 } |
|
223 |
|
224 /* We override the base class' visitor to identifier_c. |
|
225 * This is so because the base class does not consider a function block |
|
226 * to be a type, unlike this class that allows a variable instance |
|
227 * of a function block type... |
|
228 */ |
|
229 void *search_varfb_instance_type_c::visit(identifier_c *type_name) { |
|
230 /* we only store the new type id if none had been found yet. |
|
231 * Since we will recursively carry on looking at the base type |
|
232 * to determine the base type declaration and id, we must only set this variable |
|
233 * the first time. |
|
234 * e.g. TYPE myint1_t : int := 1; |
|
235 * myint2_t : int1_t := 2; |
|
236 * myint3_t : int2_t := 3; |
|
237 * END_TYPE; |
|
238 * VAR |
|
239 * myint1 : myint1_t; |
|
240 * myint2 : myint2_t; |
|
241 * myint3 : myint3_t; |
|
242 * END_VAR |
|
243 * |
|
244 * If we ask for typeid of myint3, it must return myint3_t |
|
245 * If we ask for basetypeid of myint3, it must return int |
|
246 * |
|
247 * When determining the data type of myint3, we will recursively go all the way |
|
248 * down to int, but we must still only store myint3_t as the base type id. |
|
249 */ |
|
250 if (NULL == this->current_typeid) |
|
251 this->current_typeid = type_name; |
|
252 this->current_basetypeid = type_name; |
|
253 |
|
254 /* look up the type declaration... */ |
|
255 symbol_c *fb_decl = function_block_type_symtable.find_value(type_name); |
|
256 if (fb_decl != function_block_type_symtable.end_value()) |
|
257 /* Type declaration found!! */ |
|
258 return fb_decl->accept(*this); |
|
259 |
|
260 /* No. It is not a function block, so we let |
|
261 * the base class take care of it... |
|
262 */ |
|
263 return search_base_type_c::visit(type_name); |
|
264 } |
|
265 |
158 |
266 /********************************/ |
159 /********************************/ |
267 /* B 1.3.3 - Derived data types */ |
160 /* B 1.3.3 - Derived data types */ |
268 /********************************/ |
161 /********************************/ |
269 |
|
270 /* identifier ':' array_spec_init */ |
162 /* identifier ':' array_spec_init */ |
|
163 /* NOTE: I don't think this will ever get called, since in the visit method for array_variable_c |
|
164 * we use the basetype_decl for recursively calling this class, and the base type should never be a |
|
165 * array_type_declaration_c, but for now, let's leave it in... |
|
166 */ |
271 void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) { |
167 void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) { |
272 return symbol->array_spec_init->accept(*this); |
168 ERROR; |
|
169 return NULL; |
273 } |
170 } |
274 |
171 |
275 /* array_specification [ASSIGN array_initialization] */ |
172 /* array_specification [ASSIGN array_initialization] */ |
276 /* array_initialization may be NULL ! */ |
173 /* array_initialization may be NULL ! */ |
|
174 /* NOTE: I don't think this will ever get called, since in the visit method for array_variable_c |
|
175 * we use the basetype_decl for recursively calling this class, and the base type should never be a |
|
176 * array_spec_init_c, but for now, let's leave it in... |
|
177 */ |
277 void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) { |
178 void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) { |
278 return symbol->array_specification->accept(*this); |
179 /* Note that the 'array_specification' may be either an identifier of a previsously defined array type, |
|
180 * or an array_specification_c, so we can not stop here and simply return a array_spec_init_c, |
|
181 * especially if we are looking for the base class! |
|
182 */ |
|
183 ERROR; |
|
184 return NULL; |
279 } |
185 } |
280 |
186 |
281 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
187 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
|
188 /* NOTE: This method will be reached after being called from the |
|
189 * search_varfb_instance_type_c::visit(array_variable_c *symbol) |
|
190 * method, so we must return the data type of the data stored in the array, |
|
191 * and not the data type of the array itself! |
|
192 */ |
282 void *search_varfb_instance_type_c::visit(array_specification_c *symbol) { |
193 void *search_varfb_instance_type_c::visit(array_specification_c *symbol) { |
283 this->is_complex = true; |
194 /* found the type of the element we were looking for! */ |
284 this->current_typeid = symbol; |
195 current_type_id = symbol->non_generic_type_name; |
285 return symbol->non_generic_type_name->accept(*this); |
196 current_basetype_decl = search_base_type.get_basetype_decl(current_type_id); |
286 } |
197 current_basetype_id = search_base_type.get_basetype_id (current_type_id); |
|
198 |
|
199 return NULL; |
|
200 } |
|
201 |
287 |
202 |
288 /* structure_type_name ':' structure_specification */ |
203 /* structure_type_name ':' structure_specification */ |
289 /* NOTE: this is only used inside a TYPE ... END_TYPE declaration. |
204 /* NOTE: this is only used inside a TYPE ... END_TYPE declaration. |
290 * It is never used directly when declaring a new variable! |
205 * It is never used directly when declaring a new variable! |
291 */ |
206 */ |
|
207 /* NOTE: I don't think this will ever get called, since in the visit method for structured_variable_c |
|
208 * we use the basetype_decl for recursively calling this class, and the base type should never be a |
|
209 * structure_type_declaration_c, but for now, let's leave it in... |
|
210 */ |
292 void *search_varfb_instance_type_c::visit(structure_type_declaration_c *symbol) { |
211 void *search_varfb_instance_type_c::visit(structure_type_declaration_c *symbol) { |
293 this->is_complex = true; |
212 if (NULL == current_field_selector) ERROR; |
294 |
213 symbol->structure_specification->accept(*this); |
295 if (NULL == current_structelement_name) ERROR; |
214 return NULL; |
296 return symbol->structure_specification->accept(*this); |
|
297 /* NOTE: structure_specification will point to either a |
215 /* NOTE: structure_specification will point to either a |
298 * initialized_structure_c |
216 * initialized_structure_c |
299 * OR A |
217 * OR A |
300 * structure_element_declaration_list_c |
218 * structure_element_declaration_list_c |
301 */ |
219 */ |
302 } |
220 } |
303 |
221 |
304 /* var1_list ':' structure_type_name */ |
|
305 void *search_varfb_instance_type_c::visit(structured_var_declaration_c *symbol) { |
|
306 this->is_complex = true; |
|
307 if (NULL != current_structelement_name) ERROR; |
|
308 |
|
309 /* make sure that we have decomposed all structure elements of the variable name */ |
|
310 symbol_c *var_name = decompose_var_instance_name->next_part(); |
|
311 if (NULL == var_name) { |
|
312 /* this is it... ! |
|
313 * No need to look any further... |
|
314 * Note also that, unlike for the struct types, a function block may |
|
315 * not be defined based on another (i.e. no inheritance is allowed), |
|
316 * so this function block is already the most base type. |
|
317 * We simply return it. |
|
318 */ |
|
319 return (void *)symbol; |
|
320 } |
|
321 |
|
322 /* reset current_type_id because of new structure element part */ |
|
323 this->current_typeid = NULL; |
|
324 |
|
325 /* look for the var_name in the structure declaration */ |
|
326 current_structelement_name = var_name; |
|
327 |
|
328 /* recursively find out the data type of current_structelement_name... */ |
|
329 return symbol->structure_type_name->accept(*this); |
|
330 } |
|
331 |
|
332 /* structure_type_name ASSIGN structure_initialization */ |
222 /* structure_type_name ASSIGN structure_initialization */ |
333 /* structure_initialization may be NULL ! */ |
223 /* structure_initialization may be NULL ! */ |
334 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) |
224 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) |
335 /* NOTE: only the initialized structure is ever used when declaring a new variable instance */ |
225 /* NOTE: only the initialized structure is never used when declaring a new variable instance */ |
|
226 /* NOTE: I don't think this will ever get called, since in the visit method for structured_variable_c |
|
227 * we use the basetype_decl for recursively calling this class, and the base type should never be a |
|
228 * initialized_structure_c, but for now, let's leave it in... |
|
229 */ |
336 void *search_varfb_instance_type_c::visit(initialized_structure_c *symbol) { |
230 void *search_varfb_instance_type_c::visit(initialized_structure_c *symbol) { |
337 this->is_complex = true; |
231 if (NULL != current_field_selector) ERROR; |
338 if (NULL != current_structelement_name) ERROR; |
232 |
339 |
233 /* recursively find out the data type of current_field_selector... */ |
340 /* make sure that we have decomposed all structure elements of the variable name */ |
234 symbol->structure_type_name->accept(*this); |
341 symbol_c *var_name = decompose_var_instance_name->next_part(); |
235 return NULL; |
342 if (NULL == var_name) { |
|
343 /* this is it... ! |
|
344 * No need to look any further... |
|
345 * Note also that, unlike for the struct types, a function block may |
|
346 * not be defined based on another (i.e. no inheritance is allowed), |
|
347 * so this function block is already the most base type. |
|
348 * We simply return it. |
|
349 */ |
|
350 return (void *)symbol; |
|
351 } |
|
352 |
|
353 /* reset current_type_id because of new structure element part */ |
|
354 this->current_typeid = NULL; |
|
355 |
|
356 /* look for the var_name in the structure declaration */ |
|
357 current_structelement_name = var_name; |
|
358 |
|
359 /* recursively find out the data type of current_structelement_name... */ |
|
360 return symbol->structure_type_name->accept(*this); |
|
361 } |
236 } |
362 |
237 |
363 /* helper symbol for structure_declaration */ |
238 /* helper symbol for structure_declaration */ |
364 /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ |
239 /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ |
365 /* structure_element_declaration_list structure_element_declaration ';' */ |
240 /* structure_element_declaration_list structure_element_declaration ';' */ |
366 void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol) { |
241 void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol) { |
367 if (NULL == current_structelement_name) ERROR; |
242 if (NULL == current_field_selector) ERROR; |
|
243 |
368 /* now search the structure declaration */ |
244 /* now search the structure declaration */ |
369 return visit_list(symbol); |
245 for(int i = 0; i < symbol->n; i++) { |
|
246 symbol->elements[i]->accept(*this); |
|
247 } |
|
248 |
|
249 return NULL; |
370 } |
250 } |
371 |
251 |
372 /* structure_element_name ':' spec_init */ |
252 /* structure_element_name ':' spec_init */ |
373 void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) { |
253 void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) { |
374 if (NULL == current_structelement_name) ERROR; |
254 if (NULL == current_field_selector) ERROR; |
375 |
255 |
376 if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) { |
256 if (compare_identifiers(symbol->structure_element_name, current_field_selector) == 0) { |
377 current_structelement_name = NULL; |
|
378 /* found the type of the element we were looking for! */ |
257 /* found the type of the element we were looking for! */ |
379 return symbol->spec_init->accept(*this); |
258 current_type_id = symbol->spec_init; |
|
259 current_basetype_decl = search_base_type.get_basetype_decl(current_type_id); |
|
260 current_basetype_id = search_base_type.get_basetype_id (current_type_id); |
380 } |
261 } |
381 |
262 |
382 /* Did not find the type of the element we were looking for! */ |
263 /* Did not find the type of the element we were looking for! */ |
383 /* Will keep looking... */ |
264 /* Will keep looking... */ |
384 return NULL; |
265 return NULL; |
390 void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
271 void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
391 /* structure_element_name ASSIGN value */ |
272 /* structure_element_name ASSIGN value */ |
392 void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
273 void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
393 |
274 |
394 |
275 |
|
276 /*********************/ |
|
277 /* B 1.4 - Variables */ |
|
278 /*********************/ |
|
279 // SYM_REF1(symbolic_variable_c, var_name) |
|
280 void *search_varfb_instance_type_c::visit(symbolic_variable_c *symbol) { |
|
281 symbol->var_name->accept(*this); |
|
282 return NULL; |
|
283 } |
|
284 |
|
285 /********************************************/ |
|
286 /* B.1.4.1 Directly Represented Variables */ |
|
287 /********************************************/ |
|
288 // SYM_TOKEN(direct_variable_c) |
|
289 /* We do not yet handle this. Will we ever need to handle it, as the data type of the direct variable is |
|
290 * directly obtainable from the syntax of the direct variable itself? |
|
291 */ |
|
292 |
|
293 /*************************************/ |
|
294 /* B 1.4.2 - Multi-element variables */ |
|
295 /*************************************/ |
|
296 /* subscripted_variable '[' subscript_list ']' */ |
|
297 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list) |
|
298 /* NOTE: when passed a array_variable_c, which represents some IEC61131-3 code similar to X[42] |
|
299 * we must return the data type of the value _stored_ in the array. |
|
300 * If you want to get the data type of the array itself (i.e. just the X variable, without the [42]) |
|
301 * then this class must be called with the identifier_c 'X'. |
|
302 */ |
|
303 void *search_varfb_instance_type_c::visit(array_variable_c *symbol) { |
|
304 /* determine the data type of the subscripted_variable... |
|
305 * This should be an array_specification_c |
|
306 * ARRAY [xx..yy] OF Stored_Data_Type |
|
307 */ |
|
308 symbol->subscripted_variable->accept(*this); |
|
309 symbol_c *basetype_decl = current_basetype_decl; |
|
310 this->init(); /* set all current_*** pointers to NULL ! */ |
|
311 |
|
312 /* Now we determine the 'Stored_Data_Type', i.e. the data type of the variable stored in the array. */ |
|
313 if (NULL != basetype_decl) { |
|
314 basetype_decl->accept(*this); |
|
315 } |
|
316 |
|
317 return NULL; |
|
318 } |
|
319 |
|
320 |
|
321 /* record_variable '.' field_selector */ |
|
322 /* WARNING: input and/or output variables of function blocks |
|
323 * may be accessed as fields of a structured variable! |
|
324 * Code handling a structured_variable_c must take this into account! |
|
325 * (i.e. that a FB instance may be accessed as a structured variable)! |
|
326 * |
|
327 * WARNING: Status bit (.X) and activation time (.T) of STEPS in SFC diagrams |
|
328 * may be accessed as fields of a structured variable! |
|
329 * Code handling a structured_variable_c must take this into account |
|
330 * (i.e. that an SFC STEP may be accessed as a structured variable)! |
|
331 */ |
|
332 // SYM_REF2(structured_variable_c, record_variable, field_selector) |
|
333 void *search_varfb_instance_type_c::visit(structured_variable_c *symbol) { |
|
334 symbol->record_variable->accept(*this); |
|
335 symbol_c *basetype_decl = current_basetype_decl; |
|
336 this->init(); /* set all current_*** pointers to NULL ! */ |
|
337 |
|
338 /* Now we search for the data type of the field... But only if we were able to determine the data type of the variable */ |
|
339 if (NULL != basetype_decl) { |
|
340 current_field_selector = symbol->field_selector; |
|
341 basetype_decl->accept(*this); |
|
342 current_field_selector = NULL; |
|
343 } |
|
344 |
|
345 return NULL; |
|
346 } |
|
347 |
|
348 |
395 |
349 |
396 /**************************************/ |
350 /**************************************/ |
397 /* B.1.5 - Program organization units */ |
351 /* B.1.5 - Program organization units */ |
398 /**************************************/ |
352 /**************************************/ |
399 /*****************************/ |
353 /*****************************/ |
400 /* B 1.5.2 - Function Blocks */ |
354 /* B 1.5.2 - Function Blocks */ |
401 /*****************************/ |
355 /*****************************/ |
|
356 |
402 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
357 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
403 // SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) |
358 // SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) |
404 void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) { |
359 void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) { |
405 /* make sure that we have decomposed all structure elements of the variable name */ |
360 if (NULL == current_field_selector) ERROR; |
406 symbol_c *var_name = decompose_var_instance_name->next_part(); |
361 |
407 if (NULL == var_name) { |
362 /* now search the function block declaration for the variable... */ |
408 /* this is it... ! |
363 /* If not found, these pointers will all be set to NULL!! */ |
409 * No need to look any further... |
364 search_var_instance_decl_c search_decl(symbol); |
410 * Note also that, unlike for the struct types, a function block may |
365 current_type_id = search_decl.get_decl(current_field_selector); |
411 * not be defined based on another (i.e. no inheritance is allowed), |
366 current_basetype_decl = search_base_type.get_basetype_decl(current_type_id); |
412 * so this function block is already the most base type. |
367 current_basetype_id = search_base_type.get_basetype_id (current_type_id); |
413 * We simply return it. |
368 |
414 */ |
369 return NULL; |
415 return (void *)symbol; |
370 } |
416 } |
371 |
417 |
372 |
418 /* reset current_type_id because of new structure element part */ |
373 |
419 this->current_typeid = NULL; |
374 /*********************************************/ |
420 |
375 /* B.1.6 Sequential function chart elements */ |
421 /* now search the function block declaration for the variable... */ |
376 /*********************************************/ |
422 search_var_instance_decl_c search_decl(symbol); |
377 /* INITIAL_STEP step_name ':' action_association_list END_STEP */ |
423 symbol_c *var_decl = search_decl.get_decl(var_name); |
378 // SYM_REF2(initial_step_c, step_name, action_association_list) |
424 if (NULL == var_decl) { |
379 /* NOTE: this method may be called from visit(structured_variable_c *symbol) method| */ |
425 /* variable instance declaration not found! */ |
380 void *search_varfb_instance_type_c::visit(initial_step_c *symbol) { |
426 return NULL; |
381 if (NULL == current_field_selector) ERROR; |
427 } |
382 |
428 #if 0 |
383 identifier_c T("T"); |
429 /* We have found the declaration. |
384 identifier_c X("X"); |
430 * Should we look any further? |
385 |
431 */ |
386 if (compare_identifiers(&T, current_field_selector) == 0) |
432 var_name = decompose_var_instance_name->next_part(); |
387 current_type_id = &search_constant_type_c::time_type_name; |
433 if (NULL == var_name) { |
388 if (compare_identifiers(&X, current_field_selector) == 0) |
434 /* this is it... ! */ |
389 current_type_id = &search_constant_type_c::bool_type_name; |
435 return base_type(var_decl); |
390 |
436 } |
391 current_basetype_decl = search_base_type.get_basetype_decl(current_type_id); |
437 |
392 current_basetype_id = search_base_type.get_basetype_id (current_type_id); |
438 current_structelement_name = var_name; |
393 |
439 /* recursively find out the data type of var_name... */ |
394 return NULL; |
440 return symbol->var_declarations->accept(*this); |
395 } |
441 #endif |
396 |
442 /* carry on recursively, in case the variable has more elements to be decomposed... */ |
397 |
443 return var_decl->accept(*this); |
398 /* STEP step_name ':' action_association_list END_STEP */ |
444 } |
399 // SYM_REF2(step_c, step_name, action_association_list) |
|
400 /* NOTE: this method may be called from visit(structured_variable_c *symbol) method| */ |
|
401 void *search_varfb_instance_type_c::visit(step_c *symbol) { |
|
402 /* The code here should be identicial to the code in the visit(initial_step_c *) visitor! So we simply call the other visitor! */ |
|
403 initial_step_c initial_step(NULL, NULL); |
|
404 return initial_step.accept(*this); |
|
405 } |