Start data type checking of var declarations (including direct variables!)
authorMario de Sousa <msousa@fe.up.pt>
Sat, 07 Apr 2012 16:14:17 +0100
changeset 502 a6211f73690b
parent 501 19bc099215d8
child 503 e1e7c7678c44
Start data type checking of var declarations (including direct variables!)
stage3/fill_candidate_datatypes.cc
stage3/fill_candidate_datatypes.hh
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
stage3/print_datatypes_error.cc
stage3/print_datatypes_error.hh
--- 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 */
     /**************************************/