Change the base datatype of enumerations to an enumerated_type_declaration_c (for named types!)
authorMario de Sousa <msousa@fe.up.pt>
Tue, 13 Nov 2012 18:03:17 +0000
changeset 726 9b61eb4f00dc
parent 725 bfbe4aca6b77
child 727 db5881e6facd
Change the base datatype of enumerations to an enumerated_type_declaration_c (for named types!)
absyntax_utils/absyntax_utils.cc
absyntax_utils/search_base_type.cc
absyntax_utils/search_base_type.hh
stage3/fill_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_var_list.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;
--- 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 */
--- 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;
--- 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;  
 }
 
--- 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 */
 /*********************/
--- 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 */
--- 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("__");
--- 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) {