Skip to content

Commit

Permalink
refactor(shader-ast): sideeffect-free defmulti specs
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Sep 28, 2021
1 parent 9909909 commit 1282973
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 65 deletions.
117 changes: 60 additions & 57 deletions packages/shader-ast/src/optimize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Fn, IObjectOf } from "@thi.ng/api";
import { defmulti } from "@thi.ng/defmulti/defmulti";
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
import { LogLevel } from "@thi.ng/logger/api";
import { deg, rad } from "@thi.ng/math/angle";
import { clamp } from "@thi.ng/math/interval";
Expand Down Expand Up @@ -90,71 +90,74 @@ const BUILTINS: IObjectOf<Fn<number[], number>> = {
};

/** @internal */
export const foldNode = defmulti<Term<any>, boolean | undefined>((t) => t.tag);
foldNode.setDefault(() => false);
export const foldNode = defmulti<Term<any>, boolean | undefined>(
(t) => t.tag,
{},
{
[DEFAULT]: () => false,

foldNode.addAll({
op1: (node) => {
const $node = <Op1<any>>node;
if ($node.op == "-" && isLitNumericConst($node.val)) {
(<Lit<"float">>$node.val).val *= -1;
return replaceNode(node, <Lit<"float">>$node.val);
}
},

op2: (node) => {
const $node = <Op2<any>>node;
if (isLitNumericConst($node.l) && isLitNumericConst($node.r)) {
const l: number = $node.l.val;
const r: number = $node.r.val;
let res = maybeFoldMath($node.op, l, r);
if (res !== undefined) {
return replaceNumericNode(node, res);
op1: (node) => {
const $node = <Op1<any>>node;
if ($node.op == "-" && isLitNumericConst($node.val)) {
(<Lit<"float">>$node.val).val *= -1;
return replaceNode(node, <Lit<"float">>$node.val);
}
}
},
},

call_i: (node) => {
const $node = <FnCall<any>>node;
if ($node.args.every((x) => isLitNumericConst(x))) {
const op = BUILTINS[$node.id];
if (op !== undefined) {
return replaceNumericNode(
node,
op($node.args.map((x) => (<Lit<any>>x).val))
);
op2: (node) => {
const $node = <Op2<any>>node;
if (isLitNumericConst($node.l) && isLitNumericConst($node.r)) {
const l: number = $node.l.val;
const r: number = $node.r.val;
let res = maybeFoldMath($node.op, l, r);
if (res !== undefined) {
return replaceNumericNode(node, res);
}
}
}
},
},

lit: (node) => {
const $node = <Lit<any>>node;
if (isLitNumericConst($node.val)) {
if (isFloat($node.val)) {
return replaceNode(node, float($node.val.val));
}
if (isInt($node.val)) {
return replaceNode(node, int($node.val.val));
call_i: (node) => {
const $node = <FnCall<any>>node;
if ($node.args.every((x) => isLitNumericConst(x))) {
const op = BUILTINS[$node.id];
if (op !== undefined) {
return replaceNumericNode(
node,
op($node.args.map((x) => (<Lit<any>>x).val))
);
}
}
if (isUint($node.val)) {
return replaceNode(node, uint($node.val.val));
},

lit: (node) => {
const $node = <Lit<any>>node;
if (isLitNumericConst($node.val)) {
if (isFloat($node.val)) {
return replaceNode(node, float($node.val.val));
}
if (isInt($node.val)) {
return replaceNode(node, int($node.val.val));
}
if (isUint($node.val)) {
return replaceNode(node, uint($node.val.val));
}
}
}
},
},

swizzle: (node) => {
const $node = <Swizzle<any>>node;
const val = $node.val;
if (isLitVecConst(val)) {
if (isFloat(node)) {
return replaceNode(
node,
float(val.val[COMPS[<Swizzle4_1>$node.id]])
);
swizzle: (node) => {
const $node = <Swizzle<any>>node;
const val = $node.val;
if (isLitVecConst(val)) {
if (isFloat(node)) {
return replaceNode(
node,
float(val.val[COMPS[<Swizzle4_1>$node.id]])
);
}
}
}
},
});
},
}
);

/**
* Traverses given AST (potentially several times) and applies constant folding
Expand Down
18 changes: 10 additions & 8 deletions packages/shader-ast/src/target.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Fn } from "@thi.ng/api";
import { defmulti } from "@thi.ng/defmulti/defmulti";
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
import { unsupported } from "@thi.ng/errors/unsupported";
import type { Term } from "./api/nodes";
import type { TargetImpl } from "./api/target";
Expand All @@ -13,11 +13,13 @@ import type { TargetImpl } from "./api/target";
*
* @param impls -
*/
export const defTarget = <T>(impls: TargetImpl<T>): Fn<Term<any>, T> => {
const emit = defmulti<Term<any>, T>((x) => x.tag);
emit.setDefault((t) =>
unsupported(`no impl for AST node type: '${t.tag}'`)
export const defTarget = <T>(impls: TargetImpl<T>): Fn<Term<any>, T> =>
defmulti<Term<any>, T>(
(x) => x.tag,
{},
{
[DEFAULT]: (t: Term<any>) =>
unsupported(`no impl for AST node type: '${t.tag}'`),
...(<any>impls),
}
);
emit.addAll(<any>impls);
return emit;
};

0 comments on commit 1282973

Please sign in to comment.