Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions src/generator-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,10 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
previousLineWasEmpty = false;
}

if (line.startsWith("#")) {
if (line.startsWith("#use ")) {
const uses = line
if (line.trim().startsWith("#")) {
const trimmedLine = line.trimStart();
if (trimmedLine.startsWith("#use ")) {
const uses = trimmedLine
.slice(5)
.split(" ")
.filter((s) => s.trim())
Expand All @@ -430,8 +431,8 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
}
patterns.push(pattern);
}
} else if (line.startsWith("#param ")) {
const params = line
} else if (trimmedLine.startsWith("#param ")) {
const params = trimmedLine
.slice(7)
.split(" ")
.filter((s) => s.trim())
Expand Down Expand Up @@ -467,7 +468,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
// otherwise silently ignore duplicate
}
}
} else if (line.startsWith("#if ")) {
} else if (trimmedLine.startsWith("#if ")) {
if (currentFunctionCall.length > 0) {
throw new WgslTemplateGenerateError(
`Preprocessor directive inside function call at line ${currentLine + 1}`,
Expand All @@ -477,7 +478,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
}

// Check if there's a condition after #if
const condition = line.slice(4).trim();
const condition = trimmedLine.slice(4).trim();
if (condition.length === 0) {
throw new WgslTemplateGenerateError(
`Empty condition in #if directive at line ${currentLine + 1}`,
Expand All @@ -486,7 +487,8 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
);
}

currentColumn = 4;
const leadingWhitespaceLength = line.length - trimmedLine.length;
currentColumn = leadingWhitespaceLength + 4; // Account for leading whitespace + "#if "
preprocessIfStack.push(["if", currentParenthesesState, currentBracketState, null, null]);
output("raw", "if (");
currentPreProcessorExpression = [];
Expand All @@ -511,7 +513,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
generatorState.result.push(...currentPreProcessorExpression);
currentPreProcessorExpression = null;
output("raw", ") {\n");
} else if (line.startsWith("#elif ")) {
} else if (trimmedLine.startsWith("#elif ")) {
if (
preprocessIfStack.length === 0 ||
(preprocessIfStack[preprocessIfStack.length - 1][0] !== "if" &&
Expand Down Expand Up @@ -552,7 +554,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
currentBracketState = preprocessIfStack[preprocessIfStack.length - 1][2]; // Reset bracket state to the initial state of the current block

// Check if there's a condition after #elif
const condition = line.slice(6).trim();
const condition = trimmedLine.slice(6).trim();
if (condition.length === 0) {
throw new WgslTemplateGenerateError(
`Empty condition in #elif directive at line ${currentLine + 1}`,
Expand All @@ -561,7 +563,8 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
);
}

currentColumn = 6;
const leadingWhitespaceLength = line.length - trimmedLine.length;
currentColumn = leadingWhitespaceLength + 6; // Account for leading whitespace + "#elif "
preprocessIfStack[preprocessIfStack.length - 1][0] = "elif";
output("raw", "} else if (");
currentPreProcessorExpression = [];
Expand All @@ -586,7 +589,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
generatorState.result.push(...currentPreProcessorExpression);
currentPreProcessorExpression = null;
output("raw", ") {\n");
} else if (line.startsWith("#else")) {
} else if (trimmedLine.startsWith("#else")) {
if (
preprocessIfStack.length === 0 ||
(preprocessIfStack[preprocessIfStack.length - 1][0] !== "if" &&
Expand Down Expand Up @@ -626,7 +629,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
currentParenthesesState = preprocessIfStack[preprocessIfStack.length - 1][1]; // Reset parentheses state to the initial state of the current block
currentBracketState = preprocessIfStack[preprocessIfStack.length - 1][2]; // Reset bracket state to the initial state of the current block

if (line.substring(5).trim() !== "") {
if (trimmedLine.substring(5).trim() !== "") {
throw new WgslTemplateGenerateError(
`Unexpected content after #else at line ${currentLine + 1}`,
"code-generation-failed",
Expand All @@ -635,7 +638,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
}
preprocessIfStack[preprocessIfStack.length - 1][0] = "else";
output("raw", "} else {\n");
} else if (line.startsWith("#endif")) {
} else if (trimmedLine.startsWith("#endif")) {
if (preprocessIfStack.length === 0) {
throw new WgslTemplateGenerateError(`#endif mismatch at line ${currentLine + 1}`, "code-generation-failed", {
lineNumber: currentLine + 1,
Expand Down Expand Up @@ -667,7 +670,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
);
}

if (line.substring(6).trim() !== "") {
if (trimmedLine.substring(6).trim() !== "") {
throw new WgslTemplateGenerateError(
`Unexpected content after #endif at line ${currentLine + 1}`,
"code-generation-failed",
Expand All @@ -677,7 +680,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
output("raw", "}\n");
preprocessIfStack.pop();
} else {
if (["#use", "#param", "#if", "#elif"].includes(line)) {
if (["#use", "#param", "#if", "#elif"].includes(trimmedLine)) {
throw new WgslTemplateGenerateError(
`Missing content after preprocessor directive at line ${currentLine + 1}`,
"code-generation-failed",
Expand All @@ -686,7 +689,7 @@ function generateImpl(generatorState: GeneratorState, options: GenerateOptions)
} else {
// Handle unknown preprocessor directive
throw new WgslTemplateGenerateError(
`Unknown preprocessor directive: ${line} at line ${currentLine + 1}`,
`Unknown preprocessor directive: ${trimmedLine} at line ${currentLine + 1}`,
"code-generation-failed",
{ filePath: generatorState.filePath, lineNumber: currentLine + 1 }
);
Expand Down
8 changes: 4 additions & 4 deletions src/parser-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function parsePreprocessorIncludeDirectives(includeStack: string[], parseState:
const parsedLine = currentState.lines[lineNumber];
const line = parsedLine.line;
// Process each line and extract include directives
const includeMatch = line.match(/^#include\s+(.+)$/);
const includeMatch = line.match(/^\s*#include\s+(.+)$/);
if (includeMatch) {
const includeParam = includeMatch[1].trim();
if (!(includeParam.startsWith('"') && includeParam.endsWith('"'))) {
Expand Down Expand Up @@ -154,10 +154,10 @@ function parseMacroDirectives(lines: ParsedLine[], fileName: string): ParsedLine

// Check for malformed #define directives
if (line.trim().startsWith("#define ")) {
const defineMatch = line.match(/^#define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+(.+)$/);
const defineMatch = line.match(/^\s*#define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+(.+)$/);
if (!defineMatch) {
// Check specific error cases
const emptyValueMatch = line.match(/^#define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$/);
const emptyValueMatch = line.match(/^\s*#define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$/);
if (emptyValueMatch) {
throw new WgslTemplateParseError(
`Invalid macro definition in file ${fileName} at line ${
Expand All @@ -168,7 +168,7 @@ function parseMacroDirectives(lines: ParsedLine[], fileName: string): ParsedLine
);
}

const invalidNameMatch = line.match(/^#define\s+(\S+)(?:\s+(.+))?$/);
const invalidNameMatch = line.match(/^\s*#define\s+(\S+)(?:\s+(.+))?$/);
if (invalidNameMatch) {
throw new WgslTemplateParseError(
`Invalid macro definition in file ${fileName} at line ${
Expand Down
4 changes: 2 additions & 2 deletions test/testcases/.gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Preserve line endings for expectation files
**/expected/
# Preserve line endings for test expectation files
**/expected/** text eol=lf
11 changes: 11 additions & 0 deletions test/testcases/generator-if-space-prefix/test-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"type": "generator",
"description": "Test #if directive with space at the beginning of line",
"entries": {
"test.wgsl.template": {
"generators": {
"dynamic": {}
}
}
}
}
9 changes: 9 additions & 0 deletions test/testcases/generator-if-space-prefix/test.wgsl.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#param ENABLE_FEATURE

fn test_function(value: f32) -> f32 {
#if ENABLE_FEATURE
return value * 2.0;
#else
return value;
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
emit("fn test_function(value: f32) -> f32 {\n");
if (param["ENABLE_FEATURE"]) {
emit(" return value * 2.0;\n");
} else {
emit(" return value;\n");
}
emit("}\n");
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const PI: f32 = 3.14159;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const PI: f32 = 3.14159;
8 changes: 8 additions & 0 deletions test/testcases/parser-include-space-prefix/main.wgsl.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Test #include with space at beginning of line
#include "constants.wgsl.template"

@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index = global_id.x;
let value = PI * f32(index);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

const PI: f32 = 3.14159;


@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index = global_id.x;
let value = PI * f32(index);
}
4 changes: 4 additions & 0 deletions test/testcases/parser-include-space-prefix/test-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "parser",
"description": "Test #include directive with space at the beginning of line"
}
15 changes: 15 additions & 0 deletions test/testcases/parser-macro-space-prefix/main.wgsl.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Test #define with space at beginning of line
#define PI 3.14159
#define MAX_SIZE 1024

const pi_value = PI;
const buffer_size = MAX_SIZE;

@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index = global_id.x;
let area = PI * f32(index) * f32(index);
if (index < MAX_SIZE) {
// Process within bounds
}
}
15 changes: 15 additions & 0 deletions test/testcases/parser-macro-space-prefix/main.wgsl.template.pass1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@




const pi_value = 3.14159;
const buffer_size = 1024;

@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index = global_id.x;
let area = 3.14159 * f32(index) * f32(index);
if (index < 1024) {

}
}
4 changes: 4 additions & 0 deletions test/testcases/parser-macro-space-prefix/test-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "parser",
"description": "Test #define directive with space at the beginning of line"
}