Add support for finding type of a constant enumerated value and managing conflict between same identifiers defined in different enumerated data types
authorlaurent
Tue, 28 Jun 2011 19:03:15 +0200
changeset 328 66cd5d9893dd
parent 327 da78d0d93c75
child 329 882f5f1e5f6f
Add support for finding type of a constant enumerated value and managing conflict between same identifiers defined in different enumerated data types
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
absyntax_utils/search_constant_type.cc
absyntax_utils/search_constant_type.hh
stage1_2/iec.y
stage4/generate_c/generate_c_typedecl.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<symbol_c *, &null_symbol4> 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<symbol_c *, &null_symbol4> 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) {
--- 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<symbol_c *, &null_symbol4> 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<symbol_c *, &null_symbol4> enumerated_value_symtable;
 
 
 /***********************************************************************/
--- 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<symbol_c *, &null_symbol4> 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;
--- 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
 
 
--- 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;}
--- 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;