@fs-eire/wgsl-template
Version:
A powerful template system for generating WGSL (WebGPU Shading Language) code with support for parameters, conditionals, and multiple output formats including C++ code generation.
127 lines (123 loc) • 4.03 kB
JavaScript
const renderArg = (arg) => {
const render = (segment) => {
switch (segment.type) {
case "code":
return JSON.stringify(segment.content);
default: // expression
return segment.content;
}
};
if (arg.code.length === 0) {
return "";
}
else if (arg.code.length === 1) {
if (arg.type === "string" && arg.code[0].type === "expression") {
return `"".concat(${arg.code[0].content})`;
}
else if (arg.type !== "expression" && arg.code[0].type === "code") {
return JSON.stringify(arg.code[0].content);
}
else {
return arg.code[0].content;
}
}
else {
if (arg.type !== "expression") {
return `"".concat(${arg.code.map(render).join(", ")})`;
}
else {
return arg.code.map((segment) => segment.content).join("");
}
}
};
export class DynamicCodeGenerator {
emit(code) {
return code
.map((segment) => {
switch (segment.type) {
case "raw":
return segment.content;
case "code":
// split code segments into lines and emit each line
let emitStr = "";
let text = segment.content;
while (text) {
const lineBreakIndex = text.indexOf("\n");
if (lineBreakIndex === -1) {
// If no line break, emit the whole text
emitStr += `emit(${JSON.stringify(text)});\n`;
break;
}
const line = text.slice(0, lineBreakIndex + 1);
text = text.slice(lineBreakIndex + 1);
emitStr += `emit(${JSON.stringify(line)});\n`;
}
return emitStr;
case "expression":
return `emit(${segment.content});\n`;
}
})
.join("");
}
param(name) {
return `param[${JSON.stringify(name)}]`;
}
variable(_name) {
return `variable[${JSON.stringify(_name)}]`;
}
property(obj, propertyName) {
return `variable[${JSON.stringify(obj)}].${propertyName}`;
}
function(name, args) {
const code = [name, "("];
for (let i = 0; i < args.length; i++) {
code.push(renderArg(args[i]));
if (i < args.length - 1) {
code.push(", ");
}
}
code.push(")");
return code.join("");
}
method(obj, methodName, args) {
const code = [`variable[${JSON.stringify(obj)}]`, ".", methodName, "("];
for (let i = 0; i < args.length; i++) {
code.push(renderArg(args[i]));
if (i < args.length - 1) {
code.push(", ");
}
}
code.push(")");
return code.join("");
}
build(repo, _options) {
let contents = `// This file is auto-generated by wgsl-gen. Do not edit manually.
"use strict";
globalThis.$templates = {
`;
for (const [name, template] of repo.templates) {
contents += ` ${JSON.stringify(name)}: function(param, variable, shader_helper) {
var $emitAdditional = function (code) {
shader_helper.appendAdditionalImplementation(code);
};
var $emitMain = function (code) {
shader_helper.appendMainFunctionBody(code);
};
var emit = $emitAdditional;
var MainFunctionStart = function () {
emit = $emitMain;
};
var MainFunctionEnd = function () {
emit = $emitAdditional;
};
${template.generateResult.code}
},\n`;
}
contents += "};\n";
return {
basePath: repo.basePath,
templates: new Map([["templates.js", contents]]),
};
}
}
//# sourceMappingURL=code-generator-dynamic-impl.js.map