# HG changeset patch # User Edouard Tisserant # Date 1365036311 -32400 # Node ID 0630cc31569f3ecd7478bcc7cc0cf8ebf032a0ea # Parent 7898ba56c7cf1fdff4a5389cfe5e1c18a3c63254# Parent 6679b6b212144eb13f6f3ea300991cf989a8aabb Merged Mario's changes diff -r 7898ba56c7cf -r 0630cc31569f absyntax/absyntax.def --- 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) diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/add_en_eno_param_decl.cc --- 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 diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/debug_ast.cc --- 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) diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/function_param_iterator.cc --- 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); } diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/search_base_type.cc --- 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 */ diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/search_base_type.hh --- 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 */ /*****************************/ diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/search_fb_instance_decl.cc --- 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); } diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/search_var_instance_decl.cc --- 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); } diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/spec_init_separator.cc --- 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 diff -r 7898ba56c7cf -r 0630cc31569f absyntax_utils/spec_init_separator.hh --- 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 diff -r 7898ba56c7cf -r 0630cc31569f stage1_2/iec_bison.yy --- 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; diff -r 7898ba56c7cf -r 0630cc31569f stage3/declaration_check.cc --- 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()) diff -r 7898ba56c7cf -r 0630cc31569f stage3/declaration_check.hh --- 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); }; diff -r 7898ba56c7cf -r 0630cc31569f stage3/fill_candidate_datatypes.cc --- 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; } diff -r 7898ba56c7cf -r 0630cc31569f stage3/fill_candidate_datatypes.hh --- 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 */ /**************************************/ diff -r 7898ba56c7cf -r 0630cc31569f stage3/narrow_candidate_datatypes.cc --- 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; } diff -r 7898ba56c7cf -r 0630cc31569f stage3/narrow_candidate_datatypes.hh --- 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 */ diff -r 7898ba56c7cf -r 0630cc31569f stage4/generate_c/generate_c.cc --- 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; } diff -r 7898ba56c7cf -r 0630cc31569f stage4/generate_c/generate_c_vardecl.cc --- 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); diff -r 7898ba56c7cf -r 0630cc31569f stage4/generate_c/generate_var_list.cc --- 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); diff -r 7898ba56c7cf -r 0630cc31569f stage4/generate_iec/generate_iec.cc --- 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; }