make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
authorMario de Sousa <msousa@fe.up.pt>
Wed, 06 Jun 2012 16:39:54 +0100
changeset 568 5f79478142d7
parent 567 e5deeb6d4d2f
child 569 0d1ab9e78574
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
absyntax/absyntax.hh
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
stage3/constant_folding.cc
stage3/constant_folding.hh
--- a/absyntax/absyntax.hh	Wed Jun 06 13:28:50 2012 +0100
+++ b/absyntax/absyntax.hh	Wed Jun 06 16:39:54 2012 +0100
@@ -51,6 +51,22 @@
 #include <string>
 #include <stdint.h>  // required for uint64_t, etc...
 
+
+
+/* NOTE: we cant use sizeof() in pre-processor directives, so we do it another way... */
+#include <float.h>
+#if    (LDBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
+  #define long_double long double
+  #define real64_t long_double /* so we can later use #if (real64_t == long_double) directives in the code! */
+#elif  ( DBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
+  #define real64_t double
+#elif  ( FLT_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
+  #define real64_t float
+#else 
+  #error Could not find a 64 bit floating point data type on this platform. Aborting...
+#endif
+
+
 /* Forward declaration of the visitor interface
  * declared in the visitor.hh file
  * We cannot include the visitor.hh file, as it will
@@ -86,7 +102,7 @@
      */
     symbol_c *datatype;
 
-    double   *const_value_real;
+    real64_t *const_value_real;
     int64_t  *const_value_integer;
     uint64_t *const_value_uinteger;
     bool     *const_value_bool;
@@ -147,7 +163,7 @@
 
 
 
-#define SYM_LIST(class_name_c, ...)												\
+#define SYM_LIST(class_name_c, ...)											\
 class class_name_c:	public list_c {											\
   public:														\
     __VA_ARGS__														\
@@ -162,7 +178,7 @@
 };
 
 
-#define SYM_TOKEN(class_name_c, ...)												\
+#define SYM_TOKEN(class_name_c, ...)											\
 class class_name_c: 	public token_c {										\
   public:														\
     __VA_ARGS__														\
@@ -174,7 +190,7 @@
 };
 
 
-#define SYM_REF0(class_name_c, ...)												\
+#define SYM_REF0(class_name_c, ...)											\
 class class_name_c: public symbol_c {											\
   public:														\
     __VA_ARGS__														\
@@ -250,7 +266,7 @@
 };
 
 
