UNPKG

@thi.ng/shader-ast

Version:

DSL to define shader code in TypeScript and cross-compile to GLSL, JS and other targets

165 lines (164 loc) 3.03 kB
import { isNumber } from "@thi.ng/checks/is-number"; import { assign } from "./assign.js"; import { isMat, isVec } from "./checks.js"; import { numberWithMatchingType } from "./item.js"; import { float } from "./lit.js"; const op1 = (op, val, post = false) => ({ tag: "op1", type: val.type, op, val, post }); const OP_INFO = { mave: "mv", vema: "vm", vefl: "vn", mafl: "vn", flve: "nv", flma: "nv", ivin: "vn", iniv: "nv", uvui: "vn", uiuv: "nv" }; const op2 = (op, _l, _r, rtype, info) => { const nl = isNumber(_l); const nr = isNumber(_r); let type; let l; let r; if (nl) { if (nr) { l = float(_l); r = float(_r); type = "float"; } else { r = _r; l = numberWithMatchingType(r, _l); type = r.type; } } else if (nr) { l = _l; r = numberWithMatchingType(l, _r); type = l.type; } else { l = _l; r = _r; type = rtype || (isVec(l) ? l.type : isVec(r) ? r.type : isMat(r) ? r.type : l.type); } return { tag: "op2", type: rtype || type, info: info || OP_INFO[l.type.substring(0, 2) + r.type.substring(0, 2)], op, l, r }; }; const inc = (t) => op1("++", t, true); const dec = (t) => op1("--", t, true); function add(l, r) { return op2("+", l, r); } function addSelf(l, r) { return assign(l, add(l, r)); } function sub(l, r) { return op2("-", l, r); } function subSelf(l, r) { return assign(l, sub(l, r)); } function mul(l, r) { return op2( "*", l, r, !isNumber(l) && !isNumber(r) && isMat(l) && isVec(r) ? r.type : void 0 ); } function mulSelf(l, r) { return assign(l, mul(l, r)); } function div(l, r) { return op2("/", l, r); } function divSelf(l, r) { return assign(l, div(l, r)); } function modi(l, r) { return op2( "%", isNumber(l) ? numberWithMatchingType(r, l) : l, isNumber(r) ? numberWithMatchingType(l, r) : r ); } const neg = (val) => op1("-", val); const reciprocal = (val) => op2("/", 1, val); function madd(a, b, c) { return add(mul(a, b), c); } function addm(a, b, c) { return mul(add(a, b), c); } const not = (val) => op1("!", val); const or = (a, b) => op2("||", a, b); const and = (a, b) => op2("&&", a, b); const __cmp = (op) => (a, b) => op2(op, a, b, "bool"); const eq = __cmp("=="); const neq = __cmp("!="); const lt = __cmp("<"); const lte = __cmp("<="); const gt = __cmp(">"); const gte = __cmp(">="); const bitnot = (val) => op1("~", val); function bitand(l, r) { return op2("&", l, r, void 0); } function bitor(l, r) { return op2("|", l, r, void 0); } function bitxor(l, r) { return op2("^", l, r, void 0); } function lshift(l, r) { return op2("<<", l, r, void 0); } function rshift(l, r) { return op2(">>", l, r, void 0); } export { add, addSelf, addm, and, bitand, bitnot, bitor, bitxor, dec, div, divSelf, eq, gt, gte, inc, lshift, lt, lte, madd, modi, mul, mulSelf, neg, neq, not, op1, op2, or, reciprocal, rshift, sub, subSelf };