UNPKG

@thi.ng/pointfree

Version:

Pointfree functional composition / Forth style stack execution engine

189 lines (188 loc) 4 kB
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 };