# HG changeset patch # User laurent # Date 1309280595 -7200 # Node ID 66cd5d9893dd6b6fde837fa353120b0718289484 # Parent da78d0d93c754bf821d2a4c15b4bd112c1803b98 Add support for finding type of a constant enumerated value and managing conflict between same identifiers defined in different enumerated data types diff -r da78d0d93c75 -r 66cd5d9893dd absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Mon Jun 27 18:01:43 2011 +0200 +++ b/absyntax_utils/absyntax_utils.cc Tue Jun 28 19:03:15 2011 +0200 @@ -121,6 +121,11 @@ symbol_c null_symbol4; symtable_c type_symtable; +/* A symbol table with all values declared for enumerated type... */ +/* Note that if the value is defined multiple times the value + * is the null pointer. + */ +symtable_c enumerated_value_symtable; /***********************************************************************/ @@ -131,8 +136,13 @@ class populate_symtables_c: public iterator_visitor_c { - public: - populate_symtables_c(void) {}; + private: + symbol_c *current_enumerated_type; + + public: + populate_symtables_c(void) { + current_enumerated_type = NULL; + }; virtual ~populate_symtables_c(void) {} @@ -187,9 +197,32 @@ void *visit(enumerated_type_declaration_c *symbol) { TRACE("enumerated_type_declaration_c"); type_symtable.insert(symbol->enumerated_type_name, symbol->enumerated_spec_init); - return NULL; - } - + current_enumerated_type = symbol->enumerated_type_name; + symbol->enumerated_spec_init->accept(*this); + current_enumerated_type = NULL; + return NULL; + } + + /* enumerated_specification ASSIGN enumerated_value */ + void *visit(enumerated_spec_init_c *symbol) { + return symbol->enumerated_specification->accept(*this); + } + + /* [enumerated_type_name '#'] identifier */ + void *visit(enumerated_value_c *symbol) { + if (current_enumerated_type != NULL) { + if (symbol->type != NULL) ERROR; + + symbol_c *value_type = enumerated_value_symtable.find_value(symbol->value); + if (value_type == current_enumerated_type) ERROR; + + if (value_type == enumerated_value_symtable.end_value()) + enumerated_value_symtable.insert(symbol->value, current_enumerated_type); + else if (value_type != NULL) + enumerated_value_symtable.set(symbol->value, NULL); + } + return NULL; + } /* identifier ':' array_spec_init */ void *visit(array_type_declaration_c *symbol) { diff -r da78d0d93c75 -r 66cd5d9893dd absyntax_utils/absyntax_utils.hh --- a/absyntax_utils/absyntax_utils.hh Mon Jun 27 18:01:43 2011 +0200 +++ b/absyntax_utils/absyntax_utils.hh Tue Jun 28 19:03:15 2011 +0200 @@ -74,6 +74,11 @@ extern symbol_c null_symbol4; extern symtable_c type_symtable; +/* A symbol table with all values declared for enumerated type... */ +/* Note that if the value is defined multiple times the value + * is the null pointer. + */ +extern symtable_c enumerated_value_symtable; /***********************************************************************/ diff -r da78d0d93c75 -r 66cd5d9893dd absyntax_utils/search_constant_type.cc --- a/absyntax_utils/search_constant_type.cc Mon Jun 27 18:01:43 2011 +0200 +++ b/absyntax_utils/search_constant_type.cc Tue Jun 28 19:03:15 2011 +0200 @@ -41,8 +41,16 @@ */ +#include "../util/symtable.hh" #include "search_constant_type.hh" +/* A symbol table with all values declared for enumerated type... */ +/* Note that if the value is defined multiple times the value + * is the null pointer. + */ +extern symbol_c null_symbol4; +extern symtable_c enumerated_value_symtable; + #define ERROR error_exit(__FILE__,__LINE__) /* function defined in main.cc */ extern void error_exit(const char *file_name, int line_no); @@ -117,6 +125,18 @@ void *search_constant_type_c::visit(date_literal_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ void *search_constant_type_c::visit(date_and_time_c *symbol) {return (void *)(symbol->type_name);} +/********************************/ +/* B 1.3.3 - Derived data types */ +/********************************/ +void *search_constant_type_c::visit(enumerated_value_c *symbol) { + if (symbol->type != NULL) + return (void *)(symbol->type); + + symbol_c *value_type = enumerated_value_symtable.find_value(symbol->value); + if (value_type == enumerated_value_symtable.end_value()) ERROR; + + return (void *)value_type; +} real_type_name_c search_constant_type_c::real_type_name; sint_type_name_c search_constant_type_c::sint_type_name; diff -r da78d0d93c75 -r 66cd5d9893dd absyntax_utils/search_constant_type.hh --- a/absyntax_utils/search_constant_type.hh Mon Jun 27 18:01:43 2011 +0200 +++ b/absyntax_utils/search_constant_type.hh Tue Jun 28 19:03:15 2011 +0200 @@ -153,6 +153,11 @@ void *visit(date_c *symbol); void *visit(date_literal_c *symbol); void *visit(date_and_time_c *symbol); + + /********************************/ + /* B 1.3.3 - Derived data types */ + /********************************/ + void *visit(enumerated_value_c *symbol); }; // search_constant_type_c diff -r da78d0d93c75 -r 66cd5d9893dd stage1_2/iec.y --- a/stage1_2/iec.y Mon Jun 27 18:01:43 2011 +0200 +++ b/stage1_2/iec.y Tue Jun 28 19:03:15 2011 +0200 @@ -7242,7 +7242,7 @@ primary_expression: constant //| enumerated_value_without_identifier - enumerated_value +| enumerated_value | variable | '(' expression ')' {$$ = $2;} diff -r da78d0d93c75 -r 66cd5d9893dd stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Mon Jun 27 18:01:43 2011 +0200 +++ b/stage4/generate_c/generate_c_typedecl.cc Tue Jun 28 19:03:15 2011 +0200 @@ -32,6 +32,7 @@ symbol_c* current_type_name; bool array_is_derived; search_base_type_c search_base_type; + search_constant_type_c search_constant_type; generate_c_base_c *basedecl; @@ -39,11 +40,13 @@ generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { current_typedefinition = none_td; current_basetypedeclaration = none_bd; + current_type_name = NULL; basedecl = new generate_c_base_c(&s4o_incl); } generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { current_typedefinition = none_td; current_basetypedeclaration = none_bd; + current_type_name = NULL; basedecl = new generate_c_base_c(&s4o_incl); } ~generate_c_typedecl_c(void) { @@ -177,21 +180,21 @@ TRACE("subrange_type_declaration_c"); current_typedefinition = subrange_td; + current_type_name = symbol->subrange_type_name; s4o_incl.print("__DECLARE_DERIVED_TYPE("); - symbol->subrange_type_name->accept(*basedecl); + current_type_name->accept(*basedecl); s4o_incl.print(","); current_basetypedeclaration = subrangebasetype_bd; symbol->subrange_spec_init->accept(*this); current_basetypedeclaration = none_bd; s4o_incl.print(")\n"); - current_type_name = symbol->subrange_type_name; - current_basetypedeclaration = subrangetest_bd; symbol->subrange_spec_init->accept(*this); current_basetypedeclaration = none_bd; + current_type_name = NULL; current_typedefinition = none_td; return NULL; @@ -296,20 +299,23 @@ TRACE("enumerated_type_declaration_c"); current_typedefinition = enumerated_td; + current_type_name = symbol->enumerated_type_name; s4o_incl.print("__DECLARE_ENUMERATED_TYPE("); - symbol->enumerated_type_name->accept(*basedecl); + current_type_name->accept(*basedecl); s4o_incl.print(",\n"); s4o_incl.indent_right(); symbol->enumerated_spec_init->accept(*this); s4o_incl.indent_left(); s4o_incl.print(")\n"); + current_type_name = NULL; current_typedefinition = none_td; return NULL; } +/* enumerated_specification ASSIGN enumerated_value */ void *visit(enumerated_spec_init_c *symbol) { TRACE("enumerated_spec_init_c"); if (current_typedefinition == enumerated_td) @@ -328,6 +334,16 @@ /* enumerated_type_name '#' identifier */ void *visit(enumerated_value_c *symbol) { + symbol_c *value_type; + if (current_typedefinition == enumerated_td) + current_type_name->accept(*basedecl); + else { + value_type = (symbol_c *)symbol->accept(search_constant_type); + if (value_type == NULL) ERROR; + + value_type->accept(*basedecl); + } + s4o_incl.print("_"); symbol->value->accept(*basedecl); return NULL; } @@ -337,6 +353,7 @@ TRACE("array_type_declaration_c"); current_typedefinition = array_td; + current_type_name = symbol->identifier; array_is_derived = false; current_basetypedeclaration = arrayderiveddeclaration_bd; @@ -347,7 +364,7 @@ s4o_incl.print("__DECLARE_DERIVED_TYPE("); else s4o_incl.print("__DECLARE_ARRAY_TYPE("); - symbol->identifier->accept(*basedecl); + current_type_name->accept(*basedecl); s4o_incl.print(","); current_basetypedeclaration = arraybasetypeincl_bd; symbol->array_spec_init->accept(*this); @@ -362,7 +379,7 @@ if (search_base_type.type_is_subrange(symbol->identifier)) { s4o.print("#define __CHECK_"); - symbol->identifier->accept(*this); + current_type_name->accept(*this); s4o.print(" __CHECK_"); current_basetypedeclaration = arraybasetype_bd; symbol->array_spec_init->accept(*this); @@ -370,12 +387,12 @@ s4o.print("\n"); } - current_type_name = symbol->identifier; current_basetypedeclaration = arraytranslateindex_bd; symbol->array_spec_init->accept(*this); current_basetypedeclaration = none_bd; s4o.print("\n"); + current_type_name = NULL; current_typedefinition = none_td; return NULL;