253 static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);} |
253 static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);} |
254 |
254 |
255 |
255 |
256 /* extract the value of an integer from an integer_c object !! */ |
256 /* extract the value of an integer from an integer_c object !! */ |
257 /* NOTE: it must ignore underscores! */ |
257 /* NOTE: it must ignore underscores! */ |
258 int64_t extract_int64_value(symbol_c *sym, int base, bool *overflow) { |
258 /* NOTE: To follow the basic structure used throughout the compiler's code, we should really be |
259 std::string str = ""; |
259 * writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct |
260 integer_c *integer; |
260 * symbol class types to handle, it is probably easier to read if we write it as a standard function... |
261 char *endptr; |
261 */ |
262 int64_t ret; |
262 int64_t extract_int64_value(symbol_c *sym, bool *overflow) { |
263 |
263 int64_t ret; |
264 if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR; |
264 std::string str = ""; |
265 for(unsigned int i = 0; i < strlen(integer->value); i++) |
265 char *endptr; |
266 if (integer->value[i] != '_') str += integer->value[i]; |
266 const char *value; |
|
267 int base; |
|
268 integer_c *integer; |
|
269 hex_integer_c *hex_integer; |
|
270 octal_integer_c *octal_integer; |
|
271 binary_integer_c *binary_integer; |
|
272 |
|
273 if ((integer = dynamic_cast<integer_c *>(sym)) != NULL) {value = integer ->value + 0; base = 10;} |
|
274 else if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} |
|
275 else if ((octal_integer = dynamic_cast<octal_integer_c *>(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} |
|
276 else if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} |
|
277 else ERROR; |
|
278 |
|
279 for(unsigned int i = 0; i < strlen(value); i++) |
|
280 if (value[i] != '_') str += value[i]; |
267 |
281 |
268 errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
282 errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
269 ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base); |
283 ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base); |
270 if (overflow != NULL) |
284 if (overflow != NULL) |
271 *overflow = (errno == ERANGE); |
285 *overflow = (errno == ERANGE); |
273 ERROR; |
287 ERROR; |
274 |
288 |
275 return ret; |
289 return ret; |
276 } |
290 } |
277 |
291 |
278 uint64_t extract_uint64_value(symbol_c *sym, int base, bool *overflow) { |
292 |
279 std::string str = ""; |
293 |
280 integer_c *integer; |
294 uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) { |
281 char *endptr; |
295 uint64_t ret; |
282 uint64_t ret; |
296 std::string str = ""; |
283 |
297 char *endptr; |
284 if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR; |
298 const char *value; |
285 for(unsigned int i = 0; i < strlen(integer->value); i++) |
299 int base; |
286 if (integer->value[i] != '_') str += integer->value[i]; |
300 integer_c *integer; |
|
301 hex_integer_c *hex_integer; |
|
302 octal_integer_c *octal_integer; |
|
303 binary_integer_c *binary_integer; |
|
304 |
|
305 if ((integer = dynamic_cast<integer_c *>(sym)) != NULL) {value = integer ->value + 0; base = 10;} |
|
306 else if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} |
|
307 else if ((octal_integer = dynamic_cast<octal_integer_c *>(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} |
|
308 else if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} |
|
309 else ERROR; |
|
310 |
|
311 for(unsigned int i = 0; i < strlen(value); i++) |
|
312 if (value[i] != '_') str += value[i]; |
287 |
313 |
288 errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
314 errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
289 ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base); |
315 ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base); |
290 if (overflow != NULL) |
316 if (overflow != NULL) |
291 *overflow = (errno == ERANGE); |
317 *overflow = (errno == ERANGE); |
571 } |
597 } |
572 |
598 |
573 |
599 |
574 void *constant_folding_c::visit(integer_c *symbol) { |
600 void *constant_folding_c::visit(integer_c *symbol) { |
575 bool overflow; |
601 bool overflow; |
576 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 10, &overflow)); |
602 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
577 if (overflow) SET_OVFLOW(int64, symbol); |
603 if (overflow) SET_OVFLOW(int64, symbol); |
578 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 10, &overflow)); |
604 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
579 if (overflow) SET_OVFLOW(uint64, symbol); |
605 if (overflow) SET_OVFLOW(uint64, symbol); |
580 return NULL; |
606 return NULL; |
581 } |
607 } |
582 |
608 |
583 |
609 |
606 } |
632 } |
607 |
633 |
608 |
634 |
609 void *constant_folding_c::visit(binary_integer_c *symbol) { |
635 void *constant_folding_c::visit(binary_integer_c *symbol) { |
610 bool overflow; |
636 bool overflow; |
611 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 2, &overflow)); |
637 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
612 if (overflow) SET_OVFLOW(int64, symbol); |
638 if (overflow) SET_OVFLOW(int64, symbol); |
613 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 2, &overflow)); |
639 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
614 if (overflow) SET_OVFLOW(uint64, symbol); |
640 if (overflow) SET_OVFLOW(uint64, symbol); |
615 return NULL; |
641 return NULL; |
616 } |
642 } |
617 |
643 |
618 |
644 |
619 void *constant_folding_c::visit(octal_integer_c *symbol) { |
645 void *constant_folding_c::visit(octal_integer_c *symbol) { |
620 bool overflow; |
646 bool overflow; |
621 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 8, &overflow)); |
647 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
622 if (overflow) SET_OVFLOW(int64, symbol); |
648 if (overflow) SET_OVFLOW(int64, symbol); |
623 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 8, &overflow)); |
649 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
624 if (overflow) SET_OVFLOW(uint64, symbol); |
650 if (overflow) SET_OVFLOW(uint64, symbol); |
625 return NULL; |
651 return NULL; |
626 } |
652 } |
627 |
653 |
628 |
654 |
629 void *constant_folding_c::visit(hex_integer_c *symbol) { |
655 void *constant_folding_c::visit(hex_integer_c *symbol) { |
630 bool overflow; |
656 bool overflow; |
631 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 16, &overflow)); |
657 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
632 if (overflow) SET_OVFLOW(int64, symbol); |
658 if (overflow) SET_OVFLOW(int64, symbol); |
633 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 16, &overflow)); |
659 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
634 if (overflow) SET_OVFLOW(uint64, symbol); |
660 if (overflow) SET_OVFLOW(uint64, symbol); |
635 return NULL; |
661 return NULL; |
636 } |
662 } |
637 |
663 |
638 |
664 |