functionalscript 0.11.7 → 0.11.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test": "tsc && node --test --experimental-strip-types --experimental-test-coverage --test-coverage-include=**/module.f.ts",
|
|
14
14
|
"index": "node ./fjs/module.ts r ./dev/index/module.f.ts",
|
|
15
15
|
"fst": "node ./fjs/module.ts t",
|
|
16
|
-
"
|
|
16
|
+
"start": "node ./fjs/module.ts",
|
|
17
17
|
"ci-update": "node ./fjs/module.ts r ./ci/module.f.ts",
|
|
18
18
|
"update": "git clean -fdx && npm install && npm run index && npm run ci-update",
|
|
19
19
|
"website": "node --experimental-strip-types ./fjs/module.ts r ./website/module.f.ts"
|
package/types/asn.1/module.f.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { bitLength, max } from "../bigint/module.f.js";
|
|
2
|
-
import { empty, isVec, length, listToVec, msb,
|
|
2
|
+
import { empty, isVec, length, listToVec, msb, uint, unpack, vec, vec8 } from "../bit_vec/module.f.js";
|
|
3
3
|
import { identity } from "../function/module.f.js";
|
|
4
4
|
import { encode as b128encode, decode as b128decode } from "../base128/module.f.js";
|
|
5
5
|
const pop = msb.popFront;
|
|
@@ -163,7 +163,7 @@ export const decodeSequence = (v) => {
|
|
|
163
163
|
return result;
|
|
164
164
|
};
|
|
165
165
|
/** Encodes a SET payload with canonical byte ordering. */
|
|
166
|
-
export const encodeSet = genericEncodeSequence(v => v.toSorted((a, b) =>
|
|
166
|
+
export const encodeSet = genericEncodeSequence(v => v.toSorted((a, b) => msb.cmp(a)(b)));
|
|
167
167
|
/** Decodes a SET payload. */
|
|
168
168
|
export const decodeSet = decodeSequence;
|
|
169
169
|
// encode
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Fold, Reduce as OpReduce } from '../function/operator/module.f.ts';
|
|
1
|
+
import type { Binary, Fold, Reduce as OpReduce } from '../function/operator/module.f.ts';
|
|
2
2
|
import { type List, type Thunk } from '../list/module.f.ts';
|
|
3
3
|
import { type Nominal } from '../nominal/module.f.ts';
|
|
4
4
|
import { type Sign } from '../function/compare/module.f.ts';
|
|
@@ -56,7 +56,13 @@ export declare const unpack: (v: Vec) => Unpacked;
|
|
|
56
56
|
* Packs an unpacked representation back into a vector.
|
|
57
57
|
*/
|
|
58
58
|
export declare const pack: ({ length, uint }: Unpacked) => Vec;
|
|
59
|
+
type Norm = (len: bigint) => {
|
|
60
|
+
readonly a: bigint;
|
|
61
|
+
readonly b: bigint;
|
|
62
|
+
};
|
|
63
|
+
type NormOp = Binary<Unpacked, Unpacked, Norm>;
|
|
59
64
|
export type Reduce = OpReduce<Vec>;
|
|
65
|
+
export type PopFront<T> = (len: bigint) => (u: T) => readonly [bigint, T];
|
|
60
66
|
/**
|
|
61
67
|
* Represents operations for handling bit vectors with a specific bit order.
|
|
62
68
|
*
|
|
@@ -121,7 +127,7 @@ export type BitOrder = {
|
|
|
121
127
|
* const [uM1, rM1] = msb.popFront(16n)(vector) // [0xF500n, rM1 === empty]
|
|
122
128
|
* ```
|
|
123
129
|
*/
|
|
124
|
-
readonly popFront:
|
|
130
|
+
readonly popFront: PopFront<Vec>;
|
|
125
131
|
/**
|
|
126
132
|
* Concatenates two vectors.
|
|
127
133
|
*
|
|
@@ -145,6 +151,17 @@ export type BitOrder = {
|
|
|
145
151
|
* @returns A function that takes a second vector and returns the XOR result.
|
|
146
152
|
*/
|
|
147
153
|
readonly xor: Reduce;
|
|
154
|
+
readonly unpackPopFront: PopFront<Unpacked>;
|
|
155
|
+
readonly norm: NormOp;
|
|
156
|
+
/**
|
|
157
|
+
* Lexically compares two vectors.
|
|
158
|
+
*
|
|
159
|
+
* a < b => -1
|
|
160
|
+
* a > b => 1
|
|
161
|
+
* a === b => 0
|
|
162
|
+
*/
|
|
163
|
+
readonly cmp: (a: Vec) => (b: Vec) => Sign;
|
|
164
|
+
readonly unpackSplit: (len: bigint) => (u: Unpacked) => readonly [bigint, bigint];
|
|
148
165
|
};
|
|
149
166
|
/**
|
|
150
167
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
@@ -177,7 +194,7 @@ export declare const u8ListToVec: ({ concat }: BitOrder) => (list: List<number>)
|
|
|
177
194
|
* @param v The vector to be converted.
|
|
178
195
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
179
196
|
*/
|
|
180
|
-
export declare const u8List: ({
|
|
197
|
+
export declare const u8List: ({ unpackSplit }: BitOrder) => (v: Vec) => Thunk<number>;
|
|
181
198
|
/**
|
|
182
199
|
* Concatenates a list of vectors using the provided bit order.
|
|
183
200
|
*/
|
|
@@ -187,13 +204,4 @@ export declare const listToVec: ({ concat }: BitOrder) => (list: List<Vec>) => V
|
|
|
187
204
|
*/
|
|
188
205
|
export declare const repeat: Fold<bigint, Vec>;
|
|
189
206
|
export declare const isVec: <T>(v: Vec | T) => v is Vec;
|
|
190
|
-
|
|
191
|
-
* Lexically compares two vectors based on their unsigned integer values,
|
|
192
|
-
* normalizing them to the same length. If the values are equal,
|
|
193
|
-
* the shorter vector is considered smaller.
|
|
194
|
-
*
|
|
195
|
-
* a < b => -1
|
|
196
|
-
* a > b => 1
|
|
197
|
-
* a === b => 0
|
|
198
|
-
*/
|
|
199
|
-
export declare const msbCmp: (av: Vec) => (bv: Vec) => Sign;
|
|
207
|
+
export {};
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { bitLength, mask, max, min, xor } from "../bigint/module.f.js";
|
|
25
25
|
import { flip } from "../function/module.f.js";
|
|
26
|
-
import {
|
|
26
|
+
import { fold, iterable } from "../list/module.f.js";
|
|
27
27
|
import { asBase, asNominal } from "../nominal/module.f.js";
|
|
28
28
|
import { repeat as mRepeat } from "../monoid/module.f.js";
|
|
29
29
|
import { cmp } from "../function/compare/module.f.js";
|
|
@@ -97,8 +97,6 @@ export const unpack = (v) => ({
|
|
|
97
97
|
* Packs an unpacked representation back into a vector.
|
|
98
98
|
*/
|
|
99
99
|
export const pack = ({ length, uint }) => vec(length)(uint);
|
|
100
|
-
const lsbNorm = ({ length: al, uint: a }) => ({ length: bl, uint: b }) => (len) => ({ a, b });
|
|
101
|
-
const msbNorm = ({ length: al, uint: a }) => ({ length: bl, uint: b }) => (len) => ({ a: a << (len - al), b: b << (len - bl) });
|
|
102
100
|
/**
|
|
103
101
|
* Normalizes two vectors to the same length before applying a bigint reducer.
|
|
104
102
|
*/
|
|
@@ -109,6 +107,41 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
109
107
|
const { a, b } = norm(au)(bu)(len);
|
|
110
108
|
return vec(len)(op(a)(b));
|
|
111
109
|
};
|
|
110
|
+
const bo = ({ front, removeFront, concat, norm, uintCmp, unpackSplit }) => {
|
|
111
|
+
const unpackPopFront = (len) => {
|
|
112
|
+
const m = mask(len);
|
|
113
|
+
const us = unpackSplit(len);
|
|
114
|
+
return (v) => {
|
|
115
|
+
const [uint, rest] = us(v);
|
|
116
|
+
return [uint & m, { length: v.length - len, uint: rest }];
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
front,
|
|
121
|
+
removeFront,
|
|
122
|
+
concat,
|
|
123
|
+
xor: op(norm)(xor),
|
|
124
|
+
unpackPopFront,
|
|
125
|
+
popFront: len => {
|
|
126
|
+
const f = unpackPopFront(len);
|
|
127
|
+
return v => {
|
|
128
|
+
const [uint, u] = f(unpack(v));
|
|
129
|
+
return [uint, pack(u)];
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
norm,
|
|
133
|
+
cmp: a => b => {
|
|
134
|
+
const au = unpack(a);
|
|
135
|
+
const bu = unpack(b);
|
|
136
|
+
const al = au.length;
|
|
137
|
+
const bl = bu.length;
|
|
138
|
+
const { a: aui, b: bui } = norm(au)(bu)(min(al)(bl));
|
|
139
|
+
const c = uintCmp(aui)(bui);
|
|
140
|
+
return c === 0 ? cmp(al)(bl) : c;
|
|
141
|
+
},
|
|
142
|
+
unpackSplit,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
112
145
|
/**
|
|
113
146
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
114
147
|
*
|
|
@@ -116,7 +149,7 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
116
149
|
*
|
|
117
150
|
* Usually associated with Little-Endian (LE) byte order.
|
|
118
151
|
*/
|
|
119
|
-
export const lsb = {
|
|
152
|
+
export const lsb = bo({
|
|
120
153
|
front: len => {
|
|
121
154
|
const m = mask(len);
|
|
122
155
|
return v => uint(v) & m;
|
|
@@ -125,20 +158,18 @@ export const lsb = {
|
|
|
125
158
|
const { length, uint } = unpack(v);
|
|
126
159
|
return vec(length - len)(uint >> len);
|
|
127
160
|
},
|
|
128
|
-
popFront: len => {
|
|
129
|
-
const m = mask(len);
|
|
130
|
-
return v => {
|
|
131
|
-
const { length, uint } = unpack(v);
|
|
132
|
-
return [uint & m, vec(length - len)(uint >> len)];
|
|
133
|
-
};
|
|
134
|
-
},
|
|
135
161
|
concat: (a) => (b) => {
|
|
136
162
|
const { length: al, uint: au } = unpack(a);
|
|
137
163
|
const { length: bl, uint: bu } = unpack(b);
|
|
138
164
|
return vec(al + bl)((bu << al) | au);
|
|
139
165
|
},
|
|
140
|
-
|
|
141
|
-
|
|
166
|
+
norm: ({ uint: a }) => ({ uint: b }) => () => ({ a, b }),
|
|
167
|
+
uintCmp: a => b => {
|
|
168
|
+
const diff = a ^ b;
|
|
169
|
+
return diff === 0n ? 0 : (a & (diff & -diff)) === 0n ? -1 : 1;
|
|
170
|
+
},
|
|
171
|
+
unpackSplit: len => ({ uint }) => [uint, uint >> len]
|
|
172
|
+
});
|
|
142
173
|
/**
|
|
143
174
|
* Implements operations for handling vectors in a most-significant-bit (MSb) first order.
|
|
144
175
|
*
|
|
@@ -146,7 +177,7 @@ export const lsb = {
|
|
|
146
177
|
*
|
|
147
178
|
* Usually associated with Big-Endian (BE) byte order.
|
|
148
179
|
*/
|
|
149
|
-
export const msb = {
|
|
180
|
+
export const msb = bo({
|
|
150
181
|
front: len => {
|
|
151
182
|
const m = mask(len);
|
|
152
183
|
return v => {
|
|
@@ -158,17 +189,11 @@ export const msb = {
|
|
|
158
189
|
const { length, uint } = unpack(v);
|
|
159
190
|
return vec(length - len)(uint);
|
|
160
191
|
},
|
|
161
|
-
popFront: len => {
|
|
162
|
-
const m = mask(len);
|
|
163
|
-
return v => {
|
|
164
|
-
const { length, uint } = unpack(v);
|
|
165
|
-
const d = length - len;
|
|
166
|
-
return [(uint >> d) & m, vec(d)(uint)];
|
|
167
|
-
};
|
|
168
|
-
},
|
|
169
192
|
concat: flip(lsb.concat),
|
|
170
|
-
|
|
171
|
-
|
|
193
|
+
norm: ({ length: al, uint: a }) => ({ length: bl, uint: b }) => len => ({ a: a << (len - al), b: b << (len - bl) }),
|
|
194
|
+
uintCmp: cmp,
|
|
195
|
+
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint]
|
|
196
|
+
});
|
|
172
197
|
/**
|
|
173
198
|
* Converts a list of unsigned 8-bit integers to a bit vector using the provided bit order.
|
|
174
199
|
*
|
|
@@ -211,15 +236,30 @@ export const u8ListToVec = ({ concat }) => (list) => {
|
|
|
211
236
|
* @param v The vector to be converted.
|
|
212
237
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
213
238
|
*/
|
|
214
|
-
export const u8List = ({
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
239
|
+
export const u8List = ({ unpackSplit }) => (v) => {
|
|
240
|
+
if (v === empty) {
|
|
241
|
+
return () => null;
|
|
242
|
+
}
|
|
243
|
+
const f = (stack) => () => {
|
|
244
|
+
while (true) {
|
|
245
|
+
const [first, rest] = stack;
|
|
246
|
+
const { length, uint } = first;
|
|
247
|
+
if (length <= 8n) {
|
|
248
|
+
// the last unpack split is required to align data.
|
|
249
|
+
const v = length < 8n ? unpackSplit(8n)(first)[0] : uint;
|
|
250
|
+
return { first: Number(v), tail: rest !== undefined ? f(rest) : null };
|
|
251
|
+
}
|
|
252
|
+
// `length` is bigger than `8n` so `newLen` is `8n` or bigger.
|
|
253
|
+
const aLength = ((length + 7n) >> 4n) << 3n;
|
|
254
|
+
const bLength = length - aLength;
|
|
255
|
+
const [a, b] = unpackSplit(aLength)(first);
|
|
256
|
+
stack = [
|
|
257
|
+
{ length: aLength, uint: a & mask(aLength) },
|
|
258
|
+
[{ length: bLength, uint: b & mask(bLength) }, rest],
|
|
259
|
+
];
|
|
218
260
|
}
|
|
219
|
-
const [first, tail] = popFront(8n)(v);
|
|
220
|
-
return { first: Number(first), tail: f(tail) };
|
|
221
261
|
};
|
|
222
|
-
return f;
|
|
262
|
+
return f([unpack(v), undefined]);
|
|
223
263
|
};
|
|
224
264
|
/**
|
|
225
265
|
* Concatenates a list of vectors using the provided bit order.
|
|
@@ -230,21 +270,3 @@ export const listToVec = ({ concat }) => fold(flip(concat))(empty);
|
|
|
230
270
|
*/
|
|
231
271
|
export const repeat = mRepeat({ identity: empty, operation: lsb.concat });
|
|
232
272
|
export const isVec = (v) => typeof v === 'bigint';
|
|
233
|
-
/**
|
|
234
|
-
* Lexically compares two vectors based on their unsigned integer values,
|
|
235
|
-
* normalizing them to the same length. If the values are equal,
|
|
236
|
-
* the shorter vector is considered smaller.
|
|
237
|
-
*
|
|
238
|
-
* a < b => -1
|
|
239
|
-
* a > b => 1
|
|
240
|
-
* a === b => 0
|
|
241
|
-
*/
|
|
242
|
-
export const msbCmp = (av) => (bv) => {
|
|
243
|
-
const au = unpack(av);
|
|
244
|
-
const bu = unpack(bv);
|
|
245
|
-
const al = au.length;
|
|
246
|
-
const bl = bu.length;
|
|
247
|
-
const { a, b } = msbNorm(au)(bu)(min(al)(bl));
|
|
248
|
-
const result = cmp(a)(b);
|
|
249
|
-
return result !== 0 ? result : cmp(al)(bl);
|
|
250
|
-
};
|
|
@@ -37,7 +37,9 @@ declare const _default: {
|
|
|
37
37
|
lsbXor: () => void;
|
|
38
38
|
msbXor: () => void;
|
|
39
39
|
repeat: () => void;
|
|
40
|
+
lsbCmp: () => void;
|
|
40
41
|
msbCmp: () => void;
|
|
41
|
-
u8ListToVec: () => void;
|
|
42
|
+
u8ListToVec: () => () => void;
|
|
43
|
+
u8ListUnaligned: () => void;
|
|
42
44
|
};
|
|
43
45
|
export default _default;
|
package/types/bit_vec/test.f.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mask } from "../bigint/module.f.js";
|
|
2
2
|
import { asBase, asNominal } from "../nominal/module.f.js";
|
|
3
|
-
import { length, empty, uint, vec, lsb, msb, repeat, vec8,
|
|
4
|
-
import { repeat as listRepeat } from "../list/module.f.js";
|
|
3
|
+
import { length, empty, uint, vec, lsb, msb, repeat, vec8, u8ListToVec, u8List } from "./module.f.js";
|
|
4
|
+
import { repeat as listRepeat, toArray } from "../list/module.f.js";
|
|
5
5
|
const unsafeVec = (a) => asNominal(a);
|
|
6
6
|
// 0x8 = 0b1000 = 0 + 8
|
|
7
7
|
// 0x9 = 0b1001 = 1 + 8
|
|
@@ -430,9 +430,23 @@ export default {
|
|
|
430
430
|
throw 'repeat failed';
|
|
431
431
|
}
|
|
432
432
|
},
|
|
433
|
+
lsbCmp: () => {
|
|
434
|
+
const c = (a) => (b) => (r) => {
|
|
435
|
+
const result = lsb.cmp(a)(b);
|
|
436
|
+
if (result !== r) {
|
|
437
|
+
throw `result: ${result}, expected: ${r}`;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
c(vec(4n)(0x5n))(vec(4n)(0x5n))(0); // [1,0,1,0] == [1,0,1,0]
|
|
441
|
+
c(vec(4n)(0x5n))(vec(4n)(0x6n))(1); // bit0: 1 > 0
|
|
442
|
+
c(vec(4n)(0x6n))(vec(4n)(0x5n))(-1); // bit0: 0 < 1
|
|
443
|
+
c(vec(4n)(0x5n))(vec(5n)(0x5n))(-1); // equal prefix, shorter is less
|
|
444
|
+
c(vec(5n)(0x5n))(vec(4n)(0x5n))(1); // equal prefix, longer is greater
|
|
445
|
+
c(vec(4n)(0x5n))(vec(5n)(0xan))(1); // bit0: 1 > 0
|
|
446
|
+
},
|
|
433
447
|
msbCmp: () => {
|
|
434
448
|
const c = (a) => (b) => (r) => {
|
|
435
|
-
const result =
|
|
449
|
+
const result = msb.cmp(a)(b);
|
|
436
450
|
if (result !== r) {
|
|
437
451
|
throw `result: ${result}, expected: ${r}`;
|
|
438
452
|
}
|
|
@@ -447,5 +461,26 @@ export default {
|
|
|
447
461
|
u8ListToVec: () => {
|
|
448
462
|
// 131_072 is too much for Bun
|
|
449
463
|
const x = u8ListToVec(msb)(listRepeat(0x12)(131_071));
|
|
464
|
+
return () => {
|
|
465
|
+
const m = u8List(msb)(x);
|
|
466
|
+
const y = toArray(m);
|
|
467
|
+
if (y.length !== 131_071) {
|
|
468
|
+
throw `y.lenght: ${y.length}`;
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
},
|
|
472
|
+
u8ListUnaligned: () => {
|
|
473
|
+
const x = vec(9n)(0x83n);
|
|
474
|
+
const a = toArray(u8List(msb)(x));
|
|
475
|
+
if (a.length !== 2) {
|
|
476
|
+
throw `a.lenght: ${a.length}`;
|
|
477
|
+
}
|
|
478
|
+
const [a0, a1] = a;
|
|
479
|
+
if (a0 !== 0x41) {
|
|
480
|
+
throw `a0: ${a0.toString(16)}`;
|
|
481
|
+
}
|
|
482
|
+
if (a1 !== 0x80) {
|
|
483
|
+
throw `a1: ${a1.toString(16)}`;
|
|
484
|
+
}
|
|
450
485
|
}
|
|
451
486
|
};
|
package/types/list/module.f.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ type NotLazy<T> = Result<T> | Concat<T> | readonly T[];
|
|
|
4
4
|
type Empty = null;
|
|
5
5
|
export type Result<T> = Empty | NonEmpty<T>;
|
|
6
6
|
export type Thunk<T> = () => List<T>;
|
|
7
|
-
type NonEmpty<T> = {
|
|
7
|
+
export type NonEmpty<T> = {
|
|
8
8
|
readonly first: T;
|
|
9
9
|
readonly tail: List<T>;
|
|
10
10
|
};
|