@thi.ng/shader-ast
Version:
DSL to define shader code in TypeScript and cross-compile to GLSL, JS and other targets
80 lines (79 loc) • 1.83 kB
JavaScript
import { isString } from "@thi.ng/checks/is-string";
import { assert } from "@thi.ng/errors/assert";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import { gensym } from "./idgen.js";
function sym(type, ...args) {
let id;
let opts;
let init;
switch (args.length) {
case 0:
if (!isString(type)) {
init = type;
type = init.type;
}
break;
case 1:
if (isString(args[0])) {
id = args[0];
} else if (args[0].tag) {
init = args[0];
} else {
opts = args[0];
}
break;
case 2:
if (isString(args[0])) {
[id, opts] = args;
} else {
[opts, init] = args;
}
break;
case 3:
[id, opts, init] = args;
break;
default:
illegalArgs();
}
return {
tag: "sym",
type,
id: id || gensym(),
opts: opts || {},
init
};
}
const constSym = (type, id, opts, init) => sym(type, id || gensym(), { const: true, ...opts }, init);
const arraySym = (type, id, opts = {}, init) => {
if (init && opts.num == null) {
opts.num = init.length;
}
assert(opts.num != null, "missing array length");
init && assert(
opts.num === init.length,
`expected ${opts.num} items in array, but got ${init.length}`
);
const atype = type + "[]";
return {
tag: "sym",
type: atype,
id: id || gensym(),
opts,
init: init ? {
tag: "array_init",
type: atype,
init
} : void 0
};
};
const input = (type, id, opts) => sym(type, id, { q: "in", type: "in", ...opts });
const output = (type, id, opts) => sym(type, id, { q: "out", type: "out", ...opts });
const uniform = (type, id, opts) => sym(type, id, { q: "in", type: "uni", ...opts });
export {
arraySym,
constSym,
input,
output,
sym,
uniform
};