Evaluating expanded macros in conditional expressions#58
Conversation
|
Thanks! |
9f7856b to
20b8b6f
Compare
| "watch-test": "jest --watch", | ||
| "test": "jest --colors" | ||
| "watch-test": "vitest --watch", | ||
| "test": "vitest" |
There was a problem hiding this comment.
This PR includes switching to vitest which is much faster than jest
| 'npx peggy --cache --format es --allowed-start-rules program,constant_expression -o src/preprocessor/preprocessor-parser.js src/preprocessor/preprocessor-grammar.pegjs' | ||
| ); | ||
| const { parse, parser } = require('../preprocessor'); | ||
| const { parse, parser } = await import('../preprocessor/index.js'); |
There was a problem hiding this comment.
Ths might be introducing a bug where changing the grammar does not update in the tests
f8aa228 to
3f06b49
Compare
3f06b49 to
6ced832
Compare
properly In the preprocessor grammar spec, there is a grammar spec for if statements ```` if-line: #if constant-expression #ifdef identifier #ifndef identifier ```` If there are no macros to expand, parsing a program can be done in one pass then evaluated. If there is a define like ``` true ``` Then in the current version of the parser, there is a bug, because while it does properly expand "A 2" to "1 + 2", it does not properly re-create the AST here, so when the AST is evaluated, it does not evaluate "1 + 2", it does something weird, and produces the wrong output. The fix is to parse the expressions in the grammar as strings, perform macro expansion on that string first, then parse them on the fly using the peggy parser starting from a specific entry point
6ced832 to
87b0ac3
Compare
5bc144d to
f4b7a1d
Compare
…s compiled TypeScript — including *.test.js files — into the root-level preprocessor/, parser/, and ast/ directories. Vitest found and ran these compiled test files alongside the TypeScript ones. The compiled preprocessor/preprocessor.test.js imported GlslSyntaxError from ../error.js (root-level compiled), but buildPreprocessorParser dynamically imported preprocessor/index.js which was resolved by Vite's TypeScript-aware resolver to src/preprocessor/index.ts → src/error.ts. Two different class instances → instanceof failed. Two fixes applied: 1. vite.config.ts: Added include: ['src/**/*.test.ts'] so Vitest only runs the canonical TypeScript test files in src/, ignoring compiled JS copies elsewhere. 2. prepublish.sh: Added cleanup to delete *.test.js and *.test.d.ts from published directories — test files don't belong in the npm package and cause this discovery problem.
| / token:IF expression:constant_expression? { | ||
| // Intentionally defer parsing of the expression, macro expansion is first | ||
| // done on this string, then the expanded expression lexeme is parsed again | ||
| / token:IF expression:token_string? { |
There was a problem hiding this comment.
This is the first step in the core change - defer expression parsing until later - treat it as a string for now
| ); | ||
|
|
||
| const expanded = expandMacros(defined, macros); | ||
| return evaluteExpression(expressionParser(expanded.trim()), macros); |
There was a problem hiding this comment.
This is the primary change - evaluate the expression string after the macros are expanded
| ) | ||
| .replace(/defined\s+([A-Za-z_][A-Za-z_0-9]*)/g, (_, id) => | ||
| id in macros ? '1' : '0' | ||
| ); |
There was a problem hiding this comment.
AI wrote this code. It works. It would be nice if there weren't a new mini grammar nested in here. Another way to do this is to re-generate the expression into a string then re-parse it, to avoid having to evaluate defines this way. But this still works for now.
Fix for bug where #if expressions with macros inside aren't evaluated properly
In the preprocessor grammar spec, there is a grammar spec for if statements
If there are no macros to expand, parsing a program can be done in one pass then evaluated.
If there is a define like
Then in the current version of the parser, there is a bug, because while it does properly expand "A 2" to "1 + 2", it does not properly re-create the AST here, so when the AST is evaluated, it does not evaluate "1 + 2", it does something weird, and produces the wrong output.
The fix is to parse the expressions in the grammar as strings, perform macro expansion on that string first, then parse them on the