stage3/constant_folding.cc
changeset 579 983a3b743085
parent 578 70c0456affca
child 587 1ecf916cc397
equal deleted inserted replaced
578:70c0456affca 579:983a3b743085
   116  *    actuall printing of errors for the print_datatype_errors_c class!
   116  *    actuall printing of errors for the print_datatype_errors_c class!
   117  */
   117  */
   118 
   118 
   119 #include "constant_folding.hh"
   119 #include "constant_folding.hh"
   120 #include <limits>
   120 #include <limits>
   121 #include <math.h> /* required for pow function */
   121 #include <math.h> /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */
   122 #include <stdlib.h> /* required for malloc() */
   122 #include <stdlib.h> /* required for malloc() */
   123 
   123 
   124 #if 1
       
   125 #define UINT64_MAX (std::numeric_limits< uint64_t >::max())
       
   126 #define  INT64_MAX (std::numeric_limits<  int64_t >::max())
       
   127 #define  INT64_MIN (std::numeric_limits<  int64_t >::min()) 
       
   128 #else
       
   129 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
   124 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
   130 #include <stdint.h>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
   125 #include <stdint.h>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
       
   126 
       
   127 
       
   128 
       
   129 #ifndef   UINT64_MAX 
       
   130   #define UINT64_MAX (std::numeric_limits< uint64_t >::max())
   131 #endif
   131 #endif
       
   132 #ifndef    INT64_MAX 
       
   133   #define  INT64_MAX (std::numeric_limits<  int64_t >::max())
       
   134 #endif
       
   135 #ifndef    INT64_MIN
       
   136   #define  INT64_MIN (std::numeric_limits<  int64_t >::min()) 
       
   137 #endif
       
   138 
       
   139 #if    (real64_t  == float)
       
   140   #define HUGE_VAL64  HUGE_VALF
       
   141 #elif  (real64_t  == double)
       
   142   #define HUGE_VAL64  HUGE_VAL
       
   143 #elif  (real64_t  == long_double)
       
   144   #define HUGE_VAL64  HUGE_VALL
       
   145 #else 
       
   146   #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
       
   147 #endif
       
   148 
       
   149 
       
   150 
       
   151 
       
   152 
       
   153 
       
   154 
   132 
   155 
   133 
   156 
   134 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
   157 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
   135 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
   158 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
   136 
   159 
   340 		SET_OVFLOW(int64, res);
   363 		SET_OVFLOW(int64, res);
   341 }
   364 }
   342 
   365 
   343 
   366 
   344 
   367 
   345 static void CHECK_OVERFLOW_real64(symbol_c *res) {
   368 static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) {
   346 	if (!VALID_CVALUE(real64, res))
   369 	if (!VALID_CVALUE(real64, res_ptr))
   347 		return;
   370 		return;
   348        	/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */
   371 	real64_t res = GET_CVALUE(real64, res_ptr);
   349 	if (isnan(GET_CVALUE(real64, res)))
   372 	/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */
   350 		SET_OVFLOW(real64, res);
   373 	/* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions':
       
   374 	 * "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values
       
   375 	 *  specified for the data type of the function output, or if division by zero is attempted."
       
   376 	 * For this reason, any operation that has as a result a positive or negative inifinity, is also an error!
       
   377 	 */
       
   378 	if ((isnan(res)) || (res == HUGE_VAL64) || (res == -HUGE_VAL64))
       
   379 		SET_OVFLOW(real64, res_ptr);
   351 }
   380 }
   352 
   381 
   353 
   382 
   354 
   383 
   355 
   384 
   369     current_display_error_level = 0;
   398     current_display_error_level = 0;
   370     
   399     
   371     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
   400     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
   372     symbol_c null_symbol;
   401     symbol_c null_symbol;
   373     if (! (std::numeric_limits<real64_t>::is_iec559) )
   402     if (! (std::numeric_limits<real64_t>::is_iec559) )
   374         STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 559 floating point numbers. "
   403         STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. "
   375                                                    "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
   404                                                    "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
   376                                                    " (i.e. constant folding) may themselves be erroneous, although are most probably correct.");
   405                                                    "(i.e. constant folding) may themselves be erroneous, although are most probably correct."
       
   406                                                    "However, more likely is the possible existance of overflow/underflow errors that are not detected.");
   377 }
   407 }
   378 
   408 
   379 
   409 
   380 constant_folding_c::~constant_folding_c(void) {
   410 constant_folding_c::~constant_folding_c(void) {
   381 }
   411 }