functionalscript 0.11.8 → 0.11.10
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.10",
|
|
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
|
|
@@ -153,6 +153,16 @@ export type BitOrder = {
|
|
|
153
153
|
readonly xor: Reduce;
|
|
154
154
|
readonly unpackPopFront: PopFront<Unpacked>;
|
|
155
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];
|
|
165
|
+
readonly unpackConcat: (a: Unpacked) => (b: Unpacked) => Unpacked;
|
|
156
166
|
};
|
|
157
167
|
/**
|
|
158
168
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
@@ -177,7 +187,7 @@ export declare const msb: BitOrder;
|
|
|
177
187
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
178
188
|
* @returns The resulting vector based on the provided bit order.
|
|
179
189
|
*/
|
|
180
|
-
export declare const u8ListToVec: ({
|
|
190
|
+
export declare const u8ListToVec: ({ unpackConcat }: BitOrder) => (list: List<number>) => Vec;
|
|
181
191
|
/**
|
|
182
192
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
183
193
|
*
|
|
@@ -185,7 +195,7 @@ export declare const u8ListToVec: ({ concat }: BitOrder) => (list: List<number>)
|
|
|
185
195
|
* @param v The vector to be converted.
|
|
186
196
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
187
197
|
*/
|
|
188
|
-
export declare const u8List: ({
|
|
198
|
+
export declare const u8List: ({ unpackSplit }: BitOrder) => (v: Vec) => Thunk<number>;
|
|
189
199
|
/**
|
|
190
200
|
* Concatenates a list of vectors using the provided bit order.
|
|
191
201
|
*/
|
|
@@ -195,14 +205,4 @@ export declare const listToVec: ({ concat }: BitOrder) => (list: List<Vec>) => V
|
|
|
195
205
|
*/
|
|
196
206
|
export declare const repeat: Fold<bigint, Vec>;
|
|
197
207
|
export declare const isVec: <T>(v: Vec | T) => v is Vec;
|
|
198
|
-
/**
|
|
199
|
-
* Lexically compares two vectors based on their unsigned integer values,
|
|
200
|
-
* normalizing them to the same length. If the values are equal,
|
|
201
|
-
* the shorter vector is considered smaller.
|
|
202
|
-
*
|
|
203
|
-
* a < b => -1
|
|
204
|
-
* a > b => 1
|
|
205
|
-
* a === b => 0
|
|
206
|
-
*/
|
|
207
|
-
export declare const msbCmp: (av: Vec) => (bv: Vec) => Sign;
|
|
208
208
|
export {};
|
|
@@ -107,18 +107,26 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
107
107
|
const { a, b } = norm(au)(bu)(len);
|
|
108
108
|
return vec(len)(op(a)(b));
|
|
109
109
|
};
|
|
110
|
-
const bo = ({ front, removeFront,
|
|
110
|
+
const bo = ({ front, removeFront, norm, uintCmp, unpackSplit, unpackConcatUint }) => {
|
|
111
111
|
const unpackPopFront = (len) => {
|
|
112
112
|
const m = mask(len);
|
|
113
|
+
const us = unpackSplit(len);
|
|
113
114
|
return (v) => {
|
|
114
|
-
const [uint, rest] =
|
|
115
|
-
return [uint & m, rest];
|
|
115
|
+
const [uint, rest] = us(v);
|
|
116
|
+
return [uint & m, { length: v.length - len, uint: rest }];
|
|
116
117
|
};
|
|
117
118
|
};
|
|
119
|
+
const unpackConcat = (a) => (b) => ({
|
|
120
|
+
length: a.length + b.length, uint: unpackConcatUint(a)(b)
|
|
121
|
+
});
|
|
118
122
|
return {
|
|
119
123
|
front,
|
|
120
124
|
removeFront,
|
|
121
|
-
concat
|
|
125
|
+
concat: a => b => {
|
|
126
|
+
const au = unpack(a);
|
|
127
|
+
const bu = unpack(b);
|
|
128
|
+
return pack(unpackConcat(au)(bu));
|
|
129
|
+
},
|
|
122
130
|
xor: op(norm)(xor),
|
|
123
131
|
unpackPopFront,
|
|
124
132
|
popFront: len => {
|
|
@@ -129,8 +137,20 @@ const bo = ({ front, removeFront, concat, rawPopFront, norm }) => {
|
|
|
129
137
|
};
|
|
130
138
|
},
|
|
131
139
|
norm,
|
|
140
|
+
cmp: a => b => {
|
|
141
|
+
const au = unpack(a);
|
|
142
|
+
const bu = unpack(b);
|
|
143
|
+
const al = au.length;
|
|
144
|
+
const bl = bu.length;
|
|
145
|
+
const { a: aui, b: bui } = norm(au)(bu)(min(al)(bl));
|
|
146
|
+
const c = uintCmp(aui)(bui);
|
|
147
|
+
return c === 0 ? cmp(al)(bl) : c;
|
|
148
|
+
},
|
|
149
|
+
unpackSplit,
|
|
150
|
+
unpackConcat,
|
|
132
151
|
};
|
|
133
152
|
};
|
|
153
|
+
const lsbUnpackConcatUint = ({ uint: a, length }) => ({ uint: b }) => (b << length) | a;
|
|
134
154
|
/**
|
|
135
155
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
136
156
|
*
|
|
@@ -147,13 +167,13 @@ export const lsb = bo({
|
|
|
147
167
|
const { length, uint } = unpack(v);
|
|
148
168
|
return vec(length - len)(uint >> len);
|
|
149
169
|
},
|
|
150
|
-
concat: (a) => (b) => {
|
|
151
|
-
const { length: al, uint: au } = unpack(a);
|
|
152
|
-
const { length: bl, uint: bu } = unpack(b);
|
|
153
|
-
return vec(al + bl)((bu << al) | au);
|
|
154
|
-
},
|
|
155
170
|
norm: ({ uint: a }) => ({ uint: b }) => () => ({ a, b }),
|
|
156
|
-
|
|
171
|
+
uintCmp: a => b => {
|
|
172
|
+
const diff = a ^ b;
|
|
173
|
+
return diff === 0n ? 0 : (a & (diff & -diff)) === 0n ? -1 : 1;
|
|
174
|
+
},
|
|
175
|
+
unpackSplit: len => ({ uint }) => [uint, uint >> len],
|
|
176
|
+
unpackConcatUint: lsbUnpackConcatUint
|
|
157
177
|
});
|
|
158
178
|
/**
|
|
159
179
|
* Implements operations for handling vectors in a most-significant-bit (MSb) first order.
|
|
@@ -174,13 +194,12 @@ export const msb = bo({
|
|
|
174
194
|
const { length, uint } = unpack(v);
|
|
175
195
|
return vec(length - len)(uint);
|
|
176
196
|
},
|
|
177
|
-
concat: flip(lsb.concat),
|
|
178
197
|
norm: ({ length: al, uint: a }) => ({ length: bl, uint: b }) => len => ({ a: a << (len - al), b: b << (len - bl) }),
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
198
|
+
uintCmp: cmp,
|
|
199
|
+
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint],
|
|
200
|
+
unpackConcatUint: flip(lsbUnpackConcatUint),
|
|
183
201
|
});
|
|
202
|
+
const unpackEmpty = { length: 0n, uint: 0n };
|
|
184
203
|
/**
|
|
185
204
|
* Converts a list of unsigned 8-bit integers to a bit vector using the provided bit order.
|
|
186
205
|
*
|
|
@@ -188,16 +207,10 @@ export const msb = bo({
|
|
|
188
207
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
189
208
|
* @returns The resulting vector based on the provided bit order.
|
|
190
209
|
*/
|
|
191
|
-
export const u8ListToVec = ({
|
|
192
|
-
// much faster than: `fold(appendU8(bo))(empty)(list)`
|
|
193
|
-
// where `appendU8` is defined as
|
|
194
|
-
// ```
|
|
195
|
-
// const appendU8 = ({ concat }: BitOrder) => (u8: number) => (a: Vec) =>
|
|
196
|
-
// concat(a)(vec8(BigInt(u8)))
|
|
197
|
-
// ```
|
|
210
|
+
export const u8ListToVec = ({ unpackConcat }) => (list) => {
|
|
198
211
|
let result = [];
|
|
199
212
|
for (const b of iterable(list)) {
|
|
200
|
-
let v =
|
|
213
|
+
let v = { length: 8n, uint: BigInt(b) };
|
|
201
214
|
let i = 0;
|
|
202
215
|
while (true) {
|
|
203
216
|
if (result.length <= i) {
|
|
@@ -205,16 +218,16 @@ export const u8ListToVec = ({ concat }) => (list) => {
|
|
|
205
218
|
break;
|
|
206
219
|
}
|
|
207
220
|
const old = result[i];
|
|
208
|
-
if (old ===
|
|
221
|
+
if (old.length === 0n) {
|
|
209
222
|
result = result.toSpliced(i, 1, v);
|
|
210
223
|
break;
|
|
211
224
|
}
|
|
212
|
-
result = result.toSpliced(i, 1,
|
|
213
|
-
v =
|
|
225
|
+
result = result.toSpliced(i, 1, unpackEmpty);
|
|
226
|
+
v = unpackConcat(old)(v);
|
|
214
227
|
i++;
|
|
215
228
|
}
|
|
216
229
|
}
|
|
217
|
-
return result.reduce((p, c) =>
|
|
230
|
+
return pack(result.reduce((p, c) => unpackConcat(c)(p), unpackEmpty));
|
|
218
231
|
};
|
|
219
232
|
/**
|
|
220
233
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
@@ -223,16 +236,30 @@ export const u8ListToVec = ({ concat }) => (list) => {
|
|
|
223
236
|
* @param v The vector to be converted.
|
|
224
237
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
225
238
|
*/
|
|
226
|
-
export const u8List = ({
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
+
];
|
|
231
260
|
}
|
|
232
|
-
const [first, tail] = pf(u);
|
|
233
|
-
return { first: Number(first), tail: f(tail) };
|
|
234
261
|
};
|
|
235
|
-
return
|
|
262
|
+
return f([unpack(v), undefined]);
|
|
236
263
|
};
|
|
237
264
|
/**
|
|
238
265
|
* Concatenates a list of vectors using the provided bit order.
|
|
@@ -243,21 +270,3 @@ export const listToVec = ({ concat }) => fold(flip(concat))(empty);
|
|
|
243
270
|
*/
|
|
244
271
|
export const repeat = mRepeat({ identity: empty, operation: lsb.concat });
|
|
245
272
|
export const isVec = (v) => typeof v === 'bigint';
|
|
246
|
-
/**
|
|
247
|
-
* Lexically compares two vectors based on their unsigned integer values,
|
|
248
|
-
* normalizing them to the same length. If the values are equal,
|
|
249
|
-
* the shorter vector is considered smaller.
|
|
250
|
-
*
|
|
251
|
-
* a < b => -1
|
|
252
|
-
* a > b => 1
|
|
253
|
-
* a === b => 0
|
|
254
|
-
*/
|
|
255
|
-
export const msbCmp = (av) => (bv) => {
|
|
256
|
-
const au = unpack(av);
|
|
257
|
-
const bu = unpack(bv);
|
|
258
|
-
const al = au.length;
|
|
259
|
-
const bl = bu.length;
|
|
260
|
-
const { a, b } = msb.norm(au)(bu)(min(al)(bl));
|
|
261
|
-
const result = cmp(a)(b);
|
|
262
|
-
return result !== 0 ? result : cmp(al)(bl);
|
|
263
|
-
};
|
package/types/bit_vec/test.f.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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,
|
|
3
|
+
import { length, empty, uint, vec, lsb, msb, repeat, vec8, u8ListToVec, u8List } from "./module.f.js";
|
|
4
4
|
import { repeat as listRepeat, toArray } from "../list/module.f.js";
|
|
5
5
|
const unsafeVec = (a) => asNominal(a);
|
|
6
6
|
// 0x8 = 0b1000 = 0 + 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
|
}
|
|
@@ -451,7 +465,7 @@ export default {
|
|
|
451
465
|
const m = u8List(msb)(x);
|
|
452
466
|
const y = toArray(m);
|
|
453
467
|
if (y.length !== 131_071) {
|
|
454
|
-
throw y.length
|
|
468
|
+
throw `y.lenght: ${y.length}`;
|
|
455
469
|
}
|
|
456
470
|
};
|
|
457
471
|
},
|
|
@@ -459,7 +473,7 @@ export default {
|
|
|
459
473
|
const x = vec(9n)(0x83n);
|
|
460
474
|
const a = toArray(u8List(msb)(x));
|
|
461
475
|
if (a.length !== 2) {
|
|
462
|
-
throw a
|
|
476
|
+
throw `a.lenght: ${a.length}`;
|
|
463
477
|
}
|
|
464
478
|
const [a0, a1] = a;
|
|
465
479
|
if (a0 !== 0x41) {
|
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
|
};
|