52 /* pointer to singleton instance */ |
52 /* pointer to singleton instance */ |
53 search_base_type_c *search_base_type_c::search_base_type_singleton = NULL; |
53 search_base_type_c *search_base_type_c::search_base_type_singleton = NULL; |
54 |
54 |
55 |
55 |
56 |
56 |
57 search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;} |
57 search_base_type_c::search_base_type_c(void) {current_basetype_name = NULL; current_basetype = NULL; current_equivtype = NULL;} |
58 |
58 |
59 /* static method! */ |
59 /* static method! */ |
60 void search_base_type_c::create_singleton(void) { |
60 void search_base_type_c::create_singleton(void) { |
61 if (NULL == search_base_type_singleton) search_base_type_singleton = new search_base_type_c(); |
61 if (NULL == search_base_type_singleton) search_base_type_singleton = new search_base_type_c(); |
62 if (NULL == search_base_type_singleton) ERROR; |
62 if (NULL == search_base_type_singleton) ERROR; |
63 } |
63 } |
64 |
64 |
65 /* static method! */ |
65 /* static method! */ |
|
66 symbol_c *search_base_type_c::get_equivtype_decl(symbol_c *symbol) { |
|
67 create_singleton(); |
|
68 if (NULL == symbol) return NULL; |
|
69 search_base_type_singleton->current_basetype_name = NULL; |
|
70 search_base_type_singleton->current_basetype = NULL; |
|
71 search_base_type_singleton->current_equivtype = NULL; |
|
72 symbol_c *basetype = (symbol_c *)symbol->accept(*search_base_type_singleton); |
|
73 if (NULL != search_base_type_singleton->current_equivtype) |
|
74 return search_base_type_singleton->current_equivtype; |
|
75 return basetype; |
|
76 } |
|
77 |
|
78 /* static method! */ |
66 symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) { |
79 symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) { |
67 create_singleton(); |
80 create_singleton(); |
68 if (NULL == symbol) return NULL; |
81 if (NULL == symbol) return NULL; |
69 search_base_type_singleton->current_type_name = NULL; |
82 search_base_type_singleton->current_basetype_name = NULL; |
70 search_base_type_singleton->current_basetype = NULL; |
83 search_base_type_singleton->current_basetype = NULL; |
|
84 search_base_type_singleton->current_equivtype = NULL; |
71 return (symbol_c *)symbol->accept(*search_base_type_singleton); |
85 return (symbol_c *)symbol->accept(*search_base_type_singleton); |
72 } |
86 } |
73 |
87 |
74 /* static method! */ |
88 /* static method! */ |
75 symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) { |
89 symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) { |
76 create_singleton(); |
90 create_singleton(); |
77 if (NULL == symbol) return NULL; |
91 if (NULL == symbol) return NULL; |
78 search_base_type_singleton->current_type_name = NULL; |
92 search_base_type_singleton->current_basetype_name = NULL; |
79 search_base_type_singleton->current_basetype = NULL; |
93 search_base_type_singleton->current_basetype = NULL; |
|
94 search_base_type_singleton->current_equivtype = NULL; |
80 symbol->accept(*search_base_type_singleton); |
95 symbol->accept(*search_base_type_singleton); |
81 return (symbol_c *)search_base_type_singleton->current_type_name; |
96 return (symbol_c *)search_base_type_singleton->current_basetype_name; |
82 } |
97 } |
83 |
98 |
84 |
99 |
85 /* Note by MJS: The following two functions definately do not belong in this class!! Maybe create a new utility class? |
|
86 * I will need to clean this up when the opportunity arises! |
|
87 */ |
|
88 /* static method! */ |
|
89 bool search_base_type_c::type_is_subrange(symbol_c* type_decl) { |
|
90 create_singleton(); |
|
91 search_base_type_singleton->is_subrange = false; |
|
92 type_decl->accept(*search_base_type_singleton); |
|
93 return search_base_type_singleton->is_subrange; |
|
94 } |
|
95 |
|
96 |
|
97 /* static method! */ |
|
98 bool search_base_type_c::type_is_enumerated(symbol_c* type_decl) { |
|
99 create_singleton(); |
|
100 search_base_type_singleton->is_enumerated = false; |
|
101 type_decl->accept(*search_base_type_singleton); |
|
102 return search_base_type_singleton->is_enumerated; |
|
103 } |
|
104 |
|
105 bool search_base_type_c::type_is_fb(symbol_c* type_decl) { |
|
106 create_singleton(); |
|
107 search_base_type_singleton->is_fb = false; |
|
108 type_decl->accept(*search_base_type_singleton); |
|
109 return search_base_type_singleton->is_fb; |
|
110 } |
|
111 |
100 |
112 /*************************/ |
101 /*************************/ |
113 /* B.1 - Common elements */ |
102 /* B.1 - Common elements */ |
114 /*************************/ |
103 /*************************/ |
115 |
104 |
117 /* B 1.1 - Letters, digits and identifiers */ |
106 /* B 1.1 - Letters, digits and identifiers */ |
118 /*******************************************/ |
107 /*******************************************/ |
119 void *search_base_type_c::visit(identifier_c *type_name) { |
108 void *search_base_type_c::visit(identifier_c *type_name) { |
120 symbol_c *type_decl; |
109 symbol_c *type_decl; |
121 |
110 |
122 this->current_type_name = type_name; |
111 this->current_basetype_name = type_name; |
123 /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for, |
112 /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for, |
124 * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!) |
113 * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!) |
125 */ |
114 */ |
126 this->current_basetype = NULL; |
115 this->current_basetype = NULL; |
127 |
116 |
234 return symbol->simple_specification->accept(*this); |
223 return symbol->simple_specification->accept(*this); |
235 } |
224 } |
236 |
225 |
237 /* subrange_type_name ':' subrange_spec_init */ |
226 /* subrange_type_name ':' subrange_spec_init */ |
238 void *search_base_type_c::visit(subrange_type_declaration_c *symbol) { |
227 void *search_base_type_c::visit(subrange_type_declaration_c *symbol) { |
|
228 this->current_equivtype = symbol; |
239 return symbol->subrange_spec_init->accept(*this); |
229 return symbol->subrange_spec_init->accept(*this); |
240 } |
230 } |
241 |
231 |
242 /* subrange_specification ASSIGN signed_integer */ |
232 /* subrange_specification ASSIGN signed_integer */ |
243 void *search_base_type_c::visit(subrange_spec_init_c *symbol) { |
233 void *search_base_type_c::visit(subrange_spec_init_c *symbol) { |
244 this->is_subrange = true; |
234 if (NULL == this->current_equivtype) |
|
235 this->current_equivtype = symbol; |
245 return symbol->subrange_specification->accept(*this); |
236 return symbol->subrange_specification->accept(*this); |
246 } |
237 } |
247 |
238 |
248 /* integer_type_name '(' subrange')' */ |
239 /* integer_type_name '(' subrange')' */ |
249 void *search_base_type_c::visit(subrange_specification_c *symbol) { |
240 void *search_base_type_c::visit(subrange_specification_c *symbol) { |
|
241 if (NULL == this->current_equivtype) |
|
242 this->current_equivtype = symbol; |
250 return symbol->integer_type_name->accept(*this); |
243 return symbol->integer_type_name->accept(*this); |
251 } |
244 } |
252 |
245 |
253 /* signed_integer DOTDOT signed_integer */ |
246 /* signed_integer DOTDOT signed_integer */ |
254 void *search_base_type_c::visit(subrange_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
247 void *search_base_type_c::visit(subrange_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
255 |
248 |
256 /* enumerated_type_name ':' enumerated_spec_init */ |
249 /* enumerated_type_name ':' enumerated_spec_init */ |
257 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { |
250 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { |
258 this->current_type_name = symbol->enumerated_type_name; |
251 this->current_basetype_name = symbol->enumerated_type_name; |
259 /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible |
252 /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible |
260 * (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an |
253 * (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an |
261 * anonymous datatype declared in a VAR ... AND_VAR declaration). |
254 * anonymous datatype declared in a VAR ... AND_VAR declaration). |
262 * However, we cannot return this symbol just yet, as it may not be the final base datatype. |
255 * However, we cannot return this symbol just yet, as it may not be the final base datatype. |
263 * So we store it in a temporary current_basetype variable! |
256 * So we store it in a temporary current_basetype variable! |
266 return symbol->enumerated_spec_init->accept(*this); |
259 return symbol->enumerated_spec_init->accept(*this); |
267 } |
260 } |
268 |
261 |
269 /* enumerated_specification ASSIGN enumerated_value */ |
262 /* enumerated_specification ASSIGN enumerated_value */ |
270 void *search_base_type_c::visit(enumerated_spec_init_c *symbol) { |
263 void *search_base_type_c::visit(enumerated_spec_init_c *symbol) { |
271 this->is_enumerated = true; |
|
272 // current_basetype may have been set in the previous enumerated_type_declaration_c visitor, in which case we do not want to overwrite the value! |
264 // current_basetype may have been set in the previous enumerated_type_declaration_c visitor, in which case we do not want to overwrite the value! |
273 if (NULL == this->current_basetype) |
265 if (NULL == this->current_basetype) |
274 this->current_basetype = symbol; |
266 this->current_basetype = symbol; |
275 /* NOTE: the following line may call either the visitor to |
267 /* NOTE: the following line may call either the visitor to |
276 * - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!) |
268 * - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!) |
280 } |
272 } |
281 |
273 |
282 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
274 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
283 /* enumerated_value_list ',' enumerated_value */ |
275 /* enumerated_value_list ',' enumerated_value */ |
284 void *search_base_type_c::visit(enumerated_value_list_c *symbol) { |
276 void *search_base_type_c::visit(enumerated_value_list_c *symbol) { |
285 this->is_enumerated = true; |
|
286 // current_basetype may have been set in the previous enumerated_type_declaration_c or enumerated_spec_init_c visitors, in which case we do not want to overwrite the value! |
277 // current_basetype may have been set in the previous enumerated_type_declaration_c or enumerated_spec_init_c visitors, in which case we do not want to overwrite the value! |
287 if (NULL == this->current_basetype) |
278 if (NULL == this->current_basetype) |
288 this->current_basetype = symbol; |
279 this->current_basetype = symbol; |
289 return (void *)current_basetype; |
280 return (void *)current_basetype; |
290 } |
281 } |
293 // SYM_REF2(enumerated_value_c, type, value) |
284 // SYM_REF2(enumerated_value_c, type, value) |
294 void *search_base_type_c::visit(enumerated_value_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
285 void *search_base_type_c::visit(enumerated_value_c *symbol) {ERROR; return NULL;} /* should never get called... */ |
295 |
286 |
296 /* identifier ':' array_spec_init */ |
287 /* identifier ':' array_spec_init */ |
297 void *search_base_type_c::visit(array_type_declaration_c *symbol) { |
288 void *search_base_type_c::visit(array_type_declaration_c *symbol) { |
298 this->current_type_name = symbol->identifier; |
289 this->current_basetype_name = symbol->identifier; |
299 return symbol->array_spec_init->accept(*this); |
290 return symbol->array_spec_init->accept(*this); |
300 } |
291 } |
301 |
292 |
302 /* array_specification [ASSIGN array_initialization} */ |
293 /* array_specification [ASSIGN array_initialization} */ |
303 /* array_initialization may be NULL ! */ |
294 /* array_initialization may be NULL ! */ |
330 * initialized_structure_c |
321 * initialized_structure_c |
331 * OR A |
322 * OR A |
332 * structure_element_declaration_list_c |
323 * structure_element_declaration_list_c |
333 */ |
324 */ |
334 void *search_base_type_c::visit(structure_type_declaration_c *symbol) { |
325 void *search_base_type_c::visit(structure_type_declaration_c *symbol) { |
335 this->current_type_name = symbol->structure_type_name; |
326 this->current_basetype_name = symbol->structure_type_name; |
336 return symbol->structure_specification->accept(*this); |
327 return symbol->structure_specification->accept(*this); |
337 } |
328 } |
338 |
329 |
339 /* var1_list ':' structure_type_name */ |
330 /* var1_list ':' structure_type_name */ |
340 void *search_base_type_c::visit(structured_var_declaration_c *symbol) { |
331 void *search_base_type_c::visit(structured_var_declaration_c *symbol) { |
386 /* B 1.5.2 - Function Blocks */ |
377 /* B 1.5.2 - Function Blocks */ |
387 /*****************************/ |
378 /*****************************/ |
388 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
379 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
389 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) |
380 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) |
390 void *search_base_type_c::visit(function_block_declaration_c *symbol) { |
381 void *search_base_type_c::visit(function_block_declaration_c *symbol) { |
391 this->is_fb = true; |
|
392 return (void *)symbol; |
382 return (void *)symbol; |
393 } |
383 } |
394 |
384 |
395 |
385 |
396 |
386 |
398 /* B.1.6 Sequential function chart elements */ |
388 /* B.1.6 Sequential function chart elements */ |
399 /*********************************************/ |
389 /*********************************************/ |
400 /* INITIAL_STEP step_name ':' action_association_list END_STEP */ |
390 /* INITIAL_STEP step_name ':' action_association_list END_STEP */ |
401 // SYM_REF2(initial_step_c, step_name, action_association_list) |
391 // SYM_REF2(initial_step_c, step_name, action_association_list) |
402 void *search_base_type_c::visit(initial_step_c *symbol) { |
392 void *search_base_type_c::visit(initial_step_c *symbol) { |
403 this->current_type_name = NULL; /* this pseudo data type does not have a type name! */ |
393 this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */ |
404 return (void *)symbol; |
394 return (void *)symbol; |
405 } |
395 } |
406 |
396 |
407 /* STEP step_name ':' action_association_list END_STEP */ |
397 /* STEP step_name ':' action_association_list END_STEP */ |
408 // SYM_REF2(step_c, step_name, action_association_list) |
398 // SYM_REF2(step_c, step_name, action_association_list) |
409 void *search_base_type_c::visit(step_c *symbol) { |
399 void *search_base_type_c::visit(step_c *symbol) { |
410 this->current_type_name = NULL; /* this pseudo data type does not have a type name! */ |
400 this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */ |
411 return (void *)symbol; |
401 return (void *)symbol; |
412 } |
402 } |
413 |
403 |