stage3/fill_candidate_datatypes.cc
changeset 719 19595fce59f0
parent 718 a9f8cc778444
child 720 f637ac331a68
equal deleted inserted replaced
718:a9f8cc778444 719:19595fce59f0
    51  *  Fill the candidate datatype list for all symbols that may legally 'have' a data type (e.g. variables, literals, function calls, expressions, etc.)
    51  *  Fill the candidate datatype list for all symbols that may legally 'have' a data type (e.g. variables, literals, function calls, expressions, etc.)
    52  * 
    52  * 
    53  *  The candidate datatype list will be filled with a list of all the data types that expression may legally take.
    53  *  The candidate datatype list will be filled with a list of all the data types that expression may legally take.
    54  *  For example, the very simple literal '0' (as in foo := 0), may represent a:
    54  *  For example, the very simple literal '0' (as in foo := 0), may represent a:
    55  *    BOOL, BYTE, WORD, DWORD, LWORD, USINT, SINT, UINT, INT, UDINT, DINT, ULINT, LINT (as well as the SAFE versions of these data tyes too!)
    55  *    BOOL, BYTE, WORD, DWORD, LWORD, USINT, SINT, UINT, INT, UDINT, DINT, ULINT, LINT (as well as the SAFE versions of these data tyes too!)
       
    56  *
       
    57  * WARNING: This visitor class starts off by building a map of all enumeration constants that are defined in the source code (i.e. a library_c symbol),
       
    58  *          and this map is later used to determine the datatpe of each use of an enumeration constant. By implication, the fill_candidate_datatypes_c 
       
    59  *          visitor class will only work corretly if it is asked to visit a symbol of class library_c!!
    56  */
    60  */
    57 
    61 
    58 #include <../main.hh>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
    62 #include <../main.hh>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
    59 #include "fill_candidate_datatypes.hh"
    63 #include "fill_candidate_datatypes.hh"
    60 #include "datatype_functions.hh"
    64 #include "datatype_functions.hh"
    71 /* set to 1 to see debug info during execution */
    75 /* set to 1 to see debug info during execution */
    72 static int debug = 0;
    76 static int debug = 0;
    73 
    77 
    74 
    78 
    75 
    79 
    76 
       
    77 /*****************************************************/
    80 /*****************************************************/
    78 /*                                                   */
    81 /*                                                   */
    79 /*  A small helper class...                          */
    82 /*  A small helper class...                          */
    80 /*                                                   */
    83 /*                                                   */
    81 /*****************************************************/
    84 /*****************************************************/
    82 
    85 
       
    86 /* Add to the global_enumerated_value_symtable the global enum value constants, i.e. the enum constants used in the enumerated
       
    87  * datatypes that are defined inside a TYPE ... END_TYPE declaration.
       
    88  */
       
    89 
       
    90  symbol_c null_globalenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
       
    91  static symtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable;
       
    92  
       
    93  
       
    94 class populate_globalenumvalue_symtable_c: public iterator_visitor_c {
       
    95   private:
       
    96     symbol_c *current_enumerated_type;
       
    97 
       
    98   public:
       
    99      populate_globalenumvalue_symtable_c(void) {current_enumerated_type = NULL;};
       
   100     ~populate_globalenumvalue_symtable_c(void) {}
       
   101 
       
   102   public:
       
   103   /*************************/
       
   104   /* B.1 - Common elements */
       
   105   /*************************/
       
   106   /**********************/
       
   107   /* B.1.3 - Data types */
       
   108   /**********************/
       
   109   /********************************/
       
   110   /* B 1.3.3 - Derived data types */
       
   111   /********************************/
       
   112   /*  enumerated_type_name ':' enumerated_spec_init */
       
   113   void *visit(enumerated_type_declaration_c *symbol) {
       
   114   //current_enumerated_type = symbol->enumerated_type_name;
       
   115     current_enumerated_type = symbol;
       
   116     symbol->enumerated_spec_init->accept(*this);
       
   117     current_enumerated_type = NULL;
       
   118     return NULL;
       
   119   }
       
   120 
       
   121   /* enumerated_specification ASSIGN enumerated_value */
       
   122   void *visit(enumerated_spec_init_c *symbol) {
       
   123     return symbol->enumerated_specification->accept(*this);
       
   124   }
       
   125 
       
   126   /* [enumerated_type_name '#'] identifier */
       
   127   void *visit(enumerated_value_c *symbol) {
       
   128     if (current_enumerated_type == NULL) ERROR;
       
   129     if (symbol->type != NULL) ERROR;
       
   130 
       
   131     symbol_c *value_type = global_enumerated_value_symtable.find_value(symbol->value);
       
   132     /* NOTE: The following condition checks whether the same identifier is used more than once
       
   133      *       when defining the enumerated values of the type declaration of the new enumerated type.
       
   134      *       If this occurs, then the program beeing compiled contains a semantic error, which
       
   135      *       must be caught and reported by the semantic analyser. However, since
       
   136      *       this code is run before the semantic analyser, we must not yet raise the ERROR (internal
       
   137      *       compiler error message).
       
   138      *       For this reason, the follosing check is commented out.
       
   139      */
       
   140     /* if (value_type == current_enumerated_type) ERROR; */
       
   141 
       
   142     if (value_type == global_enumerated_value_symtable.end_value())
       
   143 	/* This identifier has not yet been used in any previous declaration of an enumeration data type.
       
   144 	 * so we add it to the symbol table.
       
   145 	 */
       
   146       global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
       
   147     else if (value_type != NULL)
       
   148 	/* This identifier has already been used in a previous declaration of an enumeration data type.
       
   149 	 * so we set the symbol in symbol table pointing to NULL.
       
   150 	 */
       
   151       global_enumerated_value_symtable.set(symbol->value, NULL);
       
   152     
       
   153     return NULL;
       
   154   }
       
   155 
       
   156   /**************************************/
       
   157   /* B.1.5 - Program organization units */
       
   158   /**************************************/
       
   159   /* B 1.5.1 - Functions */
       
   160   void *visit(function_declaration_c *symbol) {return NULL;}
       
   161   /* B 1.5.2 - Function Blocks */
       
   162   void *visit(function_block_declaration_c *symbol) {return NULL;}
       
   163   /* B 1.5.3 - Programs */
       
   164   void *visit(program_declaration_c *symbol) {return NULL;}
       
   165   
       
   166 }; /* populate_globalenumvalue_symtable_c */
       
   167 
       
   168 static populate_globalenumvalue_symtable_c populate_globalenumvalue_symtable;
       
   169 
       
   170 
       
   171 /*****************************************************/
       
   172 /*                                                   */
       
   173 /*  A small helper class...                          */
       
   174 /*                                                   */
       
   175 /*****************************************************/
       
   176 
    83 /* Add to the local_enumerated_value_symtable the local enum value constants */
   177 /* Add to the local_enumerated_value_symtable the local enum value constants */
    84 /* WARNING: This visitor expects to visit a POU (function, FB, program, ...)
       
    85  *          It should not be called to visit any symbol that may include a TYPE .., END_TYPE declaration!
       
    86  */
       
    87 /* Notes:
   178 /* Notes:
    88  * Some enumerations are 
   179  * Some enumerations are 
    89  *   (A) declared anonymously inside a VAR ... END_VAR declaration
   180  *   (A) declared anonymously inside a VAR ... END_VAR declaration
    90  *       (e.g. VAR enum_var : (enumvalue1, enumvalue2); END_VAR)
   181  *       (e.g. VAR enum_var : (enumvalue1, enumvalue2); END_VAR)
    91  *  while others are 
   182  *  while others are 
   117  *     GlobalEnumVar := xxx1;   <-- We consider it an error. xxx1 will reference the anonymous type used for LocalEnumVar
   208  *     GlobalEnumVar := xxx1;   <-- We consider it an error. xxx1 will reference the anonymous type used for LocalEnumVar
   118  *     GlobalEnumVar := GlobalEnumT#xxx1;
   209  *     GlobalEnumVar := GlobalEnumT#xxx1;
   119  *     END_FUNCTION_BLOCK
   210  *     END_FUNCTION_BLOCK
   120  */
   211  */
   121  
   212  
   122  symbol_c null_enumvalue_symbol; /* cannot be static, so it may be used in the template!! */
   213  symbol_c null_localenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
   123  static symtable_c<symbol_c *, &null_enumvalue_symbol> local_enumerated_value_symtable;
   214  static symtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable;
   124 
   215 
   125 
   216 
   126 class populate_enumvalue_symtable_c: public iterator_visitor_c {
   217 class populate_enumvalue_symtable_c: public iterator_visitor_c {
   127   private:
   218   private:
   128     symbol_c *current_enumerated_type;
   219     symbol_c *current_enumerated_type;
   139   /* B.1.3 - Data types */
   230   /* B.1.3 - Data types */
   140   /**********************/
   231   /**********************/
   141   /********************************/
   232   /********************************/
   142   /* B 1.3.3 - Derived data types */
   233   /* B 1.3.3 - Derived data types */
   143   /********************************/
   234   /********************************/
       
   235   /*  TYPE type_declaration_list END_TYPE */
       
   236   void *visit(data_type_declaration_c *symbol) {return NULL;} // do not visit the type declarations!!
       
   237   
   144   /* enumerated_specification ASSIGN enumerated_value */
   238   /* enumerated_specification ASSIGN enumerated_value */
   145   void *visit(enumerated_spec_init_c *symbol) {
   239   void *visit(enumerated_spec_init_c *symbol) {
   146     current_enumerated_type = symbol;
   240     current_enumerated_type = symbol;
   147     symbol->enumerated_specification->accept(*this);
   241     symbol->enumerated_specification->accept(*this);
   148     /* DO NOT visit the symbol->enumerated_value   !!! */
   242     /* DO NOT visit the symbol->enumerated_value   !!! */
   155     /* if the enumerated_value_c is not inside a enumerated_spec_init_c (e.g. used as the inital value of a variable), we simply return */
   249     /* if the enumerated_value_c is not inside a enumerated_spec_init_c (e.g. used as the inital value of a variable), we simply return */
   156     if (current_enumerated_type == NULL) return NULL;  
   250     if (current_enumerated_type == NULL) return NULL;  
   157     /* this is really an ERROR! The initial value may use the syntax NUM_TYPE#enum_value, but in that case we should have return'd in the above statement !! */
   251     /* this is really an ERROR! The initial value may use the syntax NUM_TYPE#enum_value, but in that case we should have return'd in the above statement !! */
   158     if (symbol->type != NULL) ERROR;  
   252     if (symbol->type != NULL) ERROR;  
   159 
   253 
   160     // symbol_c *global_value_type =       enumerated_value_symtable.find_value(symbol->value);
   254     // symbol_c *global_value_type = global_enumerated_value_symtable.find_value(symbol->value);
   161     symbol_c *local_value_type  = local_enumerated_value_symtable.find_value(symbol->value);
   255     symbol_c *local_value_type  = local_enumerated_value_symtable.find_value(symbol->value);
   162     if (local_value_type == local_enumerated_value_symtable.end_value())
   256     if (local_value_type == local_enumerated_value_symtable.end_value())
   163       /* This identifier has not yet been used in any previous local declaration of an enumeration data type, so we add it to the local symbol table. */
   257       /* This identifier has not yet been used in any previous local declaration of an enumeration data type, so we add it to the local symbol table. */
   164       local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   258       local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   165     else 
   259     else 
   179 /*  Main  FILL candidate datatypes algorithm...      */
   273 /*  Main  FILL candidate datatypes algorithm...      */
   180 /*                                                   */
   274 /*                                                   */
   181 /*****************************************************/
   275 /*****************************************************/
   182 
   276 
   183 
   277 
   184 
       
   185 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) {
   278 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) {
   186 	il_operand = NULL;
   279 	il_operand = NULL;
   187 	prev_il_instruction = NULL;
   280 	prev_il_instruction = NULL;
   188 	search_varfb_instance_type = NULL;
   281 	search_varfb_instance_type = NULL;
   189 	current_enumerated_spec_type = NULL;
   282 	current_enumerated_spec_type = NULL;
   190 }
   283 }
   191 
   284 
   192 fill_candidate_datatypes_c::~fill_candidate_datatypes_c(void) {
   285 fill_candidate_datatypes_c::~fill_candidate_datatypes_c(void) {
   193 }
   286 }
       
   287 
       
   288 
       
   289 
       
   290 
       
   291 
       
   292 
   194 
   293 
   195 symbol_c *fill_candidate_datatypes_c::widening_conversion(symbol_c *left_type, symbol_c *right_type, const struct widen_entry widen_table[]) {
   294 symbol_c *fill_candidate_datatypes_c::widening_conversion(symbol_c *left_type, symbol_c *right_type, const struct widen_entry widen_table[]) {
   196 	int k;
   295 	int k;
   197 	/* find a widening table entry compatible */
   296 	/* find a widening table entry compatible */
   198 	for (k = 0; NULL != widen_table[k].left;  k++)
   297 	for (k = 0; NULL != widen_table[k].left;  k++)
   549 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used in the code. */
   648 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used in the code. */
   550 	if (symbol == NULL) return NULL;
   649 	if (symbol == NULL) return NULL;
   551 	return search_base_type_c::get_basetype_decl(symbol);
   650 	return search_base_type_c::get_basetype_decl(symbol);
   552 }
   651 }
   553 
   652 
       
   653 
       
   654 /***************************/
       
   655 /* B 0 - Programming Model */
       
   656 /***************************/
       
   657 /* main entry function! */
       
   658 void *fill_candidate_datatypes_c::visit(library_c *symbol) {
       
   659   symbol->accept(populate_globalenumvalue_symtable);
       
   660   /* Now let the base class iterator_visitor_c iterate through all the library elements */
       
   661   return iterator_visitor_c::visit(symbol);  
       
   662 }
       
   663 
       
   664 
   554 /*********************/
   665 /*********************/
   555 /* B 1.2 - Constants */
   666 /* B 1.2 - Constants */
   556 /*********************/
   667 /*********************/
   557 /******************************/
   668 /******************************/
   558 /* B 1.2.1 - Numeric Literals */
   669 /* B 1.2.1 - Numeric Literals */
   807 	symbol_c *enumerated_type;
   918 	symbol_c *enumerated_type;
   808 
   919 
   809 	if (NULL != symbol->type)
   920 	if (NULL != symbol->type)
   810 		enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */
   921 		enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */
   811 	else {
   922 	else {
   812 		global_enumerated_type =       enumerated_value_symtable.find_value(symbol->value);
   923 		global_enumerated_type = global_enumerated_value_symtable.find_value(symbol->value);
   813 		local_enumerated_type  = local_enumerated_value_symtable.find_value(symbol->value);
   924 		local_enumerated_type  =  local_enumerated_value_symtable.find_value(symbol->value);
   814 		if      ((local_enumerated_type == local_enumerated_value_symtable.end_value()) && (global_enumerated_type == enumerated_value_symtable.end_value()))
   925 		if      (( local_enumerated_type ==  local_enumerated_value_symtable.end_value()) && (global_enumerated_type == global_enumerated_value_symtable.end_value()))
   815 		  enumerated_type = NULL; // not found!
   926 		  enumerated_type = NULL; // not found!
   816 		else if ((local_enumerated_type != local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL))
   927 		else if (( local_enumerated_type !=  local_enumerated_value_symtable.end_value()) && (local_enumerated_type == NULL))
   817 			enumerated_type = NULL; // Duplicate, so it is ambiguous!
   928 			enumerated_type = NULL; // Duplicate, so it is ambiguous!
   818 		else if ((local_enumerated_type != local_enumerated_value_symtable.end_value()))
   929 		else if (( local_enumerated_type !=  local_enumerated_value_symtable.end_value()))
   819 			enumerated_type = local_enumerated_type;
   930 			enumerated_type = local_enumerated_type;
   820 		else if ((global_enumerated_type !=      enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL))
   931 		else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()) && (global_enumerated_type == NULL))
   821 			enumerated_type = NULL; // Duplicate, so it is ambiguous!
   932 			enumerated_type = NULL; // Duplicate, so it is ambiguous!
   822 		else if ((global_enumerated_type !=      enumerated_value_symtable.end_value()))
   933 		else if ((global_enumerated_type != global_enumerated_value_symtable.end_value()))
   823 			enumerated_type = global_enumerated_type;
   934 			enumerated_type = global_enumerated_type;
   824 		else ERROR;
   935 		else ERROR;
   825 	}
   936 	}
   826 	enumerated_type = base_type(enumerated_type);
   937 	enumerated_type = base_type(enumerated_type);
   827 	if (NULL != enumerated_type)
   938 	if (NULL != enumerated_type)