# HG changeset patch # User mjsousa # Date 1407490012 -3600 # Node ID d228aaa4d616c081a98bf75dfca9d125a75df5b8 # Parent 4369ce5e687fc0be55c2fd4989c681ae8767ff02 Introduce absyntax class for keyword ANY, and use REF_TO(ANY) as datatype of NULL literal. diff -r 4369ce5e687f -r d228aaa4d616 absyntax/absyntax.def --- a/absyntax/absyntax.def Wed Aug 06 10:43:15 2014 +0100 +++ b/absyntax/absyntax.def Fri Aug 08 10:26:52 2014 +0100 @@ -295,6 +295,26 @@ /* B.1.3.2 - Generic data types */ /********************************/ +/* ANY is currently only allowed when defining REF_TO ANY datatypes + * (equivalent to a (void *)). This is a non standard extension to the + * standard. + * Standard library function that use the generic datatypes (ANY_***) are + * currently handed as overloaded functions, and do not therefore require + * the use of the generic datatype keywords. + */ +SYM_REF0(generic_type_any_c) // ANY +/* +SYM_REF0(generic_type_any_derived_c) // ANY_DERIVED +SYM_REF0(generic_type_any_elementary_c) // ANY_ELEMENTARY +SYM_REF0(generic_type_any_magnitude_c) // ANY_MAGNITUDE +SYM_REF0(generic_type_any_num_c) // ANY_NUM +SYM_REF0(generic_type_any_real_c) // ANY_REAL +SYM_REF0(generic_type_any_int_c) // ANY_INT +SYM_REF0(generic_type_any_bit_c) // ANY_BIT +SYM_REF0(generic_type_any_string_c) // ANY_STRING +SYM_REF0(generic_type_any_date_c) // ANY_DATE +*/ + /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ diff -r 4369ce5e687f -r d228aaa4d616 absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Wed Aug 06 10:43:15 2014 +0100 +++ b/absyntax_utils/get_datatype_info.cc Fri Aug 08 10:26:52 2014 +0100 @@ -238,20 +238,27 @@ } +/* Returns true if both datatypes are identicial. + * WARING: When handling REF_TO datatypes, it may return 'true' even though + * the datatypes are not identicial. This occurs when at least one of the + * datatypes if a ref_to_any_c, which os equivalent to a (void *), and the + * other datatype is any REF_TO datatype (including a ref_to_any_c). + */ bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) { - if ((NULL == first_type) || (NULL == second_type)) {return false;} - if (typeid(* first_type) == typeid(invalid_type_name_c)) {return false;} - if (typeid(*second_type) == typeid(invalid_type_name_c)) {return false;} - + if (!is_type_valid( first_type)) {return false;} + if (!is_type_valid(second_type)) {return false;} + + /* GENERIC DATATYPES */ + /* For the moment, we only support the ANY generic datatype! */ + if ((is_ANY_generic_type( first_type)) || + (is_ANY_generic_type(second_type))) {return true;} + /* 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)) { - /* if either of them is the constant 'NULL' then we consider them 'equal', as NULL is compatible to a REF_TO any datatype! */ - if (typeid(* first_type) == typeid(ref_value_null_literal_c)) {return true;} - if (typeid(*second_type) == typeid(ref_value_null_literal_c)) {return true;} 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))); } @@ -260,7 +267,6 @@ } - bool get_datatype_info_c::is_type_valid(symbol_c *type) { if (NULL == type) {return false;} if (typeid(*type) == typeid(invalid_type_name_c)) {return false;} @@ -299,7 +305,6 @@ 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) */ - if (typeid(*type_decl) == typeid(ref_value_null_literal_c)) {return true;} /* REF_TO (non_generic_type_name | function_block_type_name) */ return false; } @@ -404,6 +409,12 @@ +bool get_datatype_info_c::is_ANY_generic_type(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(generic_type_any_c)) {return true;} /* The ANY keyword! */ + return false; +} bool get_datatype_info_c::is_ANY_ELEMENTARY(symbol_c *type_symbol) { diff -r 4369ce5e687f -r d228aaa4d616 absyntax_utils/get_datatype_info.hh --- a/absyntax_utils/get_datatype_info.hh Wed Aug 06 10:43:15 2014 +0100 +++ b/absyntax_utils/get_datatype_info.hh Fri Aug 08 10:26:52 2014 +0100 @@ -62,6 +62,12 @@ 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) + /* Returns true if both datatypes are identicial. + * WARING: When handling REF_TO datatypes, it may return 'true' even though + * the datatypes are not identicial. This occurs when at least one of the + * datatypes if a ref_to_any_c, which os equivalent to a (void *), and the + * other datatype is any REF_TO datatype (including a ref_to_any_c). + */ static bool is_type_equal(symbol_c *first_type, symbol_c *second_type); static bool is_type_valid(symbol_c *type); @@ -77,10 +83,14 @@ 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_generic_type (symbol_c *type_symbol); + + //static bool is_ANY_ELEMENTARY_generic_type (symbol_c *type_symbol); 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); + //static bool is_ANY_MAGNITUDE_generic_type (symbol_c *type_symbol); static bool is_ANY_MAGNITUDE (symbol_c *type_symbol); static bool is_ANY_SAFEMAGNITUDE (symbol_c *type_symbol); static bool is_ANY_MAGNITUDE_compatible (symbol_c *type_symbol); @@ -89,6 +99,7 @@ static bool is_ANY_signed_SAFEMAGNITUDE (symbol_c *type_symbol); static bool is_ANY_signed_MAGNITUDE_compatible (symbol_c *type_symbol); + //static bool is_ANY_NUM_generic_type (symbol_c *type_symbol); static bool is_ANY_NUM (symbol_c *type_symbol); static bool is_ANY_SAFENUM (symbol_c *type_symbol); static bool is_ANY_NUM_compatible (symbol_c *type_symbol); @@ -97,6 +108,7 @@ static bool is_ANY_signed_SAFENUM (symbol_c *type_symbol); static bool is_ANY_signed_NUM_compatible (symbol_c *type_symbol); + //static bool is_ANY_INT_generic_type (symbol_c *type_symbol); static bool is_ANY_INT (symbol_c *type_symbol); static bool is_ANY_SAFEINT (symbol_c *type_symbol); static bool is_ANY_INT_compatible (symbol_c *type_symbol); @@ -109,6 +121,7 @@ static bool is_ANY_unsigned_SAFEINT (symbol_c *type_symbol); static bool is_ANY_unsigned_INT_compatible (symbol_c *type_symbol); + //static bool is_ANY_REAL_generic_type (symbol_c *type_symbol); static bool is_ANY_REAL (symbol_c *type_symbol); static bool is_ANY_SAFEREAL (symbol_c *type_symbol); static bool is_ANY_REAL_compatible (symbol_c *type_symbol); @@ -121,10 +134,12 @@ static bool is_SAFEBOOL (symbol_c *type_symbol); static bool is_BOOL_compatible (symbol_c *type_symbol); + //static bool is_ANY_BIT_generic_type (symbol_c *type_symbol); static bool is_ANY_BIT (symbol_c *type_symbol); static bool is_ANY_SAFEBIT (symbol_c *type_symbol); static bool is_ANY_BIT_compatible (symbol_c *type_symbol); + //static bool is_ANY_DATE_generic_type (symbol_c *type_symbol); static bool is_ANY_DATE (symbol_c *type_symbol); static bool is_ANY_SAFEDATE (symbol_c *type_symbol); static bool is_ANY_DATE_compatible (symbol_c *type_symbol); @@ -133,6 +148,7 @@ static bool is_SAFETIME (symbol_c *type_symbol); static bool is_TIME_compatible (symbol_c *type_symbol); + //static bool is_ANY_STRING_generic_type (symbol_c *type_symbol); static bool is_ANY_STRING (symbol_c *type_symbol); static bool is_ANY_SAFESTRING (symbol_c *type_symbol); static bool is_ANY_STRING_compatible (symbol_c *type_symbol); diff -r 4369ce5e687f -r d228aaa4d616 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Wed Aug 06 10:43:15 2014 +0100 +++ b/absyntax_utils/search_base_type.cc Fri Aug 08 10:26:52 2014 +0100 @@ -133,12 +133,6 @@ /*********************/ /* B 1.2 - Constants */ /*********************/ -/*********************************/ -/* B 1.2.XX - Reference Literals */ -/*********************************/ -/* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */ -/* See the comment in fill_candidate_datatypes_c::visit(ref_value_null_literal_c) for reason why we use this symbol as a datatype! */ -void *search_base_type_c::visit(ref_value_null_literal_c *symbol) {return (void *)symbol;} /******************************/ /* B 1.2.1 - Numeric Literals */ @@ -218,6 +212,11 @@ void *search_base_type_c::visit(safewstring_type_name_c *symbol) {return (void *)symbol;} /********************************/ +/* B.1.3.2 - Generic data types */ +/********************************/ +void *search_base_type_c::visit(generic_type_any_c *symbol) {return (void *)symbol;} + +/********************************/ /* B 1.3.3 - Derived data types */ /********************************/ /* simple_type_name ':' simple_spec_init */ diff -r 4369ce5e687f -r d228aaa4d616 absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Wed Aug 06 10:43:15 2014 +0100 +++ b/absyntax_utils/search_base_type.hh Fri Aug 08 10:26:52 2014 +0100 @@ -94,12 +94,6 @@ /*********************/ /* B 1.2 - Constants */ /*********************/ - /*********************************/ - /* B 1.2.XX - Reference Literals */ - /*********************************/ - /* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */ - void *visit(ref_value_null_literal_c *symbol); - /******************************/ /* B 1.2.1 - Numeric Literals */ /******************************/ @@ -176,6 +170,11 @@ void *visit(safewstring_type_name_c *symbol); /********************************/ + /* B.1.3.2 - Generic data types */ + /********************************/ + void *visit(generic_type_any_c *symbol); + + /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ /* simple_type_name ':' simple_spec_init */ diff -r 4369ce5e687f -r d228aaa4d616 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Wed Aug 06 10:43:15 2014 +0100 +++ b/stage3/fill_candidate_datatypes.cc Fri Aug 08 10:26:52 2014 +0100 @@ -720,15 +720,10 @@ * However, doing this for all NULL constants that may show up is probably a little too crazy, just for * the 'pleasure' of following the standard fill/narrow algorithm. * - * I have therefore opted to handle this as a special case: We use the ref_value_null_literal_c symbol itself as the NULL datatype! - * This implies the following changes: - * - We change the get_datatype_info_c::is_type_equal() to take the NULL datatype into account - * - We change the get_datatype_info_c::is_ref_to() to take the NULL datatype into account - * - We change the fill_candidate_datatypes_c::visit(assignment_statement_c) to make sure it uses the datatype of the lvalue - * as the datatype of the assignment statement - * - We search_base_type_c::get_basetype_decl + * I have therefore opted to handle this as a special case: + * We use the ref_spec_c, pointing to a generic_type_any_c, as a pointer to ANY (basically, a void *) */ - add_datatype_to_candidate_list(symbol, symbol); + add_datatype_to_candidate_list(symbol, new ref_spec_c(new generic_type_any_c())); return NULL; } diff -r 4369ce5e687f -r d228aaa4d616 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Wed Aug 06 10:43:15 2014 +0100 +++ b/stage4/generate_iec/generate_iec.cc Fri Aug 08 10:26:52 2014 +0100 @@ -434,6 +434,10 @@ void *visit(safestring_type_name_c *symbol) {s4o.print("SAFESTRING"); return NULL;} void *visit(safewstring_type_name_c *symbol) {s4o.print("SAFEWSTRING"); return NULL;} +/********************************/ +/* B.1.3.2 - Generic data types */ +/********************************/ +void *visit(generic_type_any_c *symbol) {s4o.print("ANY"); return NULL;} /********************************/ /* B 1.3.3 - Derived data types */