--- a/absyntax/absyntax.def Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax/absyntax.def Thu Apr 04 09:45:11 2013 +0900
@@ -445,6 +445,29 @@
string_type_declaration_init) /* may be == NULL! */
+/* helper symbol for fb_name_decl_c */
+/* This symbol/leaf does not exist in the IEC standard syntax as an isolated symbol,
+ * as, for some reason, the standard syntax defines FB variable declarations in a slightly
+ * different style as all other spec_init declarations. I.e., fr FBs variable declarations,
+ * the standard defines a single leaf/node (fb_name_decl) that references:
+ * a) the variable name list
+ * b) the FB datatype
+ * c) the FB intial value
+ *
+ * All other variable declarations break this out into two nodes:
+ * 1) references b) and c) above (usually named ***_spec_init)
+ * 2) references a), and node 1)
+ *
+ * In order to allow the datatype analyses to proceed without special cases, we will handle
+ * FB variable declarations in the same style. For this reason, we have added the
+ * following node to the Abstract Syntax Tree, even though it does not have a direct equivalent in
+ * the standard syntax.
+ */
+/* function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+
+
/*********************/
/* B 1.4 - Variables */
/*********************/
@@ -515,7 +538,8 @@
*/
SYM_REF0(implicit_definition_c)
SYM_REF0(explicit_definition_c)
-SYM_REF4(en_param_declaration_c, name, type, value, method)
+/* type_decl is a simple_spec_init_c */
+SYM_REF3(en_param_declaration_c, name, type_decl, method)
SYM_REF3(eno_param_declaration_c, name, type, method)
/* edge -> The F_EDGE or R_EDGE directive */
@@ -568,8 +592,13 @@
SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
/* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
+/* NOTE: in order to allow datatype handling to proceed using the normal algorithm with no special cases,
+ * we will be storing the
+ * function_block_type_name ASSIGN structure_initialization
+ * componentes inside a new node, namely fb_spec_init_c
+ */
/* structure_initialization -> may be NULL ! */
-SYM_REF3(fb_name_decl_c, fb_name_list, function_block_type_name, structure_initialization)
+SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)
/* fb_name_list ',' fb_name */
SYM_LIST(fb_name_list_c)
--- a/absyntax_utils/add_en_eno_param_decl.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/add_en_eno_param_decl.cc Thu Apr 04 09:45:11 2013 +0900
@@ -91,12 +91,11 @@
input_declarations_c *add_en_eno_param_decl_c::build_en_param(void) {
- boolean_literal_c *boolean_literal =
- new boolean_literal_c(new bool_type_name_c(), new boolean_true_c());
- identifier_c *identifier =
- new identifier_c("EN");
+ boolean_literal_c *boolean_literal = new boolean_literal_c(new bool_type_name_c(), new boolean_true_c());
+ identifier_c *identifier = new identifier_c("EN");
+ simple_spec_init_c *type_spec_init = new simple_spec_init_c(new bool_type_name_c(), boolean_literal);
en_param_declaration_c *en_param_declaration =
- new en_param_declaration_c(identifier, new bool_type_name_c(), boolean_literal, new implicit_definition_c());
+ new en_param_declaration_c(identifier, type_spec_init, new implicit_definition_c());
/* the last paramater is to flag that this
* declaration was inserted automatically, i.e. an implicit declaration
*/
@@ -109,8 +108,7 @@
output_declarations_c *add_en_eno_param_decl_c::build_eno_param(void) {
- identifier_c *identifier =
- new identifier_c("ENO");
+ identifier_c *identifier = new identifier_c("ENO");
eno_param_declaration_c *eno_param_declaration =
new eno_param_declaration_c(identifier, new bool_type_name_c(), new implicit_definition_c());
/* the last paramater is to flag that this
--- a/absyntax_utils/debug_ast.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/debug_ast.cc Thu Apr 04 09:45:11 2013 +0900
@@ -95,7 +95,7 @@
void print_symbol_c::dump_symbol(symbol_c* symbol) {
- fprintf(stderr, "(%03d:%03d..%03d:%03d) \t%s\t", symbol->first_line, symbol->first_column, symbol->last_line, symbol->last_column, symbol->absyntax_cname());
+ fprintf(stderr, "(%s->%03d:%03d..%03d:%03d) \t%s\t", symbol->first_file, symbol->first_line, symbol->first_column, symbol->last_line, symbol->last_column, symbol->absyntax_cname());
fprintf(stderr, " datatype=");
if (NULL == symbol->datatype)
--- a/absyntax_utils/function_param_iterator.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/function_param_iterator.cc Thu Apr 04 09:45:11 2013 +0900
@@ -427,9 +427,9 @@
* variables will get overwritten when we visit the next
* var1_init_decl_c list!
*/
- current_param_default_value = symbol->value;
- current_param_type = symbol->type;
-
+ current_param_default_value = spec_init_sperator_c::get_init(symbol->type_decl);
+ current_param_type = spec_init_sperator_c::get_spec(symbol->type_decl);
+
void *res = handle_single_param(symbol->name);
/* If we have found the parameter we will be returning, we set the en_eno_param_implicit to TRUE if implicitly defined */
@@ -467,8 +467,8 @@
// SYM_REF3(fb_name_decl_c, fb_name_list, function_block_type_name, structure_initialization)
void *function_param_iterator_c::visit(fb_name_decl_c *symbol) {
TRACE("structured_var_init_decl_c");
- current_param_default_value = symbol->structure_initialization ;
- current_param_type = symbol->function_block_type_name ;
+ current_param_default_value = spec_init_sperator_c::get_init(symbol->fb_spec_init);
+ current_param_type = spec_init_sperator_c::get_spec(symbol->fb_spec_init);
return symbol->fb_name_list->accept(*this);
}
--- a/absyntax_utils/search_base_type.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/search_base_type.cc Thu Apr 04 09:45:11 2013 +0900
@@ -372,7 +372,15 @@
*/
void *search_base_type_c::visit(string_type_declaration_c *symbol) {return (void *)symbol;}
-
+
+/* function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+// SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+void *search_base_type_c::visit(fb_spec_init_c *symbol) {
+ return symbol->function_block_type_name->accept(*this);
+}
+
+
/*****************************/
/* B 1.5.2 - Function Blocks */
--- a/absyntax_utils/search_base_type.hh Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/search_base_type.hh Thu Apr 04 09:45:11 2013 +0900
@@ -234,6 +234,10 @@
*/
void *visit(string_type_declaration_c *symbol);
+ /* function_block_type_name ASSIGN structure_initialization */
+ /* structure_initialization -> may be NULL ! */
+ void *visit(fb_spec_init_c *symbol);
+
/*****************************/
/* B 1.5.2 - Function Blocks */
/*****************************/
--- a/absyntax_utils/search_fb_instance_decl.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/search_fb_instance_decl.cc Thu Apr 04 09:45:11 2013 +0900
@@ -87,7 +87,7 @@
/* name_list ':' function_block_type_name ASSIGN structure_initialization */
/* structure_initialization -> may be NULL ! */
void *search_fb_instance_decl_c::visit(fb_name_decl_c *symbol) {
- current_fb_type_name = symbol->function_block_type_name;
+ current_fb_type_name = spec_init_sperator_c::get_spec(symbol->fb_spec_init);
return symbol->fb_name_list->accept(*this);
}
--- a/absyntax_utils/search_var_instance_decl.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/search_var_instance_decl.cc Thu Apr 04 09:45:11 2013 +0900
@@ -105,6 +105,7 @@
this->current_vartype = none_vt;
this->current_option = none_opt;
this->search_name = get_var_name_c::get_name(variable);
+ if (NULL == search_scope) return NULL; // NOTE: This is not an ERROR! declaration_check_c, for e.g., relies on this returning NULL!
return (symbol_c *)search_scope->accept(*this);
}
@@ -112,6 +113,7 @@
this->current_vartype = none_vt;
this->current_option = none_opt;
this->search_name = get_var_name_c::get_name(variable);
+ if (NULL == search_scope) ERROR;
search_scope->accept(*this);
return this->current_vartype;
}
@@ -120,6 +122,7 @@
this->current_vartype = none_vt;
this->current_option = none_opt;
this->search_name = get_var_name_c::get_name(variable);
+ if (NULL == search_scope) ERROR;
search_scope->accept(*this);
return this->current_option;
}
@@ -340,7 +343,11 @@
/* name_list ':' function_block_type_name ASSIGN structure_initialization */
/* structure_initialization -> may be NULL ! */
void *search_var_instance_decl_c::visit(fb_name_decl_c *symbol) {
- current_type_decl = symbol->function_block_type_name;
+ // TODO: The following line is wrong! It should be
+ // current_type_decl = symbol->fb_spec_init;
+ // However, this change will require a check of all callers, to see if they would handle this correctly.
+ // For now, just keep what we have had historically, and seems to be working.
+ current_type_decl = spec_init_sperator_c::get_spec(symbol->fb_spec_init);
return symbol->fb_name_list->accept(*this);
}
--- a/absyntax_utils/spec_init_separator.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/spec_init_separator.cc Thu Apr 04 09:45:11 2013 +0900
@@ -158,24 +158,23 @@
return NULL;
}
+/* function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+//SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+void *spec_init_sperator_c::visit(fb_spec_init_c *symbol) {
+ TRACE("spec_init_sperator_c::fb_spec_init_c");
+ switch (search_what) {
+ case search_spec: return symbol->function_block_type_name;
+ case search_init: return symbol->structure_initialization;
+ }
+ ERROR; /* should never occur */
+ return NULL;
+}
/******************************************/
/* B 1.4.3 - Declaration & Initialisation */
/******************************************/
-/* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
-/* structure_initialization -> may be NULL ! */
-void *spec_init_sperator_c::visit(fb_name_decl_c *symbol) {
- TRACE("spec_init_sperator_c::fb_name_decl_c");
- switch (search_what) {
- case search_spec: return symbol->function_block_type_name;
- case search_init: return symbol->structure_initialization;
- }
- ERROR; /* should never occur */
- return NULL;
-}
-
-
/* STRING '[' integer ']'
* STRING ASSIGN single_byte_character_string
* STRING '[' integer ']' ASSIGN single_byte_character_string
--- a/absyntax_utils/spec_init_separator.hh Mon Mar 11 12:54:25 2013 +0100
+++ b/absyntax_utils/spec_init_separator.hh Thu Apr 04 09:45:11 2013 +0900
@@ -93,15 +93,16 @@
//SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
void *visit(initialized_structure_c *symbol);
-
+ /* function_block_type_name ASSIGN structure_initialization */
+ /* structure_initialization -> may be NULL ! */
+ //SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+ void *visit(fb_spec_init_c *symbol);
+
+
/******************************************/
/* B 1.4.3 - Declaration & Initialisation */
/******************************************/
- /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
- /* structure_initialization -> may be NULL ! */
- void *visit(fb_name_decl_c *symbol);
-
/* STRING '[' integer ']'
* STRING ASSIGN single_byte_character_string
* STRING '[' integer ']' ASSIGN single_byte_character_string
--- a/stage1_2/iec_bison.yy Mon Mar 11 12:54:25 2013 +0100
+++ b/stage1_2/iec_bison.yy Thu Apr 04 09:45:11 2013 +0900
@@ -3458,9 +3458,9 @@
*/
en_param_declaration:
en_identifier ':' BOOL ASSIGN boolean_literal
- {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
+ {$$ = new en_param_declaration_c($1, new simple_spec_init_c(new bool_type_name_c(locloc(@3)), $5, locf(@3), locl(@5)), new explicit_definition_c(), locloc(@$));}
| en_identifier ':' BOOL ASSIGN integer
- {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));}
+ {$$ = new en_param_declaration_c($1, new simple_spec_init_c(new bool_type_name_c(locloc(@3)), $5, locf(@3), locl(@5)), new explicit_definition_c(), locloc(@$));}
/* ERROR_CHECK_BEGIN */
| en_identifier BOOL ASSIGN boolean_literal
{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;}
@@ -3598,10 +3598,10 @@
fb_name_decl:
/* fb_name_list ':' function_block_type_name */
fb_name_list_with_colon function_block_type_name
- {$$ = new fb_name_decl_c($1, $2, NULL, locloc(@$));}
+ {$$ = new fb_name_decl_c($1, new fb_spec_init_c($2, NULL,locloc(@2)), locloc(@$));}
/*| fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
| fb_name_list_with_colon function_block_type_name ASSIGN structure_initialization
- {$$ = new fb_name_decl_c($1, $2, $4, locloc(@$));}
+ {$$ = new fb_name_decl_c($1, new fb_spec_init_c($2, $4, locf(@2), locl(@4)), locloc(@$));}
/* ERROR_CHECK_BEGIN */
| fb_name_list_with_colon ASSIGN structure_initialization
{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no function block type name defined in function block declaration with initialization."); yynerrs++;}
@@ -4042,7 +4042,7 @@
variable_name_symtable.insert($1, prev_declared_variable_name_token);
}
| global_var_name ':' function_block_type_name
- {$$ = new external_declaration_c($1, $3, locloc(@$));
+ {$$ = new external_declaration_c($1, new fb_spec_init_c($3, NULL, locloc(@3)), locloc(@$));
variable_name_symtable.insert($1, prev_declared_fb_name_token);
}
/* ERROR_CHECK_BEGIN */
@@ -4136,7 +4136,7 @@
global_var_spec ':' located_var_spec_init
{$$ = new global_var_decl_c($1, $3, locloc(@$));}
| global_var_spec ':' function_block_type_name
- {$$ = new global_var_decl_c($1, $3, locloc(@$));}
+ {$$ = new global_var_decl_c($1, new fb_spec_init_c($3, NULL, locloc(@3)), locloc(@$));}
/* ERROR_CHECK_BEGIN */
| global_var_list located_var_spec_init
{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between global variable list and type specification."); yynerrs++;}
@@ -5692,11 +5692,11 @@
resource_declaration:
- RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
+ RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name {variable_name_symtable.insert($3, prev_declared_resource_name_token);} ON resource_type_name
optional_global_var_declarations
single_resource_declaration
END_RESOURCE
- {$$ = new resource_declaration_c($3, $5, $6, $7, locloc(@$));
+ {$$ = new resource_declaration_c($3, $6, $7, $8, locloc(@$));
variable_name_symtable.pop();
direct_variable_symtable.pop();
variable_name_symtable.insert($3, prev_declared_resource_name_token);
@@ -8246,7 +8246,6 @@
symbol_c **tree_root_ref,
bool full_token_loc_ /* error messages specify full token location */
) {
-
char *libfilename = NULL;
if (includedir != NULL) {
@@ -8296,7 +8295,6 @@
library_element_symtable.end_value())
library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token);
-
/* now parse the input file... */
#if YYDEBUG
yydebug = 1;
--- a/stage3/declaration_check.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/declaration_check.cc Thu Apr 04 09:45:11 2013 +0900
@@ -73,6 +73,7 @@
declaration_check_c::declaration_check_c(symbol_c *ignore) {
current_display_error_level = 0;
current_pou_decl = NULL;
+ current_resource_decl = NULL;
error_count = 0;
}
@@ -85,36 +86,47 @@
}
void declaration_check_c::check_global_decl(symbol_c *p_decl) {
- symbol_c *var_name;
-
- search_var_instance_decl_c search_var_instance_glo_decl(current_pou_decl);
- search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
- function_param_iterator_c fpi(p_decl);
- while((var_name = fpi.next()) != NULL) {
- if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
- /* found an external reference parameter. */
- symbol_c *glo_decl = search_var_instance_glo_decl.get_decl(var_name);
- symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
- if (glo_decl == NULL) {
- STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external doesn't mach with any global var.");
- continue;
- }
- if (search_var_instance_glo_decl.get_option(var_name) != search_var_instance_ext_decl.get_option(var_name))
- STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error an external redefinition option.");
-
- /* TODO: Check redefinition data type.
- * We need a new class (like search_base_type class) to get type id by variable declaration.
- * symbol_c *glo_type = ????;
- * symbol_c *ext_type = fpi.param_type();
- */
- /* For the moment, we will just use search_base_type_c instead... */
- symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
- symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
- if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
- STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external redefinition data type.");
+ if (NULL == current_pou_decl) ERROR;
+
+ search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl);
+ search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl);
+ search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
+ function_param_iterator_c fpi(p_decl);
+
+ symbol_c *var_name;
+ while((var_name = fpi.next()) != NULL) {
+ if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
+ /* found an external reference parameter. */
+ symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
+
+ // NOTE: Must check the POU first, and RESOURCE second!
+ symbol_c *glo_decl = search_var_instance_res_glo_decl.get_decl(var_name);
+ search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl;
+ if (NULL == glo_decl) {
+ glo_decl = search_var_instance_pou_glo_decl.get_decl(var_name);
+ search_var_instance_glo_decl = &search_var_instance_pou_glo_decl;
}
- }
-
+
+ if (NULL == glo_decl) {
+ STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable.");
+ continue;
+ }
+
+ if (search_var_instance_glo_decl->get_option(var_name) != search_var_instance_ext_decl.get_option(var_name))
+ STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error. The external variable options do not match with thos of the global variable.");
+
+ /* TODO: Check redefinition data type.
+ * We need a new class (like search_base_type class) to get type id by variable declaration.
+ * symbol_c *glo_type = ????;
+ * symbol_c *ext_type = fpi.param_type();
+ */
+ /* For the moment, we will just use search_base_type_c instead... */
+ symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
+ symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
+ if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
+ STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. Data type mismatch between external and global variable declarations.");
+ }
+ }
}
@@ -125,7 +137,10 @@
/* 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)
void *declaration_check_c::visit(function_block_declaration_c *symbol) {
- current_pou_decl = symbol;
+ /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs!
+ * current_pou_decl = symbol;
+ * current_resource_decl = NULL;
+ */
/* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
if (NULL != symbol->var_declarations)
symbol->var_declarations->accept(*this);
@@ -138,7 +153,10 @@
/* 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)
void *declaration_check_c::visit(program_declaration_c *symbol) {
- current_pou_decl = symbol;
+ /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs!
+ * current_pou_decl = symbol;
+ * current_resource_decl = NULL;
+ */
/* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
if (NULL != symbol->var_declarations)
symbol->var_declarations->accept(*this);
@@ -162,9 +180,27 @@
/* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
if (NULL != symbol->resource_declarations)
symbol->resource_declarations->accept(*this);
- return NULL;
-}
-
+ current_pou_decl = NULL;
+ return NULL;
+}
+
+/*
+RESOURCE resource_name ON resource_type_name
+ optional_global_var_declarations
+ single_resource_declaration
+END_RESOURCE
+*/
+/* 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;)
+void *declaration_check_c::visit(resource_declaration_c *symbol) {
+ current_resource_decl = symbol;
+ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+ symbol->resource_declaration->accept(*this);
+ current_resource_decl = NULL;
+ return NULL;
+}
+
+/* PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
void *declaration_check_c::visit(program_configuration_c *symbol) {
symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
if (p_decl == program_type_symtable.end_value())
--- a/stage3/declaration_check.hh Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/declaration_check.hh Thu Apr 04 09:45:11 2013 +0900
@@ -39,6 +39,7 @@
int error_count;
int current_display_error_level;
symbol_c *current_pou_decl;
+ symbol_c *current_resource_decl;
public:
declaration_check_c(symbol_c *ignore);
@@ -61,5 +62,6 @@
/* B 1.7 Configuration elements */
/********************************/
void *visit(configuration_declaration_c *symbol);
- void *visit(program_configuration_c *symbol);
+ void *visit(resource_declaration_c *symbol);
+ void *visit(program_configuration_c *symbol);
};
--- a/stage3/fill_candidate_datatypes.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/fill_candidate_datatypes.cc Thu Apr 04 09:45:11 2013 +0900
@@ -798,6 +798,69 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+
+void *fill_candidate_datatypes_c::fill_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init) {
+ /* NOTE: Unlike the rest of the 'fill' algorithm that works using a bottom->up approach, when handling
+ * data type declarations (section B.1.3.3 - Derived data types) we use a top->bottom approach.
+ * This is intentional, and not a bug! Explanation follows...
+ * Here we are essentially determining the base type of each defined data type. In many cases (especially structs,
+ * enumerations, arrays, etc...), the datatype is its own base type. However, the derived datatype is stored in
+ * multiple symbol_c classes (e.g. an enumeration uses enumerated_type_declaration_c, enumerated_spec_init_c,
+ * enumerated_value_list_c, enumerated_value_c, ...). Several of these could be chosen to work as the canonical base datatype
+ * symbol. Which symbol is used is really up to the search_base_type_c, and not this fill_candidate_datatypes_c.
+ * Here we must right the code to handle whatever the search_base_type_c chooses to use as the canonical symbol to represent
+ * the base datatype.
+ * Since the base datatype may be (and sometimes/often/always(?) actually is) the top level symbol_c (an enumerated_type_declaration_c
+ * in the case of the enumerations), it only makes sense to ask search_base_type_c for a basetype when we pass it the
+ * symbol in the highest level of the type declaration (the enumerated_type_declaration_c in the case of the enumerations).
+ * For this reason, we determine the basetype at the top level, and send that info down to the bottom level of the data type
+ * declaration. In summary, a top->down algorithm!
+ */
+ add_datatype_to_candidate_list(symbol, base_type(symbol));
+ type_name->candidate_datatypes = symbol->candidate_datatypes; // use top->down algorithm!!
+ spec_init->candidate_datatypes = symbol->candidate_datatypes; // use top->down algorithm!!
+ spec_init->accept(*this);
+ return NULL;
+}
+
+
+void *fill_candidate_datatypes_c::fill_spec_init(symbol_c *symbol, symbol_c *type_spec, symbol_c *init_value) {
+ /* NOTE: The note in the fill_type_decl() function is also partially valid here,
+ * i.e. here too we work using a top->down algorithm for the type_spec part, but a bottom->up algorithm
+ * for the init_value part!!
+ */
+ /* NOTE: When a variable is declared inside a POU as, for example
+ * VAR
+ * a : ARRAY[9] OF REAL;
+ * e : ENUM (black, white, gray);
+ * s : STRUCT x, y: REAL; END_STRUCT
+ * END_VAR
+ * the anonymous datatype will be defined directly by the ***_spec_init_c, and will not have an
+ * ****_type_declaration_c. In these cases, the anonymous data type is its own basetype, and the
+ * ***_spec_init_c class will act as the canonical symbol that represents the (anonymous) basetype.
+ *
+ * This method must handle the above case, as well as the case in which the ***_spec_init_c is called
+ * from an ****_type_declaration_c.
+ */
+ if (symbol->candidate_datatypes.size() == 0) // i.e., if this is an anonymous datatype!
+ add_datatype_to_candidate_list(symbol, base_type(symbol));
+
+ // use top->down algorithm!!
+ type_spec->candidate_datatypes = symbol->candidate_datatypes;
+ type_spec->accept(*this);
+
+ // use bottom->up algorithm!!
+ if (NULL != init_value) init_value->accept(*this);
+ /* NOTE: Even if the constant and the type are of incompatible data types, we let the
+ * ***_spec_init_c object inherit the data type of the type declaration (simple_specification)
+ * This will let us produce more informative error messages when checking data type compatibility
+ * with located variables (AT %QW3.4 : WORD).
+ */
+ // if (NULL != init_value) intersect_candidate_datatype_list(symbol /*origin, dest.*/, init_value /*with*/);
+ return NULL;
+}
+
+
/* 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 */
@@ -808,32 +871,25 @@
/* 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 */
+void *fill_candidate_datatypes_c::visit(simple_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->simple_type_name, symbol->simple_spec_init);}
+
/* simple_specification ASSIGN constant */
// SYM_REF2(simple_spec_init_c, simple_specification, constant)
-void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
- if (NULL != symbol->constant) symbol->constant->accept(*this);
- add_datatype_to_candidate_list(symbol->simple_specification, base_type(symbol->simple_specification));
- symbol->candidate_datatypes = symbol->simple_specification->candidate_datatypes;
- /* NOTE: Even if the constant and the type are of incompatible data types, we let the
- * simple_spec_init_c object inherit the data type of the type declaration (simple_specification)
- * This will let us produce more informative error messages when checking data type compatibility
- * with located variables (AT %QW3.4 : WORD).
- */
- // if (NULL != symbol->constant) intersect_candidate_datatype_list(symbol /*origin, dest.*/, symbol->constant /*with*/);
- return NULL;
-}
+void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->simple_specification, symbol->constant);}
/* subrange_type_name ':' subrange_spec_init */
// SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init)
+void *fill_candidate_datatypes_c::visit(subrange_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->subrange_type_name, symbol->subrange_spec_init);}
/* subrange_specification ASSIGN signed_integer */
// SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer)
+void *fill_candidate_datatypes_c::visit(subrange_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->subrange_specification, symbol->signed_integer);}
/* integer_type_name '(' subrange')' */
// SYM_REF2(subrange_specification_c, integer_type_name, subrange)
+// NOTE: not needed! Iterator visitor already handles this!
/* signed_integer DOTDOT signed_integer */
/* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
@@ -854,41 +910,25 @@
/* enumerated_type_name ':' enumerated_spec_init */
// SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
-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;
-}
+void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->enumerated_type_name, symbol->enumerated_spec_init);}
/* 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) {
- /* 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);
- return NULL;
-}
+// NOTE: enumerated_specification is either an enumerated_value_list_c or identifier_c.
+void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);}
+
/* helper symbol for enumerated_specification->enumerated_spec_init */
/* 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;
- add_datatype_to_candidate_list(symbol, current_enumerated_spec_type);
+ if (symbol->candidate_datatypes.size() != 1) ERROR;
+ symbol_c *current_enumerated_spec_type = symbol->candidate_datatypes[0];
/* 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++)
- add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type);
+ add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); // top->down algorithm!!
return NULL;
}
@@ -969,10 +1009,12 @@
/* identifier ':' array_spec_init */
// SYM_REF2(array_type_declaration_c, identifier, array_spec_init)
+void *fill_candidate_datatypes_c::visit(array_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->identifier, symbol->array_spec_init);}
/* array_specification [ASSIGN array_initialization} */
/* array_initialization may be NULL ! */
// SYM_REF2(array_spec_init_c, array_specification, array_initialization)
+void *fill_candidate_datatypes_c::visit(array_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->array_specification, symbol->array_initialization);}
/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
// SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name)
@@ -992,10 +1034,12 @@
/* structure_type_name ':' structure_specification */
// SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+void *fill_candidate_datatypes_c::visit(structure_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->structure_type_name, symbol->structure_specification);}
/* structure_type_name ASSIGN structure_initialization */
/* structure_initialization may be NULL ! */
// SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
+void *fill_candidate_datatypes_c::visit(initialized_structure_c *symbol) {return fill_spec_init(symbol, symbol->structure_type_name, symbol->structure_initialization);}
/* helper symbol for structure_declaration */
/* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */
@@ -1017,6 +1061,11 @@
// SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */)
+/* function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+// SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+void *fill_candidate_datatypes_c::visit(fb_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->function_block_type_name, symbol->structure_initialization);}
+
/*********************/
@@ -1211,8 +1260,6 @@
-
-
/************************************/
/* B 1.5 Program organization units */
/************************************/
@@ -1249,6 +1296,12 @@
search_varfb_instance_type = NULL;
local_enumerated_value_symtable.reset();
+
+ /* The FB declaration itself may be used as a dataype! We now do the fill algorithm considering
+ * function_block_declaration_c a data type declaration...
+ */
+ // The next line is essentially equivalent to doing--> symbol->candidate_datatypes.push_back(symbol);
+ add_datatype_to_candidate_list(symbol, base_type(symbol));
return NULL;
}
--- a/stage3/fill_candidate_datatypes.hh Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/fill_candidate_datatypes.hh Thu Apr 04 09:45:11 2013 +0900
@@ -94,6 +94,8 @@
void *handle_binary_expression (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
void *handle_binary_operator (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
void *handle_conditional_il_flow_control_operator(symbol_c *symbol);
+ void *fill_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init);
+ void *fill_spec_init(symbol_c *symbol, symbol_c *type_spec, symbol_c *init_value);
/* a helper function... */
symbol_c *base_type(symbol_c *symbol);
@@ -169,29 +171,30 @@
/********************************/
// 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_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_type_declaration_c *symbol);
+ 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);
void *visit(enumerated_spec_init_c *symbol);
void *visit(enumerated_value_list_c *symbol);
void *visit(enumerated_value_c *symbol);
-// void *visit(array_type_declaration_c *symbol);
-// void *visit(array_spec_init_c *symbol);
+ 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_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);
+ void *visit(fb_spec_init_c *symbol);
/*********************/
@@ -217,7 +220,6 @@
void *visit(location_c *symbol);
void *visit(located_var_decl_c *symbol);
-
/**************************************/
/* B 1.5 - Program organization units */
/**************************************/
--- a/stage3/narrow_candidate_datatypes.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/narrow_candidate_datatypes.cc Thu Apr 04 09:45:11 2013 +0900
@@ -477,6 +477,36 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+void *narrow_candidate_datatypes_c::narrow_spec_init(symbol_c *symbol, symbol_c *type_decl, symbol_c *init_value) {
+ // 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(type_decl) method, because it does not exist!
+ // So we set the datatype ourselves!
+ if ((NULL == symbol->datatype) && (symbol->candidate_datatypes.size() == 1))
+ symbol->datatype = symbol->candidate_datatypes[0];
+
+ set_datatype(symbol->datatype, type_decl);
+ type_decl->accept(*this);
+
+ if (NULL != init_value) {
+ set_datatype(symbol->datatype, init_value);
+ init_value->accept(*this);
+ }
+ return NULL;
+}
+
+
+void *narrow_candidate_datatypes_c::narrow_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init) {
+ if (symbol->candidate_datatypes.size() == 1) {
+ symbol->datatype = symbol->candidate_datatypes[0];
+
+ set_datatype(symbol->datatype, type_name);
+ set_datatype(symbol->datatype, spec_init);
+ spec_init->accept(*this);
+ }
+ return NULL;
+}
+
+
/* 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 */
@@ -487,41 +517,37 @@
/* 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 */
+void *narrow_candidate_datatypes_c::visit(simple_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->simple_type_name, symbol->simple_spec_init);}
/* simple_specification ASSIGN constant */
// SYM_REF2(simple_spec_init_c, simple_specification, constant)
-void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
- if (symbol->candidate_datatypes.size() == 1)
- symbol->datatype = symbol->candidate_datatypes[0];
-
- if (symbol->simple_specification->candidate_datatypes.size() == 1)
- symbol->simple_specification->datatype = symbol->simple_specification->candidate_datatypes[0];
-
- if (NULL != symbol->constant) {
- set_datatype(symbol->datatype, symbol->constant);
- symbol->constant->accept(*this);
- }
- return NULL;
-}
-
+void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->simple_specification, symbol->constant);}
/* subrange_type_name ':' subrange_spec_init */
// SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init)
+void *narrow_candidate_datatypes_c::visit(subrange_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->subrange_type_name, symbol->subrange_spec_init);}
/* subrange_specification ASSIGN signed_integer */
// SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer)
+void *narrow_candidate_datatypes_c::visit(subrange_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->subrange_specification, symbol->signed_integer);}
/* integer_type_name '(' subrange')' */
// SYM_REF2(subrange_specification_c, integer_type_name, subrange)
+void *narrow_candidate_datatypes_c::visit(subrange_specification_c *symbol) {
+ set_datatype(symbol->datatype, symbol->integer_type_name);
+ symbol->integer_type_name->accept(*this);
+ set_datatype(symbol->datatype, symbol->integer_type_name);
+ symbol->integer_type_name->accept(*this);
+ return NULL;
+}
/* signed_integer DOTDOT signed_integer */
/* 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;
+ set_datatype(symbol->datatype, symbol->lower_limit);
symbol->lower_limit->accept(*this);
- symbol->upper_limit->datatype = symbol->datatype;
+ set_datatype(symbol->datatype, symbol->upper_limit);
symbol->upper_limit->accept(*this);
return NULL;
}
@@ -529,49 +555,20 @@
/* 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;
-}
+void *narrow_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->enumerated_type_name, symbol->enumerated_spec_init);}
/* 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;
-}
+void *narrow_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);}
/* 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;
- }
+//if (NULL == symbol->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ???
+ for(int i = 0; i < symbol->n; i++) set_datatype(symbol->datatype, symbol->elements[i]);
+//for(int i = 0; i < symbol->n; i++) if (NULL == symbol->elements[i]->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ???
return NULL;
}
@@ -583,54 +580,70 @@
/* identifier ':' array_spec_init */
// SYM_REF2(array_type_declaration_c, identifier, array_spec_init)
+void *narrow_candidate_datatypes_c::visit(array_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->identifier, symbol->array_spec_init);}
/* array_specification [ASSIGN array_initialization} */
/* array_initialization may be NULL ! */
// SYM_REF2(array_spec_init_c, array_specification, array_initialization)
+void *narrow_candidate_datatypes_c::visit(array_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->array_specification, symbol->array_initialization);}
/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
// SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name)
+// Not needed!!
/* helper symbol for array_specification */
/* array_subrange_list ',' subrange */
// SYM_LIST(array_subrange_list_c)
+// Not needed ??
/* 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)
+// Not needed ???
/* integer '(' [array_initial_element] ')' */
/* array_initial_element may be NULL ! */
// SYM_REF2(array_initial_elements_c, integer, array_initial_element)
+// Not needed ???
/* structure_type_name ':' structure_specification */
// SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+void *narrow_candidate_datatypes_c::visit(structure_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->structure_type_name, symbol->structure_specification);}
/* structure_type_name ASSIGN structure_initialization */
/* structure_initialization may be NULL ! */
// SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
+void *narrow_candidate_datatypes_c::visit(initialized_structure_c *symbol) {return narrow_spec_init(symbol, symbol->structure_type_name, symbol->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)
+// Not needed ???
/* structure_element_name ':' *_spec_init */
// SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
+// Not needed ???
/* 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)
+// Not needed ???
/* structure_element_name ASSIGN value */
// SYM_REF2(structure_element_initialization_c, structure_element_name, value)
+// Not needed ???
/* 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! */)
+/* structure_type_name ASSIGN structure_initialization */
+/* structure_initialization may be NULL ! */
+// SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
+void *narrow_candidate_datatypes_c::visit(fb_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->function_block_type_name, symbol->structure_initialization);}
/*********************/
@@ -709,6 +722,7 @@
}
+
/************************************/
/* B 1.5 Program organization units */
/************************************/
@@ -739,6 +753,10 @@
symbol->fblock_body->accept(*this);
delete search_varfb_instance_type;
search_varfb_instance_type = NULL;
+
+ // A FB declaration can also be used as a Datatype! We now do the narrow algorithm considering it as such!
+ if (symbol->candidate_datatypes.size() == 1)
+ symbol->datatype = symbol->candidate_datatypes[0];
return NULL;
}
--- a/stage3/narrow_candidate_datatypes.hh Mon Mar 11 12:54:25 2013 +0100
+++ b/stage3/narrow_candidate_datatypes.hh Thu Apr 04 09:45:11 2013 +0900
@@ -81,6 +81,9 @@
void *narrow_binary_expression (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL, bool allow_enums = false);
void *narrow_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL);
+ void *narrow_spec_init(symbol_c *symbol, symbol_c *type_decl, symbol_c *init_value);
+ void *narrow_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init);
+
void *narrow_conditional_flow_control_IL_instruction(symbol_c *symbol);
@@ -150,29 +153,30 @@
/********************************/
// 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_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_type_declaration_c *symbol);
+ 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);
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_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_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);
+ void *visit(fb_spec_init_c *symbol);
/*********************/
/* B 1.4 - Variables */
--- a/stage4/generate_c/generate_c.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage4/generate_c/generate_c.cc Thu Apr 04 09:45:11 2013 +0900
@@ -299,7 +299,7 @@
//void *visit(var_declaration_list_c *symbol) {iterate through list}
void *visit(fb_name_decl_c *symbol) {
- print_list(symbol->fb_name_list, symbol->function_block_type_name);
+ print_list(symbol->fb_name_list, spec_init_sperator_c::get_spec(symbol->fb_spec_init));
return NULL;
}
--- a/stage4/generate_c/generate_c_vardecl.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc Thu Apr 04 09:45:11 2013 +0900
@@ -1258,8 +1258,10 @@
return NULL;
}
+
void *visit(en_param_declaration_c *symbol) {
TRACE("en_declaration_c");
+ update_type_init(symbol->type_decl);
if (wanted_varformat == finterface_vf) {
finterface_var_count++;
}
@@ -1267,7 +1269,7 @@
if (wanted_varformat == finterface_vf) {
s4o.print(nv->get());
s4o.print("\n" + s4o.indent_spaces);
- symbol->type->accept(*this);
+ this->current_var_type_symbol->accept(*this);
s4o.print(" ");
symbol->name->accept(*this);
}
@@ -1279,11 +1281,11 @@
if (wanted_varformat == local_vf) {
s4o.print(DECLARE_VAR);
s4o.print("(");
- symbol->type->accept(*this);
+ this->current_var_type_symbol->accept(*this);
s4o.print(",");
}
else if (wanted_varformat == localinit_vf) {
- symbol->type->accept(*this);
+ this->current_var_type_symbol->accept(*this);
s4o.print(" ");
}
print_variable_prefix();
@@ -1292,7 +1294,7 @@
s4o.print(")\n");
else {
s4o.print(" = ");
- symbol->value->accept(*this);
+ this->current_var_init_symbol->accept(*this);
s4o.print(";\n");
}
}
@@ -1306,11 +1308,12 @@
// s4o.print("EN = __BOOL_LITERAL(TRUE);");
symbol->name->accept(*this);
s4o.print(",");
- symbol->value->accept(*this);
+ this->current_var_init_symbol->accept(*this);
print_retain();
s4o.print(")");
}
}
+ void_type_init();
return NULL;
}
@@ -1480,7 +1483,7 @@
/* Start off by setting the current_var_type_symbol and
* current_var_init_symbol private variables...
*/
- update_type_init(symbol);
+ update_type_init(symbol->fb_spec_init);
/* now to produce the c equivalent... */
symbol->fb_name_list->accept(*this);
--- a/stage4/generate_c/generate_var_list.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage4/generate_c/generate_var_list.cc Thu Apr 04 09:45:11 2013 +0900
@@ -603,7 +603,7 @@
/* Start off by setting the current_var_type_symbol and
* current_var_init_symbol private variables...
*/
- update_var_type_symbol(symbol);
+ update_var_type_symbol(symbol->fb_spec_init);
/* now to produce the c equivalent... */
declare_variables(symbol->fb_name_list);
@@ -731,7 +731,7 @@
/* Start off by setting the current_var_type_symbol and
* current_var_init_symbol private variables...
*/
- update_var_type_symbol(symbol->type);
+ update_var_type_symbol(symbol->type_decl);
/* now to produce the c equivalent... */
declare_variable(symbol->name);
--- a/stage4/generate_iec/generate_iec.cc Mon Mar 11 12:54:25 2013 +0100
+++ b/stage4/generate_iec/generate_iec.cc Thu Apr 04 09:45:11 2013 +0900
@@ -633,7 +633,16 @@
return NULL;
}
-
+/* function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+void *visit(fb_spec_init_c *symbol) {
+ symbol->function_block_type_name->accept(*this);
+ if (symbol->structure_initialization != NULL) {
+ s4o.print(" := ");
+ symbol->structure_initialization->accept(*this);
+ }
+ return NULL;
+}
@@ -722,9 +731,7 @@
if (typeid(*(symbol->method)) == typeid(explicit_definition_c)) {
symbol->name->accept(*this);
s4o.print(" : ");
- symbol->type->accept(*this);
- s4o.print(" := ");
- symbol->value->accept(*this);
+ symbol->type_decl->accept(*this);
}
return NULL;
}
@@ -814,11 +821,7 @@
void *visit(fb_name_decl_c *symbol) {
symbol->fb_name_list->accept(*this);
s4o.print(" : ");
- symbol->function_block_type_name->accept(*this);
- if (symbol->structure_initialization != NULL) {
- s4o.print(" := ");
- symbol->structure_initialization->accept(*this);
- }
+ symbol->fb_spec_init->accept(*this);
return NULL;
}