Skip to content

Commit

Permalink
Fixing the issue and bumping package version
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewRayCode committed Jul 29, 2024
1 parent c13fb6e commit 9ce4b36
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"engines": {
"node": ">=16"
},
"version": "5.0.0",
"version": "5.1.0",
"type": "module",
"description": "A GLSL ES 1.0 and 3.0 parser and preprocessor that can preserve whitespace and comments",
"scripts": {
Expand Down
12 changes: 10 additions & 2 deletions src/preprocessor/preprocessor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,21 @@ foo`);
test(`function macro where source variable is same as macro argument`, () => {
const program = `
#define GE(x, y) x + y
float z = GE(y, x);
GE(y, x);
GE(y.y, x.x);
GE(yy, xx);
`;

const ast = parse(program);
preprocessAst(ast);

// Ensure that if the argument passed to the fn GE(X) has the
// same name as the macro definition #define GE(X), it doesn't get expanded
// https://github.com/ShaderFrog/glsl-parser/issues/31
expect(generate(ast)).toBe(`
float z = y + x;
y + x;
y.y + x.x;
yy + xx;
`);
});

Expand Down
34 changes: 24 additions & 10 deletions src/preprocessor/preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,31 @@ const expandFunctionMacro = (
throw new Error(`'${macroName}': Not enough arguments for macro`);
}

// Collect the macro identifiers and build a replacement map from those to
// the user defined replacements
const argIdentifiers = macroArgs.map(
(a) => (a as PreprocessorIdentifierNode).identifier
);
const argKeys = argIdentifiers.reduce<Record<string, string>>(
(acc, identifier, index) => ({
...acc,
[identifier]: args[index].trim(),
}),
{}
);

const replacedBody = tokenPaste(
macroArgs.reduce(
(replaced, macroArg, index) =>
replaced.replace(
new RegExp(
`\\b${(macroArg as PreprocessorIdentifierNode).identifier}\\b`,
'g'
),
args[index].trim()
),
macro.body
macro.body.replace(
// Replace all instances of macro arguments in the macro definition
// (the arg separated by word boundaries) with its user defined
// replacement. This one-pass strategy ensures that we won't clobber
// previous replacements when the user supplied args have the same names
// as the macro arguments
new RegExp(
'(' + argIdentifiers.map((a) => `\\b${a}\\b`).join(`|`) + ')',
'g'
),
(match) => (match in argKeys ? argKeys[match] : match)
)
);

Expand Down

0 comments on commit 9ce4b36

Please sign in to comment.