-#define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5, ...)								\
+#define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5, ...)							\
 class class_name_c: public symbol_c {											\
   public:														\
     symbol_c *ref1;													\
--- a/absyntax_utils/absyntax_utils.cc	Wed Jun 06 13:28:50 2012 +0100
+++ b/absyntax_utils/absyntax_utils.cc	Wed Jun 06 16:39:54 2012 +0100
@@ -138,7 +138,7 @@
 
 /* extract the value of a real from an real_c object !! */
 /* NOTE: it must ignore underscores! */
-double extract_real_value(symbol_c *sym) {
+real64_t extract_real_value(symbol_c *sym) {
   std::string str = "";
   char *endptr;
   real_c * real_sym;
@@ -148,7 +148,15 @@
   for(unsigned int i = 3; i < strlen(real_sym->value); i++)
     if (real_sym->value[i] != '_') str += real_sym->value[i];
     
-  ret = strtod(str.c_str(), NULL);
+  #if    (real64_t  == float)
+    ret = strtof(str.c_str(), NULL);
+  #elif  (real64_t  == double)
+    ret = strtod(str.c_str(), NULL);
+  #elif  (real64_t  == long_double)
+    ret = strtold(str.c_str(), NULL);
+  #else 
+    #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
+  #endif
   if (errno != 0) ERROR;
 
   return ret;
--- a/absyntax_utils/absyntax_utils.hh	Wed Jun 06 13:28:50 2012 +0100
+++ b/absyntax_utils/absyntax_utils.hh	Wed Jun 06 16:39:54 2012 +0100
@@ -58,7 +58,7 @@
 /* extract the value of an integer/hex_integer/real from an integer_c/hex_integer_c/real_c symbol !! */
 long long extract_integer_value(symbol_c *sym);
 uint64_t  extract_hex_value    (symbol_c *sym);
-double    extract_real_value   (symbol_c *sym);
+real64_t  extract_real_value   (symbol_c *sym);
   
 /* A symbol table with all globally declared functions... */
 extern function_declaration_c null_symbol1;
--- a/stage3/constant_folding.cc	Wed Jun 06 13:28:50 2012 +0100
+++ b/stage3/constant_folding.cc	Wed Jun 06 16:39:54 2012 +0100
@@ -46,6 +46,9 @@
 #include <math.h> /* required for pow function */
 #include <stdlib.h> /* required for malloc() */
 
+
+
+
 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
 
@@ -99,7 +102,15 @@
 
 constant_folding_c::constant_folding_c(symbol_c *symbol) {
     error_count = 0;
+    warning_found = false;
     current_display_error_level = 0;
+    
+    /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
+    symbol_c null_symbol;
+    if (! (std::numeric_limits<real64_t>::is_iec559) )
+        STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 559 floating point numbers. "
+                                                   "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
+                                                   " (i.e. constant folding) may themselves be erroneous, although are most probably correct");
 }
 
 
@@ -119,7 +130,7 @@
 /* B 1.2.1 - Numeric Literals */
 /******************************/
 void *constant_folding_c::visit(real_c *symbol) {
-	MALLOC(symbol->const_value_real, double);
+	MALLOC(symbol->const_value_real, real64_t);
 	*symbol->const_value_real = extract_real_value(symbol);
 
 	return NULL;
@@ -141,7 +152,7 @@
 	symbol->exp->accept(*this);
 	if (NULL == symbol->exp->const_value_real)
 		ERROR;
-	symbol->const_value_real = (double*) malloc(sizeof(double));
+	symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 	*symbol->const_value_real = - *(symbol->exp->const_value_real);
 	return NULL;
 }
@@ -191,7 +202,7 @@
 void *constant_folding_c::visit(real_literal_c *symbol) {
 	symbol->value->accept(*this);
 	if (NULL == symbol->value->const_value_real) ERROR;
-	symbol->const_value_real = (double*) malloc(sizeof(double));
+	symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 	*symbol->const_value_real =  *(symbol->value->const_value_real);
 
 	return NULL;
@@ -395,7 +406,7 @@
 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer);
 	}
 	if (DO_OPER(real)) {
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real);
 		/*
 		 * According to the IEEE standard, NaN value is used as:
@@ -422,7 +433,7 @@
 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer);
 	}
 	if (DO_OPER(real)) {
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real);
 		/*
 		 * According to the IEEE standard, NaN value is used as:
@@ -447,7 +458,7 @@
 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer);
 	}
 	if (DO_OPER(real)) {
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real);
 		/*
 		 * According to the IEEE standard, NaN value is used as:
@@ -476,7 +487,7 @@
 	if (DO_OPER(real)) {
 		if (*(symbol->r_exp->const_value_real) == 0)
 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real);
 		/*
 		 * According to the IEEE standard, NaN value is used as:
@@ -512,7 +523,7 @@
 	symbol->l_exp->accept(*this);
 	symbol->r_exp->accept(*this);
 	if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) {
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer));
 		/*
 		 * According to the IEEE standard, NaN value is used as:
@@ -536,7 +547,7 @@
 		*(symbol->const_value_integer) = - *(symbol->exp->const_value_integer);
 	}
 	if (NULL != symbol->exp->const_value_real) {
-		symbol->const_value_real = (double*) malloc(sizeof(double));
+		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
 		*(symbol->const_value_real) = - *(symbol->exp->const_value_real);
 	}
 	return NULL;
--- a/stage3/constant_folding.hh	Wed Jun 06 13:28:50 2012 +0100
+++ b/stage3/constant_folding.hh	Wed Jun 06 16:39:54 2012 +0100
@@ -48,6 +48,7 @@
     search_varfb_instance_type_c *search_varfb_instance_type;
     search_base_type_c search_base_type;
     int error_count;
+    bool warning_found;
     int current_display_error_level;
 
 public: