functionalscript 0.11.8 → 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
|
|
@@ -153,6 +153,15 @@ 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];
|
|
156
165
|
};
|
|
157
166
|
/**
|
|
158
167
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
@@ -185,7 +194,7 @@ export declare const u8ListToVec: ({ concat }: BitOrder) => (list: List<number>)
|
|
|
185
194
|
* @param v The vector to be converted.
|
|
186
195
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
187
196
|
*/
|
|
188
|
-
export declare const u8List: ({
|
|
197
|
+
export declare const u8List: ({ unpackSplit }: BitOrder) => (v: Vec) => Thunk<number>;
|
|
189
198
|
/**
|
|
190
199
|
* Concatenates a list of vectors using the provided bit order.
|
|
191
200
|
*/
|
|
@@ -195,14 +204,4 @@ export declare const listToVec: ({ concat }: BitOrder) => (list: List<Vec>) => V
|
|
|
195
204
|
*/
|
|
196
205
|
export declare const repeat: Fold<bigint, Vec>;
|
|
197
206
|
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
207
|
export {};
|
|
@@ -107,12 +107,13 @@ 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, concat,
|
|
110
|
+
const bo = ({ front, removeFront, concat, norm, uintCmp, unpackSplit }) => {
|
|
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
|
};
|
|
118
119
|
return {
|
|
@@ -129,6 +130,16 @@ const bo = ({ front, removeFront, concat, rawPopFront, norm }) => {
|
|
|
129
130
|
};
|
|
130
131
|
},
|
|
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,
|
|
132
143
|
};
|
|
133
144
|
};
|
|
134
145
|
/**
|
|
@@ -153,7 +164,11 @@ export const lsb = bo({
|
|
|
153
164
|
return vec(al + bl)((bu << al) | au);
|
|
154
165
|
},
|
|
155
166
|
norm: ({ uint: a }) => ({ uint: b }) => () => ({ a, b }),
|
|
156
|
-
|
|
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]
|
|
157
172
|
});
|
|
158
173
|
/**
|
|
159
174
|
* Implements operations for handling vectors in a most-significant-bit (MSb) first order.
|
|
@@ -176,10 +191,8 @@ export const msb = bo({
|
|
|
176
191
|
},
|
|
177
192
|
concat: flip(lsb.concat),
|
|
178
193
|
norm: ({ length: al, uint: a }) => ({ length: bl, uint: b }) => len => ({ a: a << (len - al), b: b << (len - bl) }),
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return [uint >> d, { length: d, uint }];
|
|
182
|
-
}
|
|
194
|
+
uintCmp: cmp,
|
|
195
|
+
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint]
|
|
183
196
|
});
|
|
184
197
|
/**
|
|
185
198
|
* Converts a list of unsigned 8-bit integers to a bit vector using 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
|
};
|