Located variables may have other data types besides ANY_BIT.
authormjsousa <msousa@fe.up.pt>
Tue, 15 May 2012 15:50:43 +0100
changeset 558 9273dfc5fa7c
parent 557 95a2fe60a15c
child 559 a3b8925e640c
Located variables may have other data types besides ANY_BIT.
stage3/fill_candidate_datatypes.cc
stage3/print_datatypes_error.cc
--- a/stage3/fill_candidate_datatypes.cc	Sun May 13 17:57:15 2012 +0200
+++ b/stage3/fill_candidate_datatypes.cc	Tue May 15 15:50:43 2012 +0100
@@ -696,8 +696,83 @@
 /*  AT direct_variable */
 // SYM_REF1(location_c, direct_variable)
 void *fill_candidate_datatypes_c::visit(location_c *symbol) {
+ /* This is a special situation. 
+  *
+  * The reason is that a located variable may be declared to be of any data type, as long as the size
+  * matches the location (lines 1 3 and 4 of table 17). For example:
+  *   var1 AT %MB42.0 : BYTE;
+  *   var1 AT %MB42.1 : SINT;
+  *   var1 AT %MB42.2 : USINT;
+  *   var1 AT %MW64   : INT;
+  *   var1 AT %MD56   : DINT;
+  *   var1 AT %MD57   : REAL;
+  *  are all valid!!
+  *
+  *  However, when used inside an expression, the direct variable (uses the same syntax as the location
+  *  of a located variable) is limited to the following (ANY_BIT) data types:
+  *    %MX --> BOOL
+  *    %MB --> BYTE
+  *    %MW --> WORD
+  *    %MD --> DWORD
+  *    %ML --> LWORD
+  *
+  *  So, in order to be able to analyse expressions with direct variables
+  *   e.g:  var1 := 66 OR %MW34
+  *  where the direct variable may only take the ANY_BIT data types, the fill_candidate_datatypes_c
+  *  considers that only the ANY_BIT data types are allowed for a direct variable.
+  *  However, it appears from the examples in the standard (lines 1 3 and 4 of table 17)
+  *  a location may have any data type (presumably as long as the size in bits match).
+  *  For this reason, a location_c may have more allowable data types than a direct_variable_c
+  */
+
 	symbol->direct_variable->accept(*this);
-	symbol->candidate_datatypes = symbol->direct_variable->candidate_datatypes;
+	for (unsigned int i = 0; i < symbol->direct_variable->candidate_datatypes.size(); i++) {
+        	switch (get_sizeof_datatype_c::getsize(symbol->direct_variable->candidate_datatypes[i])) {
+			case  1: /* bit   -  1 bit  */
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safebool_type_name);
+					break;
+			case  8: /* byte  -  8 bits */
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safebyte_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::sint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safesint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::usint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeusint_type_name);
+					break;
+			case 16: /* word  - 16 bits */
+	 				add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeword_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::int_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::uint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeuint_type_name);
+					break;
+			case 32: /* dword - 32 bits */
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safedword_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::dint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safedint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::udint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeudint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::real_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safereal_type_name);
+					break;
+			case 64: /* lword - 64 bits */
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelword_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::lint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::ulint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safeulint_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::lreal_type_name);
+					add_datatype_to_candidate_list(symbol, &search_constant_type_c::safelreal_type_name);
+					break;
+			default: /* if none of the above, then no valid datatype allowed... */
+					break;
+		} /* switch() */
+	} /* for */
+
 	return NULL;
 }
 
--- a/stage3/print_datatypes_error.cc	Sun May 13 17:57:15 2012 +0200
+++ b/stage3/print_datatypes_error.cc	Tue May 15 15:50:43 2012 +0100
@@ -649,7 +649,7 @@
   /* 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.");
+    STAGE3_ERROR(0, symbol, symbol, "Bit size of data type is incompatible with bit size of location.");
   return NULL;
 }