stage3/constant_folding.cc
changeset 566 5688fa07f89a
parent 565 8acbddf75333
child 567 e5deeb6d4d2f
equal deleted inserted replaced
565:8acbddf75333 566:5688fa07f89a
    83 
    83 
    84 #define CHECK_OVERFLOW_SUB(a, b, type)\
    84 #define CHECK_OVERFLOW_SUB(a, b, type)\
    85 	((((std::numeric_limits< type >::max() - a) < (-b)) ? 1 : 0) || \
    85 	((((std::numeric_limits< type >::max() - a) < (-b)) ? 1 : 0) || \
    86 	 (((std::numeric_limits< type >::min() + a) > (-b)) ? 1 : 0))
    86 	 (((std::numeric_limits< type >::min() + a) > (-b)) ? 1 : 0))
    87 
    87 
       
    88 #define SYMBOL_BOOL_VALUE (symbol->exp->const_value_bool)
       
    89 #define SYMBOL_REAL_VALUE (symbol->exp->const_value_real)
    88 
    90 
    89 
    91 
    90 
    92 
    91 
    93 
    92 constant_folding_c::constant_folding_c(symbol_c *symbol) {
    94 constant_folding_c::constant_folding_c(symbol_c *symbol) {
   127 
   129 
   128 	return NULL;
   130 	return NULL;
   129 }
   131 }
   130 
   132 
   131 void *constant_folding_c::visit(neg_real_c *symbol) {
   133 void *constant_folding_c::visit(neg_real_c *symbol) {
   132 	double *real_value;
       
   133 
       
   134 	real_value = (double *)malloc(sizeof(double));
       
   135 	symbol->exp->accept(*this);
   134 	symbol->exp->accept(*this);
   136 	if (NULL == symbol->exp->const_value_real)
   135 	if (NULL == symbol->exp->const_value_real)
   137 		ERROR;
   136 		ERROR;
   138 	*real_value = - *(symbol->exp->const_value_real);
   137 	symbol->const_value_real = (double*) malloc(sizeof(double));
   139 	symbol->const_value_real = real_value;
   138 	*symbol->const_value_real = - *(symbol->exp->const_value_real);
   140 
       
   141 	return NULL;
   139 	return NULL;
   142 }
   140 }
   143 
   141 
   144 void *constant_folding_c::visit(neg_integer_c *symbol) {
   142 void *constant_folding_c::visit(neg_integer_c *symbol) {
   145 	int64_t *integer_value;
   143 	int64_t *integer_value;
   160 
   158 
   161 	return NULL;
   159 	return NULL;
   162 }
   160 }
   163 
   161 
   164 void *constant_folding_c::visit(hex_integer_c *symbol) {
   162 void *constant_folding_c::visit(hex_integer_c *symbol) {
   165 	int64_t *integer_value;
   163 	symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   166 
   164 	*(symbol->const_value_integer) = extract_hex_value(symbol);
   167 	integer_value = (int64_t *)malloc(sizeof(int64_t));
       
   168 	*integer_value = extract_hex_value(symbol);
       
   169 
   165 
   170 	return NULL;
   166 	return NULL;
   171 }
   167 }
   172 
   168 
   173 void *constant_folding_c::visit(integer_literal_c *symbol) {
   169 void *constant_folding_c::visit(integer_literal_c *symbol) {
   174 	int64_t *integer_value;
       
   175 
       
   176 	symbol->value->accept(*this);
   170 	symbol->value->accept(*this);
   177 	if (NULL == symbol->value->const_value_integer) ERROR;
   171 	if (NULL == symbol->value->const_value_integer) ERROR;
       
   172 	symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   178 	*(symbol->const_value_integer) = *(symbol->value->const_value_integer);
   173 	*(symbol->const_value_integer) = *(symbol->value->const_value_integer);
   179 	integer_value = (int64_t *)malloc(sizeof(int64_t));
       
   180 
   174 
   181 	return NULL;
   175 	return NULL;
   182 }
   176 }
   183 
   177 
   184 void *constant_folding_c::visit(real_literal_c *symbol) {
   178 void *constant_folding_c::visit(real_literal_c *symbol) {
   185 	double *real_value;
       
   186 
       
   187 	real_value = (double *)malloc(sizeof(double));
       
   188 	symbol->value->accept(*this);
   179 	symbol->value->accept(*this);
   189 	if (NULL == symbol->value->const_value_real)
   180 	if (NULL == symbol->value->const_value_real) ERROR;
   190 		ERROR;
   181 	symbol->const_value_real = (double*) malloc(sizeof(double));
   191 	*real_value = *(symbol->value->const_value_real);
   182 	*symbol->const_value_real =  *(symbol->value->const_value_real);
   192 	symbol->const_value_real = real_value;
       
   193 
   183 
   194 	return NULL;
   184 	return NULL;
   195 }
   185 }
   196 
   186 
   197 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
   187 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
   375 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   365 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   376 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   366 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   377 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer);
   367 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer);
   378 	}
   368 	}
   379 	if (DO_OPER(real)) {
   369 	if (DO_OPER(real)) {
   380 		if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double))
       
   381 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
       
   382 		symbol->const_value_real = (double*) malloc(sizeof(double));
   370 		symbol->const_value_real = (double*) malloc(sizeof(double));
   383 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real);
   371 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real);
       
   372 		/*
       
   373 		 * According to the IEEE standard, NaN value is used as:
       
   374 		 *   - representation of a number that has underflowed
       
   375 		 *   - representation of number that has overflowed
       
   376 		 *   - number is a higher precision format
       
   377 		 *   - A complex number
       
   378 		 */
       
   379 		 if (isnan(*(symbol->const_value_real)))
       
   380 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   384 	}
   381 	}
   385 
   382 
   386 	return NULL;
   383 	return NULL;
   387 }
   384 }
   388 
   385 
   394 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   391 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   395 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   392 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   396 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer);
   393 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer);
   397 	}
   394 	}
   398 	if (DO_OPER(real)) {
   395 	if (DO_OPER(real)) {
   399 		if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double))
       
   400 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
       
   401 		symbol->const_value_real = (double*) malloc(sizeof(double));
   396 		symbol->const_value_real = (double*) malloc(sizeof(double));
   402 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real);
   397 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real);
       
   398 		/*
       
   399 		 * According to the IEEE standard, NaN value is used as:
       
   400 		 *   - representation of a number that has underflowed
       
   401 		 *   - representation of number that has overflowed
       
   402 		 *   - number is a higher precision format
       
   403 		 *   - A complex number
       
   404 		 */
       
   405 		if (isnan(*(symbol->const_value_real)))
       
   406 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   403 	}
   407 	}
   404 
   408 
   405 	return NULL;
   409 	return NULL;
   406 }
   410 }
   407 
   411 
   408 void *constant_folding_c::visit(mul_expression_c *symbol) {
   412 void *constant_folding_c::visit(mul_expression_c *symbol) {
   409 	symbol->l_exp->accept(*this);
   413 	symbol->l_exp->accept(*this);
   410 	symbol->r_exp->accept(*this);
   414 	symbol->r_exp->accept(*this);
   411 	if (DO_OPER(integer)) {
   415 	if (DO_OPER(integer)) {
   412 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   416 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   413 		if ((*(symbol->l_exp->const_value_integer) == 0) ||
       
   414 			(*(symbol->r_exp->const_value_integer) == 0)) {
       
   415 			*(symbol->const_value_integer) = 0;
       
   416 			return NULL;
       
   417 		}
       
   418 
       
   419 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer);
   417 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer);
   420 	}
   418 	}
   421 	if (DO_OPER(real)) {
   419 	if (DO_OPER(real)) {
   422 		symbol->const_value_real = (double*) malloc(sizeof(double));
   420 		symbol->const_value_real = (double*) malloc(sizeof(double));
   423 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real);
   421 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real);
       
   422 		/*
       
   423 		 * According to the IEEE standard, NaN value is used as:
       
   424 		 *   - representation of a number that has underflowed
       
   425 		 *   - representation of number that has overflowed
       
   426 		 *   - number is a higher precision format
       
   427 		 *   - A complex number
       
   428 		 */
       
   429 		if (isnan(*(symbol->const_value_real)))
       
   430 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   424 	}
   431 	}
   425 
   432 
   426 	return NULL;
   433 	return NULL;
   427 }
   434 }
   428 
   435 
   438 	if (DO_OPER(real)) {
   445 	if (DO_OPER(real)) {
   439 		if (*(symbol->r_exp->const_value_real) == 0)
   446 		if (*(symbol->r_exp->const_value_real) == 0)
   440 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   447 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   441 		symbol->const_value_real = (double*) malloc(sizeof(double));
   448 		symbol->const_value_real = (double*) malloc(sizeof(double));
   442 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real);
   449 		*(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real);
       
   450 		/*
       
   451 		 * According to the IEEE standard, NaN value is used as:
       
   452 		 *   - representation of a number that has underflowed
       
   453 		 *   - representation of number that has overflowed
       
   454 		 *   - number is a higher precision format
       
   455 		 *   - A complex number
       
   456 		 */
       
   457 		if (isnan(*(symbol->const_value_real)))
       
   458 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   443 	}
   459 	}
   444 
   460 
   445 	return NULL;
   461 	return NULL;
   446 }
   462 }
   447 
   463 
   451 	if (DO_OPER(integer)) {
   467 	if (DO_OPER(integer)) {
   452 		if (*(symbol->r_exp->const_value_integer) == 0)
   468 		if (*(symbol->r_exp->const_value_integer) == 0)
   453 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   469 			STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression.");
   454 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   470 		symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t));
   455 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) % *(symbol->r_exp->const_value_integer);
   471 		*(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) % *(symbol->r_exp->const_value_integer);
       
   472 
   456 	}
   473 	}
   457 
   474 
   458 	return NULL;
   475 	return NULL;
   459 }
   476 }
   460 
   477 
   462 	symbol->l_exp->accept(*this);
   479 	symbol->l_exp->accept(*this);
   463 	symbol->r_exp->accept(*this);
   480 	symbol->r_exp->accept(*this);
   464 	if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) {
   481 	if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) {
   465 		symbol->const_value_real = (double*) malloc(sizeof(double));
   482 		symbol->const_value_real = (double*) malloc(sizeof(double));
   466 		*(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer));
   483 		*(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer));
       
   484 		/*
       
   485 		 * According to the IEEE standard, NaN value is used as:
       
   486 		 *   - representation of a number that has underflowed
       
   487 		 *   - representation of number that has overflowed
       
   488 		 *   - number is a higher precision format
       
   489 		 *   - A complex number
       
   490 		 */
       
   491 		if (isnan(*(symbol->const_value_real)))
       
   492 			STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression.");
   467 	}
   493 	}
   468 
   494 
   469 	return NULL;
   495 	return NULL;
   470 }
   496 }
   471 void *constant_folding_c::visit(neg_expression_c *symbol) {
   497 void *constant_folding_c::visit(neg_expression_c *symbol) {