# HG changeset patch # User mjsousa # Date 1392116127 0 # Node ID 300c27c0875390bfec4be56a43e0d0c8d25274ed # Parent 2b6b1202f8a8f5d00ec8111eb90617d9175c9d1d# Parent 06820d03a4335ceeed56c884197894b3c3a795d3 merge diff -r 06820d03a433 -r 300c27c08753 absyntax/absyntax.def --- a/absyntax/absyntax.def Mon Jan 06 12:25:21 2014 +0000 +++ b/absyntax/absyntax.def Tue Feb 11 10:55:27 2014 +0000 @@ -862,6 +862,10 @@ /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, enumvalue_symtable_t enumvalue_symtable;) +/* intermediate helper symbol for configuration_declaration */ +/* { global_var_declarations_list } */ +SYM_LIST(global_var_declarations_list_c) + /* helper symbol for configuration_declaration */ SYM_LIST(resource_declaration_list_c) diff -r 06820d03a433 -r 300c27c08753 absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/absyntax_utils/get_datatype_info.cc Tue Feb 11 10:55:27 2014 +0000 @@ -292,7 +292,7 @@ bool get_datatype_info_c::is_subrange(symbol_c *type_symbol) { - symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); /* NOTE: will work correctly once we update the way search_base_type_c works, by adding a new search_effective_type:c */ + symbol_c *type_decl = search_base_type_c::get_equivtype_decl(type_symbol); /* NOTE: do NOT call search_base_type_c !! */ if (NULL == type_decl) {return false;} if (typeid(*type_decl) == typeid(subrange_type_declaration_c)) {return true;} /* subrange_type_name ':' subrange_spec_init */ diff -r 06820d03a433 -r 300c27c08753 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/absyntax_utils/search_base_type.cc Tue Feb 11 10:55:27 2014 +0000 @@ -54,7 +54,7 @@ -search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;} +search_base_type_c::search_base_type_c(void) {current_basetype_name = NULL; current_basetype = NULL; current_equivtype = NULL;} /* static method! */ void search_base_type_c::create_singleton(void) { @@ -63,11 +63,25 @@ } /* static method! */ +symbol_c *search_base_type_c::get_equivtype_decl(symbol_c *symbol) { + create_singleton(); + if (NULL == symbol) return NULL; + search_base_type_singleton->current_basetype_name = NULL; + search_base_type_singleton->current_basetype = NULL; + search_base_type_singleton->current_equivtype = NULL; + symbol_c *basetype = (symbol_c *)symbol->accept(*search_base_type_singleton); + if (NULL != search_base_type_singleton->current_equivtype) + return search_base_type_singleton->current_equivtype; + return basetype; +} + +/* static method! */ symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) { create_singleton(); if (NULL == symbol) return NULL; - search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype_name = NULL; search_base_type_singleton->current_basetype = NULL; + search_base_type_singleton->current_equivtype = NULL; return (symbol_c *)symbol->accept(*search_base_type_singleton); } @@ -75,10 +89,11 @@ symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) { create_singleton(); if (NULL == symbol) return NULL; - search_base_type_singleton->current_type_name = NULL; + search_base_type_singleton->current_basetype_name = NULL; search_base_type_singleton->current_basetype = NULL; + search_base_type_singleton->current_equivtype = NULL; symbol->accept(*search_base_type_singleton); - return (symbol_c *)search_base_type_singleton->current_type_name; + return (symbol_c *)search_base_type_singleton->current_basetype_name; } @@ -93,7 +108,7 @@ void *search_base_type_c::visit(identifier_c *type_name) { symbol_c *type_decl; - this->current_type_name = type_name; + this->current_basetype_name = type_name; /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for, * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!) */ @@ -210,16 +225,21 @@ /* subrange_type_name ':' subrange_spec_init */ void *search_base_type_c::visit(subrange_type_declaration_c *symbol) { + this->current_equivtype = symbol; return symbol->subrange_spec_init->accept(*this); } /* subrange_specification ASSIGN signed_integer */ void *search_base_type_c::visit(subrange_spec_init_c *symbol) { + if (NULL == this->current_equivtype) + this->current_equivtype = symbol; return symbol->subrange_specification->accept(*this); } /* integer_type_name '(' subrange')' */ void *search_base_type_c::visit(subrange_specification_c *symbol) { + if (NULL == this->current_equivtype) + this->current_equivtype = symbol; return symbol->integer_type_name->accept(*this); } @@ -228,7 +248,7 @@ /* enumerated_type_name ':' enumerated_spec_init */ void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { - this->current_type_name = symbol->enumerated_type_name; + this->current_basetype_name = symbol->enumerated_type_name; /* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible * (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an * anonymous datatype declared in a VAR ... AND_VAR declaration). @@ -266,7 +286,7 @@ /* identifier ':' array_spec_init */ void *search_base_type_c::visit(array_type_declaration_c *symbol) { - this->current_type_name = symbol->identifier; + this->current_basetype_name = symbol->identifier; return symbol->array_spec_init->accept(*this); } @@ -303,7 +323,7 @@ * structure_element_declaration_list_c */ void *search_base_type_c::visit(structure_type_declaration_c *symbol) { - this->current_type_name = symbol->structure_type_name; + this->current_basetype_name = symbol->structure_type_name; return symbol->structure_specification->accept(*this); } @@ -370,14 +390,14 @@ /* INITIAL_STEP step_name ':' action_association_list END_STEP */ // SYM_REF2(initial_step_c, step_name, action_association_list) void *search_base_type_c::visit(initial_step_c *symbol) { - this->current_type_name = NULL; /* this pseudo data type does not have a type name! */ + this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */ return (void *)symbol; } /* STEP step_name ':' action_association_list END_STEP */ // SYM_REF2(step_c, step_name, action_association_list) void *search_base_type_c::visit(step_c *symbol) { - this->current_type_name = NULL; /* this pseudo data type does not have a type name! */ + this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */ return (void *)symbol; } diff -r 06820d03a433 -r 300c27c08753 absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Mon Jan 06 12:25:21 2014 +0000 +++ b/absyntax_utils/search_base_type.hh Tue Feb 11 10:55:27 2014 +0000 @@ -31,19 +31,35 @@ */ -/* Determine the data type on which another data type is based on. - * If a new default initial value is given, we DO NOT consider it a - * new base class, and continue looking further! - * - * E.g. TYPE new_int_t : INT; END_TYPE; - * TYPE new_int2_t : INT = 2; END_TYPE; - * TYPE new_subr_t : INT (4..5); END_TYPE; - * - * new_int_t is really an INT!! - * new_int2_t is also really an INT!! - * new_subr_t is also really an INT!! - * - * Note that a FB declaration is also considered a base type, as +/* Determine the data type on which another data type is based on. */ + +/* + * What is a Base Type? + * A base type is the fundamental data type from which the type is derived. + * The main idea is that if two datatyes (A and B) share a common base type, + * then these two datatypes may be used interchangeably in an expression. + * + * What is an Equivalent Type? + * An equivalent type is the data type from which the type is derived. + * The Base type and the Equivalent type will always be the same, with the + * exception of subranges! + * + * E.g. TYPE new_int_t : INT; END_TYPE; + * TYPE new_int2_t : INT := 2; END_TYPE; + * TYPE new_int3_t : new_int2_t := 3; END_TYPE; + * TYPE new_sub_t : INT (4..10); END_TYPE; + * TYPE new_sub2_t : new_sub_t := 5 ; END_TYPE; + * TYPE new_sub3_t : new_sub2_t := 6 ; END_TYPE; + * TYPE new_sub4_t : new_int3_t (4..10); END_TYPE; <----- This is NOT legal syntax! + * + * new_int_t : base type->INT equivalent type->INT + * new_int2_t : base type->INT equivalent type->INT + * new_int3_t : base type->INT equivalent type->INT + * new_sub_t : base type->INT equivalent type->new_sub_t + * new_sub2_t : base type->INT equivalent type->new_sub_t + * new_sub3_t : base type->INT equivalent type->new_sub_t + * + * Note too that a FB declaration is also considered a base type, as * we may have FB instances declared of a specific FB type. */ @@ -51,8 +67,9 @@ class search_base_type_c: public null_visitor_c { private: - symbol_c *current_type_name; + symbol_c *current_basetype_name; symbol_c *current_basetype; + symbol_c *current_equivtype; static search_base_type_c *search_base_type_singleton; // Make this a singleton class! private: @@ -60,8 +77,9 @@ public: search_base_type_c(void); - static symbol_c *get_basetype_decl (symbol_c *symbol); - static symbol_c *get_basetype_id (symbol_c *symbol); + static symbol_c *get_equivtype_decl(symbol_c *symbol); /* get the Equivalent Type declaration */ + static symbol_c *get_basetype_decl (symbol_c *symbol); /* get the Base Type declaration */ + static symbol_c *get_basetype_id (symbol_c *symbol); /* get the Base Type identifier */ public: /*************************/ diff -r 06820d03a433 -r 300c27c08753 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Mon Jan 06 12:25:21 2014 +0000 +++ b/stage1_2/iec_bison.yy Tue Feb 11 10:55:27 2014 +0000 @@ -1046,7 +1046,7 @@ // - configuration_declaration // - resource_declaration // -%type optional_global_var_declarations +%type global_var_declarations_list // helper symbol for configuration_declaration %type optional_access_declarations // helper symbol for configuration_declaration @@ -5563,7 +5563,7 @@ configuration_declaration: CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list single_resource_declaration {variable_name_symtable.pop(); direct_variable_symtable.pop();} @@ -5576,7 +5576,7 @@ direct_variable_symtable.pop(); } | CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list resource_declaration_list optional_access_declarations optional_instance_specific_initializations @@ -5588,7 +5588,7 @@ } /* ERROR_CHECK_BEGIN */ | CONFIGURATION - optional_global_var_declarations + global_var_declarations_list single_resource_declaration {variable_name_symtable.pop(); direct_variable_symtable.pop();} @@ -5597,14 +5597,14 @@ END_CONFIGURATION {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;} | CONFIGURATION - optional_global_var_declarations + global_var_declarations_list resource_declaration_list optional_access_declarations optional_instance_specific_initializations END_CONFIGURATION {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;} | CONFIGURATION error - optional_global_var_declarations + global_var_declarations_list single_resource_declaration {variable_name_symtable.pop(); direct_variable_symtable.pop();} @@ -5613,27 +5613,27 @@ END_CONFIGURATION {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;} | CONFIGURATION error - optional_global_var_declarations + global_var_declarations_list resource_declaration_list optional_access_declarations optional_instance_specific_initializations END_CONFIGURATION {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;} | CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list optional_access_declarations optional_instance_specific_initializations END_CONFIGURATION {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;} | CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list error optional_access_declarations optional_instance_specific_initializations END_CONFIGURATION {$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid resource(s) defined in configuration declaration."); yyerrok;} /*| CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list single_resource_declaration {variable_name_symtable.pop(); direct_variable_symtable.pop();} @@ -5642,7 +5642,7 @@ END_OF_INPUT {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}*/ | CONFIGURATION configuration_name - optional_global_var_declarations + global_var_declarations_list resource_declaration_list optional_access_declarations optional_instance_specific_initializations @@ -5657,12 +5657,30 @@ // - configuration_declaration // - resource_declaration // -optional_global_var_declarations: +/* NOTE: The IEC 61131-3 v2 standard defines this list as being: [global_var_declarations] + * e.g.: + * 'CONFIGURATION' configuration_name [global_var_declarations] ... + * + * However, this means that a single VAR_GLOBAL ... END_VAR construct is allowed + * in each CONFIGURATION or RESOURCE declaration. If the user wishes to have global + * variables with distinct properties (e.g. some with RETAIN, others with CONSTANT, + * and yet other variables with none of these qualifiers), the syntax defined in the + * standard does not allow this. + * Amazingly, IEC 61131-3 v3 also does not seem to allow it either!! + * Since this is most likely a bug in the standard, we are changing the syntax slightly + * to become: + * 'CONFIGURATION' configuration_name {global_var_declarations} ... + * + * Remember that: + * {S}, closure, meaning zero or more concatenations of S. + * [S], option, meaning zero or one occurrence of S. + */ +global_var_declarations_list: // empty - {$$ = NULL;} -| global_var_declarations -; - + {$$ = new global_var_declarations_list_c(locloc(@$));} +| global_var_declarations_list global_var_declarations + {$$ = $1; $$->add_element($2);} +; // helper symbol for configuration_declaration // optional_access_declarations: @@ -5693,7 +5711,7 @@ resource_declaration: 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 + global_var_declarations_list single_resource_declaration END_RESOURCE {$$ = new resource_declaration_c($3, $6, $7, $8, locloc(@$)); @@ -5703,12 +5721,12 @@ } /* ERROR_CHECK_BEGIN */ | RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} ON resource_type_name - optional_global_var_declarations + global_var_declarations_list single_resource_declaration END_RESOURCE {$$ = NULL; print_err_msg(locl(@1), locf(@3), "no resource name defined in resource declaration."); yynerrs++;} /*| RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name - optional_global_var_declarations + global_var_declarations_list single_resource_declaration END_OF_INPUT {$$ = NULL; print_err_msg(locf(@1), locl(@5), "unclosed resource declaration."); yyerrok;}*/ diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c.cc Tue Feb 11 10:55:27 2014 +0000 @@ -713,15 +713,13 @@ } inlinearray_mode_t; private: - stage4out_c *s4o_ptr; std::map inline_array_defined; std::string current_array_name; inlinearray_mode_t current_mode; public: generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) - : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { - generate_c_datatypes_c::s4o_ptr = s4o_ptr; + : generate_c_typedecl_c(s4o_incl_ptr) { current_mode = none_im; }; virtual ~generate_c_datatypes_c(void) { @@ -907,11 +905,20 @@ void *visit(array_spec_init_c *symbol) { switch (current_mode) { case arraydeclaration_im: + { + array_specification_c *specification = dynamic_cast(symbol->array_specification); + if (specification != NULL) + symbol->array_specification->accept(*this); + } + break; case arrayname_im: { array_specification_c *specification = dynamic_cast(symbol->array_specification); if (specification != NULL) symbol->array_specification->accept(*this); + identifier_c *name = dynamic_cast(symbol->array_specification); + if (name != NULL) + s4o_incl.print(name->value); } break; default: @@ -1138,14 +1145,13 @@ /***********************************************************************/ -class generate_c_pous_c: public generate_c_typedecl_c { +class generate_c_pous_c: public generate_c_base_c { private: - stage4out_c *s4o_ptr; + stage4out_c &s4o_incl; public: generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) - : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { - generate_c_pous_c::s4o_ptr = s4o_ptr; + : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { }; virtual ~generate_c_pous_c(void) {} @@ -1179,8 +1185,8 @@ /********************/ /* 2.1.6 - Pragmas */ /********************/ -void *visit(enable_code_generation_pragma_c * symbol) {s4o_ptr->enable_output(); return NULL;} -void *visit(disable_code_generation_pragma_c * symbol) {s4o_ptr->disable_output(); return NULL;} +void *visit(enable_code_generation_pragma_c * symbol) {s4o.enable_output(); return NULL;} +void *visit(disable_code_generation_pragma_c * symbol) {s4o.disable_output(); return NULL;} /*************************/ /* B.1 - Common elements */ @@ -1742,16 +1748,13 @@ /***********************************************************************/ /***********************************************************************/ -class generate_c_config_c: public generate_c_typedecl_c { +class generate_c_config_c: public generate_c_base_c { private: - stage4out_c *s4o_ptr; - stage4out_c *s4o_incl_ptr; + stage4out_c &s4o_incl; public: generate_c_config_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) - : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { - generate_c_config_c::s4o_ptr = s4o_ptr; - generate_c_config_c::s4o_incl_ptr = s4o_incl_ptr; + : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { }; virtual ~generate_c_config_c(void) {} @@ -1771,14 +1774,14 @@ /* 2.1.6 - Pragmas */ /********************/ void *visit(enable_code_generation_pragma_c * symbol) { - s4o_ptr->enable_output(); - s4o_incl_ptr->enable_output(); + s4o.enable_output(); + s4o_incl.enable_output(); return NULL; } void *visit(disable_code_generation_pragma_c * symbol) { - s4o_ptr->disable_output(); - s4o_incl_ptr->disable_output(); + s4o.disable_output(); + s4o_incl.disable_output(); return NULL; } diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_base.cc Tue Feb 11 10:55:27 2014 +0000 @@ -583,6 +583,60 @@ /********************************/ /* leave for derived classes... */ + +/* enumerated_type_name '#' identifier */ +void *visit(enumerated_value_c *symbol) { + if (NULL == symbol->datatype) { + debug_c::print(symbol); + ERROR; + } + + symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype); + if (NULL == type_name) { + ERROR_MSG("C code generator does not currently support anonymous enumerated data types."); + } + + type_name->accept(*this); + s4o.print("__"); + symbol->value->accept(*this); + return NULL; +} + + + +/* NOTE: visit(subrange_spec_init_c *) + * and visit(subrange_specification_c *) + * together simply print out the integer datatype + * on which the subrange is based. + * + * Future code clean-ups should delete these two + * visit mehotds, and make sure whoever calls them + * uses symbol->datatype instead! + */ +/* subrange_specification ASSIGN signed_integer */ +void *visit(subrange_spec_init_c *symbol) { + TRACE("subrange_spec_init_c"); + symbol->subrange_specification->accept(*this); + return NULL; +} + +/* integer_type_name '(' subrange')' */ +void *visit(subrange_specification_c *symbol) { + TRACE("subrange_specification_c"); + symbol->integer_type_name->accept(*this); + return NULL; +} + + +/* helper symbol for array_specification */ +/* array_subrange_list ',' subrange */ +void *visit(array_subrange_list_c *symbol) { + TRACE("array_subrange_list_c"); + print_list(symbol); + return NULL; +} + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_il.cc Tue Feb 11 10:55:27 2014 +0000 @@ -126,7 +126,7 @@ -class generate_c_il_c: public generate_c_typedecl_c, il_default_variable_visitor_c { +class generate_c_il_c: public generate_c_base_c, il_default_variable_visitor_c { public: typedef enum { @@ -197,7 +197,7 @@ public: generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) - : generate_c_typedecl_c(s4o_ptr), + : generate_c_base_c(s4o_ptr), implicit_variable_current (IL_DEFVAR, NULL), implicit_variable_result (IL_DEFVAR, NULL), implicit_variable_result_back(IL_DEFVAR_BACK, NULL) diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_inlinefcall.cc --- a/stage4/generate_c/generate_c_inlinefcall.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_inlinefcall.cc Tue Feb 11 10:55:27 2014 +0000 @@ -26,7 +26,7 @@ #define INLINE_RESULT_TEMP_VAR "__res" #define INLINE_PARAM_COUNT "__PARAM_COUNT" -class generate_c_inlinefcall_c: public generate_c_typedecl_c { +class generate_c_inlinefcall_c: public generate_c_base_c { public: typedef enum { @@ -76,7 +76,7 @@ public: generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) - : generate_c_typedecl_c(s4o_ptr), + : generate_c_base_c(s4o_ptr), implicit_variable_current(IL_DEFVAR, NULL) { search_varfb_instance_type = new search_varfb_instance_type_c(scope); diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_sfc.cc --- a/stage4/generate_c/generate_c_sfc.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_sfc.cc Tue Feb 11 10:55:27 2014 +0000 @@ -657,7 +657,7 @@ /***********************************************************************/ /***********************************************************************/ -class generate_c_sfc_c: public generate_c_typedecl_c { +class generate_c_sfc_c: public generate_c_base_c { private: std::list variable_list; @@ -667,7 +667,7 @@ public: generate_c_sfc_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) - : generate_c_typedecl_c(s4o_ptr) { + : generate_c_base_c(s4o_ptr) { generate_c_sfc_elements = new generate_c_sfc_elements_c(s4o_ptr, name, scope, variable_prefix); search_var_instance_decl = new search_var_instance_decl_c(scope); this->set_variable_prefix(variable_prefix); diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_sfcdecl.cc --- a/stage4/generate_c/generate_c_sfcdecl.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_sfcdecl.cc Tue Feb 11 10:55:27 2014 +0000 @@ -32,7 +32,7 @@ /***********************************************************************/ /***********************************************************************/ -class generate_c_sfcdecl_c: protected generate_c_typedecl_c { +class generate_c_sfcdecl_c: protected generate_c_base_c { public: typedef enum { @@ -59,7 +59,7 @@ public: generate_c_sfcdecl_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) - : generate_c_typedecl_c(s4o_ptr) { + : generate_c_base_c(s4o_ptr) { this->set_variable_prefix(variable_prefix); search_var_instance_decl = new search_var_instance_decl_c(scope); } diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_st.cc Tue Feb 11 10:55:27 2014 +0000 @@ -44,7 +44,7 @@ /***********************************************************************/ -class generate_c_st_c: public generate_c_typedecl_c { +class generate_c_st_c: public generate_c_base_c { public: typedef enum { @@ -95,7 +95,7 @@ public: generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) - : generate_c_typedecl_c(s4o_ptr) { + : generate_c_base_c(s4o_ptr) { search_fb_instance_decl = new search_fb_instance_decl_c (scope); search_varfb_instance_type = new search_varfb_instance_type_c(scope); search_var_instance_decl = new search_var_instance_decl_c (scope); @@ -864,20 +864,20 @@ /* fb_name '(' [param_assignment_list] ')' */ -/* param_assignment_list -> may be NULL ! */ -//SYM_REF2(fb_invocation_c, fb_name, param_assignment_list) +/* formal_param_list -> may be NULL ! */ +/* nonformal_param_list -> may be NULL ! */ +/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ +// SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;) void *visit(fb_invocation_c *symbol) { TRACE("fb_invocation_c"); - /* first figure out what is the name of the function block type of the function block being called... */ - symbol_c *function_block_type_name = this->search_fb_instance_decl->get_type_name(symbol->fb_name); - /* should never occur. The function block instance MUST have been declared... */ - if (function_block_type_name == NULL) ERROR; - - /* Now find the declaration of the function block type being called... */ - function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(function_block_type_name); - /* should never occur. The function block type being called MUST be in the symtable... */ - if (fb_decl == function_block_type_symtable.end_value()) ERROR; - + + /* find the declaration of the function block type being called... */ + symbol_c *fb_decl = symbol->called_fb_declaration; + if (fb_decl == NULL) ERROR; + /* figure out the name of the function block type of the function block being called... */ + symbol_c *function_block_type_name = get_datatype_info_c::get_id(fb_decl); + if (NULL == function_block_type_name) ERROR; + /* loop through each function block parameter, find the value we should pass * to it, and then output the c equivalent... */ diff -r 06820d03a433 -r 300c27c08753 stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_c/generate_c_typedecl.cc Tue Feb 11 10:55:27 2014 +0000 @@ -31,16 +31,9 @@ private: symbol_c* current_type_name; bool array_is_derived; - generate_c_base_c *basedecl; public: - generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { - current_typedefinition = none_td; - current_basetypedeclaration = none_bd; - current_type_name = NULL; - basedecl = new generate_c_base_c(&s4o_incl); - } generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { current_typedefinition = none_td; current_basetypedeclaration = none_bd; @@ -190,6 +183,7 @@ /* integer_type_name '(' subrange')' */ void *visit(subrange_specification_c *symbol) { + TRACE("subrange_specification_c"); if (current_typedefinition == subrange_td) { switch (current_basetypedeclaration) { case subrangebasetype_bd: @@ -197,45 +191,52 @@ break; case subrangetest_bd: if (symbol->subrange != NULL) { - current_type_name->accept(*this); - s4o.print(" __CHECK_"); - current_type_name->accept(*this); - s4o.print("("); - current_type_name->accept(*this); - s4o.print(" value) {\n"); - s4o.indent_right(); - + s4o_incl.print("static inline "); + current_type_name->accept(*basedecl); + s4o_incl.print(" __CHECK_"); + current_type_name->accept(*basedecl); + s4o_incl.print("("); + current_type_name->accept(*basedecl); + s4o_incl.print(" value) {\n"); + s4o_incl.indent_right(); + + /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */ + /* For this reason, the following condition will always be false, and therefore this is a block + * of dead code. However, let's not delete it for now. It might come in useful for IEC 61131-3 v3. + * For the moment, we just comment it out! + */ + /* if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) { - s4o.print(s4o.indent_spaces + "value = __CHECK_"); + s4o_incl.print(s4o_incl.indent_spaces + "value = __CHECK_"); symbol->integer_type_name->accept(*this); - s4o.print("(value);\n"); + s4o_incl.print("(value);\n"); } + */ symbol->subrange->accept(*this); - s4o.indent_left(); - s4o.print("}\n"); + s4o_incl.indent_left(); + s4o_incl.print("}\n"); } else { - s4o.print("#define __CHECK_"); - current_type_name->accept(*this); - s4o.print(" __CHECK_"); - symbol->integer_type_name->accept(*this); - s4o.print("\n"); + s4o_incl.print("#define __CHECK_"); + current_type_name->accept(*basedecl); + s4o_incl.print(" __CHECK_"); + symbol->integer_type_name->accept(*basedecl); + s4o_incl.print("\n"); } break; default: break; } } - else { - symbol->integer_type_name->accept(*basedecl); - } - return NULL; -} + return NULL; +} + /* signed_integer DOTDOT signed_integer */ void *visit(subrange_c *symbol) { + TRACE("subrange_c"); int dimension; switch (current_typedefinition) { case array_td: @@ -248,26 +249,26 @@ symbol->lower_limit->accept(*this); break; case subrange_td: - s4o.print(s4o.indent_spaces + "if (value < "); - symbol->lower_limit->accept(*this); - s4o.print(")\n"); - s4o.indent_right(); - s4o.print(s4o.indent_spaces + "return "); - symbol->lower_limit->accept(*this); - s4o.print(";\n"); - s4o.indent_left(); - s4o.print(s4o.indent_spaces + "else if (value > "); - symbol->upper_limit->accept(*this); - s4o.print(")\n"); - s4o.indent_right(); - s4o.print(s4o.indent_spaces + "return "); - symbol->upper_limit->accept(*this); - s4o.print(";\n"); - s4o.indent_left(); - s4o.print(s4o.indent_spaces + "else\n"); - s4o.indent_right(); - s4o.print(s4o.indent_spaces + "return value;\n"); - s4o.indent_left(); + s4o_incl.print(s4o_incl.indent_spaces + "if (value < "); + symbol->lower_limit->accept(*basedecl); + s4o_incl.print(")\n"); + s4o_incl.indent_right(); + s4o_incl.print(s4o_incl.indent_spaces + "return "); + symbol->lower_limit->accept(*basedecl); + s4o_incl.print(";\n"); + s4o_incl.indent_left(); + s4o_incl.print(s4o_incl.indent_spaces + "else if (value > "); + symbol->upper_limit->accept(*basedecl); + s4o_incl.print(")\n"); + s4o_incl.indent_right(); + s4o_incl.print(s4o_incl.indent_spaces + "return "); + symbol->upper_limit->accept(*basedecl); + s4o_incl.print(";\n"); + s4o_incl.indent_left(); + s4o_incl.print(s4o_incl.indent_spaces + "else\n"); + s4o_incl.indent_right(); + s4o_incl.print(s4o_incl.indent_spaces + "return value;\n"); + s4o_incl.indent_left(); default: break; } @@ -308,29 +309,15 @@ /* helper symbol for enumerated_specification->enumerated_spec_init */ /* enumerated_value_list ',' enumerated_value */ void *visit(enumerated_value_list_c *symbol) { + TRACE("enumerated_value_list_c"); print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); return NULL; } /* enumerated_type_name '#' identifier */ -void *visit(enumerated_value_c *symbol) { - if (current_typedefinition == enumerated_td) - current_type_name->accept(*basedecl); - else { - if (NULL == symbol->datatype) { - debug_c::print(symbol); - ERROR; - } - symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype); - if (NULL == type_name) { -// ERROR_MSG("generate_c does not support anonymous enumerated data types."); - } else - type_name->accept(*basedecl); - } - s4o_incl.print("__"); - symbol->value->accept(*basedecl); - return NULL; -} +/* Handled by generate_c_base_c class!! +void *visit(enumerated_value_c *symbol) {} +*/ /* identifier ':' array_spec_init */ void *visit(array_type_declaration_c *symbol) { @@ -393,6 +380,7 @@ /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *visit(array_specification_c *symbol) { + TRACE("array_specification_c"); switch (current_basetypedeclaration) { case arraybasetype_bd: symbol->non_generic_type_name->accept(*this); @@ -409,18 +397,12 @@ return NULL; } -/* helper symbol for array_specification */ -/* array_subrange_list ',' subrange */ -void *visit(array_subrange_list_c *symbol) { - print_list(symbol); - return NULL; -} /* TYPE type_declaration_list END_TYPE */ void *visit(data_type_declaration_c *symbol) { TRACE("data_type_declaration_c"); symbol->type_declaration_list->accept(*this); - s4o.print("\n\n"); + s4o_incl.print("\n\n"); return NULL; } @@ -441,11 +423,11 @@ s4o_incl.print(")\n"); if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) { - s4o.print("#define __CHECK_"); - current_type_name->accept(*this); - s4o.print(" __CHECK_"); + s4o_incl.print("#define __CHECK_"); + current_type_name->accept(*basedecl); + s4o_incl.print(" __CHECK_"); symbol->simple_spec_init->accept(*this); - s4o.print("\n"); + s4o_incl.print("\n"); } return NULL; @@ -565,7 +547,7 @@ s4o_incl.print(" "); symbol->structure_element_name->accept(*basedecl); s4o_incl.print(";\n"); - s4o_incl.print(s4o.indent_spaces); + s4o_incl.print(s4o_incl.indent_spaces); return NULL; } diff -r 06820d03a433 -r 300c27c08753 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Mon Jan 06 12:25:21 2014 +0000 +++ b/stage4/generate_iec/generate_iec.cc Tue Feb 11 10:55:27 2014 +0000 @@ -1422,6 +1422,10 @@ } +/* intermediate helper symbol for configuration_declaration */ +/* { global_var_declarations_list } */ +void *visit(global_var_declarations_list_c *symbol) {return print_list(symbol);} + /* helper symbol for configuration_declaration */ /*| resource_declaration_list resource_declaration */ void *visit(resource_declaration_list_c *symbol) {return print_list(symbol);}