stage3/constant_folding.cc
changeset 568 5f79478142d7
parent 567 e5deeb6d4d2f
child 569 0d1ab9e78574
equal deleted inserted replaced
567:e5deeb6d4d2f 568:5f79478142d7
    43 #include "constant_folding.hh"
    43 #include "constant_folding.hh"
    44 #include <typeinfo>
    44 #include <typeinfo>
    45 #include <limits>
    45 #include <limits>
    46 #include <math.h> /* required for pow function */
    46 #include <math.h> /* required for pow function */
    47 #include <stdlib.h> /* required for malloc() */
    47 #include <stdlib.h> /* required for malloc() */
       
    48 
       
    49 
       
    50 
    48 
    51 
    49 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
    52 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
    50 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
    53 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
    51 
    54 
    52 #define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
    55 #define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
    97 
   100 
    98 
   101 
    99 
   102 
   100 constant_folding_c::constant_folding_c(symbol_c *symbol) {
   103 constant_folding_c::constant_folding_c(symbol_c *symbol) {
   101     error_count = 0;
   104     error_count = 0;
       
   105     warning_found = false;
   102     current_display_error_level = 0;
   106     current_display_error_level = 0;
       
   107     
       
   108     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
       
   109     symbol_c null_symbol;
       
   110     if (! (std::numeric_limits<real64_t>::is_iec559) )
       
   111         STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 559 floating point numbers. "
       
   112                                                    "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
       
   113                                                    " (i.e. constant folding) may themselves be erroneous, although are most probably correct");
   103 }
   114 }
   104 
   115 
   105 
   116 
   106 constant_folding_c::~constant_folding_c(void) {
   117 constant_folding_c::~constant_folding_c(void) {
   107 }
   118 }
   117 /*********************/
   128 /*********************/
   118 /******************************/
   129 /******************************/
   119 /* B 1.2.1 - Numeric Literals */
   130 /* B 1.2.1 - Numeric Literals */
   120 /******************************/
   131 /******************************/
   121 void *constant_folding_c::visit(real_c *symbol) {
   132 void *constant_folding_c::visit(real_c *symbol) {
   122 	MALLOC(symbol->const_value_real, double);
   133 	MALLOC(symbol->const_value_real, real64_t);
   123 	*symbol->const_value_real = extract_real_value(symbol);
   134 	*symbol->const_value_real = extract_real_value(symbol);
   124 
   135 
   125 	return NULL;
   136 	return NULL;
   126 }
   137 }
   127 
   138 
   139 
   150 
   140 void *constant_folding_c::visit(neg_real_c *symbol) {
   151 void *constant_folding_c::visit(neg_real_c *symbol) {
   141 	symbol->exp->accept(*this);
   152 	symbol->exp->accept(*this);
   142 	if (NULL == symbol->exp->const_value_real)
   153 	if (NULL == symbol->exp->const_value_real)
   143 		ERROR;
   154 		ERROR;
   144 	symbol->const_value_real = (double*) malloc(sizeof(double));
   155 	symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   145 	*symbol->const_value_real = - *(symbol->exp->const_value_real);
   156 	*symbol->const_value_real = - *(symbol->exp->const_value_real);
   146 	return NULL;
   157 	return NULL;
   147 }
   158 }
   148 
   159 
   149 
   160 
   189 
   200 
   190 
   201 
   191 void *constant_folding_c::visit(real_literal_c *symbol) {
   202 void *constant_folding_c::visit(real_literal_c *symbol) {
   192 	symbol->value->accept(*this);
   203 	symbol->value->accept(*this);
   193 	if (NULL == symbol->value->const_value_real) ERROR;
   204 	if (NULL == symbol->value->const_value_real) ERROR;
   194 	symbol->const_value_real = (double*) malloc(sizeof(double));
   205 	symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   195 	*symbol->const_value_real =  *(symbol->value->const_value_real);
   206 	*symbol->const_value_real =  *(symbol->value->const_value_real);
   196 
   207 
   197 	return NULL;
   208 	return NULL;
   198 }
   209 }
   199 
   210 
   393 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   404 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   394 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   405 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   395 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer);
   406 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer);
   396 	}
   407 	}
   397 	if (DO_OPER(real)) {
   408 	if (DO_OPER(real)) {
   398 		symbol->const_value_real = (double*) malloc(sizeof(double));
   409 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   399 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real);
   410 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real);
   400 		/*
   411 		/*
   401 		 * According to the IEEE standard, NaN value is used as:
   412 		 * According to the IEEE standard, NaN value is used as:
   402 		 *   - representation of a number that has underflowed
   413 		 *   - representation of a number that has underflowed
   403 		 *   - representation of number that has overflowed
   414 		 *   - representation of number that has overflowed
   420 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   431 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   421 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   432 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   422 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer);
   433 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer);
   423 	}
   434 	}
   424 	if (DO_OPER(real)) {
   435 	if (DO_OPER(real)) {
   425 		symbol->const_value_real = (double*) malloc(sizeof(double));
   436 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   426 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real);
   437 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real);
   427 		/*
   438 		/*
   428 		 * According to the IEEE standard, NaN value is used as:
   439 		 * According to the IEEE standard, NaN value is used as:
   429 		 *   - representation of a number that has underflowed
   440 		 *   - representation of a number that has underflowed
   430 		 *   - representation of number that has overflowed
   441 		 *   - representation of number that has overflowed
   445 	if (DO_OPER(integer)) {
   456 	if (DO_OPER(integer)) {
   446 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   457 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   447 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer);
   458 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer);
   448 	}
   459 	}
   449 	if (DO_OPER(real)) {
   460 	if (DO_OPER(real)) {
   450 		symbol->const_value_real = (double*) malloc(sizeof(double));
   461 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   451 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real);
   462 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real);
   452 		/*
   463 		/*
   453 		 * According to the IEEE standard, NaN value is used as:
   464 		 * According to the IEEE standard, NaN value is used as:
   454 		 *   - representation of a number that has underflowed
   465 		 *   - representation of a number that has underflowed
   455 		 *   - representation of number that has overflowed
   466 		 *   - representation of number that has overflowed
   474 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) / *(symbol->r_exp->const_value_integer);
   485 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) / *(symbol->r_exp->const_value_integer);
   475 	}
   486 	}
   476 	if (DO_OPER(real)) {
   487 	if (DO_OPER(real)) {
   477 		if (*(symbol->r_exp->const_value_real) == 0)
   488 		if (*(symbol->r_exp->const_value_real) == 0)
   478 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   489 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   479 		symbol->const_value_real = (double*) malloc(sizeof(double));
   490 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   480 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real);
   491 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real);
   481 		/*
   492 		/*
   482 		 * According to the IEEE standard, NaN value is used as:
   493 		 * According to the IEEE standard, NaN value is used as:
   483 		 *   - representation of a number that has underflowed
   494 		 *   - representation of a number that has underflowed
   484 		 *   - representation of number that has overflowed
   495 		 *   - representation of number that has overflowed
   510 
   521 
   511 void *constant_folding_c::visit(power_expression_c *symbol) {
   522 void *constant_folding_c::visit(power_expression_c *symbol) {
   512 	symbol->l_exp->accept(*this);
   523 	symbol->l_exp->accept(*this);
   513 	symbol->r_exp->accept(*this);
   524 	symbol->r_exp->accept(*this);
   514 	if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) {
   525 	if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) {
   515 		symbol->const_value_real = (double*) malloc(sizeof(double));
   526 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   516 		*(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer));
   527 		*(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer));
   517 		/*
   528 		/*
   518 		 * According to the IEEE standard, NaN value is used as:
   529 		 * According to the IEEE standard, NaN value is used as:
   519 		 *   - representation of a number that has underflowed
   530 		 *   - representation of a number that has underflowed
   520 		 *   - representation of number that has overflowed
   531 		 *   - representation of number that has overflowed
   534 	if (NULL != symbol->exp->const_value_integer) {
   545 	if (NULL != symbol->exp->const_value_integer) {
   535 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   546 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   536 		*(symbol->const_value_integer) = - *(symbol->exp->const_value_integer);
   547 		*(symbol->const_value_integer) = - *(symbol->exp->const_value_integer);
   537 	}
   548 	}
   538 	if (NULL != symbol->exp->const_value_real) {
   549 	if (NULL != symbol->exp->const_value_real) {
   539 		symbol->const_value_real = (double*) malloc(sizeof(double));
   550 		symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t));
   540 		*(symbol->const_value_real) = - *(symbol->exp->const_value_real);
   551 		*(symbol->const_value_real) = - *(symbol->exp->const_value_real);
   541 	}
   552 	}
   542 	return NULL;
   553 	return NULL;
   543 }
   554 }
   544 
   555