@thi.ng/pointfree
Version:
Pointfree functional composition / Forth style stack execution engine
57 lines (56 loc) • 1.4 kB
JavaScript
import { isArray } from "@thi.ng/checks/is-array";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import { $, $n } from "./safe.js";
const defOp1 = (op) => {
return (ctx) => {
const stack = ctx[0];
const n = stack.length - 1;
$n(n, 0);
stack[n] = op(stack[n]);
return ctx;
};
};
const defOp2 = (op) => (ctx) => {
const stack = ctx[0];
const n = stack.length - 2;
$n(n, 0);
stack[n] = op(stack.pop(), stack[n]);
return ctx;
};
const defOp2v = (f) => (ctx) => {
$(ctx[0], 2);
const stack = ctx[0];
const b = stack.pop();
const n = stack.length - 1;
const a = stack[n];
const isa = isArray(a);
const isb = isArray(b);
stack[n] = isa && isb ? __op2vAB(f, a, b) : isb && !isa ? __op2vB(f, a, b) : isa && !isb ? __op2vA(f, a, b) : illegalArgs("at least one arg must be an array");
return ctx;
};
const __op2vAB = (f, a, b) => {
const res = new Array(Math.min(a.length, b.length));
for (let i = res.length - 1; i >= 0; i--) {
res[i] = f(b[i], a[i]);
}
return res;
};
const __op2vA = (f, a, b) => {
const res = new Array(a.length);
for (let i = res.length - 1; i >= 0; i--) {
res[i] = f(b, a[i]);
}
return res;
};
const __op2vB = (f, a, b) => {
const res = new Array(b.length);
for (let i = res.length - 1; i >= 0; i--) {
res[i] = f(b[i], a);
}
return res;
};
export {
defOp1,
defOp2,
defOp2v
};