# HG changeset patch # User mjsousa # Date 1405250818 -3600 # Node ID 8b2a31dea1319930cfad45698d2c00e8194347f0 # Parent 9e8e1ba5ca465d62391d4f41ba071189c9738f16 Add support for REF_TO derived datatypes (along with datatype verification) diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax/absyntax.def --- a/absyntax/absyntax.def Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax/absyntax.def Sun Jul 13 12:26:58 2014 +0100 @@ -335,7 +335,7 @@ /* identifier ':' array_spec_init */ SYM_REF2(array_type_declaration_c, identifier, array_spec_init) -/* array_specification [ASSIGN array_initialization} */ +/* array_specification [ASSIGN array_initialization] */ /* array_initialization may be NULL ! */ SYM_REF2(array_spec_init_c, array_specification, array_initialization) @@ -481,14 +481,14 @@ * Ref_Deref : 'DREF' '(' Ref_Name ')' ; */ -/* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ +/* REF_TO (non_generic_type_name | function_block_type_name) */ SYM_REF1(ref_spec_c, type_name) -/* For the moment, we do not support initialising reference data types */ -/* ref_spec_init: ref_spec; */ -/* SYM_REF0(ref_spec_init_c) */ - -/* ref_type_decl: identifier ':' ref_spec_init */ +/* ref_spec [ ASSIGN ref_initialization ]; */ +/* NOTE: ref_initialization may be NULL!! */ +SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) + +/* identifier ':' ref_spec_init */ SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/absyntax_utils.cc Sun Jul 13 12:26:58 2014 +0100 @@ -183,16 +183,10 @@ /********************************/ /* subrange_type_name ':' subrange_spec_init */ - void *visit(subrange_type_declaration_c *symbol) { - TRACE("subrange_type_declaration_c"); - type_symtable.insert(symbol->subrange_type_name, symbol->subrange_spec_init); - return NULL; - } - + void *visit(subrange_type_declaration_c *symbol) {type_symtable.insert(symbol->subrange_type_name, symbol->subrange_spec_init); return NULL;} /* enumerated_type_name ':' enumerated_spec_init */ void *visit(enumerated_type_declaration_c *symbol) { - TRACE("enumerated_type_declaration_c"); type_symtable.insert(symbol->enumerated_type_name, symbol); current_enumerated_type = symbol->enumerated_type_name; symbol->enumerated_spec_init->accept(*this); @@ -201,45 +195,17 @@ } /* enumerated_specification ASSIGN enumerated_value */ - void *visit(enumerated_spec_init_c *symbol) { - return symbol->enumerated_specification->accept(*this); - } - - + void *visit(enumerated_spec_init_c *symbol) {return symbol->enumerated_specification->accept(*this);} /* identifier ':' array_spec_init */ - void *visit(array_type_declaration_c *symbol) { - TRACE("array_type_declaration_c"); - type_symtable.insert(symbol->identifier, symbol->array_spec_init); - return NULL; - } - - + void *visit(array_type_declaration_c *symbol) {type_symtable.insert(symbol->identifier, symbol->array_spec_init); return NULL;} /* simple_type_name ':' simple_spec_init */ - void *visit(simple_type_declaration_c *symbol) { - TRACE("simple_type_declaration_c"); - type_symtable.insert(symbol->simple_type_name, symbol->simple_spec_init); - return NULL; - } - - + void *visit(simple_type_declaration_c *symbol) {type_symtable.insert(symbol->simple_type_name, symbol->simple_spec_init); return NULL;} /* structure_type_name ':' structure_specification */ - void *visit(structure_type_declaration_c *symbol) { - TRACE("structure_type_declaration_c"); - type_symtable.insert(symbol->structure_type_name, symbol->structure_specification); - return NULL; - } - - + void *visit(structure_type_declaration_c *symbol) {type_symtable.insert(symbol->structure_type_name, symbol->structure_specification); return NULL;} /* 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! */ - void *visit(string_type_declaration_c *symbol) { - TRACE("string_type_declaration_c"); - type_symtable.insert(symbol->string_type_name, symbol); - return NULL; -} + void *visit(string_type_declaration_c *symbol) {type_symtable.insert(symbol->string_type_name, symbol); return NULL;} + /* identifier ':' ref_spec_init */ + void *visit(ref_type_decl_c *symbol) {type_symtable.insert(symbol->ref_type_name, symbol); return NULL;} /*********************/ /* B 1.4 - Variables */ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/get_datatype_info.cc Sun Jul 13 12:26:58 2014 +0100 @@ -79,23 +79,25 @@ /* B 1.3.3 - Derived data types */ /********************************/ /* simple_type_name ':' simple_spec_init */ - void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name;} + void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name;} /* subrange_type_name ':' subrange_spec_init */ - void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name;} + void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name;} /* enumerated_type_name ':' enumerated_spec_init */ void *visit(enumerated_type_declaration_c *symbol) {return symbol->enumerated_type_name;} /* identifier ':' array_spec_init */ - void *visit(array_type_declaration_c *symbol) {return symbol->identifier;} + void *visit(array_type_declaration_c *symbol) {return symbol->identifier;} /* structure_type_name ':' structure_specification */ - void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name;} + void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name;} /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ - void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name;} + void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name;} + /* ref_type_decl: identifier ':' ref_spec_init */ + void *visit(ref_type_decl_c *symbol) {return symbol->ref_type_name;} /*****************************/ /* B 1.5.2 - Function Blocks */ /*****************************/ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ - void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name;} + void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name;} }; // get_datatype_id_c get_datatype_id_c *get_datatype_id_c::singleton = NULL; @@ -189,23 +191,25 @@ /* B 1.3.3 - Derived data types */ /********************************/ /* simple_type_name ':' simple_spec_init */ - void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name->accept(*this);} + void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name->accept(*this);} /* subrange_type_name ':' subrange_spec_init */ - void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name->accept(*this);} + void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name->accept(*this);} /* enumerated_type_name ':' enumerated_spec_init */ void *visit(enumerated_type_declaration_c *symbol) {return symbol->enumerated_type_name->accept(*this);} /* identifier ':' array_spec_init */ - void *visit(array_type_declaration_c *symbol) {return symbol->identifier->accept(*this);} + void *visit(array_type_declaration_c *symbol) {return symbol->identifier->accept(*this);} /* structure_type_name ':' structure_specification */ - void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name->accept(*this);} + void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name->accept(*this);} /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ - void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name->accept(*this);} + void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name->accept(*this);} + /* ref_type_decl: identifier ':' ref_spec_init */ + void *visit(ref_type_decl_c *symbol) {return symbol->ref_type_name->accept(*this);} /*****************************/ /* B 1.5.2 - Function Blocks */ /*****************************/ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ - void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name->accept(*this);} + void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name->accept(*this);} }; get_datatype_id_str_c *get_datatype_id_str_c::singleton = NULL; @@ -239,9 +243,15 @@ if (typeid(* first_type) == typeid(invalid_type_name_c)) {return false;} if (typeid(*second_type) == typeid(invalid_type_name_c)) {return false;} - if ((get_datatype_info_c::is_ANY_ELEMENTARY(first_type)) && + /* ANY_ELEMENTARY */ + if ((is_ANY_ELEMENTARY(first_type)) && (typeid(*first_type) == typeid(*second_type))) {return true;} + /* ANY_DERIVED */ + if (is_ref_to(first_type) && is_ref_to(second_type)) + return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )), + search_base_type_c::get_basetype_decl(get_ref_to(second_type))); + return (first_type == second_type); } @@ -258,6 +268,39 @@ + +/* returns the datatype the REF_TO datatype references/points to... */ +symbol_c *get_datatype_info_c::get_ref_to(symbol_c *type_symbol) { + ref_type_decl_c *type1 = dynamic_cast(type_symbol); + if (NULL != type1) type_symbol = type1->ref_spec_init; + + ref_spec_init_c *type2 = dynamic_cast(type_symbol); + if (NULL != type2) type_symbol = type2->ref_spec; + + ref_spec_c *type3 = dynamic_cast(type_symbol); + if (NULL != type3) return type3->type_name; + + return NULL; /* this is not a ref datatype!! */ +} + + + + + + +bool get_datatype_info_c::is_ref_to(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); + if (NULL == type_decl) {return false;} + + if (typeid(*type_decl) == typeid(ref_type_decl_c)) {return true;} /* identifier ':' ref_spec_init */ + if (typeid(*type_decl) == typeid(ref_spec_init_c)) {return true;} /* ref_spec [ ASSIGN ref_initialization ]; */ + if (typeid(*type_decl) == typeid(ref_spec_c)) {return true;} /* REF_TO (non_generic_type_name | function_block_type_name) */ + return false; +} + + + + bool get_datatype_info_c::is_sfc_initstep(symbol_c *type_symbol) { symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); if (NULL == type_decl) {return false;} @@ -267,8 +310,6 @@ - - bool get_datatype_info_c::is_sfc_step(symbol_c *type_symbol) { symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); if (NULL == type_decl) {return false;} @@ -360,10 +401,6 @@ - - - - bool get_datatype_info_c::is_ANY_ELEMENTARY(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (is_ANY_MAGNITUDE(type_symbol)) {return true;} diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/get_datatype_info.hh --- a/absyntax_utils/get_datatype_info.hh Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/get_datatype_info.hh Sun Jul 13 12:26:58 2014 +0100 @@ -59,13 +59,13 @@ public: static symbol_c *get_id (symbol_c *datatype); /* get the identifier (name) of the datatype); returns NULL if anonymous datatype! Does not work for elementary datatypes!*/ static const char *get_id_str(symbol_c *datatype); /* get the identifier (name) of the datatype); returns NULL if anonymous datatype! */ - + + static symbol_c *get_ref_to (symbol_c *type_symbol); // Defined in IEC 61131-3 v3 (returns the type that is being referenced/pointed to) + static bool is_type_equal(symbol_c *first_type, symbol_c *second_type); static bool is_type_valid(symbol_c *type); - - static bool is_ANY_REAL_literal(symbol_c *type_symbol); /* Can't we do away with this?? */ - static bool is_ANY_INT_literal (symbol_c *type_symbol); /* Can't we do away with this?? */ - + + static bool is_ref_to (symbol_c *type_symbol); // Defined in IEC 61131-3 v3 static bool is_sfc_initstep (symbol_c *type_symbol); static bool is_sfc_step (symbol_c *type_symbol); static bool is_function_block (symbol_c *type_symbol); @@ -73,8 +73,10 @@ static bool is_enumerated (symbol_c *type_symbol); static bool is_array (symbol_c *type_symbol); static bool is_structure (symbol_c *type_symbol); - + static bool is_ANY_REAL_literal(symbol_c *type_symbol); /* Can't we do away with this?? */ + static bool is_ANY_INT_literal (symbol_c *type_symbol); /* Can't we do away with this?? */ + static bool is_ANY_ELEMENTARY (symbol_c *type_symbol); static bool is_ANY_SAFEELEMENTARY (symbol_c *type_symbol); static bool is_ANY_ELEMENTARY_compatible (symbol_c *type_symbol); diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/search_base_type.cc Sun Jul 13 12:26:58 2014 +0100 @@ -361,7 +361,7 @@ string_type_declaration_size, string_type_declaration_init) // may be == NULL! */ -void *search_base_type_c::visit(string_type_declaration_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(string_type_declaration_c *symbol) {return (void *)symbol;} /* function_block_type_name ASSIGN structure_initialization */ @@ -373,6 +373,27 @@ +/* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ +// SYM_REF1(ref_spec_c, type_name) +void *search_base_type_c::visit(ref_spec_c *symbol) {return (void *)symbol;} + +/* For the moment, we do not support initialising reference data types */ +/* ref_spec_init: ref_spec [ ASSIGN ref_initialization ]; */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *search_base_type_c::visit(ref_spec_init_c *symbol) { + return symbol->ref_spec->accept(*this); +} + +/* ref_type_decl: identifier ':' ref_spec_init */ +// SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) +void *search_base_type_c::visit(ref_type_decl_c *symbol) { + this->current_basetype_name = symbol->ref_type_name; + return symbol->ref_spec_init->accept(*this); +} + + + /*****************************/ /* B 1.5.2 - Function Blocks */ /*****************************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/search_base_type.hh Sun Jul 13 12:26:58 2014 +0100 @@ -249,6 +249,13 @@ /* structure_initialization -> may be NULL ! */ void *visit(fb_spec_init_c *symbol); + /* REF_TO (non_generic_type_name | function_block_type_name) */ + void *visit(ref_spec_c *symbol); // Defined in IEC 61131-3 v3 + /* ref_spec [ ASSIGN ref_initialization ]; *//* NOTE: ref_initialization may be NULL!! */ + void *visit(ref_spec_init_c *symbol); // Defined in IEC 61131-3 v3 + /* identifier ':' ref_spec_init */ + void *visit(ref_type_decl_c *symbol); // Defined in IEC 61131-3 v3 + /*****************************/ /* B 1.5.2 - Function Blocks */ /*****************************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/spec_init_separator.cc --- a/absyntax_utils/spec_init_separator.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/spec_init_separator.cc Sun Jul 13 12:26:58 2014 +0100 @@ -171,6 +171,37 @@ return NULL; } + +/* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ +// SYM_REF1(ref_spec_c, type_name) +void *spec_init_sperator_c::visit(ref_spec_c *symbol) { + TRACE("spec_init_sperator_c::ref_spec_c"); + /* This visitor should never really be called, but there is no harm in including it... */ + switch (search_what) { + case search_spec: return symbol; + case search_init: return NULL; /* should never occur */ + } + ERROR; /* should never occur */ + return NULL; +} + + +/* For the moment, we do not support initialising reference data types */ +/* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *spec_init_sperator_c::visit(ref_spec_init_c *symbol) { + TRACE("spec_init_sperator_c::ref_spec_init_c"); + switch (search_what) { + case search_spec: return symbol->ref_spec; + case search_init: return symbol->ref_initialization; + } + ERROR; /* should never occur */ + return NULL; +} + + + /******************************************/ /* B 1.4.3 - Declaration & Initialisation */ /******************************************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 absyntax_utils/spec_init_separator.hh --- a/absyntax_utils/spec_init_separator.hh Sun Jul 06 23:31:08 2014 +0100 +++ b/absyntax_utils/spec_init_separator.hh Sun Jul 13 12:26:58 2014 +0100 @@ -98,7 +98,15 @@ //SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization) void *visit(fb_spec_init_c *symbol); + /* REF_TO (non_generic_type_name | function_block_type_name) */ + // SYM_REF1(ref_spec_c, type_name) + void *visit(ref_spec_c *symbol); + /* ref_spec [ ASSIGN ref_initialization ] */ + /* NOTE: ref_initialization may be NULL!! */ + // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) + void *visit(ref_spec_init_c *symbol); + /******************************************/ /* B 1.4.3 - Declaration & Initialisation */ /******************************************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 lib/C/iec_types_all.h --- a/lib/C/iec_types_all.h Sun Jul 06 23:31:08 2014 +0100 +++ b/lib/C/iec_types_all.h Sun Jul 13 12:26:58 2014 +0100 @@ -86,6 +86,8 @@ IEC_##type fvalue;\ } __IEC_##type##_p; + + #define __DECLARE_DERIVED_TYPE(type, base)\ typedef base type;\ typedef __IEC_##base##_t __IEC_##type##_t;\ @@ -121,6 +123,11 @@ } type;\ __DECLARE_COMPLEX_STRUCT(type) +#define __DECLARE_REFTO_TYPE(type, name)\ +typedef name * type;\ +__DECLARE_COMPLEX_STRUCT(type) + + /* Those typdefs clash with windows.h */ /* i.e. this file cannot be included aside windows.h */ __ANY(__DECLARE_IEC_TYPE) diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Sun Jul 06 23:31:08 2014 +0100 +++ b/stage1_2/iec_bison.yy Sun Jul 13 12:26:58 2014 +0100 @@ -3209,7 +3209,12 @@ ref_spec_init: /* defined in IEC 61131-3 v3 */ - ref_spec /* For the moment, we do not support initialising reference data types */ + ref_spec + {$$ = new ref_spec_init_c($1, NULL, locloc(@$));} +/* For the moment, we do not support initialising reference data types... +| ref_spec ASSIGN ... + {$$ = new ref_spec_init_c($1, $3, locloc(@$));} +*/ ; ref_type_decl: /* defined in IEC 61131-3 v3 */ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Sun Jul 06 23:31:08 2014 +0100 +++ b/stage1_2/iec_flex.ll Sun Jul 13 12:26:58 2014 +0100 @@ -1251,8 +1251,8 @@ /******************************************************/ -REF {if (get_opt_ref_operator()) return REF; else unput(0);} /* Keyword in IEC 61131-3 v3 */ -REF_TO {/*if (get_opt_ref_operator()) return REF_TO; else */unput(0);} /* Keyword in IEC 61131-3 v3 */ +REF {if (get_opt_ref_operator()) return REF; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ +REF_TO {if (get_opt_ref_operator()) return REF_TO; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ EN return EN; /* Keyword */ ENO return ENO; /* Keyword */ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sun Jul 13 12:26:58 2014 +0100 @@ -1108,6 +1108,33 @@ void *fill_candidate_datatypes_c::visit(fb_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->function_block_type_name, symbol->structure_initialization);} +/* REF_TO (non_generic_type_name | function_block_type_name) */ +// SYM_REF1(ref_spec_c, type_name) +void *fill_candidate_datatypes_c::visit(ref_spec_c *symbol) { + + // when parsing datatype declarations, fill_candidate_datatypes_c follows a top->down algorithm (see the comment in fill_type_decl() for an explanation) + add_datatype_to_candidate_list(symbol->type_name, base_type(symbol->type_name)); + symbol->type_name->accept(*this); /* The referenced/pointed to datatype! */ + + if (symbol->candidate_datatypes.size() == 0) // i.e., if this is an anonymous datatype! + add_datatype_to_candidate_list(symbol, base_type(symbol)); + + return NULL; +} + +/* For the moment, we do not support initialising reference data types */ +/* ref_spec [ ASSIGN ref_initialization ] */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *fill_candidate_datatypes_c::visit(ref_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->ref_spec, symbol->ref_initialization);} + +/* identifier ':' ref_spec_init */ +// SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) +void *fill_candidate_datatypes_c::visit(ref_type_decl_c *symbol) {return fill_type_decl(symbol, symbol->ref_type_name, symbol->ref_spec_init);} + + + + /*********************/ /* B 1.4 - Variables */ @@ -1835,7 +1862,7 @@ /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { symbol->exp->accept(*this); - /* we should really check whether the expression is merely a variable. For now, leave it for the future! */ + /* we should really check whether the expression is an lvalue. For now, leave it for the future! */ /* For now, we handle references (i.e. pointers) as ULINT datatypes! */ add_datatype_to_candidate_list(symbol, &get_datatype_info_c::ulint_type_name); return NULL; diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Sun Jul 06 23:31:08 2014 +0100 +++ b/stage3/fill_candidate_datatypes.hh Sun Jul 13 12:26:58 2014 +0100 @@ -172,7 +172,7 @@ /********************************/ // 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); void *visit(simple_spec_init_c *symbol); void *visit(subrange_type_declaration_c *symbol); void *visit(subrange_spec_init_c *symbol); @@ -196,6 +196,11 @@ // void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol); + + void *visit(ref_spec_c *symbol); // Defined in IEC 61131-3 v3 + void *visit(ref_spec_init_c *symbol); // Defined in IEC 61131-3 v3 + void *visit(ref_type_decl_c *symbol); // Defined in IEC 61131-3 v3 + /*********************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Sun Jul 13 12:26:58 2014 +0100 @@ -647,6 +647,37 @@ void *narrow_candidate_datatypes_c::visit(fb_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->function_block_type_name, symbol->structure_initialization);} +/* REF_TO (non_generic_type_name | function_block_type_name) */ +// SYM_REF1(ref_spec_c, type_name) +void *narrow_candidate_datatypes_c::visit(ref_spec_c *symbol) { + /* First handle the datatype being referenced (pointed to) */ + if (symbol->type_name->candidate_datatypes.size() == 1) { + symbol->type_name->datatype = symbol->type_name->candidate_datatypes[0]; + symbol->type_name->accept(*this); + } + + /* Now handle the reference datatype itself (i.e. the pointer) */ + // 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]; + + return NULL; +} + +/* For the moment, we do not support initialising reference data types */ +/* ref_spec [ ASSIGN ref_initialization ] */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *narrow_candidate_datatypes_c::visit(ref_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->ref_spec, symbol->ref_initialization);} + +/* identifier ':' ref_spec_init */ +// SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) +void *narrow_candidate_datatypes_c::visit(ref_type_decl_c *symbol) {return narrow_type_decl(symbol, symbol->ref_type_name, symbol->ref_spec_init);} + + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Sun Jul 06 23:31:08 2014 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Sun Jul 13 12:26:58 2014 +0100 @@ -179,6 +179,11 @@ // void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol); + + void *visit(ref_spec_c *symbol); // Defined in IEC 61131-3 v3 + void *visit(ref_spec_init_c *symbol); // Defined in IEC 61131-3 v3 + void *visit(ref_type_decl_c *symbol); // Defined in IEC 61131-3 v3 + /*********************/ /* B 1.4 - Variables */ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/stage4/generate_c/generate_c_st.cc Sun Jul 13 12:26:58 2014 +0100 @@ -464,7 +464,8 @@ /* B 3.1 - Expressions */ /***********************/ void *visit(ref_expression_c *symbol) { - s4o.print("((IEC_UDINT)"); + s4o.print("("); + s4o.print("(IEC_UDINT)"); if (this->is_variable_prefix_null()) { /* For code in FUNCTIONs */ s4o.print("&("); diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/stage4/generate_c/generate_c_typedecl.cc Sun Jul 13 12:26:58 2014 +0100 @@ -642,6 +642,48 @@ string_type_declaration_init) /* may be == NULL! */ #endif + + +/* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ +// SYM_REF1(ref_spec_c, type_name) +void *visit(ref_spec_c *symbol) { + return symbol->type_name->accept(*this); +} + +/* For the moment, we do not support initialising reference data types */ +/* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *visit(ref_spec_init_c *symbol) { + return symbol->ref_spec->accept(*this); +} + +/* ref_type_decl: identifier ':' ref_spec_init */ +// SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) +void *visit(ref_type_decl_c *symbol) { + TRACE("ref_type_decl_c"); + + current_type_name = NULL; + current_typedefinition = none_td; + + s4o_incl.print("__DECLARE_REFTO_TYPE("); + symbol->ref_type_name->accept(*basedecl); + s4o_incl.print(", "); + symbol->ref_spec_init->accept(*this); + s4o_incl.print(") "); + + current_type_name = NULL; + current_typedefinition = none_td; + + return NULL; +} + + + + + + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r 9e8e1ba5ca46 -r 8b2a31dea131 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Sun Jul 06 23:31:08 2014 +0100 +++ b/stage4/generate_iec/generate_iec.cc Sun Jul 13 12:26:58 2014 +0100 @@ -669,10 +669,18 @@ return NULL; } - /* For the moment, we do not support initialising reference data types */ -/* ref_spec_init: ref_spec; */ -/* SYM_REF0(ref_spec_init_c) */ +/* ref_spec_init: ref_spec [ ASSIGN ref_initialization ]; */ +/* NOTE: ref_initialization may be NULL!! */ +// SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) +void *visit(ref_spec_init_c *symbol) { + symbol->ref_spec->accept(*this); + if (symbol->ref_initialization != NULL) { + s4o.print(" := "); + symbol->ref_initialization->accept(*this); + } + return NULL; +} /* ref_type_decl: identifier ':' ref_spec_init */ // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init)