equal
deleted
inserted
replaced
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 |