Add numeric literal support to shader preprocessor#8402
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds support for numeric literals in #if preprocessor expressions, bringing the shader preprocessor closer to standard C preprocessor behavior. Previously, #if 1 would incorrectly be treated as an undefined symbol check rather than a numeric literal.
Changes:
- Added numeric literal evaluation in
evaluateAtomicExpression()usingparseFloat() - Numeric literals are evaluated as truthy if non-zero, falsy if zero
- Added 6 comprehensive test cases covering various numeric literal scenarios
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/core/preprocessor.js | Adds numeric literal handling to evaluateAtomicExpression() using parseFloat, checking after boolean literals but before defined() and comparison checks |
| test/core/preprocessor.test.mjs | Adds 6 test cases for numeric literals including integers, zero, floats, and combinations with logical operators |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Handle numeric literals (0 is false, non-zero is true) - standard C preprocessor behavior | ||
| const num = parseFloat(expr); | ||
| if (!isNaN(num)) { | ||
| return { result: num !== 0, error }; | ||
| } |
There was a problem hiding this comment.
The numeric literal check using parseFloat(expr) can produce incorrect results when the expression contains comparison operators with numeric literals on the left side. For example, #if 3 == 3 would be parsed as parseFloat("3 == 3") which returns 3 (parseFloat stops at the first non-numeric character), causing the expression to evaluate to true while ignoring the comparison operator entirely.
The COMPARISON regex requires the left operand to start with a letter or underscore, so it won't match numeric literals. This means numeric comparisons like #if 3 == 3 or #if 0 != 1 won't be caught by the comparison handler and will incorrectly fall through to the numeric literal handler.
Consider checking if the expression contains comparison operators before attempting to parse it as a numeric literal, or modify the COMPARISON regex to also match numeric literals on the left side.
Description
Adds support for numeric literals in
#ifpreprocessor expressions, following standard C preprocessor behavior.Changes
#if 0now evaluates to false (block is excluded)#if 1and any non-zero numeric literal evaluates to true (block is included)#if 0.0is falsy)#if 1 && defined(FOO))Why
This is standard C preprocessor behavior that developers expect to work. Previously,
#if 1would incorrectly evaluate to false because the preprocessor checked if'1'was a defined symbol rather than treating it as a numeric literal.Test Plan