fix totally broken hexadecimal constants

This commit is contained in:
K. Lange 2020-12-27 10:14:52 +09:00
parent 81e3e133c8
commit d90778c40c
2 changed files with 22 additions and 22 deletions

View File

@ -193,18 +193,21 @@ static void emitConstant(KrkValue value) {
static void number(int canAssign) { static void number(int canAssign) {
const char * start = parser.previous.start; const char * start = parser.previous.start;
int base = 10; int base = 10;
/* These special cases for hexadecimal, binary, octal values. */
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) { if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
base = 10; base = 16;
start += 2; start += 2;
} else if (start[0] == '0' && (start[1] == 'b' || start[1] == 'B')) { } else if (start[0] == '0' && (start[1] == 'b' || start[1] == 'B')) {
base = 2; base = 2;
start += 2; start += 2;
} else if (start[0] == '0') { } else if (start[0] == '0' && (start[1] == 'o' || start[1] == 'O')) {
base = 8; base = 8;
start += 1; start += 2;
} }
/* If it wasn't a special base, it may be a floating point value. */
if (base == 10) { if (base == 10) {
/* See if it's a float */
for (size_t j = 0; j < parser.previous.length; ++j) { for (size_t j = 0; j < parser.previous.length; ++j) {
if (parser.previous.start[j] == '.') { if (parser.previous.start[j] == '.') {
double value = strtod(start, NULL); double value = strtod(start, NULL);
@ -213,6 +216,8 @@ static void number(int canAssign) {
} }
} }
} }
/* If we got here, it's an integer of some sort. */
int value = strtol(start, NULL, base); int value = strtol(start, NULL, base);
emitConstant(INTEGER_VAL(value)); emitConstant(INTEGER_VAL(value));
} }

View File

@ -127,31 +127,26 @@ static int isDigit(char c) {
} }
static KrkToken number(char c) { static KrkToken number(char c) {
if (c == 0) { if (c == '0') {
/* Hexadecimal */
if (peek() == 'x' || peek() == 'X') { if (peek() == 'x' || peek() == 'X') {
/* Hexadecimal */
advance(); advance();
do { while (isDigit(peek()) || (peek() >= 'a' && peek() <= 'f') ||
char n = peek(); (peek() >= 'A' && peek() <= 'F')) advance();
if (isDigit(n) || (n >= 'a' && n <= 'f') || (n >= 'A' && n <= 'F')) {
advance();
continue;
}
} while (0);
return makeToken(TOKEN_NUMBER); return makeToken(TOKEN_NUMBER);
} } else if (peek() == 'b' || peek() == 'B') {
/* Binary */ /* Binary */
if (peek() == 'b' || peek() == 'B') {
advance(); advance();
while (peek() == '0' || peek() == '1') advance(); while (peek() == '0' || peek() == '1') advance();
return makeToken(TOKEN_NUMBER); return makeToken(TOKEN_NUMBER);
} } if (peek() == 'o' || peek() == 'O') {
/* Octal - must be 0o, none of those silly 0123 things */
/* Octal */ advance();
while (peek() >= '0' && peek() <= '7') advance(); while (peek() >= '0' && peek() <= '7') advance();
return makeToken(TOKEN_NUMBER); return makeToken(TOKEN_NUMBER);
} }
/* Otherwise, decimal and maybe 0.123 floating */
}
/* Decimal */ /* Decimal */
while (isDigit(peek())) advance(); while (isDigit(peek())) advance();