# HG changeset patch # User Mario de Sousa # Date 1340101410 -3600 # Node ID 683ae5444237017a9e5deaa1812ad91f66cfe2da # Parent f5d4e9f9151343eddb1d0230f02317903e8ce4e4 fix parsing of non base 10 constant values. diff -r f5d4e9f91513 -r 683ae5444237 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Mon Jun 18 16:11:00 2012 +0100 +++ b/stage3/constant_folding.cc Tue Jun 19 11:23:30 2012 +0100 @@ -255,15 +255,29 @@ /* extract the value of an integer from an integer_c object !! */ /* NOTE: it must ignore underscores! */ -int64_t extract_int64_value(symbol_c *sym, int base, bool *overflow) { - std::string str = ""; - integer_c *integer; - char *endptr; - int64_t ret; - - if ((integer = dynamic_cast(sym)) == NULL) ERROR; - for(unsigned int i = 0; i < strlen(integer->value); i++) - if (integer->value[i] != '_') str += integer->value[i]; +/* NOTE: To follow the basic structure used throughout the compiler's code, we should really be + * writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct + * symbol class types to handle, it is probably easier to read if we write it as a standard function... + */ +int64_t extract_int64_value(symbol_c *sym, bool *overflow) { + int64_t ret; + std::string str = ""; + char *endptr; + const char *value; + int base; + integer_c *integer; + hex_integer_c *hex_integer; + octal_integer_c *octal_integer; + binary_integer_c *binary_integer; + + if ((integer = dynamic_cast(sym)) != NULL) {value = integer ->value + 0; base = 10;} + else if ((hex_integer = dynamic_cast(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} + else if ((octal_integer = dynamic_cast(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} + else if ((binary_integer = dynamic_cast(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} + else ERROR; + + for(unsigned int i = 0; i < strlen(value); i++) + if (value[i] != '_') str += value[i]; errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base); @@ -275,15 +289,27 @@ return ret; } -uint64_t extract_uint64_value(symbol_c *sym, int base, bool *overflow) { - std::string str = ""; - integer_c *integer; - char *endptr; - uint64_t ret; - - if ((integer = dynamic_cast(sym)) == NULL) ERROR; - for(unsigned int i = 0; i < strlen(integer->value); i++) - if (integer->value[i] != '_') str += integer->value[i]; + + +uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) { + uint64_t ret; + std::string str = ""; + char *endptr; + const char *value; + int base; + integer_c *integer; + hex_integer_c *hex_integer; + octal_integer_c *octal_integer; + binary_integer_c *binary_integer; + + if ((integer = dynamic_cast(sym)) != NULL) {value = integer ->value + 0; base = 10;} + else if ((hex_integer = dynamic_cast(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} + else if ((octal_integer = dynamic_cast(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} + else if ((binary_integer = dynamic_cast(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} + else ERROR; + + for(unsigned int i = 0; i < strlen(value); i++) + if (value[i] != '_') str += value[i]; errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base); @@ -573,9 +599,9 @@ void *constant_folding_c::visit(integer_c *symbol) { bool overflow; - NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 10, &overflow)); + NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); if (overflow) SET_OVFLOW(int64, symbol); - NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 10, &overflow)); + NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); if (overflow) SET_OVFLOW(uint64, symbol); return NULL; } @@ -608,9 +634,9 @@ void *constant_folding_c::visit(binary_integer_c *symbol) { bool overflow; - NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 2, &overflow)); + NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); if (overflow) SET_OVFLOW(int64, symbol); - NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 2, &overflow)); + NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); if (overflow) SET_OVFLOW(uint64, symbol); return NULL; } @@ -618,9 +644,9 @@ void *constant_folding_c::visit(octal_integer_c *symbol) { bool overflow; - NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 8, &overflow)); + NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); if (overflow) SET_OVFLOW(int64, symbol); - NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 8, &overflow)); + NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); if (overflow) SET_OVFLOW(uint64, symbol); return NULL; } @@ -628,9 +654,9 @@ void *constant_folding_c::visit(hex_integer_c *symbol) { bool overflow; - NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, 16, &overflow)); + NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); if (overflow) SET_OVFLOW(int64, symbol); - NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 16, &overflow)); + NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); if (overflow) SET_OVFLOW(uint64, symbol); return NULL; }