@thi.ng/pointfree
Version:
Pointfree functional composition / Forth style stack execution engine
189 lines (188 loc) • 4 kB
JavaScript
import { $, $n } from "./safe.js";
const __xsp = (id) => (ctx) => (ctx[0].push(ctx[id].length), ctx);
const __dup = (id) => __copy(id, id);
const __dup2 = (id) => (ctx) => {
const stack = ctx[id];
let n = stack.length - 2;
$n(n, 0);
stack.push(stack[n], stack[n + 1]);
return ctx;
};
const __dup3 = (id) => (ctx) => {
const stack = ctx[id];
let n = stack.length - 3;
$n(n, 0);
stack.push(stack[n], stack[n + 1], stack[n + 2]);
return ctx;
};
const __drop = (id, n = 1) => (ctx) => ($(ctx[id], 1), ctx[id].length -= n, ctx);
const __swap = (i) => (ctx) => {
const stack = ctx[i];
const n = stack.length - 2;
$n(n, 0);
const a = stack[n];
stack[n] = stack[n + 1];
stack[n + 1] = a;
return ctx;
};
const __swap2 = (i) => (ctx) => {
const stack = ctx[i];
let n = stack.length - 1;
$n(n, 3);
let a = stack[n];
stack[n] = stack[n - 2];
stack[n - 2] = a;
n--;
a = stack[n];
stack[n] = stack[n - 2];
stack[n - 2] = a;
return ctx;
};
const __over = (id) => (ctx) => {
const stack = ctx[id];
const n = stack.length - 2;
$n(n, 0);
stack.push(stack[n]);
return ctx;
};
const __move = (src, dest) => (ctx) => ($(ctx[src], 1), ctx[dest].push(ctx[src].pop()), ctx);
const __move2 = (a, b) => (ctx) => {
const src = ctx[a];
$(src, 2);
const v = src.pop();
ctx[b].push(src.pop(), v);
return ctx;
};
const __copy = (src, dest) => (ctx) => ($(ctx[src], 1), ctx[dest].push(tos(ctx[src])), ctx);
const __copy2 = (a, b) => (ctx) => {
const src = ctx[a];
const n = src.length - 2;
$n(n, 0);
ctx[b].push(src[n], src[n + 1]);
return ctx;
};
const __incdec = (id, n) => (ctx) => ($(ctx[id], 1), ctx[id][ctx[id].length - 1] += n, ctx);
const tos = (stack) => stack[stack.length - 1];
const nop = (ctx) => ctx;
const dsp = __xsp(0);
const pick = (ctx) => {
const stack = ctx[0];
let n = stack.length - 1;
$n(n, 0);
$n(n -= stack.pop() + 1, 0);
stack.push(stack[n]);
return ctx;
};
const drop = __drop(0);
const drop2 = __drop(0, 2);
const dropif = (ctx) => ($(ctx[0], 1), tos(ctx[0]) && ctx[0].length--, ctx);
const defPush = (...args) => (ctx) => (ctx[0].push(...args), ctx);
const dup = __dup(0);
const dup2 = __dup2(0);
const dup3 = __dup3(0);
const dupif = (ctx) => {
$(ctx[0], 1);
const x = tos(ctx[0]);
x && ctx[0].push(x);
return ctx;
};
const swap = __swap(0);
const swap2 = __swap2(0);
const nip = (ctx) => {
const stack = ctx[0];
const n = stack.length - 2;
$n(n, 0);
stack[n] = stack.pop();
return ctx;
};
const tuck = (ctx) => {
$(ctx[0], 2);
const stack = ctx[0];
const a = stack.pop();
stack.push(a, stack.pop(), a);
return ctx;
};
const rot = (ctx) => {
const stack = ctx[0];
const n = stack.length - 1;
$n(n, 2);
const c = stack[n - 2];
stack[n - 2] = stack[n - 1];
stack[n - 1] = stack[n];
stack[n] = c;
return ctx;
};
const invrot = (ctx) => {
const stack = ctx[0];
const n = stack.length - 1;
$n(n, 2);
const c = stack[n];
stack[n] = stack[n - 1];
stack[n - 1] = stack[n - 2];
stack[n - 2] = c;
return ctx;
};
const over = __over(0);
const inc = __incdec(0, 1);
const dec = __incdec(0, -1);
const rsp = __xsp(1);
const rdup = __dup(1);
const rdup2 = __dup2(1);
const rdup3 = __dup3(1);
const rdrop = __drop(1);
const rdrop2 = __drop(1, 2);
const movdr = __move(0, 1);
const movrd = __move(1, 0);
const cpdr = __copy(0, 1);
const cprd = __copy(1, 0);
const movdr2 = __move2(0, 1);
const movrd2 = __move2(1, 0);
const cpdr2 = __copy2(0, 1);
const cprd2 = __copy2(1, 0);
const rswap = __swap(1);
const rswap2 = __swap2(1);
const rover = __over(1);
const rinc = __incdec(1, 1);
const rdec = __incdec(1, -1);
export {
cpdr,
cpdr2,
cprd,
cprd2,
dec,
defPush,
drop,
drop2,
dropif,
dsp,
dup,
dup2,
dup3,
dupif,
inc,
invrot,
movdr,
movdr2,
movrd,
movrd2,
nip,
nop,
over,
pick,
rdec,
rdrop,
rdrop2,
rdup,
rdup2,
rdup3,
rinc,
rot,
rover,
rsp,
rswap,
rswap2,
swap,
swap2,
tos,
tuck
};