Allow underscores in numeric literals

Fixes #539

Changes \@'s output to start with "_u", not "_", so it will be valid within labels but not numerics
This commit is contained in:
Rangi
2020-12-09 11:01:51 -05:00
committed by Eldred Habert
parent 58739b0bf2
commit af530859f0
7 changed files with 47 additions and 22 deletions

View File

@@ -999,16 +999,16 @@ static void readNumber(int radix, int32_t baseValue)
{ {
uint32_t value = baseValue; uint32_t value = baseValue;
for (;;) { for (;; shiftChars(1)) {
int c = peek(0); int c = peek(0);
if (c < '0' || c > '0' + radix - 1) if (c == '_')
continue;
else if (c < '0' || c > '0' + radix - 1)
break; break;
if (value > (UINT32_MAX - (c - '0')) / radix) if (value > (UINT32_MAX - (c - '0')) / radix)
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
value = value * radix + (c - '0'); value = value * radix + (c - '0');
shiftChars(1);
} }
yylval.nConstValue = value; yylval.nConstValue = value;
@@ -1019,17 +1019,19 @@ static void readFractionalPart(void)
uint32_t value = 0, divisor = 1; uint32_t value = 0, divisor = 1;
dbgPrint("Reading fractional part\n"); dbgPrint("Reading fractional part\n");
for (;;) { for (;; shiftChars(1)) {
int c = peek(0); int c = peek(0);
if (c < '0' || c > '9') if (c == '_')
continue;
else if (c < '0' || c > '9')
break; break;
shiftChars(1);
if (divisor > (UINT32_MAX - (c - '0')) / 10) { if (divisor > (UINT32_MAX - (c - '0')) / 10) {
warning(WARNING_LARGE_CONSTANT, warning(WARNING_LARGE_CONSTANT,
"Precision of fixed-point constant is too large\n"); "Precision of fixed-point constant is too large\n");
/* Discard any additional digits */ /* 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); shiftChars(1);
break; break;
} }
@@ -1055,7 +1057,7 @@ static void readBinaryNumber(void)
uint32_t value = 0; uint32_t value = 0;
dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]); dbgPrint("Reading binary number with digits [%c,%c]\n", binDigits[0], binDigits[1]);
for (;;) { for (;; shiftChars(1)) {
int c = peek(0); int c = peek(0);
int bit; int bit;
@@ -1063,13 +1065,13 @@ static void readBinaryNumber(void)
bit = 0; bit = 0;
else if (c == binDigits[1]) else if (c == binDigits[1])
bit = 1; bit = 1;
else if (c == '_')
continue;
else else
break; break;
if (value > (UINT32_MAX - bit) / 2) if (value > (UINT32_MAX - bit) / 2)
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
value = value * 2 + bit; value = value * 2 + bit;
shiftChars(1);
} }
yylval.nConstValue = value; yylval.nConstValue = value;
@@ -1081,7 +1083,7 @@ static void readHexNumber(void)
bool empty = true; bool empty = true;
dbgPrint("Reading hex number\n"); dbgPrint("Reading hex number\n");
for (;;) { for (;; shiftChars(1)) {
int c = peek(0); int c = peek(0);
if (c >= 'a' && c <= 'f') /* Convert letters to right after digits */ if (c >= 'a' && c <= 'f') /* Convert letters to right after digits */
@@ -1090,6 +1092,8 @@ static void readHexNumber(void)
c = c - 'A' + 10; c = c - 'A' + 10;
else if (c >= '0' && c <= '9') else if (c >= '0' && c <= '9')
c = c - '0'; c = c - '0';
else if (c == '_' && !empty)
continue;
else else
break; break;
@@ -1097,7 +1101,6 @@ static void readHexNumber(void)
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n");
value = value * 16 + c; value = value * 16 + c;
shiftChars(1);
empty = false; empty = false;
} }

View File

@@ -117,7 +117,8 @@ void macro_SetUniqueID(uint32_t id)
if (uniqueID > maxUniqueID) if (uniqueID > maxUniqueID)
maxUniqueID = uniqueID; maxUniqueID = uniqueID;
/* The buffer is guaranteed to be the correct size */ /* 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; uniqueIDPtr = uniqueIDBuf;
} }
} }

View File

@@ -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

Binary file not shown.

View File

@@ -1,19 +1,19 @@
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser] 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] 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] 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] warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
_1 _u1
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser] 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] 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] 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] warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
_4 _u4
FATAL: unique-id.asm(15): FATAL: unique-id.asm(15):
Macro argument '\@' not defined Macro argument '\@' not defined
while expanding symbol "print" while expanding symbol "print"