@thi.ng/pointfree 3.1.54 → 3.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/loop.js CHANGED
@@ -1,86 +1,37 @@
1
1
  import { $ } from "./safe.js";
2
2
  import { $stackFn } from "./word.js";
3
- //////////////////// Loop constructs ////////////////////
4
- /**
5
- * Higher order word. Takes a `test` and `body` stack program. Applies
6
- * test to copy of TOS and executes body. Repeats while test is truthy.
7
- *
8
- * ( -- ? )
9
- *
10
- * @example
11
- * ```ts
12
- * run([loop([dup, ispos], [dup, print, dec])], [[3]])
13
- * // 3
14
- * // 2
15
- * // 1
16
- * // [ true, [ 0 ], undefined ]
17
- * ```
18
- * @param test -
19
- * @param body -
20
- */
21
- export const defLoop = (test, body) => {
22
- const _test = $stackFn(test);
23
- const _body = $stackFn(body);
24
- return (ctx) => {
25
- while (true) {
26
- ctx = _test(ctx);
27
- $(ctx[0], 1);
28
- if (!ctx[0].pop()) {
29
- return ctx;
30
- }
31
- ctx = _body(ctx);
32
- }
33
- };
3
+ const defLoop = (test, body) => {
4
+ const _test = $stackFn(test);
5
+ const _body = $stackFn(body);
6
+ return (ctx) => {
7
+ while (true) {
8
+ ctx = _test(ctx);
9
+ $(ctx[0], 1);
10
+ if (!ctx[0].pop()) {
11
+ return ctx;
12
+ }
13
+ ctx = _body(ctx);
14
+ }
15
+ };
34
16
  };
35
- /**
36
- * Non-HOF version of {@link loop}. Expects test result and body quotation /
37
- * word on d-stack.
38
- *
39
- * ( testq bodyq -- ? )
40
- *
41
- * @param ctx -
42
- */
43
- export const loopq = (ctx) => {
44
- const stack = ctx[0];
45
- $(stack, 2);
46
- const body = stack.pop();
47
- return defLoop(stack.pop(), body)(ctx);
17
+ const loopq = (ctx) => {
18
+ const stack = ctx[0];
19
+ $(stack, 2);
20
+ const body = stack.pop();
21
+ return defLoop(stack.pop(), body)(ctx);
48
22
  };
49
- /**
50
- * Executes given `body` word/quotation `n` times. In each iteration
51
- * pushes current counter on d-stack prior to executing body.
52
- *
53
- * @example
54
- * ```ts
55
- * pf.run([3, ["i=", pf.swap, pf.add, pf.print], pf.dotimes])
56
- * // i=0
57
- * // i=1
58
- * // i=2
59
- * ```
60
- *
61
- * With empty body acts as finite range generator 0 .. n:
62
- *
63
- * ```
64
- * // range gen
65
- * pf.run([3, [], pf.dotimes])
66
- * [ [ 0, 1, 2 ], [], {} ]
67
- *
68
- * // range gen (collect results as array)
69
- * pf.runU([3, pf.cpdr, [], pf.dotimes, pf.movrd, pf.collect])
70
- * // [ 0, 1, 2 ]
71
- * ```
72
- *
73
- * ( n body -- ? )
74
- *
75
- * @param body -
76
- */
77
- export const dotimes = (ctx) => {
78
- let stack = ctx[0];
79
- $(stack, 2);
80
- const w = $stackFn(stack.pop());
81
- for (let i = 0, n = stack.pop(); i < n; i++) {
82
- ctx[0].push(i);
83
- ctx = w(ctx);
84
- }
85
- return ctx;
23
+ const dotimes = (ctx) => {
24
+ let stack = ctx[0];
25
+ $(stack, 2);
26
+ const w = $stackFn(stack.pop());
27
+ for (let i = 0, n = stack.pop(); i < n; i++) {
28
+ ctx[0].push(i);
29
+ ctx = w(ctx);
30
+ }
31
+ return ctx;
32
+ };
33
+ export {
34
+ defLoop,
35
+ dotimes,
36
+ loopq
86
37
  };
package/math.js CHANGED
@@ -1,148 +1,53 @@
1
1
  import { defOp1, defOp2 } from "./ops.js";
2
2
  import { swap } from "./stack.js";
3
3
  import { defWord } from "./word.js";
4
- //////////////////// Math ops ////////////////////
5
- /**
6
- * ( x y -- x+y )
7
- *
8
- * @param ctx -
9
- */
10
- export const add = defOp2((b, a) => a + b);
11
- /**
12
- * ( x y -- x*y )
13
- *
14
- * @param ctx -
15
- */
16
- export const mul = defOp2((b, a) => a * b);
17
- /**
18
- * ( x y -- x-y )
19
- *
20
- * @param ctx -
21
- */
22
- export const sub = defOp2((b, a) => a - b);
23
- /**
24
- * ( x y -- x/y )
25
- *
26
- * @param ctx -
27
- */
28
- export const div = defOp2((b, a) => a / b);
29
- /**
30
- * ( x -- 1/x )
31
- *
32
- * @param ctx -
33
- */
34
- export const oneover = defWord([1, swap, div]);
35
- /**
36
- * ( x y -- x%y )
37
- *
38
- * @param ctx -
39
- */
40
- export const mod = defOp2((b, a) => a % b);
41
- /**
42
- * ( x y -- min(x,y) )
43
- *
44
- * @param ctx -
45
- */
46
- export const min = defOp2(Math.min);
47
- /**
48
- * ( x y -- max(x,y) )
49
- *
50
- * @param ctx -
51
- */
52
- export const max = defOp2(Math.max);
53
- /**
54
- * ( x -- -x )
55
- *
56
- * @param ctx -
57
- */
58
- export const neg = defOp1((x) => -x);
59
- /**
60
- * ( x y -- pow(x,y) )
61
- *
62
- * @param ctx -
63
- */
64
- export const pow = defOp2((b, a) => Math.pow(a, b));
65
- /**
66
- * ( x -- sqrt(x) )
67
- *
68
- * @param ctx -
69
- */
70
- export const sqrt = defOp1(Math.sqrt);
71
- /**
72
- * ( x -- exp(x) )
73
- *
74
- * @param ctx -
75
- */
76
- export const exp = defOp1(Math.exp);
77
- /**
78
- * ( x -- log(x) )
79
- *
80
- * @param ctx -
81
- */
82
- export const log = defOp1(Math.log);
83
- /**
84
- * ( x -- sin(x) )
85
- *
86
- * @param ctx -
87
- */
88
- export const sin = defOp1(Math.sin);
89
- /**
90
- * ( x -- cos(x) )
91
- *
92
- * @param ctx -
93
- */
94
- export const cos = defOp1(Math.cos);
95
- /**
96
- * ( x -- tan(x) )
97
- *
98
- * @param ctx -
99
- */
100
- export const tan = defOp1(Math.tan);
101
- /**
102
- * ( x -- tanh(x) )
103
- *
104
- * @param ctx -
105
- */
106
- export const tanh = defOp1(Math.tanh);
107
- /**
108
- * ( x -- floor(x) )
109
- *
110
- * @param ctx -
111
- */
112
- export const floor = defOp1(Math.floor);
113
- /**
114
- * ( x -- ceil(x) )
115
- *
116
- * @param ctx -
117
- */
118
- export const ceil = defOp1(Math.ceil);
119
- /**
120
- * ( x y -- sqrt(x*x+y*y) )
121
- *
122
- * @param ctx -
123
- */
124
- export const hypot = defOp2(Math.hypot);
125
- /**
126
- * ( x y -- atan2(y,x) )
127
- *
128
- * @param ctx -
129
- */
130
- export const atan2 = defOp2(Math.atan2);
131
- /**
132
- * ( -- Math.random() )
133
- *
134
- * @param ctx -
135
- */
136
- export const rand = (ctx) => (ctx[0].push(Math.random()), ctx);
137
- /**
138
- * ( x -- bool )
139
- *
140
- * @param ctx -
141
- */
142
- export const even = defOp1((x) => !(x & 1));
143
- /**
144
- * ( x -- bool )
145
- *
146
- * @param ctx -
147
- */
148
- export const odd = defOp1((x) => !!(x & 1));
4
+ const add = defOp2((b, a) => a + b);
5
+ const mul = defOp2((b, a) => a * b);
6
+ const sub = defOp2((b, a) => a - b);
7
+ const div = defOp2((b, a) => a / b);
8
+ const oneover = defWord([1, swap, div]);
9
+ const mod = defOp2((b, a) => a % b);
10
+ const min = defOp2(Math.min);
11
+ const max = defOp2(Math.max);
12
+ const neg = defOp1((x) => -x);
13
+ const pow = defOp2((b, a) => Math.pow(a, b));
14
+ const sqrt = defOp1(Math.sqrt);
15
+ const exp = defOp1(Math.exp);
16
+ const log = defOp1(Math.log);
17
+ const sin = defOp1(Math.sin);
18
+ const cos = defOp1(Math.cos);
19
+ const tan = defOp1(Math.tan);
20
+ const tanh = defOp1(Math.tanh);
21
+ const floor = defOp1(Math.floor);
22
+ const ceil = defOp1(Math.ceil);
23
+ const hypot = defOp2(Math.hypot);
24
+ const atan2 = defOp2(Math.atan2);
25
+ const rand = (ctx) => (ctx[0].push(Math.random()), ctx);
26
+ const even = defOp1((x) => !(x & 1));
27
+ const odd = defOp1((x) => !!(x & 1));
28
+ export {
29
+ add,
30
+ atan2,
31
+ ceil,
32
+ cos,
33
+ div,
34
+ even,
35
+ exp,
36
+ floor,
37
+ hypot,
38
+ log,
39
+ max,
40
+ min,
41
+ mod,
42
+ mul,
43
+ neg,
44
+ odd,
45
+ oneover,
46
+ pow,
47
+ rand,
48
+ sin,
49
+ sqrt,
50
+ sub,
51
+ tan,
52
+ tanh
53
+ };
package/ops.js CHANGED
@@ -1,85 +1,56 @@
1
1
  import { isArray } from "@thi.ng/checks/is-array";
2
2
  import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
3
3
  import { $, $n } from "./safe.js";
4
- //////////////////// Operator generators ////////////////////
5
- /**
6
- * Higher order word. Replaces TOS of d-stack with result of given op.
7
- *
8
- * ( x -- y )
9
- *
10
- * @param op -
11
- */
12
- export const defOp1 = (op) => {
13
- return (ctx) => {
14
- const stack = ctx[0];
15
- const n = stack.length - 1;
16
- $n(n, 0);
17
- stack[n] = op(stack[n]);
18
- return ctx;
19
- };
20
- };
21
- /**
22
- * Higher order word. Takes 2 values from d-stack and writes back result
23
- * from given op. The arg order is (TOS, TOS-1)
24
- *
25
- * ( a b -- c )
26
- *
27
- * @param op -
28
- */
29
- export const defOp2 = (op) => (ctx) => {
4
+ const defOp1 = (op) => {
5
+ return (ctx) => {
30
6
  const stack = ctx[0];
31
- const n = stack.length - 2;
7
+ const n = stack.length - 1;
32
8
  $n(n, 0);
33
- stack[n] = op(stack.pop(), stack[n]);
9
+ stack[n] = op(stack[n]);
34
10
  return ctx;
11
+ };
35
12
  };
36
- /**
37
- * Similar to {@link map2}, but for array operators. Either `a` or `b` can be a
38
- * non-array value, but not both. Creates new array of result values.
39
- * The result will have the same length as the shortest arg (if `a` and
40
- * `b` have different lengths).
41
- *
42
- * - ( a b -- a ), if `a` is an array
43
- * - ( a b -- b ), if `a` is not an array
44
- *
45
- * @param f -
46
- */
47
- export const defOp2v = (f) => (ctx) => {
48
- $(ctx[0], 2);
49
- const stack = ctx[0];
50
- const b = stack.pop();
51
- const n = stack.length - 1;
52
- const a = stack[n];
53
- const isa = isArray(a);
54
- const isb = isArray(b);
55
- stack[n] =
56
- isa && isb
57
- ? op2vAB(f, a, b)
58
- : isb && !isa
59
- ? op2vB(f, a, b)
60
- : isa && !isb
61
- ? op2vA(f, a, b)
62
- : illegalArgs("at least one arg must be an array");
63
- return ctx;
13
+ const defOp2 = (op) => (ctx) => {
14
+ const stack = ctx[0];
15
+ const n = stack.length - 2;
16
+ $n(n, 0);
17
+ stack[n] = op(stack.pop(), stack[n]);
18
+ return ctx;
19
+ };
20
+ const defOp2v = (f) => (ctx) => {
21
+ $(ctx[0], 2);
22
+ const stack = ctx[0];
23
+ const b = stack.pop();
24
+ const n = stack.length - 1;
25
+ const a = stack[n];
26
+ const isa = isArray(a);
27
+ const isb = isArray(b);
28
+ 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");
29
+ return ctx;
64
30
  };
65
31
  const op2vAB = (f, a, b) => {
66
- const res = new Array(Math.min(a.length, b.length));
67
- for (let i = res.length - 1; i >= 0; i--) {
68
- res[i] = f(b[i], a[i]);
69
- }
70
- return res;
32
+ const res = new Array(Math.min(a.length, b.length));
33
+ for (let i = res.length - 1; i >= 0; i--) {
34
+ res[i] = f(b[i], a[i]);
35
+ }
36
+ return res;
71
37
  };
72
38
  const op2vA = (f, a, b) => {
73
- const res = new Array(a.length);
74
- for (let i = res.length - 1; i >= 0; i--) {
75
- res[i] = f(b, a[i]);
76
- }
77
- return res;
39
+ const res = new Array(a.length);
40
+ for (let i = res.length - 1; i >= 0; i--) {
41
+ res[i] = f(b, a[i]);
42
+ }
43
+ return res;
78
44
  };
79
45
  const op2vB = (f, a, b) => {
80
- const res = new Array(b.length);
81
- for (let i = res.length - 1; i >= 0; i--) {
82
- res[i] = f(b[i], a);
83
- }
84
- return res;
46
+ const res = new Array(b.length);
47
+ for (let i = res.length - 1; i >= 0; i--) {
48
+ res[i] = f(b[i], a);
49
+ }
50
+ return res;
51
+ };
52
+ export {
53
+ defOp1,
54
+ defOp2,
55
+ defOp2v
85
56
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/pointfree",
3
- "version": "3.1.54",
3
+ "version": "3.1.55",
4
4
  "description": "Pointfree functional composition / Forth style stack execution engine",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -24,7 +24,9 @@
24
24
  "author": "Karsten Schmidt (https://thi.ng)",
25
25
  "license": "Apache-2.0",
26
26
  "scripts": {
27
- "build": "yarn clean && tsc --declaration",
27
+ "build": "yarn build:esbuild && yarn build:decl",
28
+ "build:decl": "tsc --declaration --emitDeclarationOnly",
29
+ "build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
28
30
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
29
31
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
30
32
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
@@ -33,14 +35,15 @@
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@thi.ng/api": "^8.9.11",
37
- "@thi.ng/checks": "^3.4.11",
38
- "@thi.ng/compose": "^2.1.50",
39
- "@thi.ng/equiv": "^2.1.36",
40
- "@thi.ng/errors": "^2.4.5"
38
+ "@thi.ng/api": "^8.9.12",
39
+ "@thi.ng/checks": "^3.4.12",
40
+ "@thi.ng/compose": "^2.1.51",
41
+ "@thi.ng/equiv": "^2.1.37",
42
+ "@thi.ng/errors": "^2.4.6"
41
43
  },
42
44
  "devDependencies": {
43
45
  "@microsoft/api-extractor": "^7.38.3",
46
+ "esbuild": "^0.19.8",
44
47
  "rimraf": "^5.0.5",
45
48
  "tools": "^0.0.1",
46
49
  "typedoc": "^0.25.4",
@@ -130,5 +133,5 @@
130
133
  "thi.ng": {
131
134
  "year": 2015
132
135
  },
133
- "gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n"
136
+ "gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
134
137
  }
package/run.js CHANGED
@@ -1,42 +1,23 @@
1
1
  import { isArray } from "@thi.ng/checks/is-array";
2
2
  import { isFunction } from "@thi.ng/checks/is-function";
3
3
  import { unwrap } from "./word.js";
4
- /**
5
- * Executes program / quotation with given stack context (initial D/R
6
- * stacks and optional environment). Returns updated context.
7
- *
8
- * @param prog -
9
- * @param ctx -
10
- */
11
- export const run = (prog, ctx = [[], [], {}]) => {
12
- if (isFunction(prog)) {
13
- return prog(ctx);
4
+ const run = (prog, ctx = [[], [], {}]) => {
5
+ if (isFunction(prog)) {
6
+ return prog(ctx);
7
+ }
8
+ for (let p = isArray(prog) ? prog : [prog], n = p.length, i = 0, w; i < n; i++) {
9
+ if (isFunction(w = p[i])) {
10
+ ctx = w(ctx);
11
+ } else {
12
+ ctx[0].push(w);
14
13
  }
15
- for (let p = isArray(prog) ? prog : [prog], n = p.length, i = 0, w; i < n; i++) {
16
- if (isFunction((w = p[i]))) {
17
- ctx = w(ctx);
18
- }
19
- else {
20
- ctx[0].push(w);
21
- }
22
- }
23
- return ctx;
14
+ }
15
+ return ctx;
16
+ };
17
+ const runU = (prog, ctx, n = 1) => unwrap(run(prog, ctx), n);
18
+ const runE = (prog, ctx) => run(prog, ctx)[2];
19
+ export {
20
+ run,
21
+ runE,
22
+ runU
24
23
  };
25
- /**
26
- * Like {@link run}, but returns unwrapped result. Syntax sugar for:
27
- * `unwrap(run(...),n)`
28
- *
29
- * @param prog -
30
- * @param ctx -
31
- * @param n -
32
- */
33
- export const runU = (prog, ctx, n = 1) => unwrap(run(prog, ctx), n);
34
- /**
35
- * Like {@link run}, but returns result environment. Syntax sugar for:
36
- * `run(...)[2]`
37
- *
38
- * @param prog -
39
- * @param ctx -
40
- * @param n -
41
- */
42
- export const runE = (prog, ctx) => run(prog, ctx)[2];
package/safe.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import { NO_OP } from "@thi.ng/api/api";
2
2
  import { illegalState } from "@thi.ng/errors/illegal-state";
3
- // ensure stack size
4
- export let $;
5
- export let $n;
6
- export const safeMode = (state) => {
7
- if (state) {
8
- $n = (m, n) => m < n && illegalState(`stack underflow`);
9
- $ = (stack, n) => $n(stack.length, n);
10
- }
11
- else {
12
- $ = $n = NO_OP;
13
- }
3
+ let $;
4
+ let $n;
5
+ const safeMode = (state) => {
6
+ if (state) {
7
+ $n = (m, n) => m < n && illegalState(`stack underflow`);
8
+ $ = (stack, n) => $n(stack.length, n);
9
+ } else {
10
+ $ = $n = NO_OP;
11
+ }
14
12
  };
15
13
  safeMode(true);
14
+ export {
15
+ $,
16
+ $n,
17
+ safeMode
18
+ };