stage3/constant_folding.cc
changeset 575 a1b63f776535
parent 574 d291a942899b
child 576 8368ec909825
equal deleted inserted replaced
574:d291a942899b 575:a1b63f776535
   175 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value) 
   175 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value) 
   176 #define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow
   176 #define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow
   177     /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */
   177     /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */
   178 #define VALID_CVALUE(dtype, symbol)           ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status))
   178 #define VALID_CVALUE(dtype, symbol)           ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status))
   179 #define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
   179 #define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
       
   180 
   180 #define DO_BINARY_OPER(dtype, oper)\
   181 #define DO_BINARY_OPER(dtype, oper)\
   181 	if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) {                                \
   182 	if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) {                                \
   182 		NEW_CVALUE(dtype, symbol);                                                                             \
   183 		NEW_CVALUE(dtype, symbol);                                                                             \
   183 		SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp));     \
   184 		SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp));     \
   184 	}
   185 	}
   185 
   186 
       
   187 #define DO_UNARY_OPER(dtype, oper, arg)\
       
   188 	if (VALID_CVALUE(dtype, arg)) {                                                                                \
       
   189 		NEW_CVALUE(dtype, symbol);                                                                             \
       
   190 		SET_CVALUE(dtype, symbol, oper GET_CVALUE(dtype, arg));                                                \
       
   191 	}
   186 
   192 
   187 
   193 
   188 
   194 
   189 
   195 
   190 
   196 
   385 /*********************/
   391 /*********************/
   386 /******************************/
   392 /******************************/
   387 /* B 1.2.1 - Numeric Literals */
   393 /* B 1.2.1 - Numeric Literals */
   388 /******************************/
   394 /******************************/
   389 void *constant_folding_c::visit(real_c *symbol) {
   395 void *constant_folding_c::visit(real_c *symbol) {
   390 	NEW_CVALUE(real64, symbol);
   396 	NEW_CVALUE(real64, symbol);	SET_CVALUE(real64, symbol, extract_real_value(symbol));
   391 	SET_CVALUE(real64, symbol, extract_real_value(symbol));
       
   392 	return NULL;
   397 	return NULL;
   393 }
   398 }
   394 
   399 
   395 
   400 
   396 void *constant_folding_c::visit(integer_c *symbol) {
   401 void *constant_folding_c::visit(integer_c *symbol) {
   397 	NEW_CVALUE( int64, symbol);
   402 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_integer_value(symbol));
   398 	SET_CVALUE( int64, symbol, extract_integer_value(symbol));
   403 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_integer_value(symbol));
   399 	NEW_CVALUE(uint64, symbol);
       
   400 	SET_CVALUE(uint64, symbol, extract_integer_value(symbol));
       
   401 	return NULL;
   404 	return NULL;
   402 }
   405 }
   403 
   406 
   404 
   407 
   405 void *constant_folding_c::visit(neg_real_c *symbol) {
   408 void *constant_folding_c::visit(neg_real_c *symbol) {
   406 	symbol->exp->accept(*this);
   409 	symbol->exp->accept(*this);
   407 	if (!VALID_CVALUE(real64, symbol->exp))
   410 	DO_UNARY_OPER(real64, -, symbol->exp);
   408 		return NULL;
       
   409 	NEW_CVALUE(real64, symbol);
       
   410 	SET_CVALUE(real64, symbol, - GET_CVALUE( real64, symbol->exp));
       
   411 	CHECK_OVERFLOW_real64(symbol);
   411 	CHECK_OVERFLOW_real64(symbol);
   412 	return NULL;
   412 	return NULL;
   413 }
   413 }
   414 
   414 
   415 /* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
   415 /* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
   416 void *constant_folding_c::visit(neg_integer_c *symbol) {
   416 void *constant_folding_c::visit(neg_integer_c *symbol) {
   417 	symbol->exp->accept(*this);
   417 	symbol->exp->accept(*this);
   418 	if (VALID_CVALUE(int64, symbol->exp)) {
   418 	DO_UNARY_OPER(int64, -, symbol->exp);
   419 		NEW_CVALUE( int64, symbol);
       
   420 		SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp));
       
   421 	}
       
   422 	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
   419 	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
   423 	return NULL;
   420 	return NULL;
   424 }
   421 }
   425 
   422 
   426 
   423 
   433 	return NULL;
   430 	return NULL;
   434 }
   431 }
   435 
   432 
   436 
   433 
   437 void *constant_folding_c::visit(hex_integer_c *symbol) {
   434 void *constant_folding_c::visit(hex_integer_c *symbol) {
   438 	NEW_CVALUE( int64, symbol);
   435 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_hex_value(symbol));
   439 	SET_CVALUE( int64, symbol, extract_hex_value(symbol));
   436 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_hex_value(symbol));
   440 	NEW_CVALUE(uint64, symbol);
       
   441 	SET_CVALUE(uint64, symbol, extract_hex_value(symbol));
       
   442 	return NULL;
   437 	return NULL;
   443 }
   438 }
   444 
   439 
   445 
   440 
   446 /*
   441 /*
   451 | integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
   446 | integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
   452 */
   447 */
   453 // SYM_REF2(integer_literal_c, type, value)
   448 // SYM_REF2(integer_literal_c, type, value)
   454 void *constant_folding_c::visit(integer_literal_c *symbol) {
   449 void *constant_folding_c::visit(integer_literal_c *symbol) {
   455 	symbol->value->accept(*this);
   450 	symbol->value->accept(*this);
   456 	if (VALID_CVALUE( int64, symbol->value)) {
   451 	DO_UNARY_OPER( int64, /* none */, symbol->value);
   457 		NEW_CVALUE( int64, symbol);
   452 	DO_UNARY_OPER(uint64, /* none */, symbol->value);
   458 		SET_CVALUE( int64, symbol, GET_CVALUE( int64, symbol->value));
       
   459 	}
       
   460 	if (VALID_CVALUE(uint64, symbol->value)) {
       
   461 		NEW_CVALUE(uint64, symbol);
       
   462 		SET_CVALUE(uint64, symbol, GET_CVALUE(uint64, symbol->value));
       
   463 	}
       
   464 	return NULL;
   453 	return NULL;
   465 }
   454 }
   466 
   455 
   467 
   456 
   468 void *constant_folding_c::visit(real_literal_c *symbol) {
   457 void *constant_folding_c::visit(real_literal_c *symbol) {
   469 	symbol->value->accept(*this);
   458 	symbol->value->accept(*this);
   470 	if (VALID_CVALUE(real64, symbol->value)) {
   459 	DO_UNARY_OPER(real64, /* none */, symbol->value);
   471 		NEW_CVALUE(real64, symbol);
       
   472 		SET_CVALUE(real64, symbol,  GET_CVALUE(real64, symbol->value));
       
   473 	}
       
   474 	return NULL;
   460 	return NULL;
   475 }
   461 }
   476 
   462 
   477 
   463 
   478 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
   464 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
   480 }
   466 }
   481 
   467 
   482 
   468 
   483 void *constant_folding_c::visit(boolean_literal_c *symbol) {
   469 void *constant_folding_c::visit(boolean_literal_c *symbol) {
   484 	symbol->value->accept(*this);
   470 	symbol->value->accept(*this);
   485 	if (VALID_CVALUE(bool, symbol->value)) {
   471 	DO_UNARY_OPER(bool, /* none */, symbol->value);
   486 		NEW_CVALUE(bool, symbol);
       
   487 		SET_CVALUE(bool, symbol,  GET_CVALUE(  bool, symbol->value));
       
   488 	}
       
   489 	return NULL;
   472 	return NULL;
   490 }
   473 }
   491 
   474 
   492 
   475 
   493 void *constant_folding_c::visit(boolean_true_c *symbol) {
   476 void *constant_folding_c::visit(boolean_true_c *symbol) {
   494 	NEW_CVALUE(bool, symbol);
   477 	NEW_CVALUE(bool, symbol);	SET_CVALUE(bool, symbol, true);
   495 	SET_CVALUE(bool, symbol, true);
       
   496 	return NULL;
   478 	return NULL;
   497 }
   479 }
   498 
   480 
   499 
   481 
   500 void *constant_folding_c::visit(boolean_false_c *symbol) {
   482 void *constant_folding_c::visit(boolean_false_c *symbol) {
   501 	NEW_CVALUE(bool, symbol);
   483 	NEW_CVALUE(bool, symbol);	SET_CVALUE(bool, symbol, false);
   502 	SET_CVALUE(bool, symbol, false);
       
   503 	return NULL;
   484 	return NULL;
   504 }
   485 }
   505 
   486 
   506 
   487 
   507 /***************************************/
   488 /***************************************/
   679 }
   660 }
   680 
   661 
   681 
   662 
   682 void *constant_folding_c::visit(neg_expression_c *symbol) {
   663 void *constant_folding_c::visit(neg_expression_c *symbol) {
   683 	symbol->exp->accept(*this);
   664 	symbol->exp->accept(*this);
   684 	if (VALID_CVALUE( int64, symbol->exp)) {
   665 	DO_UNARY_OPER( int64, -, symbol->exp);	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
   685 		NEW_CVALUE( int64, symbol);
   666 	DO_UNARY_OPER(real64, -, symbol->exp);	CHECK_OVERFLOW_real64(symbol);
   686 		SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp));
       
   687 	}
       
   688 	if (VALID_CVALUE(real64, symbol->exp)) {
       
   689 		NEW_CVALUE(real64, symbol);
       
   690 		SET_CVALUE(real64, symbol, - GET_CVALUE(real64, symbol->exp));
       
   691 	}
       
   692 	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
       
   693 	CHECK_OVERFLOW_real64(symbol);
       
   694 	return NULL;
   667 	return NULL;
   695 }
   668 }
   696 
   669 
   697 
   670 
   698 
   671 
   699 void *constant_folding_c::visit(not_expression_c *symbol) {
   672 void *constant_folding_c::visit(not_expression_c *symbol) {
   700 	symbol->exp->accept(*this);
   673 	symbol->exp->accept(*this);
   701 	if (VALID_CVALUE(  bool, symbol->exp)) {
   674 	DO_UNARY_OPER(  bool, !, symbol->exp);
   702 		NEW_CVALUE(  bool, symbol);
   675 	DO_UNARY_OPER(uint64, ~, symbol->exp);
   703 		SET_CVALUE(  bool, symbol,  ! GET_CVALUE(  bool, symbol->exp));
   676 	return NULL;
   704 	}
   677 }
   705 	if (VALID_CVALUE(uint64, symbol->exp)) {
   678 
   706 		NEW_CVALUE(uint64, symbol);
   679 
   707 		SET_CVALUE(uint64, symbol,  ~ GET_CVALUE(uint64, symbol->exp));
       
   708 	}
       
   709 	return NULL;
       
   710 }
       
   711 
       
   712