# HG changeset patch # User mjsousa # Date 1417893092 0 # Node ID 7474d2cd1d6eb229c483d748036015eff84d928b # Parent 4489afa5b1c59c979f4057fe7856cda1759e5ee3 Add a new pou_typename_c object to the AST to store references to previously declared Functions, FB, and Programs. diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax/absyntax.cc --- a/absyntax/absyntax.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax/absyntax.cc Sat Dec 06 19:11:32 2014 +0000 @@ -172,7 +172,16 @@ /* corrent the new size */ n--; /* elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); */ -} + /* TODO: adjust the location parameters, taking into account the removed element. */ +} + + +/* remove element at position pos. */ +void list_c::clear(void) { + n = 0; + /* TODO: adjust the location parameters, taking into account the removed element. */ +} + #define SYM_LIST(class_name_c, ...) \ class_name_c::class_name_c( \ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax/absyntax.def --- a/absyntax/absyntax.def Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax/absyntax.def Sat Dec 06 19:11:32 2014 +0000 @@ -128,6 +128,7 @@ /* A special identifier class, used for identifiers that have been previously declared as a derived datatype */ /* This is currently needed because generate_c stage 4 needs to handle the array datatype identifiers differently to all other identifiers. */ SYM_TOKEN(derived_datatype_identifier_c) +SYM_TOKEN(poutype_identifier_c) /*********************/ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax/absyntax.hh --- a/absyntax/absyntax.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax/absyntax.hh Sat Dec 06 19:11:32 2014 +0000 @@ -247,6 +247,8 @@ virtual void insert_element(symbol_c *elem, int pos = 0); /* remove element at position pos. */ virtual void remove_element(int pos = 0); + /* remove all elements from list. Does not delete the elements in the list! */ + virtual void clear(void); }; diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/function_call_iterator.cc --- a/absyntax_utils/function_call_iterator.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/function_call_iterator.cc Sat Dec 06 19:11:32 2014 +0000 @@ -89,10 +89,10 @@ } /* Returns the name of the currently referenced function invocation */ -identifier_c *function_call_iterator_c::fname(void) { - identifier_c *identifier = dynamic_cast(current_fcall_name); - if (identifier == NULL) ERROR; - return identifier; +token_c *function_call_iterator_c::fname(void) { + token_c *fname_sym = dynamic_cast(current_fcall_name); + if (fname_sym == NULL) ERROR; + return fname_sym; } diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/function_call_iterator.hh --- a/absyntax_utils/function_call_iterator.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/function_call_iterator.hh Sat Dec 06 19:11:32 2014 +0000 @@ -73,7 +73,7 @@ symbol_c *next(void); /* Returns the name of the currently referenced function invocation */ - identifier_c *fname(void); + token_c *fname(void); private: /***************************************/ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/get_datatype_info.cc Sat Dec 06 19:11:32 2014 +0000 @@ -149,12 +149,18 @@ * That anotation is specific to the generate_c stage4 code, and must therefore NOT be referenced * in the absyntax_utils code, as this last code should be independent of the stage4 version! */ - + /*****************************/ /* 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;} + /**********************/ + /* B 1.5.3 - Programs */ + /**********************/ + /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ + void *visit(program_declaration_c *symbol) {return symbol->program_type_name;} + }; // get_datatype_id_c get_datatype_id_c *get_datatype_id_c::singleton = NULL; @@ -200,7 +206,12 @@ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ void *visit( identifier_c *symbol) {return (void *)symbol->value;}; - void *visit(derived_datatype_identifier_c *symbol) {return (void *)symbol->value;}; + // Should not be necessary, as datatype declarations currently use an identifier_c for their name! + // Only references to the datatype (when declaring variable, for ex., will use poutype_identifier_c + void *visit(derived_datatype_identifier_c *symbol) {return (void *)symbol->value;}; + // Should not be necessary, as FB declarations currently use an identifier_c for their name! + // Only references to the FB (when declaring variable, for ex., will use poutype_identifier_c + void *visit( poutype_identifier_c *symbol) {return (void *)symbol->value;}; /***********************************/ /* B 1.3.1 - Elementary Data Types */ @@ -277,11 +288,23 @@ * in the absyntax_utils code, as this last code should be independent of the stage4 version! */ + /***********************/ + /* B 1.5.1 - Functions */ + /***********************/ + /* Functions are not really datatypes, but we include it here as it helps in printing out error messages! */ + /* Currently this is needed only by remove_forward_depencies_c::print_circ_error() */ + /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ + void *visit( function_declaration_c *symbol) {return symbol->derived_function_name->accept(*this);} /*****************************/ /* 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->accept(*this);} + /**********************/ + /* B 1.5.3 - Programs */ + /**********************/ + /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ + void *visit( program_declaration_c *symbol) {return symbol->program_type_name->accept(*this);} }; get_datatype_id_str_c *get_datatype_id_str_c::singleton = NULL; diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/search_base_type.cc Sat Dec 06 19:11:32 2014 +0000 @@ -131,8 +131,9 @@ return NULL; } -void *search_base_type_c::visit( identifier_c *type_name) {return handle_datatype_identifier(type_name);} // still needed to handle FB and program datatypes! -void *search_base_type_c::visit(derived_datatype_identifier_c *type_name) {return handle_datatype_identifier(type_name);} +void *search_base_type_c::visit( identifier_c *type_name) {return handle_datatype_identifier(type_name);} +void *search_base_type_c::visit(derived_datatype_identifier_c *type_name) {return handle_datatype_identifier(type_name);} +void *search_base_type_c::visit( poutype_identifier_c *type_name) {return handle_datatype_identifier(type_name);} /*********************/ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/search_base_type.hh Sat Dec 06 19:11:32 2014 +0000 @@ -91,7 +91,8 @@ /*******************************************/ void *visit( identifier_c *type_name); void *visit(derived_datatype_identifier_c *type_name); - + void *visit( poutype_identifier_c *type_name); + /*********************/ /* B 1.2 - Constants */ /*********************/ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/spec_init_separator.cc --- a/absyntax_utils/spec_init_separator.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/spec_init_separator.cc Sat Dec 06 19:11:32 2014 +0000 @@ -74,11 +74,12 @@ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ // SYM_TOKEN(identifier_c) -/* visitor for identifier_c is necessary because spec_init_sperator_c will be called to analyse PROGRAM identfiers, - * which are still transformed into identfier_c, instead of a derived_datatype_identifier_c - */ -void *spec_init_sperator_c::visit( identifier_c *symbol) { - TRACE("spec_init_sperator_c::identifier_c"); +/* visitor for identifier_c should no longer be necessary. All references to derived datatypes are now stored in then */ +/* AST using either poutype_identifier_c or derived_datatype_identifier_c */ +void *spec_init_sperator_c::visit( identifier_c *symbol) { ERROR; return NULL;} /* should never occur */ + +void *spec_init_sperator_c::visit( poutype_identifier_c *symbol) { + TRACE("spec_init_sperator_c::poutype_identifier_c"); switch (search_what) { /* if we ever get called sith a simple identifier_c, then it must be a previously declared type... */ case search_spec: return symbol; @@ -90,7 +91,7 @@ void *spec_init_sperator_c::visit(derived_datatype_identifier_c *symbol) { - TRACE("spec_init_sperator_c::identifier_c"); + TRACE("spec_init_sperator_c::derived_datatype_identifier_c"); switch (search_what) { /* if we ever get called sith a simple identifier_c, then it must be a previously declared type... */ case search_spec: return symbol; @@ -226,6 +227,7 @@ } ERROR; /* should never occur */ return NULL; + } diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/spec_init_separator.hh --- a/absyntax_utils/spec_init_separator.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/spec_init_separator.hh Sat Dec 06 19:11:32 2014 +0000 @@ -67,7 +67,8 @@ // SYM_TOKEN(identifier_c) void *visit( identifier_c *symbol); void *visit(derived_datatype_identifier_c *symbol); - + void *visit( poutype_identifier_c *symbol); + /********************************/ /* B 1.3.3 - Derived data types */ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/type_initial_value.cc --- a/absyntax_utils/type_initial_value.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/type_initial_value.cc Sat Dec 06 19:11:32 2014 +0000 @@ -110,48 +110,29 @@ void *type_initial_value_c::handle_type_spec(symbol_c *base_type_name, symbol_c *type_spec_init) { if (type_spec_init != NULL) return type_spec_init; - /* no initial value specified, so we return - * the initial value of the type this type is based on... - */ + /* no initial value specified, so we return the initial value of the type this type is based on... */ return base_type_name->accept(*this); } -/* visitor for identifier_c is necessary because type_initial_value_c will be called to analyse PROGRAM identfiers, - * which are still transformed into identfier_c, instead of a derived_datatype_identifier_c - */ -void *type_initial_value_c::visit( identifier_c *type_name) { +void *type_initial_value_c::handle_type_name(symbol_c *type_name) { /* look up the type declaration... */ symbol_c *type_decl = type_symtable.find_value(type_name); - if (type_decl == type_symtable.end_value()) /* Type declaration not found!! */ - /* NOTE: Variables declared out of function block 'data types', - * for eg: VAR timer: TON; END_VAR - * do not have a default value, so (TON) will never be found in the - * type symbol table. This means we cannot simply consider this - * an error and abort, but must rather return a NULL. + /* NOTE: Variables declared out of function block 'data types',for eg: VAR timer: TON; END_VAR + * do not have a default value, so (TON) will never be found in the type symbol table. This means + * we cannot simply consider this an error and abort, but must rather return a NULL. */ - return NULL; + if (type_decl == type_symtable.end_value()) return NULL; return type_decl->accept(*this); } - -void *type_initial_value_c::visit(derived_datatype_identifier_c *type_name) { - /* look up the type declaration... */ - symbol_c *type_decl = type_symtable.find_value(type_name); - if (type_decl == type_symtable.end_value()) - /* Type declaration not found!! */ - /* NOTE: Variables declared out of function block 'data types', - * for eg: VAR timer: TON; END_VAR - * do not have a default value, so (TON) will never be found in the - * type symbol table. This means we cannot simply consider this - * an error and abort, but must rather return a NULL. - */ - return NULL; - - return type_decl->accept(*this); -} +/* visitor for identifier_c should no longer be necessary. All references to derived datatypes are now stored in then */ +/* AST using either poutype_identifier_c or derived_datatype_identifier_c. In principe, the following should not be necesasry */ +void *type_initial_value_c::visit( identifier_c *symbol) {return handle_type_name(symbol);} /* should never occur */ +void *type_initial_value_c::visit( poutype_identifier_c *symbol) {return handle_type_name(symbol);} /* in practice it might never get called, as FB, Functions and Programs do not have initial value */ +void *type_initial_value_c::visit(derived_datatype_identifier_c *symbol) {return handle_type_name(symbol);} /***********************************/ /* B 1.3.1 - Elementary Data Types */ diff -r 4489afa5b1c5 -r 7474d2cd1d6e absyntax_utils/type_initial_value.hh --- a/absyntax_utils/type_initial_value.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/absyntax_utils/type_initial_value.hh Sat Dec 06 19:11:32 2014 +0000 @@ -84,10 +84,12 @@ static type_initial_value_c *_instance; static type_initial_value_c *instance(void); void *handle_type_spec(symbol_c *base_type_name, symbol_c *type_spec_init); + void *handle_type_name(symbol_c *type_name); private: - void *visit( identifier_c *type_name); - void *visit(derived_datatype_identifier_c *type_name); + void *visit( identifier_c *symbol); + void *visit(derived_datatype_identifier_c *symbol); + void *visit( poutype_identifier_c *symbol); /***********************************/ /* B 1.3.1 - Elementary Data Types */ diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage1_2/create_enumtype_conversion_functions.cc --- a/stage1_2/create_enumtype_conversion_functions.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage1_2/create_enumtype_conversion_functions.cc Sat Dec 06 19:11:32 2014 +0000 @@ -76,11 +76,12 @@ return singleton->text; } - -void *create_enumtype_conversion_functions_c::visit(identifier_c *symbol) { - currentToken = symbol->value; - return NULL; -} +/* As the name of derived datatypes and POUs are still stored as identifiers in the respective datatype and POU declaration, */ +/* only the indintifier_c visitor should be necessary! */ +void *create_enumtype_conversion_functions_c::visit( identifier_c *symbol) {currentToken = symbol->value; return NULL;} +void *create_enumtype_conversion_functions_c::visit( poutype_identifier_c *symbol) {ERROR; return NULL;} +void *create_enumtype_conversion_functions_c::visit(derived_datatype_identifier_c *symbol) {ERROR; return NULL;} + /**********************/ /* B 1.3 - Data types */ diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage1_2/create_enumtype_conversion_functions.hh --- a/stage1_2/create_enumtype_conversion_functions.hh Sun Nov 30 12:49:42 2014 +0000 +++ b/stage1_2/create_enumtype_conversion_functions.hh Sat Dec 06 19:11:32 2014 +0000 @@ -55,7 +55,10 @@ virtual ~create_enumtype_conversion_functions_c(void); static std::string &get_declaration(symbol_c *symbol); - void *visit(identifier_c *symbol); + void *visit( identifier_c *symbol); + void *visit( poutype_identifier_c *symbol); + void *visit(derived_datatype_identifier_c *symbol); + /**********************/ /* B 1.3 - Data types */ /**********************/ diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Sun Nov 30 12:49:42 2014 +0000 +++ b/stage1_2/iec_bison.yy Sat Dec 06 19:11:32 2014 +0000 @@ -224,7 +224,10 @@ /* The functions declared here are defined at the end of this file... */ /* Convert an il_operator_c into an identifier_c */ -symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator); +identifier_c *il_operator_c_2_identifier_c (symbol_c *il_operator); +/* Convert an il_operator_c into an poutype_identifier_c */ +poutype_identifier_c *il_operator_c_2_poutype_identifier_c(symbol_c *il_operator); + /* return if current token is a syntax element */ /* ERROR_CHECK_BEGIN */ @@ -1597,16 +1600,25 @@ | prev_declared_array_type_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the derived_datatype_identifier_c into an identifier_c, as it will be taking the place of an identifier! | prev_declared_structure_type_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the derived_datatype_identifier_c into an identifier_c, as it will be taking the place of an identifier! | prev_declared_string_type_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the derived_datatype_identifier_c into an identifier_c, as it will be taking the place of an identifier! -| prev_declared_derived_function_name -| prev_declared_derived_function_block_name -| prev_declared_program_type_name +| prev_declared_derived_function_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the poutype_identifier_c into an identifier_c, as it will be taking the place of an identifier! +| prev_declared_derived_function_block_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the poutype_identifier_c into an identifier_c, as it will be taking the place of an identifier! +| prev_declared_program_type_name {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$));}; // change the poutype_identifier_c into an identifier_c, as it will be taking the place of an identifier! /**/ | prev_declared_resource_name | prev_declared_program_name | prev_declared_global_var_name ; - +/* NOTE: Notice that the symbol classes: + * - derived_datatype_identifier_c + * - poutype_identifier_c + * are only inserted into the AST when referencing a derived dataype or a POU + * (e.g. when declaring a variable, making a function call, instantiating a program in a resource, + * or delaring a derived datatype that derives from another previously delcared datatype). + * + * In the declaration of the datatype or POU itself, the name of the datatype or POU will be stored + * inside an identifier_c instead!! + */ prev_declared_variable_name: prev_declared_variable_name_token {$$ = new identifier_c($1, locloc(@$));}; prev_declared_fb_name: prev_declared_fb_name_token {$$ = new identifier_c($1, locloc(@$));}; @@ -1618,9 +1630,11 @@ prev_declared_string_type_name: prev_declared_string_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; prev_declared_ref_type_name: prev_declared_ref_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; /* defined in IEC 61131-3 v3 */ -prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new identifier_c($1, locloc(@$));}; -prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1, locloc(@$));}; -prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new identifier_c($1, locloc(@$));}; +prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new poutype_identifier_c($1, locloc(@$));}; +prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new poutype_identifier_c($1, locloc(@$));}; +prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new poutype_identifier_c($1, locloc(@$));}; +/* NOTE: The poutype_identifier_c was introduced to allow the implementation of remove_forward_dependencies_c */ + @@ -4825,9 +4839,10 @@ //| standard_function_name_simpleop_only_clashes ; +/* standard_function_name_no_clashes is only used in function invocations, so we use the poutype_identifier_c class! */ standard_function_name_no_clashes: standard_function_name_token - {$$ = new identifier_c($1, locloc(@$));} + {$$ = new poutype_identifier_c($1, locloc(@$));} ; @@ -4836,9 +4851,10 @@ //| standard_function_name_simpleop_only_clashes ; +/* standard_function_name_NOT_clashes is only used in function invocations, so we use the poutype_identifier_c class! */ standard_function_name_NOT_clashes: NOT - {$$ = new identifier_c(strdup("NOT"), locloc(@$));} + {$$ = new poutype_identifier_c(strdup("NOT"), locloc(@$));} ; /* Add here any other IL simple operators that collide @@ -4853,39 +4869,40 @@ ; */ +/* standard_function_name_expression_clashes is only used in function invocations, so we use the poutype_identifier_c class! */ standard_function_name_expression_clashes: - AND {$$ = new identifier_c(strdup("AND"), locloc(@$));} -| OR {$$ = new identifier_c(strdup("OR"), locloc(@$));} -| XOR {$$ = new identifier_c(strdup("XOR"), locloc(@$));} -| ADD {$$ = new identifier_c(strdup("ADD"), locloc(@$));} -| SUB {$$ = new identifier_c(strdup("SUB"), locloc(@$));} -| MUL {$$ = new identifier_c(strdup("MUL"), locloc(@$));} -| DIV {$$ = new identifier_c(strdup("DIV"), locloc(@$));} -| MOD {$$ = new identifier_c(strdup("MOD"), locloc(@$));} -| GT {$$ = new identifier_c(strdup("GT"), locloc(@$));} -| GE {$$ = new identifier_c(strdup("GE"), locloc(@$));} -| EQ {$$ = new identifier_c(strdup("EQ"), locloc(@$));} -| LT {$$ = new identifier_c(strdup("LT"), locloc(@$));} -| LE {$$ = new identifier_c(strdup("LE"), locloc(@$));} -| NE {$$ = new identifier_c(strdup("NE"), locloc(@$));} + AND {$$ = new poutype_identifier_c(strdup("AND"), locloc(@$));} +| OR {$$ = new poutype_identifier_c(strdup("OR"), locloc(@$));} +| XOR {$$ = new poutype_identifier_c(strdup("XOR"), locloc(@$));} +| ADD {$$ = new poutype_identifier_c(strdup("ADD"), locloc(@$));} +| SUB {$$ = new poutype_identifier_c(strdup("SUB"), locloc(@$));} +| MUL {$$ = new poutype_identifier_c(strdup("MUL"), locloc(@$));} +| DIV {$$ = new poutype_identifier_c(strdup("DIV"), locloc(@$));} +| MOD {$$ = new poutype_identifier_c(strdup("MOD"), locloc(@$));} +| GT {$$ = new poutype_identifier_c(strdup("GT"), locloc(@$));} +| GE {$$ = new poutype_identifier_c(strdup("GE"), locloc(@$));} +| EQ {$$ = new poutype_identifier_c(strdup("EQ"), locloc(@$));} +| LT {$$ = new poutype_identifier_c(strdup("LT"), locloc(@$));} +| LE {$$ = new poutype_identifier_c(strdup("LE"), locloc(@$));} +| NE {$$ = new poutype_identifier_c(strdup("NE"), locloc(@$));} /* - AND_operator {$$ = il_operator_c_2_identifier_c($1);} + AND_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} //NOTE: AND2 (corresponding to the source code string '&') does not clash // with a standard function name, so should be commented out! -//| AND2_operator {$$ = il_operator_c_2_identifier_c($1);} -| OR_operator {$$ = il_operator_c_2_identifier_c($1);} -| XOR_operator {$$ = il_operator_c_2_identifier_c($1);} -| ADD_operator {$$ = il_operator_c_2_identifier_c($1);} -| SUB_operator {$$ = il_operator_c_2_identifier_c($1);} -| MUL_operator {$$ = il_operator_c_2_identifier_c($1);} -| DIV_operator {$$ = il_operator_c_2_identifier_c($1);} -| MOD_operator {$$ = il_operator_c_2_identifier_c($1);} -| GT_operator {$$ = il_operator_c_2_identifier_c($1);} -| GE_operator {$$ = il_operator_c_2_identifier_c($1);} -| EQ_operator {$$ = il_operator_c_2_identifier_c($1);} -| LT_operator {$$ = il_operator_c_2_identifier_c($1);} -| LE_operator {$$ = il_operator_c_2_identifier_c($1);} -| NE_operator {$$ = il_operator_c_2_identifier_c($1);} +//| AND2_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| OR_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| XOR_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| ADD_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| SUB_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| MUL_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| DIV_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| MOD_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| GT_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| GE_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| EQ_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| LT_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| LE_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} +| NE_operator {$$ = il_operator_c_2_poutype_identifier_c($1);} */ ; @@ -4893,7 +4910,7 @@ derived_function_name: identifier /* will never occur during normal parsing, only needed for preparsing to change it to a prev_declared_derived_function_name! */ | prev_declared_derived_function_name - {$$ = $1; + {$$ = new identifier_c(((token_c *)$1)->value, locloc(@$)); // transform the poutype_identifier_c into an identifier_c if (get_preparse_state() && !allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} } | AND @@ -4927,7 +4944,7 @@ if (get_preparse_state()) {library_element_symtable.insert($2, prev_declared_derived_function_name_token);} else {print_err_msg(locl(@1), locf(@3), "FUNCTION with no variable declarations and no body."); yynerrs++;} } -/* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ +/* POST_PARSING and STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ @@ -6692,7 +6709,7 @@ * those whose names coincide with operators !! */ | function_name_no_clashes - {$$ = new il_function_call_c($1, NULL, locloc(@$));} + {$$ = new il_function_call_c($1, NULL, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c /* NOTE: the line * | il_simple_operator il_operand * already contains the 'NOT', 'MOD', etc. operators, followed by a single il_operand. @@ -6720,9 +6737,9 @@ * are followed by a il_operand_list with __two__ or more il_operands!! */ | function_name_no_clashes il_operand_list - {$$ = new il_function_call_c($1, $2, locloc(@$));} + {$$ = new il_function_call_c($1, $2, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c | il_simple_operator_clash il_operand_list2 - {$$ = new il_function_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));} + {$$ = new il_function_call_c(il_operator_c_2_poutype_identifier_c($1), $2, locloc(@$));} ; @@ -6881,9 +6898,9 @@ * (AND MOD OR XOR ADD DIV EQ GT GE LT LE MUL NE SUB) */ function_name_no_clashes '(' eol_list ')' - {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));} + {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c | function_name_simpleop_clashes '(' eol_list ')' - {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$));} + {$$ = new il_formal_funct_call_c($1, NULL, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c /* | function_name '(' eol_list il_param_list ')' */ /* For the above syntax, we no longer have two ways of interpreting the * same syntax. The above is always a function call! @@ -6898,9 +6915,9 @@ * We must therefore interpret the IL operators as function names! */ | function_name_no_clashes '(' eol_list il_param_list ')' - {$$ = new il_formal_funct_call_c($1, $4, locloc(@$));} + {$$ = new il_formal_funct_call_c($1, $4, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c | function_name_simpleop_clashes '(' eol_list il_param_list ')' - {$$ = new il_formal_funct_call_c($1, $4, locloc(@$));} + {$$ = new il_formal_funct_call_c($1, $4, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c /* The following line should read: * * | function_name_expression_clashes '(' eol_list il_param_list ')' @@ -6920,10 +6937,10 @@ * We need to figure out which symbol was created, destroy it, * and create the correct symbol for our case. * This is a lot of work, so I put it in a function - * at the end of this file... il_operator_c_2_identifier_c() + * at the end of this file... il_operator_c_2_poutype_identifier_c() */ | il_expr_operator_clash_eol_list il_param_list ')' - {$$ = new il_formal_funct_call_c(il_operator_c_2_identifier_c($1), $2, locloc(@$));} + {$$ = new il_formal_funct_call_c(il_operator_c_2_poutype_identifier_c($1), $2, locloc(@$));} /* ERROR_CHECK_BEGIN */ | function_name_no_clashes '(' eol_list error ')' {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid parameter list defined in IL formal function call."); yyerrok;} @@ -7738,9 +7755,9 @@ function_invocation: /* function_name '(' [param_assignment_list] ')' */ function_name_no_NOT_clashes '(' param_assignment_formal_list ')' - {$$ = new function_invocation_c($1, $3, NULL, locloc(@$));} + {$$ = new function_invocation_c($1, $3, NULL, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c | function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')' - {$$ = new function_invocation_c($1, NULL, $3, locloc(@$));} + {$$ = new function_invocation_c($1, NULL, $3, locloc(@$)); if (NULL == dynamic_cast($1)) ERROR;} // $1 should be a poutype_identifier_c /* ERROR_CHECK_BEGIN */ | function_name_no_NOT_clashes param_assignment_formal_list ')' {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;} @@ -8494,7 +8511,17 @@ /* NOTE: this code is very ugly and un-eficient, but I (Mario) have many * more things to worry about right now, so just let it be... */ -symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator) { +poutype_identifier_c *il_operator_c_2_poutype_identifier_c(symbol_c *il_operator) { + identifier_c * id = il_operator_c_2_identifier_c(il_operator); + poutype_identifier_c *pou_id = new poutype_identifier_c(strdup(id->value)); + + *(symbol_c *)pou_id = *(symbol_c *)id; + delete id; + return pou_id; +} + + +identifier_c *il_operator_c_2_identifier_c(symbol_c *il_operator) { const char *name = NULL; identifier_c *res; @@ -8560,7 +8587,7 @@ if (name == NULL) ERROR; - +/* res = new identifier_c(strdup(name), il_operator->first_line, il_operator->first_column, @@ -8572,6 +8599,11 @@ il_operator->last_order ); free(il_operator); +*/ + res = new identifier_c(strdup(name)); + *(symbol_c *)res = *(symbol_c *)il_operator; + delete il_operator; + return res; } diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage3/fill_candidate_datatypes.cc Sat Dec 06 19:11:32 2014 +0000 @@ -987,7 +987,7 @@ /* enumerated_specification ASSIGN enumerated_value */ // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) -// NOTE: enumerated_specification is either an enumerated_value_list_c or identifier_c. +// NOTE: enumerated_specification is either an enumerated_value_list_c or derived_datatype_identifier_c. void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);} diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage3/print_datatypes_error.cc Sat Dec 06 19:11:32 2014 +0000 @@ -164,14 +164,14 @@ /* Check if there are duplicate parameter values */ if(fcp_iterator.search_f(param_name) != param_value) { function_invocation_error = true; - STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value); continue; /* jump to next parameter */ } /* Find the corresponding parameter in function declaration */ if (NULL == fp_iterator.search(param_name)) { function_invocation_error = true; - STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value); continue; /* jump to next parameter */ } @@ -184,20 +184,20 @@ if ((function_param_iterator_c::direction_in != param_dir) && (function_param_iterator_c::direction_inout != param_dir)) { function_invocation_error = true; - STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value); continue; /* jump to next parameter */ } } else if (function_call_param_iterator_c::assign_out == call_param_dir) { if ((function_param_iterator_c::direction_out != param_dir)) { function_invocation_error = true; - STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value); continue; /* jump to next parameter */ } } else ERROR; if (!get_datatype_info_c::is_type_valid(param_value->datatype)) { function_invocation_error = true; - STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((token_c *)param_name)->value, POU_str, ((token_c *)fcall_data.function_name)->value); continue; /* jump to next parameter */ } } @@ -223,7 +223,7 @@ * We will iterate through all the real previous IL instructions, and analyse each of them one by one */ if (il_instruction_symbol->prev_il_instruction.size() == 0) { function_invocation_error = true; - STAGE3_ERROR(0, fcall, fcall, "No available data to pass to first parameter of IL function %s. Missing a previous LD instruction?", ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, fcall, fcall, "No available data to pass to first parameter of IL function %s. Missing a previous LD instruction?", ((token_c *)fcall_data.function_name)->value); } #if 0 /* NOTE: We currently comment out this code... @@ -237,14 +237,14 @@ symbol_c *value = il_instruction_symbol->prev_il_instruction[p]; if (!get_datatype_info_c::is_type_valid(value->datatype)) { function_invocation_error = true; - STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed to first parameter when invoking function '%s'", ((identifier_c *)fcall_data.function_name)->value); - STAGE3_ERROR(0, value, value, "This is the IL instruction producing the incompatible data type to first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed to first parameter when invoking function '%s'", ((token_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, value, value, "This is the IL instruction producing the incompatible data type to first parameter of function '%s'", ((token_c *)fcall_data.function_name)->value); } } #else if (!get_datatype_info_c::is_type_valid(il_instruction_symbol->datatype)) { function_invocation_error = true; - STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between value in IL 'accumulator' and first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between value in IL 'accumulator' and first parameter of function '%s'", ((token_c *)fcall_data.function_name)->value); } #endif if (function_invocation_error) @@ -253,7 +253,7 @@ } else { if (!get_datatype_info_c::is_type_valid(param_value->datatype)) { function_invocation_error = true; - STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((token_c *)fcall_data.function_name)->value); } param_value->accept(*this); } @@ -262,12 +262,12 @@ if (NULL == fcall_data.called_function_declaration) { function_invocation_error = true; - STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((token_c *)fcall_data.function_name)->value); } if (function_invocation_error) { /* No compatible function exists */ - STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value); + STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((token_c *)fcall_data.function_name)->value); } return; diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_c/generate_c.cc Sat Dec 06 19:11:32 2014 +0000 @@ -1614,13 +1614,10 @@ /*******************************************/ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ - void *visit(identifier_c *symbol) { - if (configuration_name) - s4o.print(symbol->value); - else - generate_c_base_c::visit(symbol); - return NULL; + if (configuration_name) s4o.print(symbol->value); + else generate_c_base_c::visit(symbol); + return NULL; } /********************/ @@ -1821,8 +1818,11 @@ print_retain(); s4o.print(");\n"); break; - case run_dt: - current_program_name = ((identifier_c*)(symbol->program_name))->value; + case run_dt: + { identifier_c *tmp_id = dynamic_cast(symbol->program_name); + if (NULL == tmp_id) ERROR; + current_program_name = tmp_id->value; + } if (symbol->task_name != NULL) { s4o.print(s4o.indent_spaces); s4o.print("if ("); @@ -2144,10 +2144,11 @@ /*******************************************/ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ - void *visit(identifier_c *symbol) { - current_name = symbol->value; - return NULL; - } + void *visit(identifier_c *symbol) {current_name = symbol->value; return NULL;} + /* In the derived datatype and POUs declarations, the names are stored as identfier_c, so the following visitors are not required! */ + void *visit(derived_datatype_identifier_c *symbol) {ERROR; return NULL;} + void *visit( poutype_identifier_c *symbol) {ERROR; return NULL;} + /********************************/ /* B 1.3.3 - Derived data types */ @@ -2167,6 +2168,9 @@ /**************************************/ /* B.1.5 - Program organization units */ /**************************************/ +/* WARNING: The following code is buggy when generating an independent pair of files for each POU, as the + * specially created stage4out_c (s4o_c and s4o_h) will not comply with the enable/disable_code_generation_pragma_c + */ #define handle_pou(fname,pname) \ if (!allow_output) return NULL;\ if (generate_pou_filepairs__) {\ diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_c/generate_c_base.cc Sat Dec 06 19:11:32 2014 +0000 @@ -327,7 +327,8 @@ /*******************************************/ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ - void *visit(identifier_c *symbol) {return print_token(symbol);} + void *visit( identifier_c *symbol) {return print_token(symbol);} + void *visit( poutype_identifier_c *symbol) {return print_token(symbol);} /* If you need the derived_datatype_identifier_c visitor, then you should probably be * inheriting from generate_c_base_and_typeid_c and not generate_c_base_c !! */ @@ -951,7 +952,7 @@ if (1 < implicit_id_count) ERROR; if (1 == implicit_id_count) return symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*this); - return symbol->ref_spec->accept(*this); // this is probably pointing to an identifier_c !! + return symbol->ref_spec->accept(*this); // this is probably pointing to an ***_identifier_c !! } /* ref_type_decl: identifier ':' ref_spec_init */ diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_c/generate_c_typedecl.cc Sat Dec 06 19:11:32 2014 +0000 @@ -539,7 +539,7 @@ void *visit(array_type_declaration_c *symbol) { TRACE("array_type_declaration_c"); - // NOTE: remeber that symbol->array_spec_init may point to an identifier_c, which is why we use symbol->array_spec_init->datatype instead! + // NOTE: remeber that symbol->array_spec_init may point to a derived_datatype_identifier_c, which is why we use symbol->array_spec_init->datatype instead! if (NULL == symbol->array_spec_init->datatype) ERROR; identifier_c *id = generate_datatypes_aliasid_c::create_id(symbol->array_spec_init->datatype); @@ -871,9 +871,12 @@ * we will keep track of the datatypes that have already been declared, and henceforth * only declare the datatypes that have not been previously defined. */ - if (datatypes_already_defined.find(((identifier_c *)(symbol->ref_type_name))->value) != datatypes_already_defined.end()) + identifier_c *tmp_id; + tmp_id = dynamic_cast(symbol->ref_type_name); + if (NULL == tmp_id) ERROR; + if (datatypes_already_defined.find(tmp_id->value) != datatypes_already_defined.end()) return NULL; // already defined. No need to define it again!! - datatypes_already_defined[((identifier_c *)(symbol->ref_type_name))->value] = 1; // insert this datatype into the list of already defined arrays! + datatypes_already_defined[tmp_id->value] = 1; // insert this datatype into the list of already defined arrays! current_type_name = NULL; current_typedefinition = none_td; diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_c/generate_c_vardecl.cc --- a/stage4/generate_c/generate_c_vardecl.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_c/generate_c_vardecl.cc Sat Dec 06 19:11:32 2014 +0000 @@ -59,7 +59,7 @@ }; -// Does this class really need to derive from generate_c_typedecl_c ??? + class generate_c_array_initialization_c: public generate_c_base_and_typeid_c { public: @@ -194,7 +194,6 @@ /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *visit(array_specification_c *symbol) { - identifier_c* type_name; switch (current_mode) { case arraysize_am: symbol->array_subrange_list->accept(*this); diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_c/generate_var_list.cc --- a/stage4/generate_c/generate_var_list.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_c/generate_var_list.cc Sat Dec 06 19:11:32 2014 +0000 @@ -90,7 +90,10 @@ /***********************************************************************/ /***********************************************************************/ - +/* TODO: Delete this helper class search_type_symbol_c, as well as the search_fb_typedecl_c + * in the absyntac_utils directory. They are no longer usefull, now that we have + * datatype analysis working! + */ class search_type_symbol_c: public iterator_visitor_c { public: @@ -143,7 +146,23 @@ return (this->current_var_type_name); } - void *visit(identifier_c* symbol) { + void *visit(derived_datatype_identifier_c* symbol) { + if (this->current_var_type_name == NULL) { + this->current_var_type_name = symbol; + + this->current_var_type_symbol = search_fb_typedecl->get_decl(this->current_var_type_name); + if (this->current_var_type_symbol != NULL) + this->current_var_type_category = function_block_vtc; + + else { + this->current_var_type_symbol = search_base_type_c::get_basetype_decl(this->current_var_type_name); + this->current_var_type_symbol->accept(*this); + } + } + return NULL; + } + + void *visit(poutype_identifier_c* symbol) { if (this->current_var_type_name == NULL) { this->current_var_type_name = symbol; diff -r 4489afa5b1c5 -r 7474d2cd1d6e stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Sun Nov 30 12:49:42 2014 +0000 +++ b/stage4/generate_iec/generate_iec.cc Sat Dec 06 19:11:32 2014 +0000 @@ -255,6 +255,7 @@ /*******************************************/ void *visit( identifier_c *symbol) {return print_token(symbol);} void *visit(derived_datatype_identifier_c *symbol) {return print_token(symbol);} +void *visit( poutype_identifier_c *symbol) {return print_token(symbol);} /*********************/ /* B 1.2 - Constants */