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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",
@@ -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: (len: bigint) => (v: Vec) => readonly [bigint, Vec];
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: (bo: BitOrder) => (list: List<number>) => Vec;
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: ({ popFront }: BitOrder) => (v: Vec) => Thunk<number>;
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
- xor: op(lsbNorm)(xor)
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
- xor: op(msbNorm)(xor)
171
- };
172
- const appendU8 = ({ concat }) => (u8) => (a) => concat(a)(vec8(BigInt(u8)));
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 = (bo) => fold(appendU8(bo))(empty);
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 = ({ popFront }) => {
189
- const f = (v) => () => {
190
- if (v === empty) {
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] = popFront(8n)(v);
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 } = msbNorm(au)(bu)(min(al)(bl));
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
  };
@@ -38,5 +38,7 @@ declare const _default: {
38
38
  msbXor: () => void;
39
39
  repeat: () => void;
40
40
  msbCmp: () => void;
41
+ u8ListToVec: () => () => void;
42
+ u8ListUnaligned: () => void;
41
43
  };
42
44
  export default _default;
@@ -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
  };