--- a/stage3/fill_candidate_datatypes.cc Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/fill_candidate_datatypes.cc Sat Apr 07 16:14:17 2012 +0100
@@ -522,6 +522,22 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+
+/* simple_specification ASSIGN constant */
+// SYM_REF2(simple_spec_init_c, simple_specification, constant)
+void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
+ if (NULL != symbol->constant) symbol->constant->accept(*this);
+ add_datatype_to_candidate_list(symbol->simple_specification, base_type(symbol->simple_specification));
+ symbol->candidate_datatypes = symbol->simple_specification->candidate_datatypes;
+ /* NOTE: Even if the constant and the type are of incompatible data types, we let the
+ * simple_spec_init_c object inherit the data type of the type declaration (simple_specification)
+ * This will let us produce more informative error messages when checking data type compatibility
+ * with located variables (AT %QW3.4 : WORD).
+ */
+ // if (NULL != symbol->constant) intersect_candidate_datatype_list(symbol /*origin, dest.*/, symbol->constant /*with*/);
+ return NULL;
+}
+
/* signed_integer DOTDOT signed_integer */
// SYM_REF2(subrange_c, lower_limit, upper_limit)
void *fill_candidate_datatypes_c::visit(subrange_c *symbol) {
@@ -575,6 +591,7 @@
return NULL;
}
+
/********************************************/
/* B 1.4.1 - Directly Represented Variables */
/********************************************/
@@ -588,11 +605,11 @@
* if (symbol->value[1] == '\0') ERROR;
*/
switch (symbol->value[2]) {
- case 'X': /* bit - 1 bit */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break;
- case 'B': /* byte - 8 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); break;
- case 'W': /* word - 16 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); break;
- case 'D': /* dword - 32 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); break;
- case 'L': /* lword - 64 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); break;
+ case 'x': case 'X': /* bit - 1 bit */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break;
+ case 'b': case 'B': /* byte - 8 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); break;
+ case 'w': case 'W': /* word - 16 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); break;
+ case 'd': case 'D': /* dword - 32 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); break;
+ case 'l': case 'L': /* lword - 64 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); break;
/* if none of the above, then the empty string was used <=> boolean */
default: add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break;
}
@@ -641,6 +658,46 @@
return NULL;
}
+
+
+/******************************************/
+/* B 1.4.3 - Declaration & Initialisation */
+/******************************************/
+
+void *fill_candidate_datatypes_c::visit(var1_list_c *symbol) {
+#if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */
+ for(int i = 0; i < symbol->n; i++) {
+ add_datatype_to_candidate_list(symbol->elements[i], search_varfb_instance_type->get_basetype_decl(symbol->elements[i])); /* will only add if non NULL */
+ }
+#endif
+ return NULL;
+}
+
+
+/* AT direct_variable */
+// SYM_REF1(location_c, direct_variable)
+void *fill_candidate_datatypes_c::visit(location_c *symbol) {
+ symbol->direct_variable->accept(*this);
+ symbol->candidate_datatypes = symbol->direct_variable->candidate_datatypes;
+ return NULL;
+}
+
+
+/* [variable_name] location ':' located_var_spec_init */
+/* variable_name -> may be NULL ! */
+// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init)
+void *fill_candidate_datatypes_c::visit(located_var_decl_c *symbol) {
+ symbol->located_var_spec_init->accept(*this);
+ symbol->location->accept(*this);
+ symbol->variable_name->candidate_datatypes = symbol->location->candidate_datatypes;
+ intersect_candidate_datatype_list(symbol->variable_name /*origin, dest.*/, symbol->located_var_spec_init /*with*/);
+ return NULL;
+}
+
+
+
+
+
/************************************/
/* B 1.5 Program organization units */
/************************************/
--- a/stage3/fill_candidate_datatypes.hh Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/fill_candidate_datatypes.hh Sat Apr 07 16:14:17 2012 +0100
@@ -157,6 +157,7 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+ void *visit(simple_spec_init_c *symbol);
void *visit(subrange_c *symbol);
// void *visit(data_type_declaration_c *symbol);
void *visit(enumerated_value_c *symbol);
@@ -177,6 +178,14 @@
void *visit(array_variable_c *symbol);
void *visit(structured_variable_c *symbol);
+ /******************************************/
+ /* B 1.4.3 - Declaration & Initialisation */
+ /******************************************/
+ void *visit(var1_list_c *symbol);
+ void *visit(location_c *symbol);
+ void *visit(located_var_decl_c *symbol);
+
+
/**************************************/
/* B 1.5 - Program organization units */
/**************************************/
--- a/stage3/narrow_candidate_datatypes.cc Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/narrow_candidate_datatypes.cc Sat Apr 07 16:14:17 2012 +0100
@@ -399,6 +399,24 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+/* simple_specification ASSIGN constant */
+// SYM_REF2(simple_spec_init_c, simple_specification, constant)
+void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
+ if (symbol->candidate_datatypes.size() == 1)
+ symbol->datatype = symbol->candidate_datatypes[0];
+
+ if (symbol->simple_specification->candidate_datatypes.size() == 1)
+ symbol->simple_specification->datatype = symbol->simple_specification->candidate_datatypes[0];
+
+ if (NULL != symbol->constant) {
+ set_datatype(symbol->datatype, symbol->constant);
+ symbol->constant->accept(*this);
+ }
+ return NULL;
+}
+
+
+
/* signed_integer DOTDOT signed_integer */
// SYM_REF2(subrange_c, lower_limit, upper_limit)
void *narrow_candidate_datatypes_c::visit(subrange_c *symbol) {
@@ -409,17 +427,6 @@
return NULL;
}
-/* simple_specification ASSIGN constant */
-// SYM_REF2(simple_spec_init_c, simple_specification, constant)
-void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
- symbol_c *datatype = base_type(symbol->simple_specification);
- if (NULL != symbol->constant) {
- int typeoffset = search_in_candidate_datatype_list(datatype, symbol->constant->candidate_datatypes);
- if (typeoffset >= 0)
- symbol->constant->datatype = symbol->constant->candidate_datatypes[typeoffset];
- }
- return NULL;
-}
/*********************/
/* B 1.4 - Variables */
@@ -456,6 +463,47 @@
+
+/******************************************/
+/* B 1.4.3 - Declaration & Initialisation */
+/******************************************/
+
+void *narrow_candidate_datatypes_c::visit(var1_list_c *symbol) {
+#if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */
+ for(int i = 0; i < symbol->n; i++) {
+ if (symbol->elements[i]->candidate_datatypes.size() == 1)
+ symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[0];
+ }
+#endif
+ return NULL;
+}
+
+
+/* AT direct_variable */
+// SYM_REF1(location_c, direct_variable)
+void *narrow_candidate_datatypes_c::visit(location_c *symbol) {
+ set_datatype(symbol->datatype, symbol->direct_variable);
+ symbol->direct_variable->accept(*this); /* currently does nothing! */
+ return NULL;
+}
+
+
+/* [variable_name] location ':' located_var_spec_init */
+/* variable_name -> may be NULL ! */
+// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init)
+void *narrow_candidate_datatypes_c::visit(located_var_decl_c *symbol) {
+ /* let the var_spec_init set its own symbol->datatype value */
+ symbol->located_var_spec_init->accept(*this);
+
+ if (NULL != symbol->variable_name)
+ set_datatype(symbol->located_var_spec_init->datatype, symbol->variable_name);
+
+ set_datatype(symbol->located_var_spec_init->datatype, symbol->location);
+ symbol->location->accept(*this);
+ return NULL;
+}
+
+
/************************************/
/* B 1.5 Program organization units */
/************************************/
--- a/stage3/narrow_candidate_datatypes.hh Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/narrow_candidate_datatypes.hh Sat Apr 07 16:14:17 2012 +0100
@@ -87,6 +87,13 @@
void *visit(array_variable_c *symbol);
void *visit(subscript_list_c *symbol);
+ /******************************************/
+ /* B 1.4.3 - Declaration & Initialisation */
+ /******************************************/
+ void *visit(var1_list_c *symbol);
+ void *visit(location_c *symbol);
+ void *visit(located_var_decl_c *symbol);
+
/**************************************/
/* B 1.5 - Program organization units */
/**************************************/
--- a/stage3/print_datatypes_error.cc Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/print_datatypes_error.cc Sat Apr 07 16:14:17 2012 +0100
@@ -529,6 +529,20 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+void *print_datatypes_error_c::visit(simple_spec_init_c *symbol) {
+ if (!is_type_valid(symbol->simple_specification->datatype)) {
+ STAGE3_ERROR(0, symbol->simple_specification, symbol->simple_specification, "Invalid data type.");
+ } else if (NULL != symbol->constant) {
+ if (!is_type_valid(symbol->constant->datatype))
+ STAGE3_ERROR(0, symbol->constant, symbol->constant, "Initial value has incompatible data type.");
+ } else if (!is_type_valid(symbol->datatype)) {
+ ERROR; /* If we have an error here, then we must also have an error in one of
+ * the two previous tests. If we reach this point, some strange error is ocurring!
+ */
+ }
+ return NULL;
+}
+
void *print_datatypes_error_c::visit(data_type_declaration_c *symbol) {
// TODO !!!
/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
@@ -555,8 +569,9 @@
/* B 1.4.1 - Directly Represented Variables */
/********************************************/
void *print_datatypes_error_c::visit(direct_variable_c *symbol) {
- if (symbol->candidate_datatypes.size() == 0)
- STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for located variable data type.");
+ if (symbol->candidate_datatypes.size() == 0) ERROR;
+ if (!is_type_valid(symbol->datatype))
+ STAGE3_ERROR(4, symbol, symbol, "Direct variable has incompatible data type with expression.");
return NULL;
}
@@ -597,6 +612,33 @@
return NULL;
}
+
+
+/******************************************/
+/* B 1.4.3 - Declaration & Initialisation */
+/******************************************/
+
+/* AT direct_variable */
+// SYM_REF1(location_c, direct_variable)
+void *print_datatypes_error_c::visit(location_c *symbol) {
+ symbol->direct_variable->accept(*this);
+ return NULL;
+}
+
+
+/* [variable_name] location ':' located_var_spec_init */
+/* variable_name -> may be NULL ! */
+// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init)
+void *print_datatypes_error_c::visit(located_var_decl_c *symbol) {
+ symbol->located_var_spec_init->accept(*this);
+ /* It does not make sense to call symbol->location->accept(*this). The check is done right here if the following if() */
+ // symbol->location->accept(*this);
+ if ((is_type_valid(symbol->located_var_spec_init->datatype)) && (!is_type_valid(symbol->location->datatype)))
+ STAGE3_ERROR(0, symbol, symbol, "Location is incompatible with data type.");
+ return NULL;
+}
+
+
/************************************/
/* B 1.5 Program organization units */
/************************************/
@@ -638,7 +680,7 @@
void *print_datatypes_error_c::visit(program_declaration_c *symbol) {
search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
/* We do not check for data type errors in variable declarations, Skip this for now... */
-// symbol->var_declarations->accept(*this);
+ symbol->var_declarations->accept(*this);
if (debug) printf("Print error data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
il_parenthesis_level = 0;
il_error = false;
--- a/stage3/print_datatypes_error.hh Tue Apr 03 12:42:16 2012 +0100
+++ b/stage3/print_datatypes_error.hh Sat Apr 07 16:14:17 2012 +0100
@@ -149,6 +149,7 @@
/********************************/
/* B 1.3.3 - Derived data types */
/********************************/
+ void *visit(simple_spec_init_c *symbol);
void *visit(data_type_declaration_c *symbol);
void *visit(enumerated_value_c *symbol);
@@ -168,6 +169,12 @@
void *visit(array_variable_c *symbol);
void *visit(structured_variable_c *symbol);
+ /******************************************/
+ /* B 1.4.3 - Declaration & Initialisation */
+ /******************************************/
+ void *visit(location_c *symbol);
+ void *visit(located_var_decl_c *symbol);
+
/**************************************/
/* B 1.5 - Program organization units */
/**************************************/