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) { |