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