From ede9405daff386757d3f94aeba697d7dd7a3bfe6 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sat, 4 Apr 2026 13:41:45 -0400 Subject: [PATCH] Fix some fixed-point literal lexing issues (#1914) - No fractional digits are necessary after the decimal point, e.g. `42.` is valid instead of `42.0` - Error messages refer to "fixed-point" not "integer" constants - Test more carefully for lexing unrelated to underscores --- src/asm/lexer.cpp | 10 ++++++++-- test/asm/fixed-point-syntax.asm | 15 +++++++++++++++ test/asm/fixed-point-syntax.err | 15 +++++++++++++++ test/asm/fixed-point-syntax.out | 10 ++++++++++ test/asm/invalid-underscore.asm | 4 ++++ test/asm/invalid-underscore.err | 12 ++++++++---- 6 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 test/asm/fixed-point-syntax.asm create mode 100644 test/asm/fixed-point-syntax.err create mode 100644 test/asm/fixed-point-syntax.out diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index ef13c818..145adbc4 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -958,12 +958,17 @@ static uint32_t readFractionalPart(uint32_t integer) { READFRACTIONALPART_PRECISION, READFRACTIONALPART_PRECISION_DIGITS, } state = READFRACTIONALPART_DIGITS; - bool nonDigit = true; + bool anyDigit = false; + bool nonDigit = false; for (int c = peek();; c = nextChar()) { if (state == READFRACTIONALPART_DIGITS) { if (c == '_') { - checkDigitSeparator(nonDigit); + if (nonDigit) { + error("Invalid fixed-point constant, '_' after another '_'"); + } else if (!anyDigit) { + error("Invalid fixed-point constant, '_' after '.'"); + } nonDigit = true; continue; } @@ -976,6 +981,7 @@ static uint32_t readFractionalPart(uint32_t integer) { break; } c -= '0'; + anyDigit = true; nonDigit = false; if (divisor > (UINT32_MAX - c) / 10) { diff --git a/test/asm/fixed-point-syntax.asm b/test/asm/fixed-point-syntax.asm new file mode 100644 index 00000000..e0eeb172 --- /dev/null +++ b/test/asm/fixed-point-syntax.asm @@ -0,0 +1,15 @@ +; good +println 3.14 +println 42. +println 12_34.56_78 +println 12.34_q.5 +println 1_2.3_4_q15 +println 1.q2 + +; bad +println 12.34q0 +println 12.34q_15 +println 12.34q1_5 +println 1_.2 +println 1._2 +println 1.2q diff --git a/test/asm/fixed-point-syntax.err b/test/asm/fixed-point-syntax.err new file mode 100644 index 00000000..388d7f50 --- /dev/null +++ b/test/asm/fixed-point-syntax.err @@ -0,0 +1,15 @@ +error: Invalid fixed-point constant, no significant digits after 'q' + at fixed-point-syntax.asm(10) +error: Invalid fixed-point constant, no significant digits after 'q' + at fixed-point-syntax.asm(11) +error: syntax error, unexpected symbol + at fixed-point-syntax.asm(11) +error: syntax error, unexpected symbol + at fixed-point-syntax.asm(12) +error: Invalid integer constant, trailing '_' + at fixed-point-syntax.asm(13) +error: Invalid fixed-point constant, '_' after '.' + at fixed-point-syntax.asm(14) +error: Invalid fixed-point constant, no significant digits after 'q' + at fixed-point-syntax.asm(15) +Assembly aborted with 7 errors diff --git a/test/asm/fixed-point-syntax.out b/test/asm/fixed-point-syntax.out new file mode 100644 index 00000000..cde3a113 --- /dev/null +++ b/test/asm/fixed-point-syntax.out @@ -0,0 +1,10 @@ +$323D7 +$2A0000 +$4D2915B +$18B +$62B85 +$4 +$C570A +$13333 +$13333 +$13333 diff --git a/test/asm/invalid-underscore.asm b/test/asm/invalid-underscore.asm index 0d4dc85e..5d09d449 100644 --- a/test/asm/invalid-underscore.asm +++ b/test/asm/invalid-underscore.asm @@ -30,3 +30,7 @@ println 123.456_ ; bad ('_' next to '.') println 1_.618 println 2._718 + +; bad ('_' after 'q') +println 1q_2 +println 1q2_3 diff --git a/test/asm/invalid-underscore.err b/test/asm/invalid-underscore.err index 863df40b..4061abcc 100644 --- a/test/asm/invalid-underscore.err +++ b/test/asm/invalid-underscore.err @@ -8,9 +8,9 @@ error: Invalid integer constant, '_' after another '_' at invalid-underscore.asm(17) error: Invalid integer constant, '_' after another '_' at invalid-underscore.asm(18) -error: Invalid integer constant, '_' after another '_' +error: Invalid fixed-point constant, '_' after another '_' at invalid-underscore.asm(19) -error: Invalid integer constant, '_' after another '_' +error: Invalid fixed-point constant, '_' after another '_' at invalid-underscore.asm(20) error: Invalid integer constant, trailing '_' at invalid-underscore.asm(23) @@ -26,6 +26,10 @@ error: Invalid fixed-point constant, trailing '_' at invalid-underscore.asm(28) error: Invalid integer constant, trailing '_' at invalid-underscore.asm(31) -error: Invalid integer constant, '_' after another '_' +error: Invalid fixed-point constant, '_' after '.' at invalid-underscore.asm(32) -Assembly aborted with 15 errors +error: syntax error, unexpected symbol + at invalid-underscore.asm(35) +error: syntax error, unexpected symbol + at invalid-underscore.asm(36) +Assembly aborted with 17 errors