functionalscript 0.11.6 → 0.11.8
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 +1 -1
- package/types/bit_vec/module.f.d.ts +13 -4
- package/types/bit_vec/module.f.js +71 -32
- package/types/bit_vec/test.f.d.ts +2 -0
- package/types/bit_vec/test.f.js +27 -1
package/package.json
CHANGED
|
@@ -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,8 @@ 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;
|
|
148
156
|
};
|
|
149
157
|
/**
|
|
150
158
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
@@ -169,7 +177,7 @@ export declare const msb: BitOrder;
|
|
|
169
177
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
170
178
|
* @returns The resulting vector based on the provided bit order.
|
|
171
179
|
*/
|
|
172
|
-
export declare const u8ListToVec: (
|
|
180
|
+
export declare const u8ListToVec: ({ concat }: BitOrder) => (list: List<number>) => Vec;
|
|
173
181
|
/**
|
|
174
182
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
175
183
|
*
|
|
@@ -177,7 +185,7 @@ export declare const u8ListToVec: (bo: BitOrder) => (list: List<number>) => Vec;
|
|
|
177
185
|
* @param v The vector to be converted.
|
|
178
186
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
179
187
|
*/
|
|
180
|
-
export declare const u8List: ({
|
|
188
|
+
export declare const u8List: ({ unpackPopFront }: BitOrder) => (v: Vec) => Thunk<number>;
|
|
181
189
|
/**
|
|
182
190
|
* Concatenates a list of vectors using the provided bit order.
|
|
183
191
|
*/
|
|
@@ -197,3 +205,4 @@ export declare const isVec: <T>(v: Vec | T) => v is Vec;
|
|
|
197
205
|
* a === b => 0
|
|
198
206
|
*/
|
|
199
207
|
export declare const msbCmp: (av: Vec) => (bv: Vec) => Sign;
|
|
208
|
+
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 { fold } from "../list/module.f.js";
|
|
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,30 @@ 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, rawPopFront, norm }) => {
|
|
111
|
+
const unpackPopFront = (len) => {
|
|
112
|
+
const m = mask(len);
|
|
113
|
+
return (v) => {
|
|
114
|
+
const [uint, rest] = rawPopFront(len)(v);
|
|
115
|
+
return [uint & m, rest];
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
front,
|
|
120
|
+
removeFront,
|
|
121
|
+
concat,
|
|
122
|
+
xor: op(norm)(xor),
|
|
123
|
+
unpackPopFront,
|
|
124
|
+
popFront: len => {
|
|
125
|
+
const f = unpackPopFront(len);
|
|
126
|
+
return v => {
|
|
127
|
+
const [uint, u] = f(unpack(v));
|
|
128
|
+
return [uint, pack(u)];
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
norm,
|
|
132
|
+
};
|
|
133
|
+
};
|
|
112
134
|
/**
|
|
113
135
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
114
136
|
*
|
|
@@ -116,7 +138,7 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
116
138
|
*
|
|
117
139
|
* Usually associated with Little-Endian (LE) byte order.
|
|
118
140
|
*/
|
|
119
|
-
export const lsb = {
|
|
141
|
+
export const lsb = bo({
|
|
120
142
|
front: len => {
|
|
121
143
|
const m = mask(len);
|
|
122
144
|
return v => uint(v) & m;
|
|
@@ -125,20 +147,14 @@ export const lsb = {
|
|
|
125
147
|
const { length, uint } = unpack(v);
|
|
126
148
|
return vec(length - len)(uint >> len);
|
|
127
149
|
},
|
|
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
150
|
concat: (a) => (b) => {
|
|
136
151
|
const { length: al, uint: au } = unpack(a);
|
|
137
152
|
const { length: bl, uint: bu } = unpack(b);
|
|
138
153
|
return vec(al + bl)((bu << al) | au);
|
|
139
154
|
},
|
|
140
|
-
|
|
141
|
-
}
|
|
155
|
+
norm: ({ uint: a }) => ({ uint: b }) => () => ({ a, b }),
|
|
156
|
+
rawPopFront: len => ({ length, uint }) => [uint, { length: length - len, uint: uint >> len }]
|
|
157
|
+
});
|
|
142
158
|
/**
|
|
143
159
|
* Implements operations for handling vectors in a most-significant-bit (MSb) first order.
|
|
144
160
|
*
|
|
@@ -146,7 +162,7 @@ export const lsb = {
|
|
|
146
162
|
*
|
|
147
163
|
* Usually associated with Big-Endian (BE) byte order.
|
|
148
164
|
*/
|
|
149
|
-
export const msb = {
|
|
165
|
+
export const msb = bo({
|
|
150
166
|
front: len => {
|
|
151
167
|
const m = mask(len);
|
|
152
168
|
return v => {
|
|
@@ -158,18 +174,13 @@ export const msb = {
|
|
|
158
174
|
const { length, uint } = unpack(v);
|
|
159
175
|
return vec(length - len)(uint);
|
|
160
176
|
},
|
|
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
177
|
concat: flip(lsb.concat),
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
const
|
|
178
|
+
norm: ({ length: al, uint: a }) => ({ length: bl, uint: b }) => len => ({ a: a << (len - al), b: b << (len - bl) }),
|
|
179
|
+
rawPopFront: len => ({ length, uint }) => {
|
|
180
|
+
const d = length - len;
|
|
181
|
+
return [uint >> d, { length: d, uint }];
|
|
182
|
+
}
|
|
183
|
+
});
|
|
173
184
|
/**
|
|
174
185
|
* Converts a list of unsigned 8-bit integers to a bit vector using the provided bit order.
|
|
175
186
|
*
|
|
@@ -177,7 +188,34 @@ const appendU8 = ({ concat }) => (u8) => (a) => concat(a)(vec8(BigInt(u8)));
|
|
|
177
188
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
178
189
|
* @returns The resulting vector based on the provided bit order.
|
|
179
190
|
*/
|
|
180
|
-
export const u8ListToVec = (
|
|
191
|
+
export const u8ListToVec = ({ concat }) => (list) => {
|
|
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
|
+
// ```
|
|
198
|
+
let result = [];
|
|
199
|
+
for (const b of iterable(list)) {
|
|
200
|
+
let v = vec8(BigInt(b));
|
|
201
|
+
let i = 0;
|
|
202
|
+
while (true) {
|
|
203
|
+
if (result.length <= i) {
|
|
204
|
+
result = [...result, v];
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
const old = result[i];
|
|
208
|
+
if (old === empty) {
|
|
209
|
+
result = result.toSpliced(i, 1, v);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
result = result.toSpliced(i, 1, empty);
|
|
213
|
+
v = concat(old)(v);
|
|
214
|
+
i++;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return result.reduce((p, c) => concat(c)(p), empty);
|
|
218
|
+
};
|
|
181
219
|
/**
|
|
182
220
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
183
221
|
*
|
|
@@ -185,15 +223,16 @@ export const u8ListToVec = (bo) => fold(appendU8(bo))(empty);
|
|
|
185
223
|
* @param v The vector to be converted.
|
|
186
224
|
* @returns A thunk that produces a list of unsigned 8-bit integers.
|
|
187
225
|
*/
|
|
188
|
-
export const u8List = ({
|
|
189
|
-
const
|
|
190
|
-
|
|
226
|
+
export const u8List = ({ unpackPopFront }) => {
|
|
227
|
+
const pf = unpackPopFront(8n);
|
|
228
|
+
const f = (u) => () => {
|
|
229
|
+
if (u.length <= 0n) {
|
|
191
230
|
return null;
|
|
192
231
|
}
|
|
193
|
-
const [first, tail] =
|
|
232
|
+
const [first, tail] = pf(u);
|
|
194
233
|
return { first: Number(first), tail: f(tail) };
|
|
195
234
|
};
|
|
196
|
-
return f;
|
|
235
|
+
return v => f(unpack(v));
|
|
197
236
|
};
|
|
198
237
|
/**
|
|
199
238
|
* Concatenates a list of vectors using the provided bit order.
|
|
@@ -218,7 +257,7 @@ export const msbCmp = (av) => (bv) => {
|
|
|
218
257
|
const bu = unpack(bv);
|
|
219
258
|
const al = au.length;
|
|
220
259
|
const bl = bu.length;
|
|
221
|
-
const { a, b } =
|
|
260
|
+
const { a, b } = msb.norm(au)(bu)(min(al)(bl));
|
|
222
261
|
const result = cmp(a)(b);
|
|
223
262
|
return result !== 0 ? result : cmp(al)(bl);
|
|
224
263
|
};
|
package/types/bit_vec/test.f.js
CHANGED
|
@@ -1,6 +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, msbCmp } from "./module.f.js";
|
|
3
|
+
import { length, empty, uint, vec, lsb, msb, repeat, vec8, msbCmp, u8ListToVec, u8List } from "./module.f.js";
|
|
4
|
+
import { repeat as listRepeat, toArray } from "../list/module.f.js";
|
|
4
5
|
const unsafeVec = (a) => asNominal(a);
|
|
5
6
|
// 0x8 = 0b1000 = 0 + 8
|
|
6
7
|
// 0x9 = 0b1001 = 1 + 8
|
|
@@ -442,5 +443,30 @@ export default {
|
|
|
442
443
|
c(vec(4n)(0x5n))(vec(5n)(0x5n))(1); // 0b0101_ < 0b00101
|
|
443
444
|
c(vec(5n)(0x5n))(vec(4n)(0x5n))(-1); // 0b00101 < 0b0101_
|
|
444
445
|
c(vec(4n)(0x5n))(vec(5n)(0xan))(-1); // 0b0101_ < 0b01010
|
|
446
|
+
},
|
|
447
|
+
u8ListToVec: () => {
|
|
448
|
+
// 131_072 is too much for Bun
|
|
449
|
+
const x = u8ListToVec(msb)(listRepeat(0x12)(131_071));
|
|
450
|
+
return () => {
|
|
451
|
+
const m = u8List(msb)(x);
|
|
452
|
+
const y = toArray(m);
|
|
453
|
+
if (y.length !== 131_071) {
|
|
454
|
+
throw y.length;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
},
|
|
458
|
+
u8ListUnaligned: () => {
|
|
459
|
+
const x = vec(9n)(0x83n);
|
|
460
|
+
const a = toArray(u8List(msb)(x));
|
|
461
|
+
if (a.length !== 2) {
|
|
462
|
+
throw a;
|
|
463
|
+
}
|
|
464
|
+
const [a0, a1] = a;
|
|
465
|
+
if (a0 !== 0x41) {
|
|
466
|
+
throw `a0: ${a0.toString(16)}`;
|
|
467
|
+
}
|
|
468
|
+
if (a1 !== 0x80) {
|
|
469
|
+
throw `a1: ${a1.toString(16)}`;
|
|
470
|
+
}
|
|
445
471
|
}
|
|
446
472
|
};
|