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); |