absyntax_utils/search_base_type.cc
changeset 726 9b61eb4f00dc
parent 718 a9f8cc778444
child 793 268bf4ca5fa1
equal deleted inserted replaced
725:bfbe4aca6b77 726:9b61eb4f00dc
    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;}
    57 search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = 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;
    64 
    64 
    65 /* static method! */
    65 /* static method! */
    66 symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) {
    66 symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) {
    67   create_singleton();
    67   create_singleton();
    68   if (NULL == symbol)    return NULL; 
    68   if (NULL == symbol)    return NULL; 
       
    69   search_base_type_singleton->current_type_name = NULL;
       
    70   search_base_type_singleton->current_basetype  = NULL; 
    69   return (symbol_c *)symbol->accept(*search_base_type_singleton);
    71   return (symbol_c *)symbol->accept(*search_base_type_singleton);
    70 }
    72 }
    71 
    73 
    72 /* static method! */
    74 /* static method! */
    73 symbol_c *search_base_type_c::get_basetype_id  (symbol_c *symbol) {
    75 symbol_c *search_base_type_c::get_basetype_id  (symbol_c *symbol) {
    74   create_singleton();
    76   create_singleton();
    75   if (NULL == symbol)    return NULL;
    77   if (NULL == symbol)    return NULL; 
    76   
       
    77   search_base_type_singleton->current_type_name = NULL;
    78   search_base_type_singleton->current_type_name = NULL;
       
    79   search_base_type_singleton->current_basetype  = NULL; 
    78   symbol->accept(*search_base_type_singleton);
    80   symbol->accept(*search_base_type_singleton);
    79   return (symbol_c *)search_base_type_singleton->current_type_name;
    81   return (symbol_c *)search_base_type_singleton->current_type_name;
    80 }
    82 }
    81 
    83 
    82 
    84 
   110 /*******************************************/
   112 /*******************************************/
   111 void *search_base_type_c::visit(identifier_c *type_name) {
   113 void *search_base_type_c::visit(identifier_c *type_name) {
   112   symbol_c *type_decl;
   114   symbol_c *type_decl;
   113 
   115 
   114   this->current_type_name = type_name;
   116   this->current_type_name = type_name;
       
   117   /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for,
       
   118    * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!)
       
   119    */
       
   120   this->current_basetype  = NULL; 
   115   
   121   
   116   /* look up the type declaration... */
   122   /* look up the type declaration... */
   117   type_decl = type_symtable.find_value(type_name);
   123   type_decl = type_symtable.find_value(type_name);
   118   if (type_decl != type_symtable.end_value())
   124   if (type_decl != type_symtable.end_value())
   119     return type_decl->accept(*this);
   125     return type_decl->accept(*this);
   242 void *search_base_type_c::visit(subrange_c *symbol)                                     {ERROR; return NULL;} /* should never get called... */
   248 void *search_base_type_c::visit(subrange_c *symbol)                                     {ERROR; return NULL;} /* should never get called... */
   243 
   249 
   244 /*  enumerated_type_name ':' enumerated_spec_init */
   250 /*  enumerated_type_name ':' enumerated_spec_init */
   245 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) {
   251 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) {
   246   this->current_type_name = symbol->enumerated_type_name;
   252   this->current_type_name = symbol->enumerated_type_name;
       
   253   /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible
       
   254    *       (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an
       
   255    *        anonymous datatype declared in a VAR ... AND_VAR declaration).
       
   256    *       However, we cannot return this symbol just yet, as it may not be the final base datatype.
       
   257    *       So we store it in a temporary current_basetype variable!
       
   258    */
       
   259   this->current_basetype  = symbol; 
   247   return symbol->enumerated_spec_init->accept(*this);
   260   return symbol->enumerated_spec_init->accept(*this);
   248 }
   261 }
   249 
   262 
   250 /* enumerated_specification ASSIGN enumerated_value */
   263 /* enumerated_specification ASSIGN enumerated_value */
   251 void *search_base_type_c::visit(enumerated_spec_init_c *symbol) {
   264 void *search_base_type_c::visit(enumerated_spec_init_c *symbol) {
   252   this->is_enumerated = true;
   265   this->is_enumerated = true;
   253   return symbol->enumerated_specification->accept(*this);
   266   // 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!
       
   267   if (NULL == this->current_basetype)
       
   268     this->current_basetype  = symbol; 
       
   269   /* NOTE: the following line may call either the visitor to 
       
   270    *         - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!)
       
   271    *         - enumerated_value_list_c, in which case we have found the base datatype.
       
   272    */
       
   273   return symbol->enumerated_specification->accept(*this); 
   254 }
   274 }
   255 
   275 
   256 /* helper symbol for enumerated_specification->enumerated_spec_init */
   276 /* helper symbol for enumerated_specification->enumerated_spec_init */
   257 /* enumerated_value_list ',' enumerated_value */
   277 /* enumerated_value_list ',' enumerated_value */
   258 void *search_base_type_c::visit(enumerated_value_list_c *symbol) {
   278 void *search_base_type_c::visit(enumerated_value_list_c *symbol) {
   259   this->is_enumerated = true;
   279   this->is_enumerated = true;
   260   return (void *)symbol;
   280   // 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!
       
   281   if (NULL == this->current_basetype) 
       
   282     this->current_basetype  = symbol; 
       
   283   return (void *)current_basetype;
   261 }
   284 }
   262 
   285 
   263 /* enumerated_type_name '#' identifier */
   286 /* enumerated_type_name '#' identifier */
   264 // SYM_REF2(enumerated_value_c, type, value)
   287 // SYM_REF2(enumerated_value_c, type, value)
   265 void *search_base_type_c::visit(enumerated_value_c *symbol)                             {ERROR; return NULL;} /* should never get called... */
   288 void *search_base_type_c::visit(enumerated_value_c *symbol)                             {ERROR; return NULL;} /* should never get called... */