# HG changeset patch # User Mario de Sousa # Date 1352829797 0 # Node ID 9b61eb4f00dc68ae77ba5fc2a92c1c394e3c1b7f # Parent bfbe4aca6b77dbb49813eb019263deb27f02971a Change the base datatype of enumerations to an enumerated_type_declaration_c (for named types!) diff -r bfbe4aca6b77 -r 9b61eb4f00dc absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/absyntax_utils/absyntax_utils.cc Tue Nov 13 18:03:17 2012 +0000 @@ -193,7 +193,7 @@ /* enumerated_type_name ':' enumerated_spec_init */ void *visit(enumerated_type_declaration_c *symbol) { TRACE("enumerated_type_declaration_c"); - type_symtable.insert(symbol->enumerated_type_name, symbol->enumerated_spec_init); + type_symtable.insert(symbol->enumerated_type_name, symbol); current_enumerated_type = symbol->enumerated_type_name; symbol->enumerated_spec_init->accept(*this); current_enumerated_type = NULL; diff -r bfbe4aca6b77 -r 9b61eb4f00dc absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/absyntax_utils/search_base_type.cc Tue Nov 13 18:03:17 2012 +0000 @@ -54,7 +54,7 @@ -search_base_type_c::search_base_type_c(void) {current_type_name = NULL;} +search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;} /* static method! */ void search_base_type_c::create_singleton(void) { @@ -66,15 +66,17 @@ symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) { create_singleton(); if (NULL == symbol) return NULL; + search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype = NULL; return (symbol_c *)symbol->accept(*search_base_type_singleton); } /* static method! */ symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) { create_singleton(); - if (NULL == symbol) return NULL; - + if (NULL == symbol) return NULL; search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype = NULL; symbol->accept(*search_base_type_singleton); return (symbol_c *)search_base_type_singleton->current_type_name; } @@ -112,6 +114,10 @@ symbol_c *type_decl; this->current_type_name = type_name; + /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for, + * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!) + */ + this->current_basetype = NULL; /* look up the type declaration... */ type_decl = type_symtable.find_value(type_name); @@ -244,20 +250,37 @@ /* enumerated_type_name ':' enumerated_spec_init */ void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { this->current_type_name = symbol->enumerated_type_name; + /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible + * (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an + * anonymous datatype declared in a VAR ... AND_VAR declaration). + * However, we cannot return this symbol just yet, as it may not be the final base datatype. + * So we store it in a temporary current_basetype variable! + */ + this->current_basetype = symbol; return symbol->enumerated_spec_init->accept(*this); } /* enumerated_specification ASSIGN enumerated_value */ void *search_base_type_c::visit(enumerated_spec_init_c *symbol) { this->is_enumerated = true; - return symbol->enumerated_specification->accept(*this); + // 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! + if (NULL == this->current_basetype) + this->current_basetype = symbol; + /* NOTE: the following line may call either the visitor to + * - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!) + * - enumerated_value_list_c, in which case we have found the base datatype. + */ + return symbol->enumerated_specification->accept(*this); } /* helper symbol for enumerated_specification->enumerated_spec_init */ /* enumerated_value_list ',' enumerated_value */ void *search_base_type_c::visit(enumerated_value_list_c *symbol) { this->is_enumerated = true; - return (void *)symbol; + // 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! + if (NULL == this->current_basetype) + this->current_basetype = symbol; + return (void *)current_basetype; } /* enumerated_type_name '#' identifier */ diff -r bfbe4aca6b77 -r 9b61eb4f00dc absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Tue Nov 13 18:02:15 2012 +0000 +++ b/absyntax_utils/search_base_type.hh Tue Nov 13 18:03:17 2012 +0000 @@ -52,6 +52,7 @@ private: symbol_c *current_type_name; + symbol_c *current_basetype; bool is_array; bool is_subrange; bool is_enumerated; diff -r bfbe4aca6b77 -r 9b61eb4f00dc stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/stage3/fill_candidate_datatypes.cc Tue Nov 13 18:03:17 2012 +0000 @@ -896,20 +896,14 @@ /* enumerated_value_list ',' enumerated_value */ // SYM_LIST(enumerated_value_list_c) void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { - if (NULL == current_enumerated_spec_type) ERROR; - - /* Actually, all this passing of symbol_c * through the current_enumerated_spec_type is actually useless, as the base type - * is actually this enumerated_value_list_c symbol!!! However, it is safer to do it this way, as we can then later change - * search_base_type_c without having to change this fill_candidate_datatypes_c class too!! - */ + if (NULL == current_enumerated_spec_type) ERROR; current_enumerated_spec_type = base_type(current_enumerated_spec_type); if (NULL == current_enumerated_spec_type) ERROR; /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */ - for(int i = 0; i < symbol->n; i++) { + for(int i = 0; i < symbol->n; i++) add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); - symbol->elements[i]->datatype = current_enumerated_spec_type; // To be consistent, this should really be done in the narrow_candidate_datatypes_c !! - } + return NULL; } diff -r bfbe4aca6b77 -r 9b61eb4f00dc stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Tue Nov 13 18:03:17 2012 +0000 @@ -414,9 +414,8 @@ return search_base_type_c::get_basetype_decl(symbol); } -/*********************/ -/* B 1.2 - Constants */ -/*********************/ + + /**********************/ /* B 1.3 - Data types */ @@ -424,6 +423,18 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +/* TYPE type_declaration_list END_TYPE */ +// SYM_REF1(data_type_declaration_c, type_declaration_list) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + +/* helper symbol for data_type_declaration */ +// SYM_LIST(type_declaration_list_c) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + +/* simple_type_name ':' simple_spec_init */ +// SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + /* simple_specification ASSIGN constant */ // SYM_REF2(simple_spec_init_c, simple_specification, constant) void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { @@ -441,9 +452,18 @@ } +/* subrange_type_name ':' subrange_spec_init */ +// SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init) + +/* subrange_specification ASSIGN signed_integer */ +// SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer) + +/* integer_type_name '(' subrange')' */ +// SYM_REF2(subrange_specification_c, integer_type_name, subrange) /* signed_integer DOTDOT signed_integer */ -// SYM_REF2(subrange_c, lower_limit, upper_limit) +/* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */ +// SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;) void *narrow_candidate_datatypes_c::visit(subrange_c *symbol) { symbol->lower_limit->datatype = symbol->datatype; symbol->lower_limit->accept(*this); @@ -453,6 +473,113 @@ } +/* enumerated_type_name ':' enumerated_spec_init */ +// SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) +void *narrow_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) { + symbol->datatype = search_base_type_c::get_basetype_decl(symbol); + symbol->enumerated_type_name->datatype = symbol->datatype; + symbol->enumerated_spec_init->datatype = symbol->datatype; + + symbol->enumerated_spec_init->accept(*this); + return NULL; +} + + +/* enumerated_specification ASSIGN enumerated_value */ +// SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) +void *narrow_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) { + /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration) + * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method! + */ + if (NULL == symbol->datatype) + symbol->datatype = search_base_type_c::get_basetype_decl(symbol); + symbol->enumerated_specification->datatype = symbol->datatype; + if (NULL != symbol->enumerated_value) + /* the enumerated_value_c object to which this list points to has both the datatype and the candidate_datatype_list filled in, so we + * call set_datatype() instead of setting the datatype directly! + * If the desired datatype does not match the datatypes in the candidate list, then the source code has a bug that will be caught by + * print_datatypes_error_c + */ + set_datatype(symbol->datatype, symbol->enumerated_value); + + symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */ + return NULL; +} + +/* helper symbol for enumerated_specification->enumerated_spec_init */ +/* enumerated_value_list ',' enumerated_value */ +// SYM_LIST(enumerated_value_list_c) +void *narrow_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { + if (NULL == symbol->datatype) ERROR; + + for(int i = 0; i < symbol->n; i++) { + /* the enumerated_value_c objects to which this list points to has both the datatype and the candidate_datatype_list filled in, so we + * call set_datatype() instead of setting the datatype directly! + */ + set_datatype(symbol->datatype, symbol->elements[i]); + if (NULL == symbol->elements[i]->datatype) ERROR; + } + return NULL; +} + + +/* enumerated_type_name '#' identifier */ +// SYM_REF2(enumerated_value_c, type, value) +// void *narrow_candidate_datatypes_c::visit(enumerated_value_c *symbol) {/* do nothing! */ return NULL;} + + +/* identifier ':' array_spec_init */ +// SYM_REF2(array_type_declaration_c, identifier, array_spec_init) + +/* array_specification [ASSIGN array_initialization} */ +/* array_initialization may be NULL ! */ +// SYM_REF2(array_spec_init_c, array_specification, array_initialization) + +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +// SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name) + +/* helper symbol for array_specification */ +/* array_subrange_list ',' subrange */ +// SYM_LIST(array_subrange_list_c) + +/* array_initialization: '[' array_initial_elements_list ']' */ +/* helper symbol for array_initialization */ +/* array_initial_elements_list ',' array_initial_elements */ +// SYM_LIST(array_initial_elements_list_c) + +/* integer '(' [array_initial_element] ')' */ +/* array_initial_element may be NULL ! */ +// SYM_REF2(array_initial_elements_c, integer, array_initial_element) + +/* structure_type_name ':' structure_specification */ +// SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification) + +/* structure_type_name ASSIGN structure_initialization */ +/* structure_initialization may be NULL ! */ +// SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) + +/* helper symbol for structure_declaration */ +/* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ +/* structure_element_declaration_list structure_element_declaration ';' */ +// SYM_LIST(structure_element_declaration_list_c) + +/* structure_element_name ':' *_spec_init */ +// SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init) + +/* helper symbol for structure_initialization */ +/* structure_initialization: '(' structure_element_initialization_list ')' */ +/* structure_element_initialization_list ',' structure_element_initialization */ +// SYM_LIST(structure_element_initialization_list_c) + +/* structure_element_name ASSIGN value */ +// SYM_REF2(structure_element_initialization_c, structure_element_name, value) + +/* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ +// SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) + + + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r bfbe4aca6b77 -r 9b61eb4f00dc stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Tue Nov 13 18:02:15 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.hh Tue Nov 13 18:03:17 2012 +0000 @@ -96,8 +96,31 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +// void *visit(data_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ +// void *visit(type_declaration_list_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ +// void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ + void *visit(simple_spec_init_c *symbol); +// void *visit(subrange_type_declaration_c *symbol); +// void *visit(subrange_spec_init_c *symbol); +// void *visit(subrange_specification_c *symbol); void *visit(subrange_c *symbol); - void *visit(simple_spec_init_c *symbol); + void *visit(enumerated_type_declaration_c *symbol); + void *visit(enumerated_spec_init_c *symbol); + void *visit(enumerated_value_list_c *symbol); +// void *visit(enumerated_value_c *symbol); /* Not required */ +// void *visit(array_type_declaration_c *symbol); +// void *visit(array_spec_init_c *symbol); +// void *visit(array_specification_c *symbol); +// void *visit(array_subrange_list_c *symbol); +// void *visit(array_initial_elements_list_c *symbol); +// void *visit(array_initial_elements_c *symbol); +// void *visit(structure_type_declaration_c *symbol); +// void *visit(initialized_structure_c *symbol); +// void *visit(structure_element_declaration_list_c *symbol); +// void *visit(structure_element_declaration_c *symbol); +// void *visit(structure_element_initialization_list_c *symbol); +// void *visit(structure_element_initialization_c *symbol); +// void *visit(string_type_declaration_c *symbol); /*********************/ /* B 1.4 - Variables */ diff -r bfbe4aca6b77 -r 9b61eb4f00dc stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/stage4/generate_c/generate_c_typedecl.cc Tue Nov 13 18:03:17 2012 +0000 @@ -317,7 +317,10 @@ if (current_typedefinition == enumerated_td) current_type_name->accept(*basedecl); else { - if (NULL == symbol->datatype) ERROR; + if (NULL == symbol->datatype) { + debug_c::print(symbol); + ERROR; + } symbol->datatype->accept(*basedecl); } s4o_incl.print("__"); diff -r bfbe4aca6b77 -r 9b61eb4f00dc stage4/generate_c/generate_var_list.cc --- a/stage4/generate_c/generate_var_list.cc Tue Nov 13 18:02:15 2012 +0000 +++ b/stage4/generate_c/generate_var_list.cc Tue Nov 13 18:03:17 2012 +0000 @@ -382,6 +382,40 @@ } } + +/********************************/ +/* B 1.3.3 - Derived data types */ +/********************************/ + /* enumerated_type_name ':' enumerated_spec_init */ + void *visit(enumerated_type_declaration_c *symbol) { + this->current_var_type_name->accept(*this); + return NULL; + } + + /* enumerated_specification ASSIGN enumerated_value */ + void *visit(enumerated_spec_init_c *symbol) { + /* search_base_type_c now returns an enumerated_type_declaration_c as the base type of a non-anonymous enumerated type + * (non-anonymous means it is declared inside a TYPE ... END_TYPE declaration, with a given name/identifier + * unlike implicitly defined anonymous datatypes declared inside VAR ... END_VAR declarations!). + * This means that this method should not get called. + */ + ERROR; + this->current_var_type_name->accept(*this); + return NULL; + } + + /* enumerated_value_list ',' enumerated_value */ + void *visit(enumerated_value_list_c *symbol) { + /* search_base_type_c now returns an enumerated_type_declaration_c as the base type of a non-anonymous enumerated type + * (non-anonymous means it is declared inside a TYPE ... END_TYPE declaration, with a given name/identifier + * unlike implicitly defined anonymous datatypes declared inside VAR ... END_VAR declarations!). + * This means that this method should not get called. + */ + ERROR; + this->current_var_type_name->accept(*this); + return NULL; + } + /********************************************/ /* B.1.4.3 - Declaration and initialization */ /********************************************/ @@ -556,12 +590,7 @@ return NULL; } - /* enumerated_value_list ',' enumerated_value */ - void *visit(enumerated_value_list_c *symbol) { - this->current_var_type_name->accept(*this); - return NULL; - } - + /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */ /* structure_initialization -> may be NULL ! */ void *visit(fb_name_decl_c *symbol) {