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."); } }