# HG changeset patch # User Mario de Sousa # Date 1301511212 -3600 # Node ID 90782e241346c55cb46e7540f9a8f8abc5042953 # Parent 8ffa211b7f9a7f19ef4ca0248abe5482b62cc2a0 Huge change. diff -r 8ffa211b7f9a -r 90782e241346 absyntax/absyntax.def --- a/absyntax/absyntax.def Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax/absyntax.def Wed Mar 30 19:53:32 2011 +0100 @@ -46,7 +46,7 @@ /*****************************************************************/ /*****************************************************************/ /* */ -/* Symbols defined in: */ +/* safe Symbols are defined in: */ /* PLCopen - Technical Committee 5 */ /* Safety Software Technical Specification, */ /* Part 1: Concepts and Function Blocks, */ @@ -60,10 +60,6 @@ -SYM_REF0(safebool_type_name_c) - - - /*****************************************************************/ @@ -129,14 +125,59 @@ /* Note: * We do not have signed_integer_c and signed_real_c classes. * These are stored in the parse tree as a integer_c or real_c - * preceded by a unary minus operator. + * preceded by a unary minus operator if they are inside an expression, + * or a neg_integer_c and neg_real_c when used outside an ST expression. */ /* Not required: SYM_TOKEN(signed_integer_c) SYM_TOKEN(signed_real_c) */ -SYM_REF1(neg_literal_c, exp) +/* NOTE: literal __values__ are stored directly in classes such as: + * - real_c + * - integer_c + * - binary_integer_c + * - etc... + * + * However, for both the real_c and the integer_c, if they are preceded + * by a '-' negation sign, they are further encapsulated inside + * a neg_literal_c (i.e. the neg_literal_c will point to the + * real_c or integer_c with the value being negated. + * neg_literal_c -> integer_literal_c + * OR + * neg_literal_c -> real_literal_c + * + * In the semantic verification and code generation stages of the compiler, + * the integer_c is treated as a basic (undefined) data type, since an integer + * constant may be used as a BYTE, BOOLEAN, REAL, etc..., depending on the + * context in which it is used. + * However, an integer_c that is preceded by a '-' may not be used + * as an ANY_BIT data type (BYTE, BOOLEAN, WORD, ...). + * We must therefore be able to determine, holding a simple pointer + * to an integer_c, if that integer_c value is preceded by a '-'. + * However, since the neg_literal_c points to the integer_c, and not + * vice-versa, we can't determine that. + * There are 3 simple ways of working around this: + * - change the order of the pointers: + * have the integer_c and real_c point to the neg_literal_c + * - maintain the order of the pointers, and + * add redundant info to the integer_c and real_c + * - replace the neg_literal_c with two distinc classes + * (neg_integer_c and neg_real_c), one for each + * lietral type. This means that we can now treat + * each of these classes as an unknown data type + * just as we do with the integer_c and real_c. + * + * The second option is simply ugly. + * and the first has a serious drawback: when generating code it is + * easier to encapsulate the real or integer values inside prefix + * and postfix symbols (e.g. NEG() - with postfix ')' ) + * if we keep the pointer order as is. + * + * For the above reasoning, we use the third option. + */ +SYM_REF1(neg_real_c, exp) +SYM_REF1(neg_integer_c, exp) /* Not required: SYM_REF2(numeric_literal_c, type, value) @@ -144,6 +185,8 @@ SYM_REF2(integer_literal_c, type, value) SYM_REF2(real_literal_c, type, value) SYM_REF2(bit_string_literal_c, type, value) +/* A typed or untyped boolean literal... */ +/* type may be NULL */ SYM_REF2(boolean_literal_c, type, value) /* helper class for boolean_literal_c */ @@ -168,7 +211,7 @@ /* B 1.2.3.1 - Duration */ /************************/ SYM_REF0(neg_time_c) -SYM_REF2(duration_c, neg, interval) +SYM_REF3(duration_c, type_name, neg, interval) SYM_TOKEN(fixed_point_c) SYM_REF2(days_c, days, hours) SYM_REF2(hours_c, hours, minutes) @@ -180,11 +223,11 @@ /************************************/ /* B 1.2.3.2 - Time of day and Date */ /************************************/ -SYM_REF1(time_of_day_c, daytime) +SYM_REF2(time_of_day_c, type_name, daytime) SYM_REF3(daytime_c, day_hour, day_minute, day_second) -SYM_REF1(date_c, date_literal) +SYM_REF2(date_c, type_name, date_literal) SYM_REF3(date_literal_c, year, month, day) -SYM_REF2(date_and_time_c, date_literal, daytime) +SYM_REF3(date_and_time_c, type_name, date_literal, daytime) /**********************/ @@ -215,10 +258,31 @@ SYM_REF0(string_type_name_c) SYM_REF0(wstring_type_name_c) -/* -SYM_REF0(constant_int_type_name_c) -SYM_REF0(constant_real_type_name_c) -*/ + /*****************************************************************/ + /* Keywords defined in "Safety Software Technical Specification" */ + /*****************************************************************/ + +SYM_REF0(safetime_type_name_c) +SYM_REF0(safebool_type_name_c) +SYM_REF0(safesint_type_name_c) +SYM_REF0(safeint_type_name_c) +SYM_REF0(safedint_type_name_c) +SYM_REF0(safelint_type_name_c) +SYM_REF0(safeusint_type_name_c) +SYM_REF0(safeuint_type_name_c) +SYM_REF0(safeudint_type_name_c) +SYM_REF0(safeulint_type_name_c) +SYM_REF0(safereal_type_name_c) +SYM_REF0(safelreal_type_name_c) +SYM_REF0(safedate_type_name_c) +SYM_REF0(safetod_type_name_c) +SYM_REF0(safedt_type_name_c) +SYM_REF0(safebyte_type_name_c) +SYM_REF0(safeword_type_name_c) +SYM_REF0(safedword_type_name_c) +SYM_REF0(safelword_type_name_c) +SYM_REF0(safestring_type_name_c) +SYM_REF0(safewstring_type_name_c) /********************************/ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/get_sizeof_datatype.cc --- a/absyntax_utils/get_sizeof_datatype.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/get_sizeof_datatype.cc Wed Mar 30 19:53:32 2011 +0100 @@ -147,14 +147,19 @@ * If 'x' were a SINT, then the '30' would have to be a SINT too! */ -/* NOTE: all integer and real literal tokens will always be positive (i.e. no leading '-') +/* NOTE: all integer_c and real_c tokens will always be positive (i.e. no leading '-') * due to the way the source code is parsed by iec.flex. */ void *get_sizeof_datatype_c::visit(real_c *symbol) { return _encode_int(32); } -/* NOTE: all integer and real literal tokens will always be positive (i.e. no leading '-') +void *get_sizeof_datatype_c::visit(neg_real_c *symbol) { + return symbol->exp->accept(*this); +} + + +/* NOTE: all integer_c and real_c literal tokens will always be positive (i.e. no leading '-') * due to the way the source code is parsed by iec.flex. */ void *get_sizeof_datatype_c::visit(integer_c *symbol) { @@ -224,8 +229,13 @@ } -/* NOTE: all integer and real literal tokens will always be positive (i.e. no leading '-') - * due to the way the source code is parsed by iec.flex. +void *get_sizeof_datatype_c::visit(neg_integer_c *symbol) { + return symbol->exp->accept(*this); +} + + +/* NOTE: all binary_integer_c tokens will always be positive (i.e. no leading '-') + * due to the syntax definition of IEC 61131-3. */ void *get_sizeof_datatype_c::visit(binary_integer_c *symbol) { const char *sval = symbol->value; @@ -255,8 +265,8 @@ } -/* NOTE: all integer and real literal tokens will always be positive (i.e. no leading '-') - * due to the way the source code is parsed by iec.flex. +/* NOTE: all octal_integer_c tokens will always be positive (i.e. no leading '-') + * due to the syntax definition of IEC 61131-3. */ void *get_sizeof_datatype_c::visit(octal_integer_c *symbol) { const char *sval = symbol->value; @@ -287,8 +297,8 @@ } -/* NOTE: all integer and real literal tokens will always be positive (i.e. no leading '-') - * due to the way the source code is parsed by iec.flex. +/* NOTE: all hex_integer_c tokens will always be positive (i.e. no leading '-') + * due to the syntax definition of IEC 61131-3. */ void *get_sizeof_datatype_c::visit(hex_integer_c *symbol) { const char *sval = symbol->value; @@ -327,27 +337,27 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ -// void *get_sizeof_datatype_c::visit(time_type_name_c *symbol) {return _encode_int(0); } -void *get_sizeof_datatype_c::visit(bool_type_name_c *symbol) {return _encode_int(1); } -void *get_sizeof_datatype_c::visit(sint_type_name_c *symbol) {return _encode_int(8); } -void *get_sizeof_datatype_c::visit(int_type_name_c *symbol) {return _encode_int(16);} -void *get_sizeof_datatype_c::visit(dint_type_name_c *symbol) {return _encode_int(32);} -void *get_sizeof_datatype_c::visit(lint_type_name_c *symbol) {return _encode_int(64);} -void *get_sizeof_datatype_c::visit(usint_type_name_c *symbol) {return _encode_int(8); } -void *get_sizeof_datatype_c::visit(uint_type_name_c *symbol) {return _encode_int(16);} -void *get_sizeof_datatype_c::visit(udint_type_name_c *symbol) {return _encode_int(32);} -void *get_sizeof_datatype_c::visit(ulint_type_name_c *symbol) {return _encode_int(64);} -void *get_sizeof_datatype_c::visit(real_type_name_c *symbol) {return _encode_int(32);} -void *get_sizeof_datatype_c::visit(lreal_type_name_c *symbol) {return _encode_int(64);} -// void *get_sizeof_datatype_c::visit(date_type_name_c *symbol) {return _encode_int(0); } -// void *get_sizeof_datatype_c::visit(tod_type_name_c *symbol) {return _encode_int(0); } -// void *get_sizeof_datatype_c::visit(dt_type_name_c *symbol) {return _encode_int(0); } -void *get_sizeof_datatype_c::visit(byte_type_name_c *symbol) {return _encode_int(8); } -void *get_sizeof_datatype_c::visit(word_type_name_c *symbol) {return _encode_int(16);} -void *get_sizeof_datatype_c::visit(dword_type_name_c *symbol) {return _encode_int(32);} -void *get_sizeof_datatype_c::visit(lword_type_name_c *symbol) {return _encode_int(64);} -// void *get_sizeof_datatype_c::visit(string_type_name_c *symbol) {return _encode_int(0); } -// void *get_sizeof_datatype_c::visit(wstring_type_name_c *symbol) {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(time_type_name_c *symbol) {return _encode_int(0); } +void *get_sizeof_datatype_c::visit(bool_type_name_c *symbol) {return _encode_int(1); } +void *get_sizeof_datatype_c::visit(sint_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(int_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(dint_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(lint_type_name_c *symbol) {return _encode_int(64);} +void *get_sizeof_datatype_c::visit(usint_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(uint_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(udint_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(ulint_type_name_c *symbol) {return _encode_int(64);} +void *get_sizeof_datatype_c::visit(real_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(lreal_type_name_c *symbol) {return _encode_int(64);} +// void *get_sizeof_datatype_c::visit(date_type_name_c *symbol) {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(tod_type_name_c *symbol) {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(dt_type_name_c *symbol) {return _encode_int(0); } +void *get_sizeof_datatype_c::visit(byte_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(word_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(dword_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(lword_type_name_c *symbol) {return _encode_int(64);} +// void *get_sizeof_datatype_c::visit(string_type_name_c *symbol) {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(wstring_type_name_c *symbol) {return _encode_int(0); } /******************************************************/ /* Extensions to the base standard as defined in */ /* "Safety Software Technical Specification, */ @@ -355,7 +365,28 @@ /* Version 1.0 – Official Release" */ /* by PLCopen - Technical Committee 5 - 2006-01-31 */ /******************************************************/ -void *get_sizeof_datatype_c::visit(safebool_type_name_c *symbol) {return _encode_int(1);} +// void *get_sizeof_datatype_c::visit(safetime_type_name_c *symbol); {return _encode_int(0); } +void *get_sizeof_datatype_c::visit(safebool_type_name_c *symbol) {return _encode_int(1); } +void *get_sizeof_datatype_c::visit(safesint_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(safeint_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(safedint_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(safelint_type_name_c *symbol) {return _encode_int(64);} +void *get_sizeof_datatype_c::visit(safeusint_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(safeuint_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(safeudint_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(safeulint_type_name_c *symbol) {return _encode_int(64);} +void *get_sizeof_datatype_c::visit(safereal_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(safelreal_type_name_c *symbol) {return _encode_int(64);} +// void *get_sizeof_datatype_c::visit(safedate_type_name_c *symbol); {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(safetod_type_name_c *symbol); {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(safedt_type_name_c *symbol); {return _encode_int(0); } +void *get_sizeof_datatype_c::visit(safebyte_type_name_c *symbol) {return _encode_int(8); } +void *get_sizeof_datatype_c::visit(safeword_type_name_c *symbol) {return _encode_int(16);} +void *get_sizeof_datatype_c::visit(safedword_type_name_c *symbol) {return _encode_int(32);} +void *get_sizeof_datatype_c::visit(safelword_type_name_c *symbol) {return _encode_int(64);} +// void *get_sizeof_datatype_c::visit(safestring_type_name_c *symbol); {return _encode_int(0); } +// void *get_sizeof_datatype_c::visit(safewstring_type_name_c *symbol); {return _encode_int(0); } + /********************************/ /* B 1.3.3 - Derived data types */ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/get_sizeof_datatype.hh --- a/absyntax_utils/get_sizeof_datatype.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/get_sizeof_datatype.hh Wed Mar 30 19:53:32 2011 +0100 @@ -91,7 +91,9 @@ * If 'x' were a SINT, then the '30' would have to be a SINT too! */ void *visit(real_c *symbol); + void *visit(neg_real_c *symbol); void *visit(integer_c *symbol); + void *visit(neg_integer_c *symbol); void *visit(binary_integer_c *symbol); void *visit(octal_integer_c *symbol); void *visit(hex_integer_c *symbol); @@ -128,7 +130,27 @@ /* Version 1.0 – Official Release" */ /* by PLCopen - Technical Committee 5 - 2006-01-31 */ /******************************************************/ +// void *visit(safetime_type_name_c *symbol); void *visit(safebool_type_name_c *symbol); + void *visit(safesint_type_name_c *symbol); + void *visit(safeint_type_name_c *symbol); + void *visit(safedint_type_name_c *symbol); + void *visit(safelint_type_name_c *symbol); + void *visit(safeusint_type_name_c *symbol); + void *visit(safeuint_type_name_c *symbol); + void *visit(safeudint_type_name_c *symbol); + void *visit(safeulint_type_name_c *symbol); + void *visit(safereal_type_name_c *symbol); + void *visit(safelreal_type_name_c *symbol); +// void *visit(safedate_type_name_c *symbol); +// void *visit(safetod_type_name_c *symbol); +// void *visit(safedt_type_name_c *symbol) ; + void *visit(safebyte_type_name_c *symbol); + void *visit(safeword_type_name_c *symbol); + void *visit(safedword_type_name_c *symbol); + void *visit(safelword_type_name_c *symbol); +// void *visit(safestring_type_name_c *symbol); +// void *visit(safewstring_type_name_c *symbol); /********************************/ /* B 1.3.3 - Derived data types */ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/search_base_type.cc Wed Mar 30 19:53:32 2011 +0100 @@ -85,10 +85,14 @@ * If 'x' were a SINT, then the '30' would have to be a SINT too! */ void *search_base_type_c::visit(real_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(neg_real_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(integer_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(neg_integer_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(binary_integer_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(octal_integer_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(hex_integer_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(boolean_true_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(boolean_false_c *symbol) {return (void *)symbol;} /***********************************/ @@ -115,10 +119,8 @@ void *search_base_type_c::visit(lword_type_name_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(string_type_name_c *symbol) {return (void *)symbol;} void *search_base_type_c::visit(wstring_type_name_c *symbol) {return (void *)symbol;} -/* -void *search_base_type_c::visit(constant_int_type_name_c *symbol) {return (void *)symbol;} -void *search_base_type_c::visit(constant_real_type_name_c *symbol) {return (void *)symbol;} -*/ + + /******************************************************/ /* Extensions to the base standard as defined in */ /* "Safety Software Technical Specification, */ @@ -126,7 +128,28 @@ /* Version 1.0 – Official Release" */ /* by PLCopen - Technical Committee 5 - 2006-01-31 */ /******************************************************/ -void *search_base_type_c::visit(safebool_type_name_c *symbol) {return (void *)symbol;} + +void *search_base_type_c::visit(safetime_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safebool_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safesint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safedint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safelint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeusint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeuint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeudint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeulint_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safereal_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safelreal_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safedate_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safetod_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safedt_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safebyte_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safeword_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safedword_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safelword_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safestring_type_name_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(safewstring_type_name_c *symbol) {return (void *)symbol;} /********************************/ /* B 1.3.3 - Derived data types */ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/search_base_type.hh Wed Mar 30 19:53:32 2011 +0100 @@ -71,10 +71,14 @@ * If 'x' were a SINT, then the '30' would have to be a SINT too! */ void *visit(real_c *symbol); + void *visit(neg_real_c *symbol); void *visit(integer_c *symbol); + void *visit(neg_integer_c *symbol); void *visit(binary_integer_c *symbol); void *visit(octal_integer_c *symbol); void *visit(hex_integer_c *symbol); + void *visit(boolean_true_c *symbol); + void *visit(boolean_false_c *symbol); /***********************************/ @@ -102,11 +106,6 @@ void *visit(string_type_name_c *symbol); void *visit(wstring_type_name_c *symbol); -/* - void *visit(constant_int_type_name_c *symbol); - void *visit(constant_real_type_name_c *symbol); -*/ - /******************************************************/ /* Extensions to the base standard as defined in */ /* "Safety Software Technical Specification, */ @@ -114,7 +113,27 @@ /* Version 1.0 – Official Release" */ /* by PLCopen - Technical Committee 5 - 2006-01-31 */ /******************************************************/ + void *visit(safetime_type_name_c *symbol); void *visit(safebool_type_name_c *symbol); + void *visit(safesint_type_name_c *symbol); + void *visit(safeint_type_name_c *symbol); + void *visit(safedint_type_name_c *symbol); + void *visit(safelint_type_name_c *symbol); + void *visit(safeusint_type_name_c *symbol); + void *visit(safeuint_type_name_c *symbol); + void *visit(safeudint_type_name_c *symbol); + void *visit(safeulint_type_name_c *symbol); + void *visit(safereal_type_name_c *symbol); + void *visit(safelreal_type_name_c *symbol); + void *visit(safedate_type_name_c *symbol); + void *visit(safetod_type_name_c *symbol); + void *visit(safedt_type_name_c *symbol) ; + void *visit(safebyte_type_name_c *symbol); + void *visit(safeword_type_name_c *symbol); + void *visit(safedword_type_name_c *symbol); + void *visit(safelword_type_name_c *symbol); + void *visit(safestring_type_name_c *symbol); + void *visit(safewstring_type_name_c *symbol); /********************************/ /* B 1.3.3 - Derived data types */ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/search_constant_type.cc --- a/absyntax_utils/search_constant_type.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/search_constant_type.cc Wed Mar 30 19:53:32 2011 +0100 @@ -59,7 +59,9 @@ * If 'x' were a SINT, then the '30' would have to be a SINT too! */ void *search_constant_type_c::visit(real_c *symbol) {return (void *)symbol;} +void *search_constant_type_c::visit(neg_real_c *symbol) {return (void *)symbol;} void *search_constant_type_c::visit(integer_c *symbol) {return (void *)symbol;} +void *search_constant_type_c::visit(neg_integer_c *symbol) {return (void *)symbol;} void *search_constant_type_c::visit(binary_integer_c *symbol) {return (void *)symbol;} void *search_constant_type_c::visit(octal_integer_c *symbol) {return (void *)symbol;} void *search_constant_type_c::visit(hex_integer_c *symbol) {return (void *)symbol;} @@ -90,7 +92,7 @@ /* B 1.2.3.1 - Duration */ /************************/ void *search_constant_type_c::visit(neg_time_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(duration_c *symbol) {return (void *)&time_type_name;} +void *search_constant_type_c::visit(duration_c *symbol) {return (void *)(symbol->type_name);} void *search_constant_type_c::visit(fixed_point_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ void *search_constant_type_c::visit(days_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ void *search_constant_type_c::visit(hours_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ @@ -101,11 +103,12 @@ /************************************/ /* B 1.2.3.2 - Time of day and Date */ /************************************/ -void *search_constant_type_c::visit(time_of_day_c *symbol) {return (void *)&tod_type_name;} +void *search_constant_type_c::visit(time_of_day_c *symbol) {return (void *)(symbol->type_name);} void *search_constant_type_c::visit(daytime_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(date_c *symbol) {return (void *)&date_type_name;} +void *search_constant_type_c::visit(date_c *symbol) {return (void *)(symbol->type_name);} void *search_constant_type_c::visit(date_literal_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(date_and_time_c *symbol) {return (void *)&dt_type_name;} +void *search_constant_type_c::visit(date_and_time_c *symbol) {return (void *)(symbol->type_name);} + real_type_name_c search_constant_type_c::real_type_name; sint_type_name_c search_constant_type_c::sint_type_name; @@ -129,10 +132,16 @@ time_type_name_c search_constant_type_c::time_type_name; int_type_name_c search_constant_type_c::int_type_name; -/* -constant_real_type_name_c search_constant_type_c::constant_real_type_name; -constant_int_type_name_c search_constant_type_c::constant_int_type_name; -*/ +// safebool_type_name_c search_constant_type_c::safebool_type_name; + /* The following is required because the expression (TOD_var - TOD_var) will result in a data type + * (in this case, TIME) that is neither of the expression elements... + */ +safetime_type_name_c search_constant_type_c::safetime_type_name; +safetod_type_name_c search_constant_type_c::safetod_type_name; +safedt_type_name_c search_constant_type_c::safedt_type_name; + + + /* temporarily here until we remove the st_code_gen.c and il_code_gen.c files... */ /* It should then move to search_expression_type_c */ integer_c search_constant_type_c::integer("1"); diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/search_constant_type.hh --- a/absyntax_utils/search_constant_type.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/search_constant_type.hh Wed Mar 30 19:53:32 2011 +0100 @@ -67,10 +67,6 @@ static time_type_name_c time_type_name; static int_type_name_c int_type_name; -/* - static constant_real_type_name_c constant_real_type_name; - static constant_int_type_name_c constant_int_type_name; -*/ /* temporarily here until we remove the st_code_gen.c and il_code_gen.c files... */ static integer_c integer; @@ -81,7 +77,15 @@ /* Version 1.0 – Official Release" */ /* by PLCopen - Technical Committee 5 - 2006-01-31 */ /******************************************************/ - static safebool_type_name_c safebool_type_name; + +// static safebool_type_name_c safebool_type_name; + /* The following is required because the expression (TOD_var - TOD_var) will result in a data type + * (in this case, TIME) that is neither of the expression elements... + */ + static safetime_type_name_c safetime_type_name; + static safetod_type_name_c safetod_type_name; + static safedt_type_name_c safedt_type_name; + public: @@ -97,7 +101,9 @@ /* B 1.2.1 - Numeric Literals */ /******************************/ void *visit(real_c *symbol); + void *visit(neg_real_c *symbol); void *visit(integer_c *symbol); + void *visit(neg_integer_c *symbol); void *visit(binary_integer_c *symbol); void *visit(octal_integer_c *symbol); void *visit(hex_integer_c *symbol); diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/search_expression_type.cc --- a/absyntax_utils/search_expression_type.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/search_expression_type.cc Wed Mar 30 19:53:32 2011 +0100 @@ -49,24 +49,34 @@ bool search_expression_type_c::is_bool_type(symbol_c *type_symbol) { bool_type_name_c tt; if (type_symbol == NULL) {return true;} - return (typeid(*type_symbol) == typeid(bool_type_name_c)); + if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(boolean_true_c)) {return true;} + if (typeid(*type_symbol) == typeid(boolean_false_c)) {return true;} + return false; } /* A helper function... */ bool search_expression_type_c::is_time_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safetod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedt_type_name_c)) {return true;} return false; } /* A helper function... */ bool search_expression_type_c::is_string_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safestring_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;} return false; } @@ -74,6 +84,7 @@ bool search_expression_type_c::is_literal_integer_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} if (typeid(*type_symbol) == typeid(integer_c)) {return true;} + if (typeid(*type_symbol) == typeid(neg_integer_c)) {return true;} if (typeid(*type_symbol) == typeid(binary_integer_c)) {return true;} if (typeid(*type_symbol) == typeid(octal_integer_c)) {return true;} if (typeid(*type_symbol) == typeid(hex_integer_c)) {return true;} @@ -83,29 +94,40 @@ /* A helper function... */ bool search_expression_type_c::is_integer_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeuint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;} return is_literal_integer_type(type_symbol); } /* A helper function... */ bool search_expression_type_c::is_literal_real_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(real_c)) {return true;} + if (typeid(*type_symbol) == typeid(real_c)) {return true;} + if (typeid(*type_symbol) == typeid(neg_real_c)) {return true;} return false; } /* A helper function... */ bool search_expression_type_c::is_real_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safereal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;} return is_literal_real_type(type_symbol); } @@ -116,28 +138,34 @@ bool search_expression_type_c::is_nbinary_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safebyte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelword_type_name_c)) {return true;} return is_literal_integer_type(type_symbol); } bool search_expression_type_c::is_binary_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} - return is_nbinary_type(type_symbol); +// if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} +// if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} + return (is_nbinary_type(type_symbol) || is_bool_type(type_symbol)); } bool search_expression_type_c::is_same_type(symbol_c *first_type, symbol_c *second_type) { if (first_type == NULL || second_type == NULL) {return true;} if (typeid(*first_type) == typeid(*second_type)) {return true;} - if (is_integer_type(first_type) && is_literal_integer_type(second_type)) {return true;} - if (is_literal_integer_type(first_type) && is_integer_type(second_type)) {return true;} - if (is_binary_type(first_type) && is_literal_integer_type(second_type)) {return true;} - if (is_literal_integer_type(first_type) && is_binary_type(second_type)) {return true;} - if (is_real_type(first_type) && is_literal_real_type(second_type)) {return true;} - if (is_literal_real_type(first_type) && is_real_type(second_type)) {return true;} + if (is_bool_type(first_type) && is_bool_type(second_type)) {return true;} + if (is_integer_type(first_type) && is_literal_integer_type(second_type)) {return true;} + if (is_literal_integer_type(first_type) && is_integer_type(second_type)) {return true;} + if (is_binary_type(first_type) && is_literal_integer_type(second_type)) {return true;} + if (is_literal_integer_type(first_type) && is_binary_type(second_type)) {return true;} + if (is_real_type(first_type) && is_literal_real_type(second_type)) {return true;} + if (is_literal_real_type(first_type) && is_real_type(second_type)) {return true;} return false; } @@ -146,12 +174,12 @@ if (first_type == NULL) {return second_type;} if (second_type == NULL) {return first_type;} if (typeid(*first_type) == typeid(*second_type)) {return first_type;} - if (is_integer_type(first_type) && is_literal_integer_type(second_type)) {return first_type;} - if (is_literal_integer_type(first_type) && is_integer_type(second_type)) {return second_type;} - if (is_binary_type(first_type) && is_literal_integer_type(second_type)) {return first_type;} - if (is_literal_integer_type(first_type) && is_binary_type(second_type)) {return second_type;} - if (is_real_type(first_type) && is_literal_real_type(second_type)) {return first_type;} - if (is_literal_real_type(first_type) && is_real_type(second_type)) {return second_type;} + if (is_integer_type(first_type) && is_literal_integer_type(second_type)) {return first_type;} + if (is_literal_integer_type(first_type) && is_integer_type(second_type)) {return second_type;} + if (is_binary_type(first_type) && is_literal_integer_type(second_type)) {return first_type;} + if (is_literal_integer_type(first_type) && is_binary_type(second_type)) {return second_type;} + if (is_real_type(first_type) && is_literal_real_type(second_type)) {return first_type;} + if (is_literal_real_type(first_type) && is_real_type(second_type)) {return second_type;} return NULL; } diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/type_initial_value.cc --- a/absyntax_utils/type_initial_value.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/type_initial_value.cc Wed Mar 30 19:53:32 2011 +0100 @@ -76,10 +76,10 @@ date_literal_0 = new date_literal_c(integer_1, integer_1, integer_1); date_literal_0 = new date_literal_c(new integer_c("1970"), integer_1, integer_1); daytime_literal_0 = new daytime_c(integer_0, integer_0, real_0); - time_0 = new duration_c(NULL, new seconds_c(integer_0, NULL)); // T#0S - date_0 = new date_c(date_literal_0); // D#0001-01-01 - tod_0 = new time_of_day_c(daytime_literal_0); // TOD#00:00:00 - dt_0 = new date_and_time_c(date_literal_0, daytime_literal_0); // DT#0001-01-01-00:00:00 + time_0 = new duration_c(new time_type_name_c(), NULL, new seconds_c(integer_0, NULL)); // T#0S + date_0 = new date_c(new date_type_name_c(), date_literal_0); // D#0001-01-01 + tod_0 = new time_of_day_c(new tod_type_name_c(), daytime_literal_0); // TOD#00:00:00 + dt_0 = new date_and_time_c(new dt_type_name_c(), date_literal_0, daytime_literal_0); // DT#0001-01-01-00:00:00 string_0 = new single_byte_character_string_c("''"); wstring_0 = new double_byte_character_string_c("\"\""); @@ -128,27 +128,49 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ -void *type_initial_value_c::visit(time_type_name_c *symbol) {return (void *)time_0;} -void *type_initial_value_c::visit(bool_type_name_c *symbol) {return (void *)bool_0;} -void *type_initial_value_c::visit(sint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(int_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(dint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(lint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(usint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(uint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(udint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(ulint_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(real_type_name_c *symbol) {return (void *)real_0;} -void *type_initial_value_c::visit(lreal_type_name_c *symbol) {return (void *)real_0;} -void *type_initial_value_c::visit(date_type_name_c *symbol) {return (void *)date_0;} -void *type_initial_value_c::visit(tod_type_name_c *symbol) {return (void *)tod_0;} -void *type_initial_value_c::visit(dt_type_name_c *symbol) {return (void *)dt_0;} -void *type_initial_value_c::visit(byte_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(word_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(dword_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(lword_type_name_c *symbol) {return (void *)integer_0;} -void *type_initial_value_c::visit(string_type_name_c *symbol) {return (void *)string_0;} -void *type_initial_value_c::visit(wstring_type_name_c *symbol) {return (void *)wstring_0;} +void *type_initial_value_c::visit(time_type_name_c *symbol) {return (void *)time_0;} +void *type_initial_value_c::visit(bool_type_name_c *symbol) {return (void *)bool_0;} +void *type_initial_value_c::visit(sint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(int_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(dint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(lint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(usint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(uint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(udint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(ulint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(real_type_name_c *symbol) {return (void *)real_0;} +void *type_initial_value_c::visit(lreal_type_name_c *symbol) {return (void *)real_0;} +void *type_initial_value_c::visit(date_type_name_c *symbol) {return (void *)date_0;} +void *type_initial_value_c::visit(tod_type_name_c *symbol) {return (void *)tod_0;} +void *type_initial_value_c::visit(dt_type_name_c *symbol) {return (void *)dt_0;} +void *type_initial_value_c::visit(byte_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(word_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(dword_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(lword_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(string_type_name_c *symbol) {return (void *)string_0;} +void *type_initial_value_c::visit(wstring_type_name_c *symbol) {return (void *)wstring_0;} + +void *type_initial_value_c::visit(safetime_type_name_c *symbol) {return (void *)time_0;} +void *type_initial_value_c::visit(safebool_type_name_c *symbol) {return (void *)bool_0;} +void *type_initial_value_c::visit(safesint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safedint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safelint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeusint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeuint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeudint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeulint_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safereal_type_name_c *symbol) {return (void *)real_0;} +void *type_initial_value_c::visit(safelreal_type_name_c *symbol) {return (void *)real_0;} +void *type_initial_value_c::visit(safedate_type_name_c *symbol) {return (void *)date_0;} +void *type_initial_value_c::visit(safetod_type_name_c *symbol) {return (void *)tod_0;} +void *type_initial_value_c::visit(safedt_type_name_c *symbol) {return (void *)dt_0;} +void *type_initial_value_c::visit(safebyte_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safeword_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safedword_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safelword_type_name_c *symbol) {return (void *)integer_0;} +void *type_initial_value_c::visit(safestring_type_name_c *symbol) {return (void *)string_0;} +void *type_initial_value_c::visit(safewstring_type_name_c *symbol) {return (void *)wstring_0;} /********************************/ /* B 1.3.3 - Derived data types */ diff -r 8ffa211b7f9a -r 90782e241346 absyntax_utils/type_initial_value.hh --- a/absyntax_utils/type_initial_value.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/absyntax_utils/type_initial_value.hh Wed Mar 30 19:53:32 2011 +0100 @@ -107,6 +107,28 @@ void *visit(string_type_name_c *symbol); void *visit(wstring_type_name_c *symbol); + void *visit(safetime_type_name_c *symbol); + void *visit(safebool_type_name_c *symbol); + void *visit(safesint_type_name_c *symbol); + void *visit(safeint_type_name_c *symbol); + void *visit(safedint_type_name_c *symbol); + void *visit(safelint_type_name_c *symbol); + void *visit(safeusint_type_name_c *symbol); + void *visit(safeuint_type_name_c *symbol); + void *visit(safeudint_type_name_c *symbol); + void *visit(safeulint_type_name_c *symbol); + void *visit(safereal_type_name_c *symbol); + void *visit(safelreal_type_name_c *symbol); + void *visit(safedate_type_name_c *symbol); + void *visit(safetod_type_name_c *symbol); + void *visit(safedt_type_name_c *symbol); + void *visit(safebyte_type_name_c *symbol); + void *visit(safeword_type_name_c *symbol); + void *visit(safedword_type_name_c *symbol); + void *visit(safelword_type_name_c *symbol); + void *visit(safestring_type_name_c *symbol); + void *visit(safewstring_type_name_c *symbol); + /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ diff -r 8ffa211b7f9a -r 90782e241346 lib/counter.txt --- a/lib/counter.txt Thu Aug 27 16:29:23 2009 +0100 +++ b/lib/counter.txt Wed Mar 30 19:53:32 2011 +0100 @@ -28,6 +28,10 @@ Q : BOOL; CV : INT; END_VAR + + VAR RRR : REAL; END_VAR + RRR := 9.9; + IF R THEN CV := 0 ; ELSIF CU AND (CV < PV) THEN CV := CV+1; diff -r 8ffa211b7f9a -r 90782e241346 stage1_2/Makefile --- a/stage1_2/Makefile Thu Aug 27 16:29:23 2009 +0100 +++ b/stage1_2/Makefile Wed Mar 30 19:53:32 2011 +0100 @@ -3,12 +3,11 @@ -default: all +default: all all: iec.flex.o iec.y.o stage1_2.o clean: - echo > Makefile.depend -rm -f iec.flex.c iec.y.cc iec.y.hh iec.y.output -rm -f iec.noerrorcheck.y -rm -f test_flex @@ -22,7 +21,7 @@ iec.flex.c: iec.flex flex -oiec.flex.c iec.flex -stage1_2.cc: iec.y.hh +stage1_2.o: stage1_2.cc iec.y.hh iec.flex.o: iec.y.hh iec.flex.c $(CXX) -c iec.flex.c -D DEFAULT_LIBDIR='"$(IECLIBDIR)"' $(CFLAGS) @@ -44,10 +43,3 @@ ../% /%: $(MAKE) -C $(@D) $(@F) - -Makefile.depend depend: - $(CXX) -MM -MG -I. *.cc > Makefile.depend - #| perl -pe 's/:/ Makefile.depend:/' > Makefile.depend - -include Makefile.depend - diff -r 8ffa211b7f9a -r 90782e241346 stage1_2/iec.flex --- a/stage1_2/iec.flex Thu Aug 27 16:29:23 2009 +0100 +++ b/stage1_2/iec.flex Wed Mar 30 19:53:32 2011 +0100 @@ -1034,11 +1034,16 @@ /* B 1.2.1 - Numeric Literals */ /******************************/ TRUE return TRUE; /* Keyword */ -BOOL#1 return TRUE; /* Keyword (Data Type) + Delimiter */ -BOOL#TRUE return TRUE; /* Keyword (Data Type) + Delimiter + Keyword */ +BOOL#1 return boolean_true_literal_token; +BOOL#TRUE return boolean_true_literal_token; +SAFEBOOL#1 {if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ +SAFEBOOL#TRUE {if (get_opt_safe_extensions()) {return safeboolean_true_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ + FALSE return FALSE; /* Keyword */ -BOOL#0 return FALSE; /* Keyword (Data Type) + Delimiter */ -BOOL#FALSE return FALSE; /* Keyword (Data Type) + Delimiter + Keyword */ +BOOL#0 return boolean_false_literal_token; +BOOL#FALSE return boolean_false_literal_token; +SAFEBOOL#0 {if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ +SAFEBOOL#FALSE {if (get_opt_safe_extensions()) {return safeboolean_false_literal_token;} else{REJECT;}} /* Keyword (Data Type) */ /************************/ @@ -1064,11 +1069,82 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ +BOOL return BOOL; /* Keyword (Data Type) */ + BYTE return BYTE; /* Keyword (Data Type) */ WORD return WORD; /* Keyword (Data Type) */ DWORD return DWORD; /* Keyword (Data Type) */ LWORD return LWORD; /* Keyword (Data Type) */ +SINT return SINT; /* Keyword (Data Type) */ +INT return INT; /* Keyword (Data Type) */ +DINT return DINT; /* Keyword (Data Type) */ +LINT return LINT; /* Keyword (Data Type) */ + +USINT return USINT; /* Keyword (Data Type) */ +UINT return UINT; /* Keyword (Data Type) */ +UDINT return UDINT; /* Keyword (Data Type) */ +ULINT return ULINT; /* Keyword (Data Type) */ + +REAL return REAL; /* Keyword (Data Type) */ +LREAL return LREAL; /* Keyword (Data Type) */ + +WSTRING return WSTRING; /* Keyword (Data Type) */ +STRING return STRING; /* Keyword (Data Type) */ + +TIME return TIME; /* Keyword (Data Type) */ +DATE return DATE; /* Keyword (Data Type) */ +DT return DT; /* Keyword (Data Type) */ +TOD return TOD; /* Keyword (Data Type) */ +DATE_AND_TIME return DATE_AND_TIME; /* Keyword (Data Type) */ +TIME_OF_DAY return TIME_OF_DAY; /* Keyword (Data Type) */ + + /*****************************************************************/ + /* Keywords defined in "Safety Software Technical Specification" */ + /*****************************************************************/ + /* + * NOTE: The following keywords are define in + * "Safety Software Technical Specification, + * Part 1: Concepts and Function Blocks, + * Version 1.0 – Official Release" + * written by PLCopen - Technical Committee 5 + * + * We only support these extensions and keywords + * if the apropriate command line option is given. + */ +SAFEBOOL {if (get_opt_safe_extensions()) {return SAFEBOOL;} else {REJECT;}} + +SAFEBYTE {if (get_opt_safe_extensions()) {return SAFEBYTE;} else {REJECT;}} +SAFEWORD {if (get_opt_safe_extensions()) {return SAFEWORD;} else {REJECT;}} +SAFEDWORD {if (get_opt_safe_extensions()) {return SAFEDWORD;} else{REJECT;}} +SAFELWORD {if (get_opt_safe_extensions()) {return SAFELWORD;} else{REJECT;}} + +SAFEREAL {if (get_opt_safe_extensions()) {return SAFESINT;} else{REJECT;}} +SAFELREAL {if (get_opt_safe_extensions()) {return SAFELREAL;} else{REJECT;}} + +SAFESINT {if (get_opt_safe_extensions()) {return SAFESINT;} else{REJECT;}} +SAFEINT {if (get_opt_safe_extensions()) {return SAFEINT;} else{REJECT;}} +SAFEDINT {if (get_opt_safe_extensions()) {return SAFEDINT;} else{REJECT;}} +SAFELINT {if (get_opt_safe_extensions()) {return SAFELINT;} else{REJECT;}} + +SAFEUSINT {if (get_opt_safe_extensions()) {return SAFEUSINT;} else{REJECT;}} +SAFEUINT {if (get_opt_safe_extensions()) {return SAFEUINT;} else{REJECT;}} +SAFEUDINT {if (get_opt_safe_extensions()) {return SAFEUDINT;} else{REJECT;}} +SAFEULINT {if (get_opt_safe_extensions()) {return SAFEULINT;} else{REJECT;}} + + /* SAFESTRING and SAFEWSTRING are not yet supported, i.e. checked correctly, in the semantic analyser (stage 3) */ + /* so it is best not to support them at all... */ + /* +SAFEWSTRING {if (get_opt_safe_extensions()) {return SAFEWSTRING;} else{REJECT;}} +SAFESTRING {if (get_opt_safe_extensions()) {return SAFESTRING;} else{REJECT;}} + */ + +SAFETIME {if (get_opt_safe_extensions()) {return SAFETIME;} else{REJECT;}} +SAFEDATE {if (get_opt_safe_extensions()) {return SAFEDATE;} else{REJECT;}} +SAFEDT {if (get_opt_safe_extensions()) {return SAFEDT;} else{REJECT;}} +SAFETOD {if (get_opt_safe_extensions()) {return SAFETOD;} else{REJECT;}} +SAFEDATE_AND_TIME {if (get_opt_safe_extensions()) {return SAFEDATE_AND_TIME;} else{REJECT;}} +SAFETIME_OF_DAY {if (get_opt_safe_extensions()) {return SAFETIME_OF_DAY;} else{REJECT;}} /********************************/ /* B 1.3.2 - Generic data types */ @@ -1105,30 +1181,6 @@ /*********************/ /* B 1.4 - Variables */ /*********************/ -REAL return REAL; /* Keyword (Data Type) */ -LREAL return LREAL; /* Keyword (Data Type) */ - -SINT return SINT; /* Keyword (Data Type) */ -INT return INT; /* Keyword (Data Type) */ -DINT return DINT; /* Keyword (Data Type) */ -LINT return LINT; /* Keyword (Data Type) */ - -USINT return USINT; /* Keyword (Data Type) */ -UINT return UINT; /* Keyword (Data Type) */ -UDINT return UDINT; /* Keyword (Data Type) */ -ULINT return ULINT; /* Keyword (Data Type) */ - - -WSTRING return WSTRING; /* Keyword (Data Type) */ -STRING return STRING; /* Keyword (Data Type) */ -BOOL return BOOL; /* Keyword (Data Type) */ -TIME return TIME; /* Keyword (Data Type) */ -DATE return DATE; /* Keyword (Data Type) */ -DT return DT; /* Keyword (Data Type) */ -TOD return TOD; /* Keyword (Data Type) */ -DATE_AND_TIME return DATE_AND_TIME; /* Keyword (Data Type) */ -TIME_OF_DAY return TIME_OF_DAY; /* Keyword (Data Type) */ - /******************************************/ /* B 1.4.3 - Declaration & Initialisation */ @@ -1388,20 +1440,7 @@ EXIT return EXIT; /* Keyword */ - /*****************************************************************/ - /* Keywords defined in "Safety Software Technical Specification" */ - /*****************************************************************/ - /* - * NOTE: The following keywords are define in - * "Safety Software Technical Specification, - * Part 1: Concepts and Function Blocks, - * Version 1.0 – Official Release" - * written by PLCopen - Technical Committee 5 - * - * We only support these extensions and keywords - * if the apropriate command line option is given. - */ -SAFEBOOL {if (get_opt_safe_extensions()) {return SAFEBOOL;} else{REJECT;}} /* Keyword (Data Type) */ + diff -r 8ffa211b7f9a -r 90782e241346 stage1_2/iec.y --- a/stage1_2/iec.y Thu Aug 27 16:29:23 2009 +0100 +++ b/stage1_2/iec.y Wed Mar 30 19:53:32 2011 +0100 @@ -326,9 +326,7 @@ /* B 1.2 - Constants */ /*********************/ %type constant -/* a helper symbol for expression */ -%type non_negative_constant - +%type non_negative_constant /******************************/ /* B 1.2.1 - Numeric Literals */ @@ -337,12 +335,8 @@ bit */ %type numeric_literal -/* helper symbol for non_negative_constant */ -%type non_negative_numeric_literal %type integer_literal %type signed_integer -/* a helper symbol for non_negative_constant */ -%type non_negative_signed_integer %token integer_token %type integer %token binary_integer_token @@ -354,15 +348,16 @@ %token real_token %type real %type signed_real -/* helper symbol for non_negative_real_literal */ -%type non_negative_signed_real %type real_literal -/* helper symbol for non_negative_numeric_literal */ -%type non_negative_real_literal // %type exponent %type bit_string_literal %type boolean_literal +%token safeboolean_true_literal_token +%token safeboolean_false_literal_token +%token boolean_true_literal_token +%token boolean_false_literal_token + %token FALSE %token TRUE @@ -419,7 +414,7 @@ %token fixed_point_ms_token %token integer_ms_token -%token TIME +// %token TIME %token T_SHARP @@ -438,10 +433,10 @@ %type day %type date_and_time -%token TIME_OF_DAY -%token DATE +// %token TIME_OF_DAY +// %token DATE %token D_SHARP -%token DATE_AND_TIME +// %token DATE_AND_TIME /**********************/ @@ -522,13 +517,49 @@ %token STRING %token BOOL -// %token TIME -// %token DATE -// %token DATE_AND_TIME +%token TIME +%token DATE +%token DATE_AND_TIME %token DT -// %token TIME_OF_DAY +%token TIME_OF_DAY %token TOD +/******************************************************/ +/* Symbols defined in */ +/* "Safety Software Technical Specification, */ +/* Part 1: Concepts and Function Blocks, */ +/* Version 1.0 – Official Release" */ +/* by PLCopen - Technical Committee 5 - 2006-01-31 */ +/******************************************************/ + +%token SAFEBYTE +%token SAFEWORD +%token SAFEDWORD +%token SAFELWORD + +%token SAFELREAL +%token SAFEREAL + +%token SAFESINT +%token SAFEINT +%token SAFEDINT +%token SAFELINT + +%token SAFEUSINT +%token SAFEUINT +%token SAFEUDINT +%token SAFEULINT + +%token SAFEWSTRING +%token SAFESTRING +%token SAFEBOOL + +%token SAFETIME +%token SAFEDATE +%token SAFEDATE_AND_TIME +%token SAFEDT +%token SAFETIME_OF_DAY +%token SAFETOD /********************************/ /* B 1.3.2 - Generic data types */ @@ -1168,6 +1199,7 @@ %type unary_expression // %type unary_operator %type primary_expression +%type non_negative_primary_expression /* intermediate helper symbol for primary_expression */ %type function_invocation @@ -1274,15 +1306,6 @@ %token EXIT -/******************************************************/ -/* Symbols defined in */ -/* "Safety Software Technical Specification, */ -/* Part 1: Concepts and Function Blocks, */ -/* Version 1.0 – Official Release" */ -/* by PLCopen - Technical Committee 5 - 2006-01-31 */ -/******************************************************/ -%token SAFEBOOL - %% @@ -1597,10 +1620,23 @@ | bit_string_literal | boolean_literal /* NOTE: in order to remove reduce/reduce conflicts, + * [between -9.5 being parsed as + * (i) a signed real, + * (ii) or as a real preceded by the '-' operator + * ] + * we need to define a variant of the constant construct + * where any constant is never preceded by the '-' character. + * In order to do this, we have borugh the signed_real + * directly into the definition of the constant construct + * (so we can define another non_negative_constant + * construct that does not include it!) + */ +| signed_real +/* NOTE: in order to remove reduce/reduce conflicts, * unsigned_integer, signed_integer, binary_integer, octal_integer * and hex_integer have been integrated directly into * the constants construct, instead of belonging to - * either the bit_string_literal or integer_literal + * both the bit_string_literal or integer_literal * construct. */ /* NOTE: unsigned_integer, although used in some @@ -1614,24 +1650,58 @@ | hex_integer ; -/* a helper symbol for expression */ -/* A constant without any preceding '-', but may - * include a preceding '+' ! + +/* NOTE: in order to remove reduce/reduce conflicts, + * [between -9.5 being parsed as + * (i) a signed real, + * (ii) or as a real preceded by the '-' operator + * ] + * we need to define a variant of the constant construct + * where any constant is never preceded by the '-' character. + * In order to do this, we have borugh the signed_real + * directly into the definition of the constant construct + * (so we can define another non_negative_constant + * construct that does not include it!) */ non_negative_constant: - non_negative_numeric_literal + numeric_literal | character_string | time_literal | bit_string_literal | boolean_literal -| non_negative_signed_integer +/* NOTE: in order to remove reduce/reduce conflicts, + * [between -9.5 being parsed as + * (i) a signed real, + * (ii) or as a real preceded by the '-' operator + * ] + * we need to define a variant of the constant construct + * where any constant is never preceded by the '-' character. + * In order to do this, we have borugh the signed_real + * directly into the definition of the constant construct + * (so we can define another non_negative_constant + * construct that does not include it!) + */ +/* | signed_real */ +| real /* an unsigned real */ +/* NOTE: in order to remove reduce/reduce conflicts, + * unsigned_integer, signed_integer, binary_integer, octal_integer + * and hex_integer have been integrated directly into + * the constants construct, instead of belonging to + * both the bit_string_literal or integer_literal + * construct. + */ +/* NOTE: unsigned_integer, although used in some + * rules, is not defined in the spec! + * We therefore replaced unsigned_integer as integer + */ +| integer /* i.e. an unsigned_integer */ +/* | signed_integer */ | binary_integer | octal_integer | hex_integer ; - /******************************/ /* B 1.2.1 - Numeric Literals */ /******************************/ @@ -1663,7 +1733,7 @@ * Flex handles real, while bison handles signed_real * and real_literal. * - * - According to the spec, intger '.' integer + * - According to the spec, integer '.' integer * may be reduced to either a real or a fixed_point. * It is nevertheless possible to figure out from the * context which of the two rules should be used in @@ -1720,12 +1790,6 @@ | real_literal ; -/* helper symbol for non_negative_constant */ -non_negative_numeric_literal: - integer_literal -| non_negative_real_literal -; - integer_literal: integer_type_name '#' signed_integer @@ -1761,22 +1825,16 @@ signed_integer: integer | '+' integer {$$ = $2;} -| '-' integer {$$ = new neg_literal_c($2, locloc(@$));} -; - -/* a helper symbol for non_negative_constant */ -/* A integer without any preceding '-', but may - * include a preceding '+' ! - */ -non_negative_signed_integer: - integer -| '+' integer {$$ = $2;} +| '-' integer {$$ = new neg_integer_c($2, locloc(@$));} ; real_literal: - signed_real -| real_type_name '#' signed_real +/* NOTE: see note in the definition of constant for reason + * why signed_real is missing here! + */ +/* signed_real */ + real_type_name '#' signed_real {$$ = new real_literal_c($1, $3, locf(@1), locl(@3));} /* ERROR_CHECK_BEGIN */ | real_type_name signed_real @@ -1790,24 +1848,13 @@ /* ERROR_CHECK_END */ ; -/* helper symbol for non_negative_numeric_literal */ -non_negative_real_literal: - non_negative_signed_real -| real_type_name '#' signed_real - {$$ = new real_literal_c($1, $3, locf(@1), locl(@3));} -; signed_real: real | '+' real {$$ = $2;} -| '-' real {$$ = new neg_literal_c($2, locloc(@2));} -; - -/* helper symbol for non_negative_real_literal */ -non_negative_signed_real: - real -| '+' real {$$ = $2;} -; +| '-' real {$$ = new neg_real_c($2, locloc(@2));} +; + bit_string_literal: @@ -1838,7 +1885,7 @@ | bit_string_type_name hex_integer {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between bit string type name and value in bit string literal."); yynerrs++;} | bit_string_type_name '#' error - {$$ = NULL; + {$$ = NULL; if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for bit string literal.");} else {print_err_msg(locf(@3), locl(@3), "invalid value for bit string literal."); yyclearin;} yyerrok; @@ -1848,12 +1895,36 @@ boolean_literal: - TRUE {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)), - new boolean_true_c(locloc(@$)), - locloc(@$));} -| FALSE {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)), + boolean_true_literal_token + {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)), + new boolean_true_c(locloc(@$)), + locloc(@$)); + } +| boolean_false_literal_token + {$$ = new boolean_literal_c(new bool_type_name_c(locloc(@$)), new boolean_false_c(locloc(@$)), - locloc(@$));} + locloc(@$)); + } +| safeboolean_true_literal_token + {$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)), + new boolean_true_c(locloc(@$)), + locloc(@$)); + } +| safeboolean_false_literal_token + {$$ = new boolean_literal_c(new safebool_type_name_c(locloc(@$)), + new boolean_false_c(locloc(@$)), + locloc(@$)); + } +| FALSE + {$$ = new boolean_literal_c(NULL, + new boolean_false_c(locloc(@$)), + locloc(@$)); + } +| TRUE + {$$ = new boolean_literal_c(NULL, + new boolean_true_c(locloc(@$)), + locloc(@$)); + } /* | BOOL '#' '1' {} | BOOL '#' '0' {} @@ -1935,13 +2006,17 @@ * when it comes across 'T#' */ TIME '#' interval - {$$ = new duration_c(NULL, $3, locloc(@$));} + {$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $3, locloc(@$));} | TIME '#' '-' interval - {$$ = new duration_c(new neg_time_c(locloc(@$)), $4, locloc(@$));} + {$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));} | T_SHARP interval - {$$ = new duration_c(NULL, $2, locloc(@$));} + {$$ = new duration_c(new time_type_name_c(locloc(@1)), NULL, $2, locloc(@$));} | T_SHARP '-' interval - {$$ = new duration_c(new neg_time_c(locloc(@$)), $3, locloc(@$));} + {$$ = new duration_c(new time_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $3, locloc(@$));} +| SAFETIME '#' interval + {$$ = new duration_c(new safetime_type_name_c(locloc(@1)), NULL, $3, locloc(@$));} +| SAFETIME '#' '-' interval + {$$ = new duration_c(new safetime_type_name_c(locloc(@1)), new neg_time_c(locloc(@$)), $4, locloc(@$));} /* ERROR_CHECK_BEGIN */ | TIME interval {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;} @@ -2106,7 +2181,9 @@ /************************************/ time_of_day: TIME_OF_DAY '#' daytime - {$$ = new time_of_day_c($3, locloc(@$));} + {$$ = new time_of_day_c(new tod_type_name_c(locloc(@1)), $3, locloc(@$));} +| SAFETIME_OF_DAY '#' daytime + {$$ = new time_of_day_c(new safetod_type_name_c(locloc(@1)), $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ | TIME_OF_DAY daytime {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME_OF_DAY' and daytime in time of day."); yynerrs++;} @@ -2153,9 +2230,11 @@ date: DATE '#' date_literal - {$$ = new date_c($3, locloc(@$));} + {$$ = new date_c(new date_type_name_c(locloc(@1)), $3, locloc(@$));} | D_SHARP date_literal - {$$ = new date_c($2, locloc(@$));} + {$$ = new date_c(new date_type_name_c(locloc(@1)), $2, locloc(@$));} +| SAFEDATE '#' date_literal + {$$ = new date_c(new safedate_type_name_c(locloc(@1)), $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ | DATE date_literal {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE' and date literal in date."); yynerrs++;} @@ -2206,7 +2285,9 @@ date_and_time: DATE_AND_TIME '#' date_literal '-' daytime - {$$ = new date_and_time_c($3, $5, locloc(@$));} + {$$ = new date_and_time_c(new dt_type_name_c(locloc(@1)), $3, $5, locloc(@$));} +| SAFEDATE_AND_TIME '#' date_literal '-' daytime + {$$ = new date_and_time_c(new safedt_type_name_c(locloc(@1)), $3, $5, locloc(@$));} /* ERROR_CHECK_BEGIN */ | DATE_AND_TIME date_literal '-' daytime {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'DATE_AND_TIME' and date literal in date and time."); yynerrs++;} @@ -2251,6 +2332,14 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ + /******************************************************/ + /* SAFExxxx Symbols defined in */ + /* "Safety Software Technical Specification, */ + /* Part 1: Concepts and Function Blocks, */ + /* Version 1.0 – Official Release" */ + /* by PLCopen - Technical Committee 5 - 2006-01-31 */ + /******************************************************/ + elementary_type_name: numeric_type_name | date_type_name @@ -2262,13 +2351,7 @@ * and grouping type definition for reason why BOOL * was added to this definition. */ - /******************************************************/ - /* Symbols defined in */ - /* "Safety Software Technical Specification, */ - /* Part 1: Concepts and Function Blocks, */ - /* Version 1.0 – Official Release" */ - /* by PLCopen - Technical Committee 5 - 2006-01-31 */ - /******************************************************/ +| SAFETIME {$$ = new safetime_type_name_c(locloc(@$));} | SAFEBOOL {$$ = new safebool_type_name_c(locloc(@$));} ; @@ -2283,38 +2366,57 @@ ; signed_integer_type_name: - SINT {$$ = new sint_type_name_c(locloc(@$));} -| INT {$$ = new int_type_name_c(locloc(@$));} -| DINT {$$ = new dint_type_name_c(locloc(@$));} -| LINT {$$ = new lint_type_name_c(locloc(@$));} + SINT {$$ = new sint_type_name_c(locloc(@$));} +| INT {$$ = new int_type_name_c(locloc(@$));} +| DINT {$$ = new dint_type_name_c(locloc(@$));} +| LINT {$$ = new lint_type_name_c(locloc(@$));} +| SAFESINT {$$ = new safesint_type_name_c(locloc(@$));} +| SAFEINT {$$ = new safeint_type_name_c(locloc(@$));} +| SAFEDINT {$$ = new safedint_type_name_c(locloc(@$));} +| SAFELINT {$$ = new safelint_type_name_c(locloc(@$));} ; unsigned_integer_type_name: - USINT {$$ = new usint_type_name_c(locloc(@$));} -| UINT {$$ = new uint_type_name_c(locloc(@$));} -| UDINT {$$ = new udint_type_name_c(locloc(@$));} -| ULINT {$$ = new ulint_type_name_c(locloc(@$));} + USINT {$$ = new usint_type_name_c(locloc(@$));} +| UINT {$$ = new uint_type_name_c(locloc(@$));} +| UDINT {$$ = new udint_type_name_c(locloc(@$));} +| ULINT {$$ = new ulint_type_name_c(locloc(@$));} +| SAFEUSINT {$$ = new safeusint_type_name_c(locloc(@$));} +| SAFEUINT {$$ = new safeuint_type_name_c(locloc(@$));} +| SAFEUDINT {$$ = new safeudint_type_name_c(locloc(@$));} +| SAFEULINT {$$ = new safeulint_type_name_c(locloc(@$));} ; real_type_name: - REAL {$$ = new real_type_name_c(locloc(@$));} -| LREAL {$$ = new lreal_type_name_c(locloc(@$));} + REAL {$$ = new real_type_name_c(locloc(@$));} +| LREAL {$$ = new lreal_type_name_c(locloc(@$));} +| SAFEREAL {$$ = new safereal_type_name_c(locloc(@$));} +| SAFELREAL {$$ = new safelreal_type_name_c(locloc(@$));} ; date_type_name: - DATE {$$ = new date_type_name_c(locloc(@$));} -| TIME_OF_DAY {$$ = new tod_type_name_c(locloc(@$));} -| TOD {$$ = new tod_type_name_c(locloc(@$));} -| DATE_AND_TIME {$$ = new dt_type_name_c(locloc(@$));} -| DT {$$ = new dt_type_name_c(locloc(@$));} + DATE {$$ = new date_type_name_c(locloc(@$));} +| TIME_OF_DAY {$$ = new tod_type_name_c(locloc(@$));} +| TOD {$$ = new tod_type_name_c(locloc(@$));} +| DATE_AND_TIME {$$ = new dt_type_name_c(locloc(@$));} +| DT {$$ = new dt_type_name_c(locloc(@$));} +| SAFEDATE {$$ = new safedate_type_name_c(locloc(@$));} +| SAFETIME_OF_DAY {$$ = new safetod_type_name_c(locloc(@$));} +| SAFETOD {$$ = new safetod_type_name_c(locloc(@$));} +| SAFEDATE_AND_TIME {$$ = new safedt_type_name_c(locloc(@$));} +| SAFEDT {$$ = new safedt_type_name_c(locloc(@$));} ; bit_string_type_name: - BYTE {$$ = new byte_type_name_c(locloc(@$));} -| WORD {$$ = new word_type_name_c(locloc(@$));} -| DWORD {$$ = new dword_type_name_c(locloc(@$));} -| LWORD {$$ = new lword_type_name_c(locloc(@$));} + BYTE {$$ = new byte_type_name_c(locloc(@$));} +| WORD {$$ = new word_type_name_c(locloc(@$));} +| DWORD {$$ = new dword_type_name_c(locloc(@$));} +| LWORD {$$ = new lword_type_name_c(locloc(@$));} +| SAFEBYTE {$$ = new safebyte_type_name_c(locloc(@$));} +| SAFEWORD {$$ = new safeword_type_name_c(locloc(@$));} +| SAFEDWORD {$$ = new safedword_type_name_c(locloc(@$));} +| SAFELWORD {$$ = new safelword_type_name_c(locloc(@$));} /* NOTE: see note under the B 1.2.1 section of token * and grouping type definition for reason why the BOOL * was omitted from this definition. @@ -2333,6 +2435,8 @@ elementary_string_type_name: STRING {$$ = new string_type_name_c(locloc(@$));} | WSTRING {$$ = new wstring_type_name_c(locloc(@$));} +| SAFESTRING {$$ = new safestring_type_name_c(locloc(@$));} +| SAFEWSTRING {$$ = new safewstring_type_name_c(locloc(@$));} ; @@ -6375,7 +6479,7 @@ il_param_instruction: - il_param_assignment ',' eol_list + il_param_assignment ',' eol_list | il_param_out_assignment ',' eol_list /* ERROR_CHECK_BEGIN */ | il_param_assignment ',' error @@ -6591,13 +6695,61 @@ /* any_identifier SENDTO */ sendto_identifier SENDTO {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));} +/* The following is not required, as the sendto_identifier_token returned by flex will + * also include the 'ENO' identifier. + * The resulting abstract syntax tree is identical with or without this following rule, + * as both the eno_identifier and the sendto_identifier are stored as + * an identifier_c !! + */ +/* | eno_identifier SENDTO {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));} +*/ /*| NOT variable_name SENDTO */ | NOT sendto_identifier SENDTO {$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));} +/* The following is not required, as the sendto_identifier_token returned by flex will + * also include the 'ENO' identifier. + * The resulting abstract syntax tree is identical with or without this following rule, + * as both the eno_identifier and the sendto_identifier are stored as + * an identifier_c !! + * + * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser. + * This conflict is not really an error/ambiguity in the syntax, but rather + * due to the fact that more than a single look-ahead token would be required + * to correctly parse the syntax, something that bison does not support. + * + * The shift/reduce conflict arises because bison does not know whether + * to parse the 'NOT ENO' in the following code + * LD 1 + * funct_name ( + * NOT ENO => bool_var, + * EN := TRUE + * ) + * as either a il_param_assignment (wrong!) or an il_param_out_assignment.(correct). + * The '=>' delimiter (known as SEND_TO in this iec.y file) is a dead giveaway that + * it should be parsed as an il_param_out_assignment, but still, bison gets confused! + * Bison considers the possibility of reducing the 'NOT ENO' as an NOT_operator with + * the 'ENO' operand + * (NOT_operator -> il_simple_operator -> il_simple_operation -> il_simple_instruction -> + * -> simple_instr_list -> il_param_assignment) + * instead of reducing it to an il_param_out_operator. + * ( il_param_out_operator -> il_param_out_assignment) + * + * Note that the shift/reduce conflict only manifests itself in the il_formal_funct_call, + * where both the il_param_out_assignment and il_param_assignment are used! + * + * il_param_out_assignment --+--> il_param_instruction -> il_param_instruction_list --+ + * | | + * il_param_assignment --+ | + * | + * il_formal_funct_call <- il_param_list <-+ + * + */ +/* | NOT eno_identifier SENDTO {$$ = new il_assign_out_operator_c(new not_paramassign_c(locloc(@1)), $2, locloc(@$));} +*/ /* ERROR_CHECK_BEGIN */ | error SENDTO {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid parameter defined in parameter out assignment."); yyerrok;} @@ -6838,8 +6990,8 @@ unary_expression: - primary_expression -| '-' primary_expression + non_negative_primary_expression +| '-' non_negative_primary_expression {$$ = new neg_expression_c($2, locloc(@$));} | NOT primary_expression {$$ = new not_expression_c($2, locloc(@$));} @@ -6874,8 +7026,9 @@ * expression<-unary_expression<-constant<-integer * (i.e. the constant 9, preceded by a unary negation) * - * To remove the conlfict, we only allow constants without + * To remove the conflict, we only allow constants without * a preceding '-' to be used in primary_expression + * (i.e. as a parameter to the unary negation operator) */ /* NOTE: We use enumerated_value_without_identifier instead of enumerated_value * in order to remove a reduce/reduce conflict between reducing an @@ -6887,8 +7040,7 @@ * for a variable and an enumerated value, then the variable shall be * considered. */ -primary_expression: -/* constant */ +non_negative_primary_expression: non_negative_constant //| enumerated_value_without_identifier | enumerated_value @@ -6903,6 +7055,22 @@ ; +primary_expression: + constant +//| enumerated_value_without_identifier + enumerated_value +| variable +| '(' expression ')' + {$$ = $2;} +| function_invocation +/* ERROR_CHECK_BEGIN */ +| '(' expression error + {$$ = NULL; print_err_msg(locl(@2), locf(@3), "')' missing at the end of expression in ST expression."); yyerrok;} +/* ERROR_CHECK_END */ +; + + + /* intermediate helper symbol for primary_expression */ /* NOTE: function_name includes the standard function name 'NOT' ! * This introduces a reduce/reduce conflict, as NOT(var) @@ -7122,14 +7290,30 @@ /*| any_identifier SENDTO variable */ | sendto_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));} +/* The following is not required, as the sendto_identifier_token returned by flex will + * also include the 'ENO' identifier. + * The resulting abstract syntax tree is identical with or without this following rule, + * as both the eno_identifier and the sendto_identifier are stored as + * an identifier_c !! + */ +/* | eno_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));} +*/ /*| NOT variable_name SENDTO variable */ /*| NOT any_identifier SENDTO variable*/ | NOT sendto_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));} +/* The following is not required, as the sendto_identifier_token returned by flex will + * also include the 'ENO' identifier. + * The resulting abstract syntax tree is identical with or without this following rule, + * as both the eno_identifier and the sendto_identifier are stored as + * an identifier_c !! + */ +/* | NOT eno_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));} +*/ /* ERROR_CHECK_BEGIN */ | any_identifier ASSIGN error {$$ = NULL; @@ -7149,12 +7333,14 @@ else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;} yyerrok; } +/* | eno_identifier SENDTO error {$$ = NULL; if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no expression defined in ST formal parameter out assignment.");} else {print_err_msg(locf(@3), locl(@3), "invalid expression in ST formal parameter out assignment."); yyclearin;} yyerrok; } +*/ | NOT SENDTO variable {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no parameter name defined in ST formal parameter out negated assignment."); yynerrs++;} | NOT error SENDTO variable @@ -7165,12 +7351,14 @@ else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;} yyerrok; } +/* | NOT eno_identifier SENDTO error {$$ = NULL; if (is_current_syntax_token()) {print_err_msg(locl(@3), locf(@4), "no expression defined in ST formal parameter out negated assignment.");} else {print_err_msg(locf(@4), locl(@4), "invalid expression in ST formal parameter out negated assignment."); yyclearin;} yyerrok; } +*/ /* ERROR_CHECK_END */ ; @@ -7763,6 +7951,11 @@ } /* first parse the standard library file... */ + /* + #if YYDEBUG + yydebug = 1; + #endif + */ yyin = lib_file; allow_function_overloading = true; full_token_loc = full_token_loc_; @@ -7786,11 +7979,11 @@ library_element_symtable.end_value()) library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token); -#if YYDEBUG - yydebug = 1; -#endif /* now parse the input file... */ + #if YYDEBUG + yydebug = 1; + #endif yyin = in_file; allow_function_overloading = false; full_token_loc = full_token_loc_; diff -r 8ffa211b7f9a -r 90782e241346 stage3/stage3.cc --- a/stage3/stage3.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage3/stage3.cc Wed Mar 30 19:53:32 2011 +0100 @@ -1,5 +1,5 @@ /* - * (c) 20099 Catarina da Costa Boucinha + * (c) 2009 Mario de Sousa * * Offered to the public under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of the diff -r 8ffa211b7f9a -r 90782e241346 stage3/stage3.hh --- a/stage3/stage3.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/stage3/stage3.hh Wed Mar 30 19:53:32 2011 +0100 @@ -1,5 +1,5 @@ /* - * (c) 2009 Catarina da Costa Boucinha + * (c) 2009 Mario de Sousa * * Offered to the public under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of the diff -r 8ffa211b7f9a -r 90782e241346 stage3/visit_expression_type.cc --- a/stage3/visit_expression_type.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage3/visit_expression_type.cc Wed Mar 30 19:53:32 2011 +0100 @@ -71,6 +71,7 @@ symbol->function_block_body->accept(*this); il_default_variable_type = NULL; delete search_varfb_instance_type; + search_varfb_instance_type = NULL; return NULL; } @@ -84,6 +85,7 @@ symbol->function_body->accept(*this); il_default_variable_type = NULL; delete search_varfb_instance_type; + search_varfb_instance_type = NULL; return NULL; } @@ -97,6 +99,7 @@ symbol->fblock_body->accept(*this); il_default_variable_type = NULL; delete search_varfb_instance_type; + search_varfb_instance_type = NULL; return NULL; } @@ -115,13 +118,55 @@ } + + +/* NOTE on data type handling and literals... + * ========================================== + * + * Literals that are explicitly type cast + * e.g.: BYTE#42 + * INT#65 + * TIME#45h23m + * etc... + * are NOT considered literals in the following code. + * Since they are type cast, and their data type is fixed and well known, + * they are treated as a variable of that data type (except when determining lvalues) + * In other words, when calling search_constant_type_c on these constants, it returns + * a xxxxx_type_name_c, and not one of the xxxx_literal_c ! + * + * When the following code handles a literal, it is really a literal of unknown data type. + * e.g. 42, may be considered an int, a byte, a word, etc... + */ + /* A helper function... */ bool visit_expression_type_c::is_ANY_ELEMENTARY_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} return is_ANY_MAGNITUDE_type(type_symbol) - || is_ANY_BIT_type(type_symbol) - || is_ANY_STRING_type(type_symbol) - || is_ANY_DATE_type(type_symbol); + || is_ANY_BIT_type (type_symbol) + || is_ANY_STRING_type (type_symbol) + || is_ANY_DATE_type (type_symbol); +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEELEMENTARY_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + return is_ANY_SAFEMAGNITUDE_type(type_symbol) + || is_ANY_SAFEBIT_type (type_symbol) + || is_ANY_SAFESTRING_type (type_symbol) + || is_ANY_SAFEDATE_type (type_symbol); +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_ELEMENTARY_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + /* NOTE: doing + * return is_ANY_SAFEELEMENTARY_type() || is_ANY_ELEMENTARY_type() + * is incorrect, as the literals would never be considered compatible... + */ + return is_ANY_MAGNITUDE_compatible(type_symbol) + || is_ANY_BIT_compatible (type_symbol) + || is_ANY_STRING_compatible (type_symbol) + || is_ANY_DATE_compatible (type_symbol); } @@ -132,32 +177,95 @@ return is_ANY_NUM_type(type_symbol); } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEMAGNITUDE_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} + return is_ANY_SAFENUM_type(type_symbol); +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_MAGNITUDE_type (type_symbol)) {return true;} + if (is_ANY_SAFEMAGNITUDE_type(type_symbol)) {return true;} + + return is_ANY_NUM_compatible(type_symbol); +} /* A helper function... */ bool visit_expression_type_c::is_ANY_NUM_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} - return is_ANY_REAL_type(type_symbol) || is_ANY_INT_type(type_symbol); -} - + if (is_ANY_REAL_type(type_symbol)) {return true;} + if (is_ANY_INT_type(type_symbol)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFENUM_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + return is_ANY_SAFEREAL_type(type_symbol) + || is_ANY_SAFEINT_type (type_symbol); +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_NUM_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_REAL_compatible(type_symbol)) {return true;} + if (is_ANY_INT_compatible(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_ANY_DATE_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} return false; } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEDATE_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safetod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedt_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_DATE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_DATE_type (type_symbol)) {return true;} + if (is_ANY_SAFEDATE_type(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_ANY_STRING_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;} +// TODO literal_string ??? return false; } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFESTRING_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safestring_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_STRING_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_STRING_type (type_symbol)) {return true;} + if (is_ANY_SAFESTRING_type(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_ANY_INT_type(symbol_c *type_symbol) { @@ -170,49 +278,130 @@ if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} - if (is_literal_integer_type(type_symbol)) {return true;} return false; } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEINT_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeuint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_INT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_INT_type (type_symbol)) {return true;} + if (is_ANY_SAFEINT_type(type_symbol)) {return true;} + if (is_literal_integer_type(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_ANY_REAL_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} - if (is_literal_real_type(type_symbol)) {return true;} return false; } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEREAL_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safereal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_REAL_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_REAL_type (type_symbol)) {return true;} + if (is_ANY_SAFEREAL_type(type_symbol)) {return true;} + if (is_literal_real_type(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_ANY_BIT_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} - if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} - if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} - if (is_literal_integer_type(type_symbol)) {return true;} + if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} return false; } +/* A helper function... */ +bool visit_expression_type_c::is_ANY_SAFEBIT_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safebyte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelword_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_BIT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_ANY_BIT_type (type_symbol)) {return true;} + if (is_ANY_SAFEBIT_type(type_symbol)) {return true;} + if (is_nonneg_literal_integer_type(type_symbol)) {return true;} + if (is_literal_bool_type(type_symbol)) {return true;} + return false; +} /* A helper function... */ bool visit_expression_type_c::is_BOOL_type(symbol_c *type_symbol) { if (type_symbol == NULL) {ERROR;} - if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} - if (is_literal_bool_type(type_symbol)) {return true;} + if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} return false; } +/* A helper function... */ +bool visit_expression_type_c::is_SAFEBOOL_type(symbol_c *type_symbol){ + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool visit_expression_type_c::is_ANY_BOOL_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} + if (is_BOOL_type (type_symbol)) {return true;} + if (is_SAFEBOOL_type(type_symbol)) {return true;} + if (is_literal_bool_type(type_symbol)) {return true;} + return false; +} + + +#define is_type(type_name_symbol, type_name_class) (typeid(*type_name_symbol) == typeid(type_name_class)) + #define sizeoftype(symbol) get_sizeof_datatype_c::getsize(symbol) /* A helper function... */ bool visit_expression_type_c::is_literal_integer_type(symbol_c *type_symbol) { - if (type_symbol == NULL) {return true;} + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(neg_integer_c)) {return true;} + return is_nonneg_literal_integer_type(type_symbol); +} + + +/* A helper function... */ +bool visit_expression_type_c::is_nonneg_literal_integer_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {ERROR;} if (typeid(*type_symbol) == typeid(integer_c)) {return true;} if (typeid(*type_symbol) == typeid(binary_integer_c)) {return true;} if (typeid(*type_symbol) == typeid(octal_integer_c)) {return true;} @@ -223,8 +412,9 @@ /* A helper function... */ bool visit_expression_type_c::is_literal_real_type(symbol_c *type_symbol) { - if (type_symbol == NULL) {return true;} - if (typeid(*type_symbol) == typeid(real_c)) {return true;} + if (type_symbol == NULL) {ERROR;} + if (typeid(*type_symbol) == typeid(real_c)) {return true;} + if (typeid(*type_symbol) == typeid(neg_real_c)) {return true;} return false; } @@ -233,15 +423,14 @@ bool visit_expression_type_c::is_literal_bool_type(symbol_c *type_symbol) { bool_type_name_c bool_t; - if (type_symbol == NULL) {return true;} + if (type_symbol == NULL) {ERROR;} if (typeid(*type_symbol) == typeid(boolean_true_c)) {return true;} if (typeid(*type_symbol) == typeid(boolean_false_c)) {return true;} - if (is_literal_integer_type(type_symbol)) + if (is_nonneg_literal_integer_type(type_symbol)) if (sizeoftype(&bool_t) >= sizeoftype(type_symbol)) {return true;} return false; } - /* Determine the common data type between two data types. * If no common data type found, return NULL. * @@ -253,6 +442,7 @@ * * If two literals, then return the literal that requires more bits... */ + symbol_c *visit_expression_type_c::common_type__(symbol_c *first_type, symbol_c *second_type) { if (first_type == NULL && second_type == NULL) {ERROR;} if (first_type == NULL) {return second_type;} @@ -267,30 +457,82 @@ if (is_literal_bool_type(first_type) && is_literal_bool_type(second_type)) {return first_type;} - /* This check can only be made after the is_literal_XXXX checks */ + /* The following check can only be made after the is_literal_XXXX checks */ /* When two literals of the same type, with identical typeid's are checked, - * we must return the one that occupies more bits... + * we must return the one that occupies more bits... This is done above. */ if (typeid(*first_type) == typeid(*second_type)) {return first_type;} - if (is_BOOL_type(first_type) && is_literal_bool_type(second_type)) {return first_type;} - if (is_BOOL_type(second_type) && is_literal_bool_type(first_type)) {return second_type;} - - if (is_ANY_BIT_type(first_type) && is_literal_integer_type(second_type)) + /* NOTE Although a BOOL is also an ANY_BIT, we must check it explicitly since some + * literal bool values are not literal integers... + */ + if (is_BOOL_type(first_type) && is_literal_bool_type(second_type)) {return first_type;} + if (is_BOOL_type(second_type) && is_literal_bool_type(first_type)) {return second_type;} + + if (is_SAFEBOOL_type(first_type) && is_literal_bool_type(second_type)) {return first_type;} + if (is_SAFEBOOL_type(second_type) && is_literal_bool_type(first_type)) {return second_type;} + + if (is_SAFEBOOL_type(first_type) && is_BOOL_type(second_type)) {return second_type;} + if (is_SAFEBOOL_type(second_type) && is_BOOL_type(first_type)) {return first_type;} + + if (is_ANY_BIT_type(first_type) && is_nonneg_literal_integer_type(second_type)) {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} - if (is_ANY_BIT_type(second_type) && is_literal_integer_type(first_type)) + if (is_ANY_BIT_type(second_type) && is_nonneg_literal_integer_type(first_type)) {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} - if (is_ANY_INT_type(first_type) && is_literal_integer_type(second_type)) + if (is_ANY_SAFEBIT_type(first_type) && is_nonneg_literal_integer_type(second_type)) {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} - if (is_ANY_INT_type(second_type) && is_literal_integer_type(first_type)) + if (is_ANY_SAFEBIT_type(second_type) && is_nonneg_literal_integer_type(first_type)) {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} - if (is_ANY_REAL_type(first_type) && is_literal_real_type(second_type)) + if (is_ANY_SAFEBIT_type(first_type) && is_ANY_BIT_type(second_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? second_type:NULL);} + if (is_ANY_SAFEBIT_type(second_type) && is_ANY_BIT_type(first_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? first_type :NULL);} + + if (is_ANY_INT_type(first_type) && is_literal_integer_type(second_type)) {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} - if (is_ANY_REAL_type(second_type) && is_literal_real_type(first_type)) + if (is_ANY_INT_type(second_type) && is_literal_integer_type(first_type)) {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} + if (is_ANY_SAFEINT_type(first_type) && is_literal_integer_type(second_type)) + {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} + if (is_ANY_SAFEINT_type(second_type) && is_literal_integer_type(first_type)) + {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} + + if (is_ANY_SAFEINT_type(first_type) && is_ANY_INT_type(second_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? second_type:NULL);} + if (is_ANY_SAFEINT_type(second_type) && is_ANY_INT_type(first_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? first_type :NULL);} + + if (is_ANY_REAL_type(first_type) && is_literal_real_type(second_type)) + {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} + if (is_ANY_REAL_type(second_type) && is_literal_real_type(first_type)) + {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} + + if (is_ANY_SAFEREAL_type(first_type) && is_literal_real_type(second_type)) + {return ((sizeoftype(first_type) >= sizeoftype(second_type))? first_type :NULL);} + if (is_ANY_SAFEREAL_type(second_type) && is_literal_real_type(first_type)) + {return ((sizeoftype(second_type) >= sizeoftype(first_type)) ? second_type:NULL);} + + if (is_ANY_SAFEREAL_type(first_type) && is_ANY_REAL_type(second_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? second_type:NULL);} + if (is_ANY_SAFEREAL_type(second_type) && is_ANY_REAL_type(first_type)) + {return ((sizeoftype(first_type) == sizeoftype(second_type))? first_type :NULL);} + + /* the Time and Date types... */ + if (is_type(first_type, safetime_type_name_c) && is_type(second_type, time_type_name_c)) {return second_type;} + if (is_type(second_type, safetime_type_name_c) && is_type( first_type, time_type_name_c)) {return first_type;} + + if (is_type(first_type, safedate_type_name_c) && is_type(second_type, date_type_name_c)) {return second_type;} + if (is_type(second_type, safedate_type_name_c) && is_type( first_type, date_type_name_c)) {return first_type;} + + if (is_type(first_type, safedt_type_name_c) && is_type(second_type, dt_type_name_c)) {return second_type;} + if (is_type(second_type, safedt_type_name_c) && is_type( first_type, dt_type_name_c)) {return first_type;} + + if (is_type(first_type, safetod_type_name_c) && is_type(second_type, tod_type_name_c)) {return second_type;} + if (is_type(second_type, safetod_type_name_c) && is_type( first_type, tod_type_name_c)) {return first_type;} + /* no common type */ return NULL; } @@ -306,7 +548,44 @@ } +/* Return TRUE if the second (value) data type may be assigned to a variable of the first (variable) data type + * such as: + * var_type value_type + * BOOL BYTE#7 -> returns false + * INT INT#7 -> returns true + * INT 7 -> returns true + * REAL 7.89 -> returns true + * REAL 7 -> returns true + * INT 7.89 -> returns false + * SAFEBOOL BOOL#1 -> returns false !!! + * etc... + * + * NOTE: It is assumed that the var_type is the data type of an lvalue + */ +bool visit_expression_type_c::is_valid_assignment(symbol_c *var_type, symbol_c *value_type) { + if (var_type == NULL) {/* STAGE3_ERROR(value_type, value_type, "Var_type == NULL"); */ ERROR;} + if (value_type == NULL) {/* STAGE3_ERROR(var_type, var_type, "Value_type == NULL"); */ ERROR;} + if (var_type == NULL || value_type == NULL) {ERROR;} + + symbol_c *common_type = common_type__(var_type, value_type); + if (NULL == common_type) + return false; + return (typeid(*var_type) == typeid(*common_type)); +} + + /* Return TRUE if there is a common data type, otherwise return FALSE + * i.e., return TRUE if both data types may be used simultaneously in an expression + * such as: + * BOOL#0 AND BYTE#7 -> returns false + * 0 AND BYTE#7 -> returns true + * INT#10 AND INT#7 -> returns true + * INT#10 AND 7 -> returns true + * REAL#34.3 AND 7.89 -> returns true + * REAL#34.3 AND 7 -> returns true + * INT#10 AND 7.89 -> returns false + * SAFEBOOL#0 AND BOOL#1 -> returns true !!! + * etc... */ bool visit_expression_type_c::is_compatible_type(symbol_c *first_type, symbol_c *second_type) { if (first_type == NULL || second_type == NULL) {ERROR;} @@ -315,12 +594,12 @@ -#define is_num_type is_ANY_NUM_type -#define is_integer_type is_ANY_INT_type -#define is_real_type is_ANY_REAL_type -#define is_binary_type is_ANY_BIT_type +#define is_num_type is_ANY_NUM_compatible +#define is_integer_type is_ANY_INT_compatible +#define is_real_type is_ANY_REAL_compatible +#define is_binary_type is_ANY_BIT_compatible /* actually the ROR, ROL, SHL, and SHR function also accept boolean type! */ -#define is_nbinary_type is_ANY_BIT_type +#define is_nbinary_type is_ANY_BIT_compatible #define compute_standard_function_default visit_expression_type_c::compute_standard_function_default #define compute_standard_function_il visit_expression_type_c::compute_standard_function_il #define search_expression_type_c visit_expression_type_c @@ -350,20 +629,24 @@ /* A helper function... */ +/* symbol_c *visit_expression_type_c::compute_boolean_expression(symbol_c *left_type, symbol_c *right_type, is_data_type_t is_data_type) { +*/ +symbol_c *visit_expression_type_c::compute_expression(symbol_c *left_type, symbol_c *right_type, + is_data_type_t is_data_type) { bool error = false; if (!(this->*is_data_type)(left_type)) { - STAGE3_ERROR(left_type, left_type, "invalid data type of first operand."); + STAGE3_ERROR(left_type, left_type, "Invalid data type of left operand."); error = true; } if (!(this->*is_data_type)(right_type)) { - STAGE3_ERROR(right_type, right_type, "invalid data type of second operand."); + STAGE3_ERROR(right_type, right_type, "Invalid data type of right operand."); error = true; } if (!is_compatible_type(left_type, right_type)) { - STAGE3_ERROR(left_type, right_type, "type mismatch between operands."); + STAGE3_ERROR(left_type, right_type, "Type mismatch between operands."); error = true; } @@ -374,26 +657,44 @@ } +# if 0 /* A helper function... */ symbol_c *visit_expression_type_c::compute_numeric_expression(symbol_c *left_type, symbol_c *right_type, is_data_type_t is_data_type) { - if (!(this->*is_data_type)(left_type)) - STAGE3_ERROR(left_type, right_type, "Both parts of the equation must be the same type."); - if (!(this->*is_data_type)(right_type)) - STAGE3_ERROR(left_type, right_type, "Both parts of the equation must be the same type."); - if (!is_compatible_type(left_type, right_type)) - STAGE3_ERROR(left_type, right_type, "Both parts of the equation must be the same type."); - + bool error = false; + + if (!(this->*is_data_type)(left_type)) { + STAGE3_ERROR(left_type, right_type, "Invalid data type of left operand."); + error = true; + } + if (!(this->*is_data_type)(right_type)) { + STAGE3_ERROR(left_type, right_type, "Invalid data type of right operand."); + error = true; + } + if (!is_compatible_type(left_type, right_type)) { + STAGE3_ERROR(left_type, right_type, "Type mismatch between operands."); + error = true; + } + +/* if (is_literal_integer_type(left_type) || is_literal_real_type(left_type)) { return right_type; } else { return left_type; } +*/ + + if (error) + return NULL; + else + return common_type(left_type, right_type); /* humour the compiler... */ - return NULL; -} - +/* + return NULL; +*/ +} +#endif @@ -425,7 +726,7 @@ */ if(param_name != NULL) { param_type = fp_iterator.param_type(); - if(!is_compatible_type(il_default_variable_type,param_type)) + if(!is_valid_assignment(param_type, il_default_variable_type)) STAGE3_ERROR(f_call, f_call, "In function/FB call, first parameter has invalid data type."); } } // if (use_il_defvar) @@ -449,7 +750,7 @@ /* Get the parameter type */ param_type = fp_iterator.param_type(); /* If the declared parameter and the parameter from the function call do no have the same type */ - if(!is_compatible_type(call_param_type,param_type)) STAGE3_ERROR(call_param_value, call_param_value, "Type mismatch in function/FB call parameter."); + if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_value, call_param_value, "Type mismatch in function/FB call parameter."); } } } @@ -499,8 +800,7 @@ /* Get the parameter type */ param_type = fp_iterator.param_type(); /* If the declared parameter and the parameter from the function call have the same type */ -// if(!is_compatible_type(call_param_type, param_type)) STAGE3_ERROR(call_param_name, call_param_value, "Type mismatch function/FB call parameter."); - if(!is_compatible_type(call_param_type, param_type)) STAGE3_ERROR(call_param_name, call_param_name, "Type mismatch function/FB call parameter."); + if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_name, call_param_name, "Type mismatch function/FB call parameter."); } } @@ -549,7 +849,7 @@ /* Get the parameter type */ param_type = fp_iterator.param_type(); /* If the declared parameter and the parameter from the function call have the same type */ - if(!is_compatible_type(call_param_type, param_type)) STAGE3_ERROR(call_param_name, call_param_value, "Type mismatch function/FB call parameter."); + if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_name, call_param_value, "Type mismatch function/FB call parameter."); } } } @@ -929,7 +1229,7 @@ void *visit_expression_type_c::visit(LDN_operator_c *symbol) { if(il_operand_type == NULL) STAGE3_ERROR(symbol, symbol, "LDN operator requires an operand."); - if(!is_ANY_BIT_type(il_operand_type)) + if(!is_ANY_BIT_compatible(il_operand_type)) STAGE3_ERROR(symbol, symbol, "invalid data type of LDN operand, should be of type ANY_BIT."); il_default_variable_type = il_operand_type; return NULL; @@ -938,7 +1238,8 @@ // SYM_REF0(ST_operator_c) void *visit_expression_type_c::visit(ST_operator_c *symbol) { verify_null(symbol); - if(!is_compatible_type(il_default_variable_type, il_operand_type)) + + if(!is_valid_assignment(il_operand_type, il_default_variable_type)) STAGE3_ERROR(symbol, symbol, "Type mismatch in ST operation."); /* TODO: check whether il_operand_type is an LVALUE !! */ /* data type of il_default_variable_type is unchanged... */ @@ -949,12 +1250,12 @@ // SYM_REF0(STN_operator_c) void *visit_expression_type_c::visit(STN_operator_c *symbol) { verify_null(symbol); - if(!is_compatible_type(il_default_variable_type, il_operand_type)) + if(!is_valid_assignment(il_operand_type, il_default_variable_type)) STAGE3_ERROR(symbol, symbol, "Type mismatch in ST operation."); /* TODO: check whether il_operand_type is an LVALUE !! */ - if(!is_ANY_BIT_type(il_default_variable_type)) + if(!is_ANY_BIT_compatible(il_default_variable_type)) STAGE3_ERROR(symbol, symbol, "invalid data type of il_default_variable for STN operand, should be of type ANY_BIT."); - if(!is_ANY_BIT_type(il_operand_type)) + if(!is_ANY_BIT_compatible(il_operand_type)) STAGE3_ERROR(symbol, symbol, "invalid data type of STN operand, should be of type ANY_BIT."); /* data type of il_default_variable_type is unchanged... */ // il_default_variable_type = il_default_variable_type; @@ -971,7 +1272,7 @@ STAGE3_ERROR(symbol, symbol, "Il default variable should not be NULL."); return NULL; } - if(!is_ANY_BIT_type(il_default_variable_type)) { + if(!is_ANY_BIT_compatible(il_default_variable_type)) { STAGE3_ERROR(symbol, symbol, "Il default variable should be of type ANY_BIT."); return NULL; } @@ -1054,42 +1355,42 @@ //SYM_REF0(AND_operator_c) void *visit_expression_type_c::visit(AND_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } //SYM_REF0(OR_operator_c) void *visit_expression_type_c::visit(OR_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } //SYM_REF0(XOR_operator_c) void *visit_expression_type_c::visit(XOR_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } // SYM_REF0(ANDN_operator_c) void *visit_expression_type_c::visit(ANDN_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } // SYM_REF0(ORN_operator_c) void *visit_expression_type_c::visit(ORN_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } // SYM_REF0(XORN_operator_c) void *visit_expression_type_c::visit(XORN_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_BIT_compatible); return NULL; } @@ -1098,13 +1399,32 @@ verify_null(symbol); symbol_c *left_type = il_default_variable_type; symbol_c *right_type = il_operand_type; - if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) + +/* The following is not required, it is already handled by compute_expression() ... */ +/* + if (is_type(left_type, time_type_name_c) && is_type(right_type, time_type_name_c)) il_default_variable_type = &time_type_name; - else if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) +*/ + + if (is_type(left_type, tod_type_name_c) && is_type(right_type, time_type_name_c)) il_default_variable_type = &tod_type_name; - else if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &tod_type_name; + else if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &tod_type_name; + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &safetod_type_name; + + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, time_type_name_c)) il_default_variable_type = &dt_type_name; - else il_default_variable_type = compute_numeric_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_MAGNITUDE_type); + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &dt_type_name; + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &dt_type_name; + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &safedt_type_name; + + else il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_MAGNITUDE_compatible); return NULL; } @@ -1113,19 +1433,59 @@ verify_null(symbol); symbol_c *left_type = il_default_variable_type; symbol_c *right_type = il_operand_type;; + +/* The following is not required, it is already handled by compute_expression() ... */ +/* if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) il_default_variable_type = &time_type_name; - else if (typeid(*left_type) == typeid(date_type_name_c) && typeid(*right_type) == typeid(date_type_name_c)) +*/ + + if (is_type(left_type, tod_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &tod_type_name; + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &tod_type_name; + else if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &tod_type_name; + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &safetod_type_name; + + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &dt_type_name; + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, time_type_name_c)) + il_default_variable_type = &dt_type_name; + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &dt_type_name; + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safetime_type_name_c)) + il_default_variable_type = &safedt_type_name; + + else if (is_type(left_type, date_type_name_c) && is_type(right_type, date_type_name_c)) il_default_variable_type = &time_type_name; - else if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) - il_default_variable_type = &tod_type_name; - else if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) + else if (is_type(left_type, safedate_type_name_c) && is_type(right_type, date_type_name_c)) il_default_variable_type = &time_type_name; - else if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) - il_default_variable_type = &dt_type_name; - else if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)) + else if (is_type(left_type, date_type_name_c) && is_type(right_type, safedate_type_name_c)) il_default_variable_type = &time_type_name; - else il_default_variable_type = compute_numeric_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_MAGNITUDE_type); + else if (is_type(left_type, safedate_type_name_c) && is_type(right_type, safedate_type_name_c)) + il_default_variable_type = &safetime_type_name; + + else if (is_type(left_type, tod_type_name_c) && is_type(right_type, tod_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, tod_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetod_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetod_type_name_c)) + il_default_variable_type = &safetime_type_name; + + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, dt_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, dt_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, dt_type_name_c) && is_type(right_type, safedt_type_name_c)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safedt_type_name_c)) + il_default_variable_type = &safetime_type_name; + + else il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_MAGNITUDE_compatible); return NULL; } @@ -1134,9 +1494,20 @@ verify_null(symbol); symbol_c *left_type = il_default_variable_type; symbol_c *right_type = il_operand_type; - if (typeid(*left_type) == typeid(time_type_name_c) && is_ANY_NUM_type(right_type)) + + if (is_type(left_type, time_type_name_c) && is_ANY_NUM_compatible(right_type)) il_default_variable_type = &time_type_name; - else il_default_variable_type = compute_numeric_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_NUM_type); + else if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_type(right_type)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safetime_type_name_c) && is_ANY_SAFENUM_type(right_type)) + il_default_variable_type = &safetime_type_name; + /* Since we have already checked for ANY_NUM_type and ANY_SAFENUM_type in the previous lines, + * this next line is really only to check for integers/reals of undefined type on 'right_type'... + */ + else if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_compatible(right_type)) + il_default_variable_type = &safetime_type_name; + + else il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_NUM_compatible); return NULL; } @@ -1145,23 +1516,34 @@ verify_null(symbol); symbol_c *left_type = il_default_variable_type; symbol_c *right_type = il_operand_type; - if (typeid(*left_type) == typeid(time_type_name_c) && is_ANY_NUM_type(right_type)) + + if (is_type(left_type, time_type_name_c) && is_ANY_NUM_compatible(right_type)) il_default_variable_type = &time_type_name; - else il_default_variable_type = compute_numeric_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_NUM_type); + else if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_type(right_type)) + il_default_variable_type = &time_type_name; + else if (is_type(left_type, safetime_type_name_c) && is_ANY_SAFENUM_type(right_type)) + il_default_variable_type = &safetime_type_name; + /* Since we have already checked for ANY_NUM_type and ANY_SAFENUM_type in the previous lines, + * this next line is really only to check for integers/reals of undefined type on 'right_type'... + */ + else if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_compatible(right_type)) + il_default_variable_type = &safetime_type_name; + + else il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_NUM_compatible); return NULL; } // SYM_REF0(MOD_operator_c) void *visit_expression_type_c::visit(MOD_operator_c *symbol) { verify_null(symbol); - il_default_variable_type = compute_numeric_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_INT_type); + il_default_variable_type = compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_INT_compatible); return NULL; } // SYM_REF0(GT_operator_c) void *visit_expression_type_c::visit(GT_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1169,7 +1551,7 @@ //SYM_REF0(GE_operator_c) void *visit_expression_type_c::visit(GE_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1177,7 +1559,7 @@ //SYM_REF0(EQ_operator_c) void *visit_expression_type_c::visit(EQ_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1185,7 +1567,7 @@ //SYM_REF0(LT_operator_c) void *visit_expression_type_c::visit(LT_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1193,7 +1575,7 @@ //SYM_REF0(LE_operator_c) void *visit_expression_type_c::visit(LE_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1201,7 +1583,7 @@ //SYM_REF0(NE_operator_c) void *visit_expression_type_c::visit(NE_operator_c *symbol) { verify_null(symbol); - compute_boolean_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(il_default_variable_type, il_operand_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); il_default_variable_type = &search_expression_type_c::bool_type_name; return NULL; } @@ -1299,28 +1681,28 @@ void *visit_expression_type_c::visit(or_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - return compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_type); + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_compatible); } void *visit_expression_type_c::visit(xor_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - return compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_type); + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_compatible); } void *visit_expression_type_c::visit(and_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - return compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_type); + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_BIT_compatible); } void *visit_expression_type_c::visit(equ_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1328,7 +1710,7 @@ void *visit_expression_type_c::visit(notequ_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1336,7 +1718,7 @@ void *visit_expression_type_c::visit(lt_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1344,7 +1726,7 @@ void *visit_expression_type_c::visit(gt_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1352,7 +1734,7 @@ void *visit_expression_type_c::visit(le_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1360,7 +1742,7 @@ void *visit_expression_type_c::visit(ge_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - compute_boolean_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_type); + compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_ELEMENTARY_compatible); return &search_expression_type_c::bool_type_name; } @@ -1368,55 +1750,147 @@ void *visit_expression_type_c::visit(add_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;} - if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;} - if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;} - return compute_numeric_expression(left_type, right_type, &visit_expression_type_c::is_ANY_MAGNITUDE_type); + +/* The following is already checked in compute_expression */ +/* + if (is_type(left_type, time_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&time_type_name; +*/ + + if (is_type(left_type, tod_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&safetod_type_name; + + if (is_type(left_type, dt_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, dt_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&safedt_type_name; + + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_MAGNITUDE_compatible); } void *visit_expression_type_c::visit(sub_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;} - if (typeid(*left_type) == typeid(date_type_name_c) && typeid(*right_type) == typeid(date_type_name_c)) {return (void *)&time_type_name;} - if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;} - if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) {return (void *)&time_type_name;} - if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;} - if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)) {return (void *)&time_type_name;} - return compute_numeric_expression(left_type, right_type, &visit_expression_type_c::is_ANY_MAGNITUDE_type); + +/* The following is already checked in compute_expression */ +/* + if (is_type(left_type, time_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&time_type_name; +*/ + + if (is_type(left_type, tod_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&tod_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&safetod_type_name; + + if (is_type(left_type, dt_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, time_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, dt_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&dt_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safetime_type_name_c)) + return (void *)&safedt_type_name; + + if (is_type(left_type, tod_type_name_c) && is_type(right_type, tod_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, tod_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, tod_type_name_c) && is_type(right_type, safetod_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safetod_type_name_c) && is_type(right_type, safetod_type_name_c)) + return (void *)&safetime_type_name; + + if (is_type(left_type, date_type_name_c) && is_type(right_type, date_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safedate_type_name_c) && is_type(right_type, date_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, date_type_name_c) && is_type(right_type, safedate_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safedate_type_name_c) && is_type(right_type, safedate_type_name_c)) + return (void *)&safetime_type_name; + + if (is_type(left_type, dt_type_name_c) && is_type(right_type, dt_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, dt_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, dt_type_name_c) && is_type(right_type, safedt_type_name_c)) + return (void *)&time_type_name; + if (is_type(left_type, safedt_type_name_c) && is_type(right_type, safedt_type_name_c)) + return (void *)&safetime_type_name; + + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_MAGNITUDE_compatible); } void *visit_expression_type_c::visit(mul_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (typeid(*left_type) == typeid(time_type_name_c) && is_ANY_NUM_type(right_type)) {return (void *)&time_type_name;} - return compute_numeric_expression(left_type, right_type, &visit_expression_type_c::is_ANY_NUM_type); + + if (is_type(left_type, time_type_name_c) && is_ANY_NUM_compatible(right_type)) + return (void *)&time_type_name; + if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_type(right_type)) + return (void *)&time_type_name; + if (is_type(left_type, safetime_type_name_c) && is_ANY_SAFENUM_type(right_type)) + return (void *)&safetime_type_name; + /* Since we have already checked for ANY_NUM_type and ANY_SAFENUM_type in the previous lines, + * this next line is really only to check for integers/reals of undefined type on 'right_type'... + */ + if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_compatible(right_type)) + return (void *)&safetime_type_name; + + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_NUM_compatible); } void *visit_expression_type_c::visit(div_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (typeid(*left_type) == typeid(time_type_name_c) && is_ANY_NUM_type(right_type)){return (void *)&time_type_name;} - return compute_numeric_expression(left_type, right_type, &visit_expression_type_c::is_ANY_NUM_type); + + if (is_type(left_type, time_type_name_c) && is_ANY_NUM_compatible(right_type)) + return (void *)&time_type_name; + if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_type(right_type)) + return (void *)&time_type_name; + if (is_type(left_type, safetime_type_name_c) && is_ANY_SAFENUM_type(right_type)) + return (void *)&safetime_type_name; + /* Since we have already checked for ANY_NUM_type and ANY_SAFENUM_type in the previous lines, + * this next line is really only to check for integers/reals of undefined type on 'right_type'... + */ + if (is_type(left_type, safetime_type_name_c) && is_ANY_NUM_compatible(right_type)) + return (void *)&safetime_type_name; + + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_NUM_compatible); } void *visit_expression_type_c::visit(mod_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - return compute_numeric_expression(left_type, right_type, &visit_expression_type_c::is_ANY_INT_type); + return compute_expression(left_type, right_type, &visit_expression_type_c::is_ANY_INT_compatible); } void *visit_expression_type_c::visit(power_expression_c *symbol) { symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (!is_ANY_REAL_type(left_type)) + if (!is_ANY_REAL_compatible(left_type)) STAGE3_ERROR(symbol->l_exp, symbol->l_exp, "first operand of ** operator has invalid data type, should be of type ANY_REAL."); - if (!is_ANY_NUM_type(right_type)) + if (!is_ANY_NUM_compatible(right_type)) STAGE3_ERROR(symbol->r_exp, symbol->r_exp, "second operand of ** operator has invalid data type, should be of type ANY_NUM."); return (void *)left_type; @@ -1425,7 +1899,7 @@ void *visit_expression_type_c::visit(neg_expression_c *symbol) { symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this)); - if (!is_ANY_MAGNITUDE_type(exp_type)) + if (!is_ANY_MAGNITUDE_compatible(exp_type)) STAGE3_ERROR(symbol, symbol, "operand of negate expression '-' has invalid data type, should be of type ANY_MAGNITUDE."); return exp_type; @@ -1434,7 +1908,7 @@ void *visit_expression_type_c::visit(not_expression_c *symbol) { symbol_c *type = base_type((symbol_c *)symbol->exp->accept(*this)); - return compute_boolean_expression(type, type, &visit_expression_type_c::is_ANY_BIT_type); + return compute_expression(type, type, &visit_expression_type_c::is_ANY_BIT_compatible); } @@ -1475,7 +1949,7 @@ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); - if (!is_compatible_type(left_type, right_type)) { + if (!is_valid_assignment(left_type, right_type)) { STAGE3_ERROR(symbol, symbol, "data type mismatch in assignment statement!\n"); } return NULL; @@ -1595,6 +2069,7 @@ } else { element_type = base_type(element_type); if (NULL != element_type){ + /* The CASE value is only used for comparison (and not assingment), so we only check for compatibility! */ if (!is_compatible_type(case_expression_type, element_type)) STAGE3_ERROR(symbol->elements[i], symbol->elements[i], "Invalid data type of case list element."); } @@ -1616,21 +2091,24 @@ if (NULL == var_type) ERROR; // ASSIGN symbol_c *beg_expr_type = base_type((symbol_c*)symbol->beg_expression->accept(*this)); - if (NULL != beg_expr_type) { - if(!is_compatible_type(var_type,beg_expr_type)) + if (NULL != beg_expr_type) { + /* The BEG value is assigned to the variable, so we check for assignment validity! */ + if(!is_valid_assignment(var_type, beg_expr_type)) STAGE3_ERROR(symbol, symbol, "Data type mismatch between control variable and initial value."); } // TO symbol_c *end_expr_type = base_type((symbol_c*)symbol->end_expression->accept(*this)); if (NULL != end_expr_type) { - if(!is_compatible_type(var_type,end_expr_type)) + /* The TO value is only used for comparison, so we only check for compatibility! */ + if(!is_compatible_type(var_type, end_expr_type)) STAGE3_ERROR(symbol, symbol, "Data type mismatch between control variable and final value."); } // BY if(symbol->by_expression != NULL) { symbol_c *by_expr_type = base_type((symbol_c*)symbol->by_expression->accept(*this)); if (NULL != end_expr_type) { - if(!is_compatible_type(var_type,by_expr_type)) + /* The BY value is used in an expression (add, sub, ...), so we only check for compatibility! */ + if(!is_compatible_type(var_type, by_expr_type)) STAGE3_ERROR(symbol, symbol, "Data type mismatch between control variable and BY value."); } } diff -r 8ffa211b7f9a -r 90782e241346 stage3/visit_expression_type.hh --- a/stage3/visit_expression_type.hh Thu Aug 27 16:29:23 2009 +0100 +++ b/stage3/visit_expression_type.hh Wed Mar 30 19:53:32 2011 +0100 @@ -76,20 +76,53 @@ visit_expression_type_c(symbol_c *search_scope); virtual ~visit_expression_type_c(void); + + typedef struct { + symbol_c *value; + symbol_c *type; + } value_and_type_t; + /* A helper function... */ - bool is_ANY_ELEMENTARY_type(symbol_c *type_symbol); - bool is_ANY_MAGNITUDE_type(symbol_c *type_symbol); - bool is_ANY_DATE_type(symbol_c *type_symbol); - bool is_ANY_STRING_type(symbol_c *type_symbol); - bool is_ANY_INT_type(symbol_c *type_symbol); - bool is_ANY_REAL_type(symbol_c *type_symbol); - bool is_ANY_NUM_type(symbol_c *type_symbol); - bool is_ANY_BIT_type(symbol_c *type_symbol); - bool is_BOOL_type(symbol_c *type_symbol); - - bool is_literal_integer_type(symbol_c *type_symbol); - bool is_literal_real_type(symbol_c *type_symbol); - bool is_literal_bool_type(symbol_c *type_symbol); + bool is_ANY_ELEMENTARY_type (symbol_c *type_symbol); + bool is_ANY_SAFEELEMENTARY_type (symbol_c *type_symbol); + bool is_ANY_ELEMENTARY_compatible (symbol_c *type_symbol); + + bool is_ANY_MAGNITUDE_type (symbol_c *type_symbol); + bool is_ANY_SAFEMAGNITUDE_type (symbol_c *type_symbol); + bool is_ANY_MAGNITUDE_compatible (symbol_c *type_symbol); + + bool is_ANY_DATE_type (symbol_c *type_symbol); + bool is_ANY_SAFEDATE_type (symbol_c *type_symbol); + bool is_ANY_DATE_compatible (symbol_c *type_symbol); + + bool is_ANY_STRING_type (symbol_c *type_symbol); + bool is_ANY_SAFESTRING_type (symbol_c *type_symbol); + bool is_ANY_STRING_compatible (symbol_c *type_symbol); + + bool is_ANY_INT_type (symbol_c *type_symbol); + bool is_ANY_SAFEINT_type (symbol_c *type_symbol); + bool is_ANY_INT_compatible (symbol_c *type_symbol); + + bool is_ANY_REAL_type (symbol_c *type_symbol); + bool is_ANY_SAFEREAL_type (symbol_c *type_symbol); + bool is_ANY_REAL_compatible (symbol_c *type_symbol); + + bool is_ANY_NUM_type (symbol_c *type_symbol); + bool is_ANY_SAFENUM_type (symbol_c *type_symbol); + bool is_ANY_NUM_compatible (symbol_c *type_symbol); + + bool is_ANY_BIT_type (symbol_c *type_symbol); + bool is_ANY_SAFEBIT_type (symbol_c *type_symbol); + bool is_ANY_BIT_compatible (symbol_c *type_symbol); + + bool is_BOOL_type (symbol_c *type_symbol); + bool is_SAFEBOOL_type (symbol_c *type_symbol); + bool is_ANY_BOOL_compatible (symbol_c *type_symbol); + + bool is_nonneg_literal_integer_type (symbol_c *type_symbol); + bool is_literal_integer_type (symbol_c *type_symbol); + bool is_literal_real_type (symbol_c *type_symbol); + bool is_literal_bool_type (symbol_c *type_symbol); /* Determine the common data type between two data types. * If no common data type found, return NULL. @@ -108,7 +141,35 @@ * if no common data type is found. */ symbol_c *common_type(symbol_c *first_type, symbol_c *second_type); - /* Return TRUE if there is a common data type, otherwise return FALSE */ +/* Return TRUE if the second (value) data type may be assigned to a variable of the first (variable) data type + * such as: + * var_type value_type + * BOOL BYTE#7 -> returns false + * INT INT#7 -> returns true + * INT 7 -> returns true + * REAL 7.89 -> returns true + * REAL 7 -> returns true + * INT 7.89 -> returns false + * SAFEBOOL BOOL#1 -> returns false !!! + * etc... + * + * NOTE: It is assumed that the var_type is the data type of an lvalue + */ + bool is_valid_assignment(symbol_c *var_type, symbol_c *value_type); + +/* Return TRUE if there is a common data type, otherwise return FALSE + * i.e., return TRUE if both data types may be used simultaneously in an expression + * such as: + * BOOL#0 AND BYTE#7 -> returns false + * 0 AND BYTE#7 -> returns true + * INT#10 AND INT#7 -> returns true + * INT#10 AND 7 -> returns true + * REAL#34.3 AND 7.89 -> returns true + * REAL#34.3 AND 7 -> returns true + * INT#10 AND 7.89 -> returns false + * SAFEBOOL#0 AND BOOL#1 -> returns true !!! + * etc... + */ bool is_compatible_type(symbol_c *first_type, symbol_c *second_type); void compute_input_operatores(symbol_c *symbol, const char *input_operator); @@ -128,8 +189,9 @@ /* A helper function... */ typedef bool (visit_expression_type_c::*is_data_type_t)(symbol_c *type_symbol); /* a pointer to a function! */ - symbol_c *compute_boolean_expression(symbol_c *left_exp, symbol_c *right_exp, is_data_type_t is_data_type); - symbol_c *compute_numeric_expression(symbol_c *left_exp, symbol_c *right_exp, is_data_type_t is_data_type); +// symbol_c *compute_boolean_expression(symbol_c *left_exp, symbol_c *right_exp, is_data_type_t is_data_type); +// symbol_c *compute_numeric_expression(symbol_c *left_exp, symbol_c *right_exp, is_data_type_t is_data_type); + symbol_c *compute_expression(symbol_c *left_exp, symbol_c *right_exp, is_data_type_t is_data_type); /* a helper function... */ symbol_c *base_type(symbol_c *symbol); diff -r 8ffa211b7f9a -r 90782e241346 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage4/generate_c/generate_c.cc Wed Mar 30 19:53:32 2011 +0100 @@ -960,6 +960,7 @@ s4o.print("/* Editing this file is not recommended... */\n"); s4o.print("/*******************************************/\n\n"); s4o.print("#include \"iec_std_lib.h\"\n\n"); + s4o.print("#include \"accessor.h\"\n\n"); /* (A) configuration declaration... */ /* (A.1) configuration name in comment */ diff -r 8ffa211b7f9a -r 90782e241346 stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage4/generate_c/generate_c_base.cc Wed Mar 30 19:53:32 2011 +0100 @@ -255,21 +255,34 @@ void *visit(octal_integer_c *symbol) {s4o.print("0"); return print_striped_token(symbol, 2);} void *visit(hex_integer_c *symbol) {s4o.print("0x"); return print_striped_token(symbol, 3);} + void *visit(neg_real_c *symbol) { + s4o.print("-"); + symbol->exp->accept(*this); + return NULL; + } + + void *visit(neg_integer_c *symbol) { + s4o.print("-"); + symbol->exp->accept(*this); + return NULL; + } + void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} void *visit(bit_string_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} - void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} + void *visit(boolean_literal_c *symbol) { + if (NULL != symbol->type) + return print_literal(symbol->type, symbol->value); + else { + bool_type_name_c bool_type; + return print_literal(&bool_type, symbol->value); + } + } /* helper class for boolean_literal_c */ void *visit(boolean_true_c *symbol) {s4o.print("TRUE"); return NULL;} void *visit(boolean_false_c *symbol) {s4o.print("FALSE"); return NULL;} - void *visit(neg_literal_c *symbol) { - s4o.print("-"); - symbol->exp->accept(*this); - return NULL; - } - void *visit(neg_expression_c *symbol) { s4o.print("-"); symbol->exp->accept(*this); @@ -514,35 +527,49 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ - void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;} - void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} - void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} - void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;} - void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} - void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} - void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} - void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} - void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} - void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} - void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;} - void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} - void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;} - void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} - void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;} - void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} - void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;} - void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} - void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} - void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;} - void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} - /******************************************************/ - /* Extensions to the base standard as defined in */ - /* "Safety Software Technical Specification, */ - /* Part 1: Concepts and Function Blocks, */ - /* Version 1.0 – Official Release" */ - /* by PLCopen - Technical Committee 5 - 2006-01-31 */ - /******************************************************/ - void *visit(safebool_type_name_c *symbol) {s4o.print("SAFEBOOL"); return NULL;} + void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;} + void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} + void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} + void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;} + void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} + void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} + void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} + void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} + void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} + void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} + void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;} + void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} + void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;} + void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} + void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;} + void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} + void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;} + void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} + void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} + void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;} + void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} + + void *visit(safetime_type_name_c *symbol) {s4o.print("TIME"); return NULL;} + void *visit(safebool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} + void *visit(safesint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} + void *visit(safeint_type_name_c *symbol) {s4o.print("INT"); return NULL;} + void *visit(safedint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} + void *visit(safelint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} + void *visit(safeusint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} + void *visit(safeuint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} + void *visit(safeudint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} + void *visit(safeulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} + void *visit(safereal_type_name_c *symbol) {s4o.print("REAL"); return NULL;} + void *visit(safelreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} + void *visit(safedate_type_name_c *symbol) {s4o.print("DATE"); return NULL;} + void *visit(safetod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} + void *visit(safedt_type_name_c *symbol) {s4o.print("DT"); return NULL;} + void *visit(safebyte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} + void *visit(safeword_type_name_c *symbol) {s4o.print("WORD"); return NULL;} + void *visit(safelword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} + void *visit(safedword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} + void *visit(safestring_type_name_c *symbol) {s4o.print("STRING"); return NULL;} + void *visit(safewstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} /********************************/ /* B.1.3.2 - Generic data types */ diff -r 8ffa211b7f9a -r 90782e241346 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage4/generate_c/generate_c_st.cc Wed Mar 30 19:53:32 2011 +0100 @@ -383,13 +383,13 @@ } /* TODO: power expression... */ -void *visit(power_expression_c *symbol) {ERROR; return print_binary_expression(symbol->l_exp, symbol->r_exp, " ** ");} +void *visit(power_expression_c *symbol) { + ERROR; + return print_binary_expression(symbol->l_exp, symbol->r_exp, " ** "); +} + void *visit(neg_expression_c *symbol) { - symbol_c *exp_type = search_expression_type->get_type(symbol->exp); - if (search_expression_type->is_integer_type(exp_type) || search_expression_type->is_real_type(exp_type)) - return print_unary_expression(symbol->exp, " -"); - ERROR; - return NULL; + return print_unary_expression(symbol->exp, " -"); } void *visit(not_expression_c *symbol) { diff -r 8ffa211b7f9a -r 90782e241346 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Thu Aug 27 16:29:23 2009 +0100 +++ b/stage4/generate_iec/generate_iec.cc Wed Mar 30 19:53:32 2011 +0100 @@ -71,8 +71,10 @@ } void *print_literal(symbol_c *type, symbol_c *value) { - type->accept(*this); - s4o.print("#"); + if (NULL != type) { + type->accept(*this); + s4o.print("#"); + } value->accept(*this); return NULL; } @@ -168,22 +170,22 @@ /******************************/ /* B 1.2.1 - Numeric Literals */ /******************************/ -void *visit(real_c *symbol) {return print_token(symbol);} -void *visit(integer_c *symbol) {return print_token(symbol);} -void *visit(binary_integer_c *symbol) {return print_token(symbol);} -void *visit(octal_integer_c *symbol) {return print_token(symbol);} -void *visit(hex_integer_c *symbol) {return print_token(symbol);} - -void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} -void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} +void *visit(real_c *symbol) {return print_token(symbol);} +void *visit(neg_real_c *symbol) {return print_unary_expression(symbol->exp, "-");} +void *visit(integer_c *symbol) {return print_token(symbol);} +void *visit(neg_integer_c *symbol) {return print_unary_expression(symbol->exp, "-");} +void *visit(binary_integer_c *symbol) {return print_token(symbol);} +void *visit(octal_integer_c *symbol) {return print_token(symbol);} +void *visit(hex_integer_c *symbol) {return print_token(symbol);} + +void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} +void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} void *visit(bit_string_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} -void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} -void *visit(neg_literal_c *symbol) {return print_unary_expression(symbol->exp, "-");} - +void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);} /* helper class for boolean_literal_c */ -void *visit(boolean_true_c *symbol) {s4o.print(/*"TRUE"*/"1"); return NULL;} -void *visit(boolean_false_c *symbol) {s4o.print(/*"FALSE"*/"0"); return NULL;} +void *visit(boolean_true_c *symbol) {s4o.print(/*"TRUE"*/"1"); return NULL;} +void *visit(boolean_false_c *symbol) {s4o.print(/*"FALSE"*/"0"); return NULL;} /*******************************/ /* B.1.2.2 Character Strings */ @@ -297,39 +299,50 @@ /***********************************/ /* B 1.3.1 - Elementary Data Types */ /***********************************/ -void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;} -void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} -/******************************************************/ -/* whether we are suporting safe extensions */ -/* as defined in PLCopen - Technical Committee 5 */ -/* Safety Software Technical Specification, */ -/* Part 1: Concepts and Function Blocks, */ -/* Version 1.0 – Official Release */ -/******************************************************/ -void *visit(safebool_type_name_c *symbol) {s4o.print("SAFEBOOL"); return NULL;} -void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} -void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;} -void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} -void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} -void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} -void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} -void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} -void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} -void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;} -void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} -void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;} -void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} -void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;} -void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} -void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;} -void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} -void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} -void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;} -void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} -/* -void *visit(constant_int_type_name_c *symbol) {return NULL;} -void *visit(constant_real_type_name_c *symbol) {return NULL;} -*/ +void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;} +void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;} +void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;} +void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;} +void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;} +void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;} +void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;} +void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;} +void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;} +void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;} +void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;} +void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;} +void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;} +void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;} +void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;} +void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;} +void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;} +void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;} +void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;} +void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;} +void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;} + +void *visit(safetime_type_name_c *symbol) {s4o.print("SAFETIME"); return NULL;} +void *visit(safebool_type_name_c *symbol) {s4o.print("SAFEBOOL"); return NULL;} +void *visit(safesint_type_name_c *symbol) {s4o.print("SAFESINT"); return NULL;} +void *visit(safeint_type_name_c *symbol) {s4o.print("SAFEINT"); return NULL;} +void *visit(safedint_type_name_c *symbol) {s4o.print("SAFEDINT"); return NULL;} +void *visit(safelint_type_name_c *symbol) {s4o.print("SAFELINT"); return NULL;} +void *visit(safeusint_type_name_c *symbol) {s4o.print("SAFEUSINT"); return NULL;} +void *visit(safeuint_type_name_c *symbol) {s4o.print("SAFEUINT"); return NULL;} +void *visit(safeudint_type_name_c *symbol) {s4o.print("SAFEUDINT"); return NULL;} +void *visit(safeulint_type_name_c *symbol) {s4o.print("SAFEULINT"); return NULL;} +void *visit(safereal_type_name_c *symbol) {s4o.print("SAFEREAL"); return NULL;} +void *visit(safelreal_type_name_c *symbol) {s4o.print("SAFELREAL"); return NULL;} +void *visit(safedate_type_name_c *symbol) {s4o.print("SAFEDATE"); return NULL;} +void *visit(safetod_type_name_c *symbol) {s4o.print("SAFETOD"); return NULL;} +void *visit(safedt_type_name_c *symbol) {s4o.print("SAFEDT"); return NULL;} +void *visit(safebyte_type_name_c *symbol) {s4o.print("SAFEBYTE"); return NULL;} +void *visit(safeword_type_name_c *symbol) {s4o.print("SAFEWORD"); return NULL;} +void *visit(safelword_type_name_c *symbol) {s4o.print("SAFELWORD"); return NULL;} +void *visit(safedword_type_name_c *symbol) {s4o.print("SAFEDWORD"); return NULL;} +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.3 - Derived data types */