Add a new pou_typename_c object to the AST to store references to previously declared Functions, FB, and Programs.
--- 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( \
--- 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)
/*********************/
--- 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);
};
--- 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<identifier_c *>(current_fcall_name);
- if (identifier == NULL) ERROR;
- return identifier;
+token_c *function_call_iterator_c::fname(void) {
+ token_c *fname_sym = dynamic_cast<token_c *>(current_fcall_name);
+ if (fname_sym == NULL) ERROR;
+ return fname_sym;
}
--- 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:
/***************************************/
--- 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;
--- 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);}
/*********************/
--- 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 */
/*********************/
--- 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;
+
}
--- 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 */
--- 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 */
--- 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 */
--- 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 */
--- 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 */
/**********************/
--- 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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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<poutype_identifier_c*>($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;
}
--- 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);}
--- 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;
--- 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<identifier_c*>(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__) {\
--- 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 */
--- 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<identifier_c *>(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;
--- 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);
--- 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;
--- 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 */