diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 42a2d15d..45269493 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -999,16 +999,16 @@ static void readNumber(int radix, int32_t baseValue) { uint32_t value = baseValue; - for (;;) { + for (;; shiftChars(1)) { int c = peek(0); - if (c < '0' || c > '0' + radix - 1) + if (c == '_') + continue; + else if (c < '0' || c > '0' + radix - 1) break; if (value > (UINT32_MAX - (c - '0')) / radix) warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * radix + (c - '0'); - - shiftChars(1); } yylval.nConstValue = value; @@ -1019,17 +1019,19 @@ static void readFractionalPart(void) uint32_t value = 0, divisor = 1; dbgPrint("Reading fractional part\n"); - for (;;) { + for (;; shiftChars(1)) { int c = peek(0); - if (c < '0' || c > '9') + if (c == '_') + continue; + else if (c < '0' || c > '9') break; - shiftChars(1); if (divisor > (UINT32_MAX - (c - '0')) / 10) { warning(WARNING_LARGE_CONSTANT, "Precision of fixed-point constant is too large\n"); /* Discard any additional digits */ - while (c = peek(0), c >= '0' && c <= '9') + shiftChars(1); + while (c = peek(0), (c >= '0' && c <= '9') || c == '_') shiftChars(1); break; } @@ -1055,7 +1057,7 @@ static void readBinaryNumber(void) uint32_t value = 0; dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]); - for (;;) { + for (;; shiftChars(1)) { int c = peek(0); int bit; @@ -1063,13 +1065,13 @@ static void readBinaryNumber(void) bit = 0; else if (c == binDigits[1]) bit = 1; + else if (c == '_') + continue; else break; if (value > (UINT32_MAX - bit) / 2) warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * 2 + bit; - - shiftChars(1); } yylval.nConstValue = value; @@ -1081,7 +1083,7 @@ static void readHexNumber(void) bool empty = true; dbgPrint("Reading hex number\n"); - for (;;) { + for (;; shiftChars(1)) { int c = peek(0); if (c >= 'a' && c <= 'f') /* Convert letters to right after digits */ @@ -1090,6 +1092,8 @@ static void readHexNumber(void) c = c - 'A' + 10; else if (c >= '0' && c <= '9') c = c - '0'; + else if (c == '_' && !empty) + continue; else break; @@ -1097,7 +1101,6 @@ static void readHexNumber(void) warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * 16 + c; - shiftChars(1); empty = false; } diff --git a/src/asm/macro.c b/src/asm/macro.c index e3d95200..e87471a4 100644 --- a/src/asm/macro.c +++ b/src/asm/macro.c @@ -117,7 +117,8 @@ void macro_SetUniqueID(uint32_t id) if (uniqueID > maxUniqueID) maxUniqueID = uniqueID; /* The buffer is guaranteed to be the correct size */ - sprintf(uniqueIDBuf, "_%" PRIu32, id); + /* This is a valid label fragment, but not a valid numeric */ + sprintf(uniqueIDBuf, "_u%" PRIu32, id); uniqueIDPtr = uniqueIDBuf; } } diff --git a/test/asm/underscore-in-numeric-literal.asm b/test/asm/underscore-in-numeric-literal.asm new file mode 100644 index 00000000..2575d024 --- /dev/null +++ b/test/asm/underscore-in-numeric-literal.asm @@ -0,0 +1,21 @@ +SECTION "Test", ROM0 + +_1234:: + +; without underscores + dw _1234 ; label + db 123, 123, 123 ; decimal + dw 12345 ; decimal + dw $abcd ; hex + db &200 ; octal + db %11110000, %10 ; binary + dl 6.283185 ; fixed point + +; with underscores + dw _1234 ; label + db 123, 1_23, 1__23 ; decimal + dw 12_345 ; decimal + dw $ab_cd ; hex + db &2_0_0_ ; octal + db %1111_0000, %1_0 ; binary + dl 6_._283_185 ; fixed point diff --git a/test/asm/underscore-in-numeric-literal.err b/test/asm/underscore-in-numeric-literal.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/underscore-in-numeric-literal.out b/test/asm/underscore-in-numeric-literal.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/underscore-in-numeric-literal.out.bin b/test/asm/underscore-in-numeric-literal.out.bin new file mode 100644 index 00000000..c4f16cdd Binary files /dev/null and b/test/asm/underscore-in-numeric-literal.out.bin differ diff --git a/test/asm/unique-id.err b/test/asm/unique-id.err index 9c5fdd47..4367e1db 100644 --- a/test/asm/unique-id.err +++ b/test/asm/unique-id.err @@ -1,19 +1,19 @@ warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser] - _1 + _u1 warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser] - _2 + _u2 warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser] - _3 + _u3 warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser] - _1 + _u1 warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser] - _4 + _u4 warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser] - _5 + _u5 warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser] - _6 + _u6 warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser] - _4 + _u4 FATAL: unique-id.asm(15): Macro argument '\@' not defined while expanding symbol "print"