first commit
This commit is contained in:
143
framework/WGSLReflection.js
Normal file
143
framework/WGSLReflection.js
Normal file
@@ -0,0 +1,143 @@
|
||||
export class WGSLReflection {
|
||||
|
||||
constructor(wgslSource) {
|
||||
|
||||
this.src = wgslSource;
|
||||
this.structs = {};
|
||||
this.bindings = [];
|
||||
|
||||
this.parseStructs();
|
||||
this.parseBindings();
|
||||
}
|
||||
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// STRUCT PARSING
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
parseStructs() {
|
||||
|
||||
const structRegex =
|
||||
/struct\s+(\w+)\s*\{([^}]+)\}/g;
|
||||
|
||||
let match;
|
||||
while ((match = structRegex.exec(this.src))) {
|
||||
|
||||
const structName = match[1];
|
||||
const body = match[2].trim();
|
||||
|
||||
const fields = this.parseStructFields(body);
|
||||
const size = fields.reduce((sum, f) => sum + f.size, 0);
|
||||
|
||||
this.structs[structName] = {
|
||||
name: structName,
|
||||
fields,
|
||||
size
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
parseStructFields(body) {
|
||||
|
||||
const lines = body.split("\n");
|
||||
const fields = [];
|
||||
|
||||
for (let line of lines) {
|
||||
|
||||
line = line.trim();
|
||||
if (!line) continue;
|
||||
|
||||
const m = line.match(/(\w+)\s*:\s*([^;]+);/);
|
||||
if (!m) continue;
|
||||
|
||||
const fieldName = m[1];
|
||||
const wgslType = m[2].trim();
|
||||
const size = this.computeTypeSize(wgslType);
|
||||
|
||||
fields.push({ fieldName, wgslType, size });
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// BINDING PARSING
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
parseBindings() {
|
||||
|
||||
const varRegex =
|
||||
/@group\((\d+)\)\s*@binding\((\d+)\)\s*var<([^>]+)>\s+(\w+)\s*:\s*([^;]+);/g;
|
||||
|
||||
let match;
|
||||
while ((match = varRegex.exec(this.src))) {
|
||||
|
||||
const group = parseInt(match[1]);
|
||||
const binding = parseInt(match[2]);
|
||||
const type = match[3].trim();
|
||||
const varName = match[4].trim();
|
||||
const varType = match[5].trim();
|
||||
|
||||
const size = this.computeTypeSize(varType);
|
||||
|
||||
this.bindings.push({
|
||||
group,
|
||||
binding,
|
||||
type,
|
||||
varName,
|
||||
varType,
|
||||
size
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// TYPE SIZE COMPUTATION (Simplified)
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
computeTypeSize(wgslType) {
|
||||
|
||||
// scalar
|
||||
if (wgslType === "f32" || wgslType === "u32" || wgslType === "i32") {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// array<f32, N>
|
||||
const arrMatch = wgslType.match(/array<(\w+),\s*(\d+)>/);
|
||||
if (arrMatch) {
|
||||
const elementType = arrMatch[1];
|
||||
const count = parseInt(arrMatch[2]);
|
||||
return this.computeTypeSize(elementType) * count;
|
||||
}
|
||||
|
||||
// array<f32> runtime-sized → minimal
|
||||
const runtimeArr = wgslType.match(/array<(\w+)>/);
|
||||
if (runtimeArr) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// struct
|
||||
if (this.structs[wgslType]) {
|
||||
return this.structs[wgslType].size;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// SUMMARY OUTPUT
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
reflect() {
|
||||
return {
|
||||
structs: this.structs,
|
||||
bindings: this.bindings
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user