absyntax_utils/get_datatype_info.cc
changeset 945 477393b00f95
parent 939 5074236fb3c4
child 946 c012a64dc2fa
equal deleted inserted replaced
943:566414d7ba1f 945:477393b00f95
   197     /* B.1 - Common elements */
   197     /* B.1 - Common elements */
   198     /*************************/
   198     /*************************/
   199     /*******************************************/
   199     /*******************************************/
   200     /* B 1.1 - Letters, digits and identifiers */
   200     /* B 1.1 - Letters, digits and identifiers */
   201     /*******************************************/
   201     /*******************************************/
   202     void *visit(identifier_c *symbol) {return (void *)symbol->value;};
   202     void *visit(                 identifier_c *symbol) {return (void *)symbol->value;};
       
   203     void *visit(derived_datatype_identifier_c *symbol) {return (void *)symbol->value;};
   203 
   204 
   204     /***********************************/
   205     /***********************************/
   205     /* B 1.3.1 - Elementary Data Types */
   206     /* B 1.3.1 - Elementary Data Types */
   206     /***********************************/
   207     /***********************************/
   207     void *visit(time_type_name_c        *symbol) {return (void *)"TIME";        };
   208     void *visit(time_type_name_c        *symbol) {return (void *)"TIME";        };
   245     void *visit(safeword_type_name_c    *symbol) {return (void *)"SAFEWORD";    };
   246     void *visit(safeword_type_name_c    *symbol) {return (void *)"SAFEWORD";    };
   246     void *visit(safelword_type_name_c   *symbol) {return (void *)"SAFELWORD";   };
   247     void *visit(safelword_type_name_c   *symbol) {return (void *)"SAFELWORD";   };
   247     void *visit(safedword_type_name_c   *symbol) {return (void *)"SAFEDWORD";   };
   248     void *visit(safedword_type_name_c   *symbol) {return (void *)"SAFEDWORD";   };
   248     void *visit(safestring_type_name_c  *symbol) {return (void *)"SAFESTRING";  };
   249     void *visit(safestring_type_name_c  *symbol) {return (void *)"SAFESTRING";  };
   249     void *visit(safewstring_type_name_c *symbol) {return (void *)"SAFEWSTRING"; };
   250     void *visit(safewstring_type_name_c *symbol) {return (void *)"SAFEWSTRING"; };
       
   251 
       
   252     /********************************/
       
   253     /* B.1.3.2 - Generic data types */
       
   254     /********************************/
       
   255     void *visit(generic_type_any_c *symbol) {return (void *)"ANY"; };
   250 
   256 
   251     /********************************/
   257     /********************************/
   252     /* B 1.3.3 - Derived data types */
   258     /* B 1.3.3 - Derived data types */
   253     /********************************/
   259     /********************************/
   254     /*  simple_type_name ':' simple_spec_init */
   260     /*  simple_type_name ':' simple_spec_init */
   415 
   421 
   416 symbol_c *get_datatype_info_c::get_struct_field_type_id(symbol_c *struct_datatype, symbol_c *struct_fieldname) {
   422 symbol_c *get_datatype_info_c::get_struct_field_type_id(symbol_c *struct_datatype, symbol_c *struct_fieldname) {
   417   return get_struct_info_c::get_field_type_id(struct_datatype, struct_fieldname);
   423   return get_struct_info_c::get_field_type_id(struct_datatype, struct_fieldname);
   418 }
   424 }
   419 
   425 
       
   426 
       
   427 
   420 symbol_c *get_datatype_info_c::get_array_storedtype_id(symbol_c *type_symbol) {
   428 symbol_c *get_datatype_info_c::get_array_storedtype_id(symbol_c *type_symbol) {
   421   // returns the datatype of the variables stored in the array
   429   // returns the datatype of the variables stored in the array
   422   symbol_c *basetype = search_base_type_c::get_basetype_decl(type_symbol);
   430   array_specification_c *symbol = NULL;
   423   array_specification_c *symbol = dynamic_cast<array_specification_c *>(basetype);
   431   if (NULL == symbol)  symbol = dynamic_cast<array_specification_c *>(type_symbol);
   424 
   432   if (NULL == symbol)  symbol = dynamic_cast<array_specification_c *>(search_base_type_c::get_basetype_decl(type_symbol));
   425   if (NULL != symbol) 
   433   if (NULL != symbol)  
   426     return symbol->non_generic_type_name;
   434     return symbol->non_generic_type_name;
   427   return NULL; // this is not an array!
   435   return NULL; // this is not an array!
   428 }
   436 }
   429   
   437   
   430   
   438   
       
   439   
       
   440 
   431 /* Returns true if both datatypes are equivalent (not necessarily equal!).
   441 /* Returns true if both datatypes are equivalent (not necessarily equal!).
   432  * WARNING: May return true even though the datatypes are not the same/identicial!!!
   442  * WARNING: May return true even though the datatypes are not the same/identicial!!!
   433  *          This occurs when at least one of the datatypes is of a generic
   443  *          This occurs when at least one of the datatypes is of a generic
   434  *          datatype (or a REF_TO a generic datatype). 
   444  *          datatype (or a REF_TO a generic datatype). 
   435  *          (Generic dataypes: ANY, ANY_INT, ANY_NUM, ...)
   445  *          (Generic dataypes: ANY, ANY_INT, ANY_NUM, ...)
   437  * NOTE: Currently stage1_2 only allows the use of the ANY keyword when in conjuntion with
   447  * NOTE: Currently stage1_2 only allows the use of the ANY keyword when in conjuntion with
   438  *       the REF_TO keyword (i.e. REF_TO ANY), so when handling non REF_TO datatypes,
   448  *       the REF_TO keyword (i.e. REF_TO ANY), so when handling non REF_TO datatypes,
   439  *       this function will currently only return true if the dataypes are identicial.
   449  *       this function will currently only return true if the dataypes are identicial.
   440  */
   450  */
   441 
   451 
   442 /* NOTE: Currently the datatype model used by matiec considers any implicitly defined datatype
   452 /* NOTE: matiec supports a strict and a relaxed data type model. Which datatype model to use is chosen
       
   453  *       as a command line option.
       
   454  * 
       
   455  * 
       
   456  *       The Strict Datatype Model
       
   457  *       =========================
       
   458  *       The strict datatype model used by matiec considers any implicitly defined datatype
   443  *       (e.g. an array datatype defined in the variable declaration itself, instead of inside a TYPE ... END_TYPE
   459  *       (e.g. an array datatype defined in the variable declaration itself, instead of inside a TYPE ... END_TYPE
   444  *       construct) to be different (i.e. not the same datatype, and therefore not compatible) to any other
   460  *       construct) to be different (i.e. not the same datatype, and therefore not compatible) to any other
   445  *       datatype, including with datatypes declared identically to the implicit datatype.
   461  *       datatype, including with datatypes declared identically to the implicit datatype.
   446  *       e.g.
   462  *       e.g.
   447  *         TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE;
   463  *         TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE;
   457  *       There are 2 exceptions to the above rule:
   473  *       There are 2 exceptions to the above rule:
   458  *        (1) Datatypes that are directly derived from other datatypes.
   474  *        (1) Datatypes that are directly derived from other datatypes.
   459  *              (this rule is specified in the standard, so we follow it!)
   475  *              (this rule is specified in the standard, so we follow it!)
   460  *        (2) REF_TO datatypes that reference the same datatype
   476  *        (2) REF_TO datatypes that reference the same datatype
   461  *              (I dont think the standard says anything about this!)
   477  *              (I dont think the standard says anything about this!)
       
   478  *              (This rule should actually be part of the relaxed datatype model, but for now we
       
   479  *               will leave it in the strict datatype model) 
   462  *
   480  *
   463  *         TYPE 
   481  *         TYPE 
   464  *          my_array_1_t: ARRAY [1..3] OF INT; 
   482  *          my_array_1_t: ARRAY [1..3] OF INT; 
   465  *          my_array_2_t: ARRAY [1..3] OF INT; 
   483  *          my_array_2_t: ARRAY [1..3] OF INT; 
   466  *          my_array_3_t: my_array_1_t; 
   484  *          my_array_3_t: my_array_1_t; 
   509  * 
   527  * 
   510  *       Rule/exception (2) goes against the datatype model used for all other datatypes.
   528  *       Rule/exception (2) goes against the datatype model used for all other datatypes.
   511  *       This rule was adopted as without it, the datatype of the value returned by the REF() 
   529  *       This rule was adopted as without it, the datatype of the value returned by the REF() 
   512  *       operator would be considered distinct to all other datatypes, and therefore the
   530  *       operator would be considered distinct to all other datatypes, and therefore the
   513  *       REF() operator would be essentially useless.
   531  *       REF() operator would be essentially useless.
       
   532  * 
       
   533  * 
       
   534  *       The Relaxed Datatype Model
       
   535  *       ==========================
       
   536  *       In the relaxed datatype model, the same rules as the strict datatype model are followed, with the
       
   537  *       exception of implicitly defined array datatypes, which are now considered equal if they define
       
   538  *       identical datatypes.
       
   539  *       This means that in the following example
       
   540  *         TYPE 
       
   541  *          array_t: ARRAY [1..3] OF INT; 
       
   542  *         END_TYPE;
       
   543  *         VAR
       
   544  *          array_var1: array_t; 
       
   545  *          array_var2: ARRAY [1..3] OF INT; 
       
   546  *          array_var3: ARRAY [1..3] OF INT; 
       
   547  *         END_VAR
       
   548  * 
       
   549  *       all three variables (array_var1, array_var2, and array_var3) are considered as being of the
       
   550  *       same datatype.
       
   551  *      
       
   552  *       Note that the strict datatype model currently actually uses a relaxed datatype model for 
       
   553  *       REF_TO datatypes, so in both the relaxed and strict datatype models matiec currently uses a 
       
   554  *       relaxed datatype equivalince for REF_TO datatypes.
   514  */
   555  */
   515 bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) {
   556 bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) {
   516   if (!is_type_valid( first_type))                                   {return false;}
   557   if (!is_type_valid( first_type))                                   {return false;}
   517   if (!is_type_valid(second_type))                                   {return false;}
   558   if (!is_type_valid(second_type))                                   {return false;}
   518 
   559 
   520   /* For the moment, we only support the ANY generic datatype! */
   561   /* For the moment, we only support the ANY generic datatype! */
   521   if ((is_ANY_generic_type( first_type)) ||
   562   if ((is_ANY_generic_type( first_type)) ||
   522       (is_ANY_generic_type(second_type)))                            {return true;}
   563       (is_ANY_generic_type(second_type)))                            {return true;}
   523       
   564       
   524   /* ANY_ELEMENTARY */
   565   /* ANY_ELEMENTARY */
   525   if ((is_ANY_ELEMENTARY(first_type)) &&
   566   if ((is_ANY_ELEMENTARY_compatible(first_type)) &&
   526       (typeid(*first_type) == typeid(*second_type)))                 {return true;}
   567       (typeid(*first_type) == typeid(*second_type)))                 {return true;}
   527 
   568   if (   is_ANY_ELEMENTARY_compatible(first_type) 
   528   /* ANY_DERIVED */
   569       || is_ANY_ELEMENTARY_compatible(second_type))                  {return false;}  
       
   570   
       
   571   /* ANY_DERIVED  */
       
   572   // from now on, we are sure both datatypes are derived...
   529   if (is_ref_to(first_type) && is_ref_to(second_type)) {
   573   if (is_ref_to(first_type) && is_ref_to(second_type)) {
   530     return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )),
   574     return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )),
   531                          search_base_type_c::get_basetype_decl(get_ref_to(second_type)));
   575                          search_base_type_c::get_basetype_decl(get_ref_to(second_type)));
   532   }
   576   }
   533   return (first_type == second_type);
   577 
   534 }
   578     // check for same datatype
       
   579   if (first_type == second_type)                                       {return true;}
       
   580   
       
   581     // remaining type equivalence rules are not applied in the strict datatype model
       
   582   //if (!option...relaxed_datatypemodel)
       
   583     //return false;
       
   584   
       
   585     // check for array equivalence usig the relaxed datatype model
       
   586   if (is_arraytype_equal_relaxed(first_type, second_type))             {return true;}
       
   587 
       
   588   return false;
       
   589 }
       
   590 
       
   591 
       
   592 
       
   593 /* A local helper function that transforms strings conatining signed_integers into a normalized
       
   594  * form, so they can be compared for equality.
       
   595  *   examples:
       
   596  *     82  ->  82 
       
   597  *     8_2 ->  82 
       
   598  *    +82  ->  82
       
   599  *    082  ->  82
       
   600  *   +082  ->  82
       
   601  *    -82  -> -82
       
   602  *    -8_2 -> -82
       
   603  *   -082  -> -82
       
   604  */
       
   605 #include <string.h>  /* required for strlen() */
       
   606 static std::string normalize_integer(symbol_c *symbol) {
       
   607   integer_c *token = dynamic_cast<integer_c *>(symbol);
       
   608   if (NULL == token) ERROR;
       
   609   
       
   610   std::string str = "";
       
   611   bool leading_zero = true;
       
   612   unsigned int offset = 0;
       
   613 
       
   614   // handle any possible leading '-' or '+'
       
   615   if        (token->value[0] == '-') {
       
   616       //    '-' -> retained
       
   617       str += token->value[0];
       
   618       offset++;
       
   619   } else if (token->value[0] == '+')
       
   620       //    '+' -> skip, so '+8' and '8' will both result in '8'
       
   621       offset++;
       
   622     
       
   623   for (unsigned int i = offset; i < strlen(token->value); i++) {
       
   624     if (leading_zero && (token->value[i] != '0'))
       
   625       leading_zero = false;
       
   626     if (!leading_zero && token->value[i] != '_')
       
   627       str += token->value[i];
       
   628   }
       
   629   return str;
       
   630 }
       
   631 
       
   632 
       
   633 /* A helper method to get_datatype_info_c::is_type_equal()
       
   634  *  Assuming the relaxed datatype model, determine whether the two array datatypes are equal/equivalent
       
   635  */
       
   636 bool get_datatype_info_c::is_arraytype_equal_relaxed(symbol_c *first_type, symbol_c *second_type) {
       
   637   symbol_c *basetype_1 = search_base_type_c::get_basetype_decl( first_type);
       
   638   symbol_c *basetype_2 = search_base_type_c::get_basetype_decl(second_type);
       
   639   array_specification_c *array_1 = dynamic_cast<array_specification_c *>(basetype_1);
       
   640   array_specification_c *array_2 = dynamic_cast<array_specification_c *>(basetype_2);
       
   641 
       
   642   // are they both array datatypes? 
       
   643   if ((NULL == array_1) || (NULL == array_2))
       
   644     return false;
       
   645   
       
   646   // number of subranges
       
   647   array_subrange_list_c *subrange_list_1 = dynamic_cast<array_subrange_list_c *>(array_1->array_subrange_list);
       
   648   array_subrange_list_c *subrange_list_2 = dynamic_cast<array_subrange_list_c *>(array_2->array_subrange_list);
       
   649   if ((NULL == subrange_list_1) || (NULL == subrange_list_2)) ERROR;
       
   650   if (subrange_list_1->n != subrange_list_2->n)
       
   651     return false;
       
   652   
       
   653   // comparison of each subrange start and end elements
       
   654   for (int i = 0; i < subrange_list_1->n; i++) {
       
   655     subrange_c *subrange_1 = dynamic_cast<subrange_c *>(subrange_list_1->elements[i]);
       
   656     subrange_c *subrange_2 = dynamic_cast<subrange_c *>(subrange_list_2->elements[i]);
       
   657     if ((NULL == subrange_1) || (NULL == subrange_2)) ERROR;
       
   658     #if 0
       
   659     /* An alternative method of checking whether the subranges have the same values, using the result of the constant folding agorithm.
       
   660      * This method has the drawback that it inserts a dependency on having to run the constant folding algorithm before
       
   661      *  the get_datatype_info_c::is_type_equal() method is called.
       
   662      * The probably slower alternative of comparing the strings themselves is therefor used.
       
   663      */
       
   664     if (!constant_folding_c::is_equal_cvalue(subrange_1->lower_limit, subrange_2->lower_limit)) return false;
       
   665     if (!constant_folding_c::is_equal_cvalue(subrange_1->upper_limit, subrange_2->upper_limit)) return false;
       
   666     #endif
       
   667     if (normalize_integer(subrange_1->lower_limit) != normalize_integer(subrange_2->lower_limit)) return false;
       
   668     if (normalize_integer(subrange_1->upper_limit) != normalize_integer(subrange_2->upper_limit)) return false;
       
   669   }
       
   670 
       
   671   return is_type_equal(search_base_type_c::get_basetype_decl(array_1->non_generic_type_name),
       
   672                        search_base_type_c::get_basetype_decl(array_2->non_generic_type_name));
       
   673 }
       
   674 
       
   675 
       
   676 
   535 
   677 
   536 
   678 
   537 bool get_datatype_info_c::is_type_valid(symbol_c *type) {
   679 bool get_datatype_info_c::is_type_valid(symbol_c *type) {
   538   if (NULL == type)                                                  {return false;}
   680   if (NULL == type)                                                  {return false;}
   539   if (typeid(*type) == typeid(invalid_type_name_c))                  {return false;}
   681   if (typeid(*type) == typeid(invalid_type_name_c))                  {return false;}