secondlife / secondlife/sl-vscode-plugin

Preprocessor reports false "Invalid number literal: exponent has no digits" for hex literals such as `0x9E`

Open Beginner friendly
#147 0 comments 0 reactions 0 assignees View on GitHub

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
  1. Open a Luau (or LSL) script with the preprocessor enabled.
  2. 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 })
    
  3. 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:

  1. It read the integer part 0.
  2. It then consumed the next identifier-start character x as a numeric "suffix", producing the token 0x.
  3. Lexing resumed at 9E, which it read as the digit 9 followed by an exponent marker E with 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.