secondlife / secondlife/sl-vscode-plugin
Preprocessor reports false "Invalid number literal: exponent has no digits" for hex literals such as `0x9E`
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 33
- Forks
- 15
- Avg merge
- 14h 50m
- Merged PRs (30d)
- 9
Description
Description
The preprocessor's lexer doesn't recognise hexadecimal (or Luau binary) literals. It splits them into two tokens, and if the second half looks like an incomplete exponent it reports a false error. This makes valid scripts fail to preprocess.
Steps to reproduce
- Open a Luau (or LSL) script with the preprocessor enabled.
- Add a line containing a hex literal whose digits include a decimal digit immediately followed by
E/e, with no digit after it:base = writeBytecode(state, { 0x9E, 16, 0 }) - Save the file.
Expected behaviour
The line preprocesses without error. 0x9E is valid and equals 158.
Actual behaviour
Preprocessing fails and the Problems panel shows:
Invalid number literal: exponent has no digits (source: "luau Preprocessor")
The script isn't synced, and the only other feedback is a generic "Preprocessing failed" toast.
Cause
Lexer.readNumber in src/shared/lexer.ts had no hex or binary handling. For 0x9E:
- It read the integer part
0. - It then consumed the next identifier-start character
xas a numeric "suffix", producing the token0x. - Lexing resumed at
9E, which it read as the digit9followed by an exponent markerEwith no digits after it, and reported the error.
Scope
Any hex literal was mis-tokenised. It only produced an error when a decimal digit was directly followed by E/e and then a non-digit, for example 0x9E, 0x1E or 0x0E. Other forms were split silently and harmlessly, since tokens are re-emitted verbatim:
| Literal | Tokens before the fix | Visible effect |
|---|---|---|
0x9E, 0x1E, 0x0E |
0x + 9E |
False error (this issue) |
0xFF, 0xAE |
0x + FF (identifier) |
None |
0x1E5 |
0x + 1E5 (valid float) |
None |
0x1E+2 |
0x + 1E+2 |
Silently mis-tokenised |
0b1010 (Luau) |
0b + 1010 |
None |
Fix
readNumber now recognises 0x… and 0b… up front and returns the whole literal as a single NUMBER_LITERAL token, without going through the exponent or suffix logic. It only does so when a valid digit follows the prefix, so a bare 0x and every other literal behave as before. Genuine bad exponents such as 123e and 1.5e+ are still reported.
Regression tests were added to src/test/suite/lexer-diagnostics.test.ts, covering the reported case, mixed-case hex, Luau binary, 0x1E+2, and the bare-prefix case.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/shared/lexer.ts at Lexer.readNumber and review the regression coverage in src/test/suite/lexer-diagnostics.test.ts. Reproduce the reported 0x9E case along with the listed hexadecimal, Luau binary, bare-prefix, and malformed-exponent cases. Done means valid literals preprocess without diagnostics while genuine bad exponents still report errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100