stage3/fill_candidate_datatypes.cc
changeset 724 d19877568878
parent 720 f637ac331a68
child 726 9b61eb4f00dc
equal deleted inserted replaced
723:d475ae61c7f8 724:d19877568878
    70 
    70 
    71 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
    71 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
    72 #define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
    72 #define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
    73 #define IS_OVERFLOW(dtype, symbol)            (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status)
    73 #define IS_OVERFLOW(dtype, symbol)            (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status)
    74 
    74 
       
    75 
       
    76 
       
    77 
       
    78 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
       
    79 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
       
    80 
       
    81 
       
    82 #define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
       
    83     fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
       
    84             FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
       
    85                                                  LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
       
    86     fprintf(stderr, __VA_ARGS__);                                                                                           \
       
    87     fprintf(stderr, "\n");                                                                                                  \
       
    88 }  
       
    89 
       
    90 
       
    91 #define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
       
    92     fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
       
    93             FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
       
    94                                                  LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
       
    95     fprintf(stderr, __VA_ARGS__);                                                                                           \
       
    96     fprintf(stderr, "\n");                                                                                                  \
       
    97 }  
       
    98 
       
    99 
       
   100 
    75 /* set to 1 to see debug info during execution */
   101 /* set to 1 to see debug info during execution */
    76 static int debug = 0;
   102 static int debug = 0;
    77 
   103 
    78 
   104 
    79 
   105 
    84 /*****************************************************/
   110 /*****************************************************/
    85 
   111 
    86 /* Add to the global_enumerated_value_symtable the global enum value constants, i.e. the enum constants used in the enumerated
   112 /* 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.
   113  * datatypes that are defined inside a TYPE ... END_TYPE declaration.
    88  */
   114  */
    89 
   115 /* NOTE: we do not store any NULL values in this symbol table, so we can safely use NULL and the null value. */
    90  symbol_c null_globalenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
   116 
    91  static dsymtable_c<symbol_c *, &null_globalenumvalue_symbol> global_enumerated_value_symtable;
   117 symbol_c null_enumvalue_symbol; /* cannot be static, so it may be used in the template!! */
       
   118 typedef dsymtable_c<symbol_c *, &null_enumvalue_symbol> enumerated_value_symtable_t;
       
   119 static enumerated_value_symtable_t global_enumerated_value_symtable;
    92  
   120  
    93  
   121  
    94 class populate_globalenumvalue_symtable_c: public iterator_visitor_c {
   122 class populate_globalenumvalue_symtable_c: public iterator_visitor_c {
    95   private:
   123   private:
    96     symbol_c *current_enumerated_type;
   124     symbol_c *current_enumerated_type;
   126   /* [enumerated_type_name '#'] identifier */
   154   /* [enumerated_type_name '#'] identifier */
   127   void *visit(enumerated_value_c *symbol) {
   155   void *visit(enumerated_value_c *symbol) {
   128     if (current_enumerated_type == NULL) ERROR;
   156     if (current_enumerated_type == NULL) ERROR;
   129     if (symbol->type != NULL) ERROR;
   157     if (symbol->type != NULL) ERROR;
   130 
   158 
   131     symbol_c *value_type = global_enumerated_value_symtable.find_value(symbol->value);
   159     enumerated_value_symtable_t::iterator lower = global_enumerated_value_symtable.lower_bound(symbol->value);
   132     /* NOTE: The following condition checks whether the same identifier is used more than once
   160     enumerated_value_symtable_t::iterator upper = global_enumerated_value_symtable.upper_bound(symbol->value);
   133      *       when defining the enumerated values of the type declaration of the new enumerated type.
   161     for (; lower != upper; lower++)
   134      *       If this occurs, then the program beeing compiled contains a semantic error, which
   162       if (lower->second == current_enumerated_type) {
   135      *       must be caught and reported by the semantic analyser. However, since
   163         /*  The same identifier is used more than once as an enumerated value/constant inside the same enumerated datat type! */
   136      *       this code is run before the semantic analyser, we must not yet raise the ERROR (internal
   164         STAGE3_ERROR(0, symbol, symbol, "Duplicate identifier in enumerated data type.");
   137      *       compiler error message).
   165         return NULL; /* No need to insert it! It is already in the table! */
   138      *       For this reason, the follosing check is commented out.
   166       }
   139      */
       
   140     /* if (value_type == current_enumerated_type) ERROR; */
       
   141 
   167 
   142     global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   168     global_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   143     return NULL;
   169     return NULL;
   144   }
   170   }
   145 
   171 
   198  *     GlobalEnumVar := xxx1;   <-- We consider it an error. xxx1 will reference the anonymous type used for LocalEnumVar
   224  *     GlobalEnumVar := xxx1;   <-- We consider it an error. xxx1 will reference the anonymous type used for LocalEnumVar
   199  *     GlobalEnumVar := GlobalEnumT#xxx1;
   225  *     GlobalEnumVar := GlobalEnumT#xxx1;
   200  *     END_FUNCTION_BLOCK
   226  *     END_FUNCTION_BLOCK
   201  */
   227  */
   202  
   228  
   203  symbol_c null_localenumvalue_symbol; /* cannot be static, so it may be used in the template!! */
   229 static enumerated_value_symtable_t local_enumerated_value_symtable;
   204  static dsymtable_c<symbol_c *, &null_localenumvalue_symbol> local_enumerated_value_symtable;
       
   205 
   230 
   206 
   231 
   207 class populate_enumvalue_symtable_c: public iterator_visitor_c {
   232 class populate_enumvalue_symtable_c: public iterator_visitor_c {
   208   private:
   233   private:
   209     symbol_c *current_enumerated_type;
   234     symbol_c *current_enumerated_type;
   239     /* 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 */
   264     /* 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 */
   240     if (current_enumerated_type == NULL) return NULL;  
   265     if (current_enumerated_type == NULL) return NULL;  
   241     /* 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 !! */
   266     /* 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 !! */
   242     if (symbol->type != NULL) ERROR;  
   267     if (symbol->type != NULL) ERROR;  
   243 
   268 
   244     symbol_c *local_value_type  = local_enumerated_value_symtable.find_value(symbol->value);
   269     enumerated_value_symtable_t::iterator lower = local_enumerated_value_symtable.lower_bound(symbol->value);
       
   270     enumerated_value_symtable_t::iterator upper = local_enumerated_value_symtable.upper_bound(symbol->value);
       
   271     for (; lower != upper; lower++)
       
   272       if (lower->second == current_enumerated_type) {
       
   273         /*  The same identifier is used more than once as an enumerated value/constant inside the same enumerated datat type! */
       
   274         STAGE3_ERROR(0, symbol, symbol, "Duplicate identifier in enumerated data type.");
       
   275         return NULL; /* No need to insert it! It is already in the table! */
       
   276       }
   245     
   277     
   246     /* add it to the local symbol table. */
   278     /* add it to the local symbol table. */
   247     local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   279     local_enumerated_value_symtable.insert(symbol->value, current_enumerated_type);
   248     return NULL;
   280     return NULL;
   249   }
   281   }
   381 			param_name = fp_iterator.next();
   413 			param_name = fp_iterator.next();
   382 			/* If there is no other parameter declared, then we are passing too many parameters... */
   414 			/* If there is no other parameter declared, then we are passing too many parameters... */
   383 			if(param_name == NULL) return false;
   415 			if(param_name == NULL) return false;
   384 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
   416 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
   385 
   417 
   386 		/* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */
       
   387 		/* Get the parameter type */
   418 		/* Get the parameter type */
   388 		param_datatype = base_type(fp_iterator.param_type());
   419 		param_datatype = base_type(fp_iterator.param_type());
   389 		
   420 		
   390 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
   421 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
   391 		if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0)
   422 		if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0)
   772 /***************************/
   803 /***************************/
   773 /************************/
   804 /************************/
   774 /* B 1.2.3.1 - Duration */
   805 /* B 1.2.3.1 - Duration */
   775 /************************/
   806 /************************/
   776 void *fill_candidate_datatypes_c::visit(duration_c *symbol) {
   807 void *fill_candidate_datatypes_c::visit(duration_c *symbol) {
   777 	/* TODO: check whether the literal follows the rules specified in section '2.2.3.1 Duration' of the standard! */
       
   778 	
       
   779 	add_datatype_to_candidate_list(symbol, symbol->type_name);
   808 	add_datatype_to_candidate_list(symbol, symbol->type_name);
   780 	if (debug) std::cout << "TIME_LITERAL [" << symbol->candidate_datatypes.size() << "]\n";
   809 	if (debug) std::cout << "TIME_LITERAL [" << symbol->candidate_datatypes.size() << "]\n";
   781 	return NULL;
   810 	return NULL;
   782 }
   811 }
   783 
   812 
   901 void *fill_candidate_datatypes_c::visit(enumerated_value_c *symbol) {
   930 void *fill_candidate_datatypes_c::visit(enumerated_value_c *symbol) {
   902 	symbol_c *global_enumerated_type;
   931 	symbol_c *global_enumerated_type;
   903 	symbol_c *local_enumerated_type;
   932 	symbol_c *local_enumerated_type;
   904 	symbol_c *enumerated_type;
   933 	symbol_c *enumerated_type;
   905 
   934 
   906 	if (NULL != symbol->type)
   935 	if (NULL != symbol->type) {
   907 		enumerated_type = symbol->type; /* TODO: check whether the value really belongs to that datatype!! */
   936 #if 1
       
   937 		enumerated_type = symbol->type; 
       
   938 #else
       
   939 		/* NOTE: The following code works but is not complete, that is why it is currently commented out!
       
   940 		 *  
       
   941 		 *        It is not complete because it does not yet consider the following situation:
       
   942 		 *
       
   943 		 *        TYPE  
       
   944 		 *           base_enum_t: (x1, x2, x3);
       
   945 		 *           enum_t1 : base_enum_t := x1;
       
   946 		 *           enum_t2 : base_enum_t := x2;
       
   947 		 *           enum_t12: enum_t1     := x2;
       
   948 		 *        END_TYPE
       
   949 		 *
       
   950 		 *     considering the above, ALL of the following are correct!
       
   951 		 *         base_enum_t#x1
       
   952 		 *             enum_t1#x1
       
   953 		 *             enum_t2#x1
       
   954 		 *            enum_t12#x1
       
   955 		 *
       
   956 		 *      However, the following code only considers 
       
   957  		 *         base_enum_t#x1
       
   958 		 *      as correct, and all the others as incorrect!
       
   959 		 */
       
   960 		/* check whether the value really belongs to that datatype!! */
       
   961 		/* All local enum values are declared inside anonymous enumeration datatypes (i.e. inside a VAR ... END_VAR declaration, with
       
   962 		 * the enum type having no type name), so thay cannot possibly be referenced using a datatype_t#enumvalue syntax.
       
   963 		 * Because of this, we only look for the datatype identifier in the global enum value symbol table!
       
   964 		 */
       
   965 		enumerated_type = NULL;  // assume error...
       
   966 		enumerated_value_symtable_t::iterator lower = global_enumerated_value_symtable.lower_bound(symbol->value);
       
   967 		enumerated_value_symtable_t::iterator upper = global_enumerated_value_symtable.upper_bound(symbol->value);
       
   968 		for (; lower != upper; lower++)
       
   969 			if (compare_identifiers(search_base_type_c::get_basetype_id(lower->second), symbol->type) == 0)  // returns 0 if identifiers are equal!!
       
   970 				enumerated_type = symbol->type; 
       
   971 #endif
       
   972 	}
   908 	else {
   973 	else {
   909 		symbol_c *global_enumerated_type = global_enumerated_value_symtable.find_value  (symbol->value);
   974 		symbol_c *global_enumerated_type = global_enumerated_value_symtable.find_value  (symbol->value);
   910 		symbol_c * local_enumerated_type =  local_enumerated_value_symtable.find_value  (symbol->value);
   975 		symbol_c * local_enumerated_type =  local_enumerated_value_symtable.find_value  (symbol->value);
   911 		int       global_multiplicity    = global_enumerated_value_symtable.count(symbol->value);
   976 		int       global_multiplicity    = global_enumerated_value_symtable.count(symbol->value);
   912 		int        local_multiplicity    =  local_enumerated_value_symtable.count(symbol->value);
   977 		int        local_multiplicity    =  local_enumerated_value_symtable.count(symbol->value);