# HG changeset patch # User Mario de Sousa # Date 1353611988 0 # Node ID 6ecb387157244f0154e7c9227b157f3b4555eee9 # Parent a9741eb5aaabc9512e320ed123d6f857e90071e0# Parent fbf77edf54ca71e16dc9ad6c35f2081551d68399 merge diff -r fbf77edf54ca -r 6ecb38715724 absyntax/absyntax.def --- a/absyntax/absyntax.def Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax/absyntax.def Thu Nov 22 19:19:48 2012 +0000 @@ -114,7 +114,8 @@ /***************************/ /* B 0 - Programming Model */ /***************************/ -SYM_LIST(library_c) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_LIST(library_c, enumvalue_symtable_t enumvalue_symtable;) /*************************/ @@ -701,7 +702,8 @@ /***********************/ /* B 1.5.1 - Functions */ /***********************/ -SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;) /* intermediate helper symbol for * - function_declaration @@ -721,7 +723,8 @@ /* B 1.5.2 - Function Blocks */ /*****************************/ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ -SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;) /* intermediate helper symbol for function_declaration */ /* { io_var_declarations | other_var_declarations } */ @@ -743,7 +746,8 @@ /* B 1.5.3 - Programs */ /**********************/ /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ -SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;) /* intermediate helper symbol for program_declaration_c */ /* { io_var_declarations | other_var_declarations } */ @@ -826,7 +830,8 @@ optional_instance_specific_initializations END_CONFIGURATION */ -SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, enumvalue_symtable_t enumvalue_symtable;) /* helper symbol for configuration_declaration */ SYM_LIST(resource_declaration_list_c) @@ -837,7 +842,8 @@ single_resource_declaration END_RESOURCE */ -SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration) +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, enumvalue_symtable_t enumvalue_symtable;) /* task_configuration_list program_configuration_list */ SYM_REF2(single_resource_declaration_c, task_configuration_list, program_configuration_list) diff -r fbf77edf54ca -r 6ecb38715724 absyntax/absyntax.hh --- a/absyntax/absyntax.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax/absyntax.hh Thu Nov 22 19:19:48 2012 +0000 @@ -48,6 +48,7 @@ #include // required for NULL #include +#include #include #include // required for uint64_t, etc... #include "../main.hh" // required for uint8_t, real_64_t, ..., and the macros INT8_MAX, REAL32_MAX, ... */ @@ -72,6 +73,28 @@ +/* Case insensitive string compare */ + /* Case insensitive string compare copied from + * "The C++ Programming Language" - 3rd Edition + * by Bjarne Stroustrup, ISBN 0201889544. + */ +class nocasecmp_c { + public: + bool operator() (const std::string& x, const std::string& y) const { + std::string::const_iterator ix = x.begin(); + std::string::const_iterator iy = y.begin(); + + for(; (ix != x.end()) && (iy != y.end()) && (toupper(*ix) == toupper(*iy)); ++ix, ++iy); + if (ix == x.end()) return (iy != y.end()); + if (iy == y.end()) return false; + return (toupper(*ix) < toupper(*iy)); + }; + }; + + + + + @@ -99,7 +122,7 @@ /* * Annotations produced during stage 3 - */ + */ /*** Data type analysis ***/ std::vector candidate_datatypes; /* All possible data types the expression/literal/etc. may take. Filled in stage3 by fill_candidate_datatypes_c class */ /* Data type of the expression/literal/etc. Filled in stage3 by narrow_candidate_datatypes_c @@ -138,6 +161,12 @@ } const_value_t; const_value_t const_value; + /*** Enumeration datatype checking ***/ + /* Not all symbols will contain the following anotations, which is why they are not declared here in symbol_c + * They will be declared only inside the symbols that require them (have a look at absyntax.def) + */ + typedef std::multimap enumvalue_symtable_t; + public: /* default constructor */ @@ -153,6 +182,8 @@ }; + + class token_c: public symbol_c { public: /* WARNING: only use this method for debugging purposes!! */ @@ -169,6 +200,8 @@ }; + + /* a list of symbols... */ class list_c: public symbol_c { public: @@ -200,6 +233,11 @@ + + + + + #define SYM_LIST(class_name_c, ...) \ class class_name_c: public list_c { \ public: \ diff -r fbf77edf54ca -r 6ecb38715724 absyntax/visitor.cc --- a/absyntax/visitor.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax/visitor.cc Thu Nov 22 19:19:48 2012 +0000 @@ -70,7 +70,7 @@ null_visitor_c::~null_visitor_c(void) {return;} -#define SYM_LIST(class_name_c) \ +#define SYM_LIST(class_name_c, ...) \ void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} #define SYM_TOKEN(class_name_c, ...) \ @@ -174,7 +174,7 @@ } -#define SYM_LIST(class_name_c) \ +#define SYM_LIST(class_name_c, ...) \ void *iterator_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} #define SYM_TOKEN(class_name_c, ...) \ @@ -318,7 +318,7 @@ } -#define SYM_LIST(class_name_c) \ +#define SYM_LIST(class_name_c, ...) \ void *search_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} #define SYM_TOKEN(class_name_c, ...) \ diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/absyntax_utils.cc Thu Nov 22 19:19:48 2012 +0000 @@ -193,7 +193,7 @@ /* enumerated_type_name ':' enumerated_spec_init */ void *visit(enumerated_type_declaration_c *symbol) { TRACE("enumerated_type_declaration_c"); - type_symtable.insert(symbol->enumerated_type_name, symbol->enumerated_spec_init); + type_symtable.insert(symbol->enumerated_type_name, symbol); current_enumerated_type = symbol->enumerated_type_name; symbol->enumerated_spec_init->accept(*this); current_enumerated_type = NULL; diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/debug_ast.cc --- a/absyntax_utils/debug_ast.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/debug_ast.cc Thu Nov 22 19:19:48 2012 +0000 @@ -44,14 +44,32 @@ #include #include /* required for NULL */ #include "absyntax_utils.hh" - - - - - - - - +#include "../absyntax/visitor.hh" + + + + + + +/*********************************/ +/* Class to print a symbol */ +/*********************************/ + + +class print_symbol_c: public fcall_visitor_c { + public: + static void print(symbol_c *symbol); + + protected: + void fcall(symbol_c *symbol); + /* AST symbols with extra data have their own specialised methods for printing that data */ + void *visit(il_instruction_c *symbol); + + private: + static print_symbol_c *singleton; + + void dump_symbol(symbol_c* symbol); +}; @@ -70,9 +88,6 @@ - - - void print_symbol_c::fcall(symbol_c* symbol) { dump_symbol(symbol); fprintf(stderr, "\n"); @@ -85,8 +100,9 @@ fprintf(stderr, " datatype="); if (NULL == symbol->datatype) fprintf(stderr, "NULL\t\t"); - else - fprintf(stderr, symbol->datatype->absyntax_cname()); + else { + fprintf(stderr, "%s", symbol->datatype->absyntax_cname()); + } fprintf(stderr, "\t<-{"); if (symbol->candidate_datatypes.size() == 0) { fprintf(stderr, "\t\t\t\t\t"); @@ -97,9 +113,13 @@ else fprintf(stderr, "\t\t\t"); } else { - fprintf(stderr, "(%d)\t\t\t\t\t", symbol->candidate_datatypes.size()); + fprintf(stderr, "(%lu)\t\t\t\t\t", (unsigned long int)symbol->candidate_datatypes.size()); } - fprintf(stderr, "}\t"); + fprintf(stderr, "}\t"); + + /* print the const values... */ + fprintf(stderr, " constv{f=%f, i=%"PRId64", u=%"PRIu64", b=%d}\t", symbol->const_value._real64.value, symbol->const_value._int64.value, symbol->const_value._uint64.value, symbol->const_value._bool.value?1:0); + } @@ -107,8 +127,9 @@ void *print_symbol_c::visit(il_instruction_c *symbol) { dump_symbol(symbol); - fprintf(stderr, " next_il_=%d ", symbol->next_il_instruction.size()); - fprintf(stderr, " prev_il_=%d ", symbol->prev_il_instruction.size()); + /* NOTE: std::map.size() returns a size_type, whose type is dependent on compiler/platform. To be portable, we need to do an explicit type cast. */ + fprintf(stderr, " next_il_=%lu ", (unsigned long int)symbol->next_il_instruction.size()); + fprintf(stderr, " prev_il_=%lu ", (unsigned long int)symbol->prev_il_instruction.size()); if (symbol->prev_il_instruction.size() == 0) fprintf(stderr, "(----,"); @@ -137,10 +158,22 @@ - - - - +/*********************************/ +/* Class to print an AST */ +/*********************************/ + +class print_ast_c: public fcall_iterator_visitor_c { + public: + static void print(symbol_c *symbol); + static void print(const char *str); + + protected: + void prefix_fcall(symbol_c *symbol); + void suffix_fcall(symbol_c *symbol); + + private: + static print_ast_c *singleton; +}; @@ -155,6 +188,11 @@ symbol->accept(*singleton); } + +void print_ast_c::print(const char *str) { + fprintf(stderr, str); +} + void print_ast_c::prefix_fcall(symbol_c* symbol) {print_symbol_c::print(symbol);} void print_ast_c::suffix_fcall(symbol_c* symbol) {} @@ -163,14 +201,26 @@ - - - - - - - - - - - +/*********************************/ +/* The DEBUG class */ +/*********************************/ + + + + +void debug_c::print(const char *str) { + fprintf(stderr, str); +} + +void debug_c::print(symbol_c *symbol) { + print_symbol_c::print(symbol); +} + +void debug_c::print_ast(symbol_c *symbol) { + print_ast_c::print(symbol); +} + + + + + diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/debug_ast.hh --- a/absyntax_utils/debug_ast.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/debug_ast.hh Thu Nov 22 19:19:48 2012 +0000 @@ -41,40 +41,16 @@ -#include "../absyntax/visitor.hh" +#include "../absyntax/absyntax.hh" - -class print_symbol_c: public fcall_visitor_c { +class debug_c { public: static void print(symbol_c *symbol); - - protected: - void fcall(symbol_c *symbol); - /* AST symbols with extra data have their own specialised methods for printing that data */ - void *visit(il_instruction_c *symbol); + static void print(const char *str); - private: - static print_symbol_c *singleton; - - void dump_symbol(symbol_c* symbol); -}; - - - - - - -class print_ast_c: public fcall_iterator_visitor_c { - public: - static void print(symbol_c *symbol); - - protected: - void prefix_fcall(symbol_c *symbol); - void suffix_fcall(symbol_c *symbol); - - private: - static print_ast_c *singleton; + /* print the AST from this point downwards */ + static void print_ast(symbol_c *root_symbol); }; @@ -92,3 +68,5 @@ + + diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/get_datatype_info.cc Thu Nov 22 19:19:48 2012 +0000 @@ -50,13 +50,78 @@ #include // required for typeid - - - - - - - +/**********************************************************/ +/**********************************************************/ +/**********************************************************/ +/***** *****/ +/***** *****/ +/***** Some helper classes *****/ +/***** *****/ +/***** *****/ +/**********************************************************/ +/**********************************************************/ +/**********************************************************/ + +/* Return the identifier (name) of a datatype, typically declared in a TYPE .. END_TYPE declaration */ +class get_datatype_id_c: null_visitor_c { + private: + static get_datatype_id_c *singleton; + + public: + static symbol_c *get_id(symbol_c *symbol) { + if (NULL == singleton) singleton = new get_datatype_id_c(); + if (NULL == singleton) ERROR; + return (symbol_c *)symbol->accept(*singleton); + } + + protected: + /********************************/ + /* B 1.3.3 - Derived data types */ + /********************************/ + /* simple_type_name ':' simple_spec_init */ + void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name;} + /* subrange_type_name ':' subrange_spec_init */ + void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name;} + /* enumerated_type_name ':' enumerated_spec_init */ + void *visit(enumerated_type_declaration_c *symbol) {return symbol->enumerated_type_name;} + /* identifier ':' array_spec_init */ + void *visit(array_type_declaration_c *symbol) {return symbol->identifier;} + /* structure_type_name ':' structure_specification */ + void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name;} + /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ + void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name;} + + /*****************************/ + /* B 1.5.2 - Function Blocks */ + /*****************************/ + /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ + void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name;} +}; // get_datatype_id_c + +get_datatype_id_c *get_datatype_id_c::singleton = NULL; + + + + + + +/**********************************************************/ +/**********************************************************/ +/**********************************************************/ +/***** *****/ +/***** *****/ +/***** GET_DATATYPE_INFO_C *****/ +/***** *****/ +/***** *****/ +/**********************************************************/ +/**********************************************************/ +/**********************************************************/ + + + +symbol_c *get_datatype_info_c::get_datatype_id(symbol_c *datatype) { + return get_datatype_id_c::get_id(datatype); +} bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) { diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/get_datatype_info.hh --- a/absyntax_utils/get_datatype_info.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/get_datatype_info.hh Thu Nov 22 19:19:48 2012 +0000 @@ -57,6 +57,8 @@ public: + static symbol_c *get_datatype_id(symbol_c *datatype); /* get the identifier (name) of the datatype); returns NULL if anonymous datatype! */ + static bool is_type_equal(symbol_c *first_type, symbol_c *second_type); static bool is_type_valid(symbol_c *type); diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/search_base_type.cc Thu Nov 22 19:19:48 2012 +0000 @@ -54,7 +54,7 @@ -search_base_type_c::search_base_type_c(void) {current_type_name = NULL;} +search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;} /* static method! */ void search_base_type_c::create_singleton(void) { @@ -66,15 +66,17 @@ symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) { create_singleton(); if (NULL == symbol) return NULL; + search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype = NULL; return (symbol_c *)symbol->accept(*search_base_type_singleton); } /* static method! */ symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) { create_singleton(); - if (NULL == symbol) return NULL; - + if (NULL == symbol) return NULL; search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype = NULL; symbol->accept(*search_base_type_singleton); return (symbol_c *)search_base_type_singleton->current_type_name; } @@ -112,6 +114,10 @@ symbol_c *type_decl; this->current_type_name = type_name; + /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for, + * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!) + */ + this->current_basetype = NULL; /* look up the type declaration... */ type_decl = type_symtable.find_value(type_name); @@ -244,20 +250,37 @@ /* enumerated_type_name ':' enumerated_spec_init */ void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { this->current_type_name = symbol->enumerated_type_name; + /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible + * (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an + * anonymous datatype declared in a VAR ... AND_VAR declaration). + * However, we cannot return this symbol just yet, as it may not be the final base datatype. + * So we store it in a temporary current_basetype variable! + */ + this->current_basetype = symbol; return symbol->enumerated_spec_init->accept(*this); } /* enumerated_specification ASSIGN enumerated_value */ void *search_base_type_c::visit(enumerated_spec_init_c *symbol) { this->is_enumerated = true; - return symbol->enumerated_specification->accept(*this); + // 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! + if (NULL == this->current_basetype) + this->current_basetype = symbol; + /* NOTE: the following line may call either the visitor to + * - identifier_c, in which case this is not yet the base datatype we are looking for (it will set current_basetype to NULL!) + * - enumerated_value_list_c, in which case we have found the base datatype. + */ + return symbol->enumerated_specification->accept(*this); } /* helper symbol for enumerated_specification->enumerated_spec_init */ /* enumerated_value_list ',' enumerated_value */ void *search_base_type_c::visit(enumerated_value_list_c *symbol) { this->is_enumerated = true; - return (void *)symbol; + // 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! + if (NULL == this->current_basetype) + this->current_basetype = symbol; + return (void *)current_basetype; } /* enumerated_type_name '#' identifier */ diff -r fbf77edf54ca -r 6ecb38715724 absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/absyntax_utils/search_base_type.hh Thu Nov 22 19:19:48 2012 +0000 @@ -52,6 +52,7 @@ private: symbol_c *current_type_name; + symbol_c *current_basetype; bool is_array; bool is_subrange; bool is_enumerated; diff -r fbf77edf54ca -r 6ecb38715724 lib/iec_types.h --- a/lib/iec_types.h Mon Nov 12 22:36:55 2012 +0100 +++ b/lib/iec_types.h Thu Nov 22 19:19:48 2012 +0000 @@ -32,7 +32,7 @@ typedef struct { long int tv_sec; /* Seconds. */ long int tv_nsec; /* Nanoseconds. */ -} IEC_TIMESPEC; +} /* __attribute__((packed)) */ IEC_TIMESPEC; /* packed is gcc specific! */ typedef IEC_TIMESPEC IEC_TIME; typedef IEC_TIMESPEC IEC_DATE; @@ -51,6 +51,6 @@ typedef struct { __strlen_t len; uint8_t body[STR_MAX_LEN]; -} IEC_STRING; +} /* __attribute__((packed)) */ IEC_STRING; /* packed is gcc specific! */ #endif /*IEC_TYPES_H*/ diff -r fbf77edf54ca -r 6ecb38715724 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Mon Nov 12 22:36:55 2012 +0100 +++ b/stage1_2/iec_bison.yy Thu Nov 22 19:19:48 2012 +0000 @@ -2549,10 +2549,13 @@ simple_type_declaration: /* simple_type_name ':' simple_spec_init */ - identifier ':' simple_spec_init - {$$ = new simple_type_declaration_c($1, $3, locloc(@$)); - library_element_symtable.insert($1, prev_declared_simple_type_name_token); - } +/* To understand why simple_spec_init was brocken up into its consituent components in the following rules, please see note in the definition of 'enumerated_type_declaration'. */ + identifier ':' simple_specification {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} + {$$ = new simple_type_declaration_c($1, $3, locloc(@$));} +| identifier ':' elementary_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant + {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} +| identifier ':' prev_declared_simple_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant + {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} /* ERROR_CHECK_BEGIN */ | error ':' simple_spec_init {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;} @@ -2687,10 +2690,23 @@ enumerated_type_declaration: /* enumerated_type_name ':' enumerated_spec_init */ - identifier ':' enumerated_spec_init - {$$ = new enumerated_type_declaration_c($1, $3, locloc(@$)); - library_element_symtable.insert($1, prev_declared_enumerated_type_name_token); - } +/* NOTE: The 'identifier' used for the name of the new enumerated type is inserted early into the library_element_symtable so it may be used + * in defining the default initial value of this type, using the fully qualified enumerated constant syntax: type_name#enum_value + * In other words, this allows us to correclty parse the following IEC 61131-3 code: + * TYPE enum_t : (x1, x2, x3) := enum_t#x3; END_TYPE + * ^^^^^^^ + * + * However, we can only introduce it after we are sure we are parsing an enumerated_spec. For this reason, instead of using the + * symbol enumerated_spec_init in this rule, we decompose it here instead! + * + * If it were not for the above, we could use the rule + * identifier ':' enumerated_spec_init + * and include the library_element_symtable.insert(...) code in the rule actions! + */ + identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} + {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));} +| identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value + {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} /* ERROR_CHECK_BEGIN */ | error ':' enumerated_spec_init {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;} diff -r fbf77edf54ca -r 6ecb38715724 stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Mon Nov 12 22:36:55 2012 +0100 +++ b/stage1_2/iec_flex.ll Thu Nov 22 19:19:48 2012 +0000 @@ -416,7 +416,7 @@ /* we are parsing a function, program or function block declaration */ %s decl_state -/* we will be parsing a function body. Whether il/st is remains unknown */ +/* we will be parsing a function body. Whether il/st/sfc remains to be determined */ %x body_state /* we are parsing il code -> flex must return the EOL tokens! */ @@ -924,8 +924,7 @@ * calling yyterminate() is equivalent to doing that. */ yyterminate(); - } - else { + } else { --include_stack_ptr; yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state); @@ -1735,12 +1734,10 @@ * return 0; */ - /* to we stop processing... - * + /* to stop processing... * return 1; */ - return 1; /* Stop scanning at end of input file. */ } diff -r fbf77edf54ca -r 6ecb38715724 stage3/Makefile.am --- a/stage3/Makefile.am Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/Makefile.am Thu Nov 22 19:19:48 2012 +0000 @@ -13,5 +13,6 @@ lvalue_check.cc \ array_range_check.cc \ constant_folding.cc \ - declaration_check.cc + declaration_check.cc \ + enum_declaration_check.cc diff -r fbf77edf54ca -r 6ecb38715724 stage3/Makefile.in --- a/stage3/Makefile.in Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/Makefile.in Thu Nov 22 19:19:48 2012 +0000 @@ -83,7 +83,8 @@ forced_narrow_candidate_datatypes.$(OBJEXT) \ print_datatypes_error.$(OBJEXT) datatype_functions.$(OBJEXT) \ lvalue_check.$(OBJEXT) array_range_check.$(OBJEXT) \ - constant_folding.$(OBJEXT) declaration_check.$(OBJEXT) + constant_folding.$(OBJEXT) declaration_check.$(OBJEXT) \ + enum_declaration_check.$(OBJEXT) libstage3_a_OBJECTS = $(am_libstage3_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config depcomp = $(SHELL) $(top_srcdir)/config/depcomp @@ -209,7 +210,8 @@ lvalue_check.cc \ array_range_check.cc \ constant_folding.cc \ - declaration_check.cc + declaration_check.cc \ + enum_declaration_check.cc all: all-am @@ -291,6 +293,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constant_folding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/datatype_functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/declaration_check.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enum_declaration_check.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fill_candidate_datatypes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow_control_analysis.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forced_narrow_candidate_datatypes.Po@am__quote@ diff -r fbf77edf54ca -r 6ecb38715724 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/constant_folding.cc Thu Nov 22 19:19:48 2012 +0000 @@ -253,7 +253,7 @@ int64_t ret; std::string str = ""; char *endptr; - const char *value; + const char *value = NULL; int base; integer_c *integer; hex_integer_c *hex_integer; @@ -285,7 +285,7 @@ uint64_t ret; std::string str = ""; char *endptr; - const char *value; + const char *value = NULL; int base; integer_c *integer; hex_integer_c *hex_integer; diff -r fbf77edf54ca -r 6ecb38715724 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/fill_candidate_datatypes.cc Thu Nov 22 19:19:48 2012 +0000 @@ -75,29 +75,6 @@ -#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) -#define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) - - -#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) { \ - fprintf(stderr, "%s:%d-%d..%d-%d: error: ", \ - FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ - LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ -} - - -#define STAGE3_WARNING(symbol1, symbol2, ...) { \ - fprintf(stderr, "%s:%d-%d..%d-%d: warning: ", \ - FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ - LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ -} - - - /* set to 1 to see debug info during execution */ static int debug = 0; @@ -161,7 +138,6 @@ for (; lower != upper; lower++) if (lower->second == current_enumerated_type) { /* The same identifier is used more than once as an enumerated value/constant inside the same enumerated datat type! */ - STAGE3_ERROR(0, symbol, symbol, "Duplicate identifier in enumerated data type."); return NULL; /* No need to insert it! It is already in the table! */ } @@ -229,13 +205,13 @@ static enumerated_value_symtable_t local_enumerated_value_symtable; -class populate_enumvalue_symtable_c: public iterator_visitor_c { +class populate_localenumvalue_symtable_c: public iterator_visitor_c { private: symbol_c *current_enumerated_type; public: - populate_enumvalue_symtable_c(void) {current_enumerated_type = NULL;}; - ~populate_enumvalue_symtable_c(void) {} + populate_localenumvalue_symtable_c(void) {current_enumerated_type = NULL;}; + ~populate_localenumvalue_symtable_c(void) {} public: /*************************/ @@ -271,7 +247,6 @@ for (; lower != upper; lower++) if (lower->second == current_enumerated_type) { /* The same identifier is used more than once as an enumerated value/constant inside the same enumerated datat type! */ - STAGE3_ERROR(0, symbol, symbol, "Duplicate identifier in enumerated data type."); return NULL; /* No need to insert it! It is already in the table! */ } @@ -281,7 +256,7 @@ } }; // class populate_enumvalue_symtable_c -static populate_enumvalue_symtable_c populate_enumvalue_symtable; +static populate_localenumvalue_symtable_c populate_enumvalue_symtable; @@ -879,13 +854,25 @@ /* enumerated_type_name ':' enumerated_spec_init */ // SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) -/* NOTE: Not required. already handled by iterator_visitor_c base class */ +void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) { + current_enumerated_spec_type = base_type(symbol); + add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); + add_datatype_to_candidate_list(symbol->enumerated_type_name, current_enumerated_spec_type); + symbol->enumerated_spec_init->accept(*this); + current_enumerated_spec_type = NULL; + return NULL; +} /* enumerated_specification ASSIGN enumerated_value */ // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) { - current_enumerated_spec_type = symbol; + /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration) + * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method! + */ + if (NULL == current_enumerated_spec_type) + current_enumerated_spec_type = base_type(symbol); + add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */ current_enumerated_spec_type = NULL; if (NULL != symbol->enumerated_value) symbol->enumerated_value->accept(*this); @@ -896,20 +883,13 @@ /* enumerated_value_list ',' enumerated_value */ // SYM_LIST(enumerated_value_list_c) void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { - if (NULL == current_enumerated_spec_type) ERROR; - - /* Actually, all this passing of symbol_c * through the current_enumerated_spec_type is actually useless, as the base type - * is actually this enumerated_value_list_c symbol!!! However, it is safer to do it this way, as we can then later change - * search_base_type_c without having to change this fill_candidate_datatypes_c class too!! - */ - current_enumerated_spec_type = base_type(current_enumerated_spec_type); - if (NULL == current_enumerated_spec_type) ERROR; + if (NULL == current_enumerated_spec_type) ERROR; + add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */ - for(int i = 0; i < symbol->n; i++) { + for(int i = 0; i < symbol->n; i++) add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); - symbol->elements[i]->datatype = current_enumerated_spec_type; // To be consistent, this should really be done in the narrow_candidate_datatypes_c !! - } + return NULL; } @@ -930,15 +910,10 @@ void *fill_candidate_datatypes_c::visit(enumerated_value_c *symbol) { symbol_c *global_enumerated_type; symbol_c *local_enumerated_type; - symbol_c *enumerated_type; + symbol_c *enumerated_type = NULL; if (NULL != symbol->type) { -#if 1 - enumerated_type = symbol->type; -#else - /* NOTE: The following code works but is not complete, that is why it is currently commented out! - * - * It is not complete because it does not yet consider the following situation: + /* NOTE: This code must take into account the following situation: * * TYPE * base_enum_t: (x1, x2, x3); @@ -952,10 +927,6 @@ * enum_t1#x1 * enum_t2#x1 * enum_t12#x1 - * - * However, the following code only considers - * base_enum_t#x1 - * as correct, and all the others as incorrect! */ /* check whether the value really belongs to that datatype!! */ /* All local enum values are declared inside anonymous enumeration datatypes (i.e. inside a VAR ... END_VAR declaration, with @@ -966,9 +937,8 @@ enumerated_value_symtable_t::iterator lower = global_enumerated_value_symtable.lower_bound(symbol->value); enumerated_value_symtable_t::iterator upper = global_enumerated_value_symtable.upper_bound(symbol->value); for (; lower != upper; lower++) - if (compare_identifiers(search_base_type_c::get_basetype_id(lower->second), symbol->type) == 0) // returns 0 if identifiers are equal!! + if (get_datatype_info_c::is_type_equal(base_type(lower->second), base_type(symbol->type))) enumerated_type = symbol->type; -#endif } else { symbol_c *global_enumerated_type = global_enumerated_value_symtable.find_value (symbol->value); @@ -1132,11 +1102,12 @@ /******************************************/ void *fill_candidate_datatypes_c::visit(var1_list_c *symbol) { -#if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */ for(int i = 0; i < symbol->n; i++) { - add_datatype_to_candidate_list(symbol->elements[i], search_varfb_instance_type->get_basetype_decl(symbol->elements[i])); /* will only add if non NULL */ + /* We don't really need to set the datatype of each variable. We just check the declaration itself! + add_datatype_to_candidate_list(symbol->elements[i], search_varfb_instance_type->get_basetype_decl(symbol->elements[i])); // will only add if non NULL + */ + symbol->elements[i]->accept(*this); // handle the extensible_input_parameter_c, etc... } -#endif return NULL; } diff -r fbf77edf54ca -r 6ecb38715724 stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/fill_candidate_datatypes.hh Thu Nov 22 19:19:48 2012 +0000 @@ -175,7 +175,7 @@ // void *visit(subrange_spec_init_c *symbol); // void *visit(subrange_specification_c *symbol); void *visit(subrange_c *symbol); -// void *visit(enumerated_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ + void *visit(enumerated_type_declaration_c *symbol); void *visit(enumerated_spec_init_c *symbol); void *visit(enumerated_value_list_c *symbol); void *visit(enumerated_value_c *symbol); diff -r fbf77edf54ca -r 6ecb38715724 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Thu Nov 22 19:19:48 2012 +0000 @@ -414,9 +414,8 @@ return search_base_type_c::get_basetype_decl(symbol); } -/*********************/ -/* B 1.2 - Constants */ -/*********************/ + + /**********************/ /* B 1.3 - Data types */ @@ -424,6 +423,18 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +/* TYPE type_declaration_list END_TYPE */ +// SYM_REF1(data_type_declaration_c, type_declaration_list) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + +/* helper symbol for data_type_declaration */ +// SYM_LIST(type_declaration_list_c) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + +/* simple_type_name ':' simple_spec_init */ +// SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init) +/* NOTE: Not required. already handled by iterator_visitor_c base class */ + /* simple_specification ASSIGN constant */ // SYM_REF2(simple_spec_init_c, simple_specification, constant) void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { @@ -441,9 +452,18 @@ } +/* subrange_type_name ':' subrange_spec_init */ +// SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init) + +/* subrange_specification ASSIGN signed_integer */ +// SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer) + +/* integer_type_name '(' subrange')' */ +// SYM_REF2(subrange_specification_c, integer_type_name, subrange) /* signed_integer DOTDOT signed_integer */ -// SYM_REF2(subrange_c, lower_limit, upper_limit) +/* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */ +// SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;) void *narrow_candidate_datatypes_c::visit(subrange_c *symbol) { symbol->lower_limit->datatype = symbol->datatype; symbol->lower_limit->accept(*this); @@ -453,6 +473,112 @@ } +/* enumerated_type_name ':' enumerated_spec_init */ +// SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) +void *narrow_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) { + if (symbol->candidate_datatypes.size() != 1) ERROR; + + symbol->datatype = symbol->candidate_datatypes[0]; + set_datatype(symbol->datatype, symbol->enumerated_type_name); + set_datatype(symbol->datatype, symbol->enumerated_spec_init); + + symbol->enumerated_spec_init->accept(*this); + return NULL; +} + + +/* enumerated_specification ASSIGN enumerated_value */ +// SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) +void *narrow_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) { + /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration) + * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method! + */ + if (NULL == symbol->datatype) { + if (symbol->candidate_datatypes.size() != 1) ERROR; + symbol->datatype = symbol->candidate_datatypes[0]; + } + set_datatype(symbol->datatype, symbol->enumerated_specification); + if (NULL != symbol->enumerated_value) + set_datatype(symbol->datatype, symbol->enumerated_value); + + symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */ + return NULL; +} + +/* helper symbol for enumerated_specification->enumerated_spec_init */ +/* enumerated_value_list ',' enumerated_value */ +// SYM_LIST(enumerated_value_list_c) +void *narrow_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { + if (NULL == symbol->datatype) ERROR; + + for(int i = 0; i < symbol->n; i++) { + /* the enumerated_value_c objects to which this list points to has both the datatype and the candidate_datatype_list filled in, so we + * call set_datatype() instead of setting the datatype directly! + */ + set_datatype(symbol->datatype, symbol->elements[i]); + if (NULL == symbol->elements[i]->datatype) ERROR; + } + return NULL; +} + + +/* enumerated_type_name '#' identifier */ +// SYM_REF2(enumerated_value_c, type, value) +// void *narrow_candidate_datatypes_c::visit(enumerated_value_c *symbol) {/* do nothing! */ return NULL;} + + +/* identifier ':' array_spec_init */ +// SYM_REF2(array_type_declaration_c, identifier, array_spec_init) + +/* array_specification [ASSIGN array_initialization} */ +/* array_initialization may be NULL ! */ +// SYM_REF2(array_spec_init_c, array_specification, array_initialization) + +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +// SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name) + +/* helper symbol for array_specification */ +/* array_subrange_list ',' subrange */ +// SYM_LIST(array_subrange_list_c) + +/* array_initialization: '[' array_initial_elements_list ']' */ +/* helper symbol for array_initialization */ +/* array_initial_elements_list ',' array_initial_elements */ +// SYM_LIST(array_initial_elements_list_c) + +/* integer '(' [array_initial_element] ')' */ +/* array_initial_element may be NULL ! */ +// SYM_REF2(array_initial_elements_c, integer, array_initial_element) + +/* structure_type_name ':' structure_specification */ +// SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification) + +/* structure_type_name ASSIGN structure_initialization */ +/* structure_initialization may be NULL ! */ +// SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) + +/* helper symbol for structure_declaration */ +/* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ +/* structure_element_declaration_list structure_element_declaration ';' */ +// SYM_LIST(structure_element_declaration_list_c) + +/* structure_element_name ':' *_spec_init */ +// SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init) + +/* helper symbol for structure_initialization */ +/* structure_initialization: '(' structure_element_initialization_list ')' */ +/* structure_element_initialization_list ',' structure_element_initialization */ +// SYM_LIST(structure_element_initialization_list_c) + +/* structure_element_name ASSIGN value */ +// SYM_REF2(structure_element_initialization_c, structure_element_name, value) + +/* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ +// SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) + + + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r fbf77edf54ca -r 6ecb38715724 stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Thu Nov 22 19:19:48 2012 +0000 @@ -96,8 +96,31 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +// void *visit(data_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ +// void *visit(type_declaration_list_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ +// void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */ + void *visit(simple_spec_init_c *symbol); +// void *visit(subrange_type_declaration_c *symbol); +// void *visit(subrange_spec_init_c *symbol); +// void *visit(subrange_specification_c *symbol); void *visit(subrange_c *symbol); - void *visit(simple_spec_init_c *symbol); + void *visit(enumerated_type_declaration_c *symbol); + void *visit(enumerated_spec_init_c *symbol); + void *visit(enumerated_value_list_c *symbol); +// void *visit(enumerated_value_c *symbol); /* Not required */ +// void *visit(array_type_declaration_c *symbol); +// void *visit(array_spec_init_c *symbol); +// void *visit(array_specification_c *symbol); +// void *visit(array_subrange_list_c *symbol); +// void *visit(array_initial_elements_list_c *symbol); +// void *visit(array_initial_elements_c *symbol); +// void *visit(structure_type_declaration_c *symbol); +// void *visit(initialized_structure_c *symbol); +// void *visit(structure_element_declaration_list_c *symbol); +// void *visit(structure_element_declaration_c *symbol); +// void *visit(structure_element_initialization_list_c *symbol); +// void *visit(structure_element_initialization_c *symbol); +// void *visit(string_type_declaration_c *symbol); /*********************/ /* B 1.4 - Variables */ diff -r fbf77edf54ca -r 6ecb38715724 stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/print_datatypes_error.cc Thu Nov 22 19:19:48 2012 +0000 @@ -536,11 +536,6 @@ return NULL; } -void *print_datatypes_error_c::visit(data_type_declaration_c *symbol) { - // TODO !!! - /* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */ - return NULL; -} void *print_datatypes_error_c::visit(enumerated_value_c *symbol) { if (symbol->candidate_datatypes.size() == 0) @@ -648,8 +643,7 @@ /*********************/ void *print_datatypes_error_c::visit(function_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); - /* We do not check for data type errors in variable declarations, Skip this for now... */ -// symbol->var_declarations_list->accept(*this); + symbol->var_declarations_list->accept(*this); if (debug) printf("Print error data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value); il_parenthesis_level = 0; il_error = false; @@ -664,8 +658,7 @@ /***************************/ void *print_datatypes_error_c::visit(function_block_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); - /* We do not check for data type errors in variable declarations, Skip this for now... */ -// symbol->var_declarations->accept(*this); + symbol->var_declarations->accept(*this); if (debug) printf("Print error data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value); il_parenthesis_level = 0; il_error = false; @@ -680,7 +673,6 @@ /**********************/ void *print_datatypes_error_c::visit(program_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); - /* We do not check for data type errors in variable declarations, Skip this for now... */ symbol->var_declarations->accept(*this); if (debug) printf("Print error data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value); il_parenthesis_level = 0; diff -r fbf77edf54ca -r 6ecb38715724 stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/print_datatypes_error.hh Thu Nov 22 19:19:48 2012 +0000 @@ -159,7 +159,7 @@ /* B 1.3.3 - Derived data types */ /********************************/ void *visit(simple_spec_init_c *symbol); - void *visit(data_type_declaration_c *symbol); +// void *visit(data_type_declaration_c *symbol); /* use base iterator_c method! */ void *visit(enumerated_value_c *symbol); /*********************/ diff -r fbf77edf54ca -r 6ecb38715724 stage3/stage3.cc --- a/stage3/stage3.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage3/stage3.cc Thu Nov 22 19:19:48 2012 +0000 @@ -43,6 +43,15 @@ #include "array_range_check.hh" #include "constant_folding.hh" #include "declaration_check.hh" +#include "enum_declaration_check.hh" + + +static int enum_declaration_check(symbol_c *tree_root){ + enum_declaration_check_c enum_declaration_check(NULL); + tree_root->accept(enum_declaration_check); + return enum_declaration_check.get_error_count(); +} + static int declaration_safety(symbol_c *tree_root){ declaration_check_c declaration_check(tree_root); @@ -107,6 +116,7 @@ int stage3(symbol_c *tree_root){ int error_count = 0; + error_count += enum_declaration_check(tree_root); error_count += declaration_safety(tree_root); error_count += flow_control_analysis(tree_root); error_count += constant_folding(tree_root); diff -r fbf77edf54ca -r 6ecb38715724 stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage4/generate_c/generate_c_typedecl.cc Thu Nov 22 19:19:48 2012 +0000 @@ -317,8 +317,15 @@ if (current_typedefinition == enumerated_td) current_type_name->accept(*basedecl); else { - if (NULL == symbol->datatype) ERROR; - symbol->datatype->accept(*basedecl); + if (NULL == symbol->datatype) { + debug_c::print(symbol); + ERROR; + } + symbol_c *type_name = get_datatype_info_c::get_datatype_id(symbol->datatype); + if (NULL == type_name) { +// ERROR_MSG("generate_c does not support anonymous enumerated data types."); + } else + type_name->accept(*basedecl); } s4o_incl.print("__"); symbol->value->accept(*basedecl); diff -r fbf77edf54ca -r 6ecb38715724 stage4/generate_c/generate_var_list.cc --- a/stage4/generate_c/generate_var_list.cc Mon Nov 12 22:36:55 2012 +0100 +++ b/stage4/generate_c/generate_var_list.cc Thu Nov 22 19:19:48 2012 +0000 @@ -382,6 +382,40 @@ } } + +/********************************/ +/* B 1.3.3 - Derived data types */ +/********************************/ + /* enumerated_type_name ':' enumerated_spec_init */ + void *visit(enumerated_type_declaration_c *symbol) { + this->current_var_type_name->accept(*this); + return NULL; + } + + /* enumerated_specification ASSIGN enumerated_value */ + void *visit(enumerated_spec_init_c *symbol) { + /* search_base_type_c now returns an enumerated_type_declaration_c as the base type of a non-anonymous enumerated type + * (non-anonymous means it is declared inside a TYPE ... END_TYPE declaration, with a given name/identifier + * unlike implicitly defined anonymous datatypes declared inside VAR ... END_VAR declarations!). + * This means that this method should not get called. + */ + ERROR; + this->current_var_type_name->accept(*this); + return NULL; + } + + /* enumerated_value_list ',' enumerated_value */ + void *visit(enumerated_value_list_c *symbol) { + /* search_base_type_c now returns an enumerated_type_declaration_c as the base type of a non-anonymous enumerated type + * (non-anonymous means it is declared inside a TYPE ... END_TYPE declaration, with a given name/identifier + * unlike implicitly defined anonymous datatypes declared inside VAR ... END_VAR declarations!). + * This means that this method should not get called. + */ + ERROR; + this->current_var_type_name->accept(*this); + return NULL; + } + /********************************************/ /* B.1.4.3 - Declaration and initialization */ /********************************************/ @@ -556,12 +590,7 @@ return NULL; } - /* enumerated_value_list ',' enumerated_value */ - void *visit(enumerated_value_list_c *symbol) { - this->current_var_type_name->accept(*this); - return NULL; - } - + /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */ /* structure_initialization -> may be NULL ! */ void *visit(fb_name_decl_c *symbol) {