functionalscript 0.8.2 → 0.9.1

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.
Files changed (51) hide show
  1. package/README.md +4 -4
  2. package/bnf/data/module.f.d.ts +10 -1
  3. package/bnf/data/module.f.js +58 -19
  4. package/bnf/data/test.f.d.ts +2 -0
  5. package/bnf/data/test.f.js +244 -3
  6. package/cas/module.f.d.ts +17 -0
  7. package/cas/module.f.js +77 -0
  8. package/cas/test.f.d.ts +2 -0
  9. package/cas/test.f.js +1 -0
  10. package/ci/module.f.js +8 -6
  11. package/crypto/sha2/module.f.js +0 -1
  12. package/dev/module.f.js +3 -2
  13. package/dev/version/module.f.d.ts +2 -2
  14. package/dev/version/module.f.js +4 -3
  15. package/dev/version/test.f.js +3 -2
  16. package/djs/module.f.d.ts +1 -1
  17. package/djs/module.f.js +4 -4
  18. package/djs/transpiler/module.f.js +3 -2
  19. package/djs/transpiler/test.f.js +12 -11
  20. package/fjs/module.f.d.ts +2 -0
  21. package/fjs/module.f.js +24 -0
  22. package/{dev/tf → fjs}/module.js +1 -1
  23. package/io/module.f.d.ts +4 -9
  24. package/io/virtual/module.f.d.ts +1 -1
  25. package/io/virtual/module.f.js +3 -3
  26. package/js/tokenizer/module.f.d.ts +1 -1
  27. package/js/tokenizer/module.f.js +0 -1
  28. package/nanvm-lib/tests/test.f.d.ts +1 -1
  29. package/nanvm-lib/tests/test.f.js +114 -104
  30. package/package.json +5 -7
  31. package/types/btree/find/module.f.d.ts +7 -8
  32. package/types/btree/set/module.f.js +21 -0
  33. package/types/cbase32/module.f.d.ts +6 -0
  34. package/types/cbase32/module.f.js +71 -0
  35. package/types/cbase32/test.f.d.ts +7 -0
  36. package/types/cbase32/test.f.js +74 -0
  37. package/types/list/module.f.d.ts +1 -0
  38. package/types/list/module.f.js +2 -2
  39. package/types/nullable/module.f.d.ts +2 -0
  40. package/types/nullable/module.f.js +1 -0
  41. package/types/nullable/test.f.d.ts +1 -1
  42. package/types/nullable/test.f.js +23 -11
  43. package/types/option/module.f.d.ts +9 -0
  44. package/types/option/module.f.js +6 -0
  45. package/types/uint8array/module.f.d.ts +11 -0
  46. package/types/uint8array/module.f.js +21 -0
  47. package/types/uint8array/test.f.d.ts +12 -0
  48. package/types/uint8array/test.f.js +58 -0
  49. package/fsc/module.d.ts +0 -2
  50. package/fsc/module.js +0 -4
  51. /package/{dev/tf → fjs}/module.d.ts +0 -0
@@ -0,0 +1,71 @@
1
+ import { msb, lsb, length, vec, empty } from "../bit_vec/module.f.js";
2
+ // 0123456789abcdef
3
+ const m = '0123456789abcdefghjkmnpqrstvwxyz';
4
+ const { popFront, concat } = msb;
5
+ const popBack1 = lsb.popFront(1n);
6
+ const popFront5 = popFront(5n);
7
+ export const vec5xToCBase32 = (v) => {
8
+ let result = '';
9
+ while (true) {
10
+ const len = length(v);
11
+ if (len === 0n) {
12
+ break;
13
+ }
14
+ const [r, rest] = popFront5(v);
15
+ result += m[Number(r)];
16
+ v = rest;
17
+ }
18
+ return result;
19
+ };
20
+ export const vecToCBase32 = (v) => {
21
+ const len = length(v);
22
+ const extraLen = 5n - len % 5n;
23
+ const last = 1n << (extraLen - 1n);
24
+ const padded = concat(v)(vec(extraLen)(last));
25
+ return vec5xToCBase32(padded);
26
+ };
27
+ const vec5 = vec(5n);
28
+ const normalizeChar = (c) => {
29
+ const lower = c.toLowerCase();
30
+ switch (lower) {
31
+ case 'i': {
32
+ return '1';
33
+ }
34
+ case 'l': {
35
+ return '1';
36
+ }
37
+ case 'o': {
38
+ return '0';
39
+ }
40
+ default: {
41
+ return lower;
42
+ }
43
+ }
44
+ };
45
+ const toCrockfordIndex = (c) => m.indexOf(normalizeChar(c));
46
+ export const cBase32ToVec5x = (s) => {
47
+ let result = empty;
48
+ for (const c of s) {
49
+ const index = toCrockfordIndex(c);
50
+ if (index < 0) {
51
+ return null;
52
+ }
53
+ const v = vec5(BigInt(index));
54
+ result = concat(result)(v);
55
+ }
56
+ return result;
57
+ };
58
+ export const cBase32ToVec = (s) => {
59
+ let v = cBase32ToVec5x(s);
60
+ if (v === null || v === empty) {
61
+ return null;
62
+ }
63
+ // TODO: replace with a function that computes trailing zeros.
64
+ while (true) {
65
+ const [last, v0] = popBack1(v);
66
+ v = v0;
67
+ if (last === 1n) {
68
+ return v;
69
+ }
70
+ }
71
+ };
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ roundtrip5x: () => void;
3
+ roundtrip: () => void;
4
+ unalignedBits: () => void;
5
+ caseInsensitive: () => void;
6
+ };
7
+ export default _default;
@@ -0,0 +1,74 @@
1
+ import { empty, vec } from "../bit_vec/module.f.js";
2
+ import { cBase32ToVec, cBase32ToVec5x, vec5xToCBase32, vecToCBase32 } from "./module.f.js";
3
+ const check5x = (s, v) => {
4
+ const sr = vec5xToCBase32(v);
5
+ if (sr !== s) {
6
+ throw [sr, s];
7
+ }
8
+ const vr = cBase32ToVec5x(s);
9
+ if (vr !== v) {
10
+ throw [vr, v];
11
+ }
12
+ //
13
+ check(`${s}g`, v);
14
+ };
15
+ const check = (s, v) => {
16
+ const sr = vecToCBase32(v);
17
+ if (sr !== s) {
18
+ throw [sr, s];
19
+ }
20
+ const vr = cBase32ToVec(s);
21
+ if (vr !== v) {
22
+ throw [vr, v];
23
+ }
24
+ };
25
+ export default {
26
+ roundtrip5x: () => {
27
+ check5x("", empty);
28
+ check5x("0", vec(5n)(0n));
29
+ check5x("1", vec(5n)(1n));
30
+ check5x("7", vec(5n)(7n));
31
+ check5x("a", vec(5n)(10n));
32
+ check5x("b", vec(5n)(11n));
33
+ check5x("f", vec(5n)(15n));
34
+ check5x("gh", vec(10n)(529n));
35
+ check5x("jk", vec(10n)(595n));
36
+ check5x("mnpq", vec(20n)(677591n));
37
+ check5x("rstvwxyz", vec(40n)(852378941407n));
38
+ },
39
+ roundtrip: () => {
40
+ check("g", empty);
41
+ check("8", vec(1n)(0n));
42
+ check("r", vec(1n)(1n));
43
+ check("4", vec(2n)(0n));
44
+ check("c", vec(2n)(1n));
45
+ check("2", vec(3n)(0n));
46
+ check("1", vec(4n)(0n));
47
+ check("2g", vec(5n)(2n));
48
+ check("01", vec(9n)(0n));
49
+ },
50
+ unalignedBits: () => {
51
+ const v = vec(1n)(1n);
52
+ const cr = vec5xToCBase32(v);
53
+ if (cr !== "g") {
54
+ throw ['g', cr];
55
+ }
56
+ },
57
+ caseInsensitive: () => {
58
+ if (cBase32ToVec5x("A") !== cBase32ToVec5x("a")) {
59
+ throw 'case-insensitive expected';
60
+ }
61
+ if (cBase32ToVec5x("I") !== cBase32ToVec5x("1")) {
62
+ throw 'i maps to 1';
63
+ }
64
+ if (cBase32ToVec5x("l") !== cBase32ToVec5x("1")) {
65
+ throw 'l maps to 1';
66
+ }
67
+ if (cBase32ToVec5x("o") !== cBase32ToVec5x("0")) {
68
+ throw 'o maps to 0';
69
+ }
70
+ if (cBase32ToVec5x("u") !== null) {
71
+ throw 'should error on invalid character';
72
+ }
73
+ }
74
+ };
@@ -12,6 +12,7 @@ type Concat<T> = {
12
12
  readonly head: List<T>;
13
13
  readonly tail: List<T>;
14
14
  };
15
+ export declare const fromArrayLike: <T>(array: ArrayLike<T>) => Result<T>;
15
16
  export declare const concat: <T>(head: List<T>) => (tail: List<T>) => List<T>;
16
17
  export declare const next: <T>(head: List<T>) => Result<T>;
17
18
  export declare const iterable: <T>(list: List<T>) => Iterable<T>;
@@ -1,6 +1,6 @@
1
1
  import { identity, fn, compose } from "../function/module.f.js";
2
2
  import { addition, logicalNot, strictEqual, stateScanToScan, foldToScan, reduceToScan, } from "../function/operator/module.f.js";
3
- const fromArray = (array) => {
3
+ export const fromArrayLike = (array) => {
4
4
  const at = (i) => i < array.length ? { first: array[i], tail: () => at(i + 1) } : null;
5
5
  return at(0);
6
6
  };
@@ -16,7 +16,7 @@ export const next = (head) => {
16
16
  while (true) {
17
17
  head = trampoline(head);
18
18
  if (head instanceof Array) {
19
- head = fromArray(head);
19
+ head = fromArrayLike(head);
20
20
  }
21
21
  else if (head !== null && 'head' in head) {
22
22
  [head, tail] = [head.head, concat(head.tail)(tail)];
@@ -1,3 +1,5 @@
1
+ import type { Option } from '../option/module.f.ts';
1
2
  export type Nullable<T> = T | null;
2
3
  export declare const map: <T, R>(f: (value: T) => R) => (value: Nullable<T>) => Nullable<R>;
3
4
  export declare const match: <T, R>(f: (_: T) => R) => (none: () => R) => (_: Nullable<T>) => Nullable<R>;
5
+ export declare const toOption: <T>(value: Nullable<T>) => Option<T>;
@@ -1,2 +1,3 @@
1
1
  export const map = f => value => value === null ? null : f(value);
2
2
  export const match = f => none => value => value === null ? none() : f(value);
3
+ export const toOption = (value) => value === null ? [] : [value];
@@ -1,2 +1,2 @@
1
- declare const _default: () => void;
1
+ declare const _default: (() => void)[];
2
2
  export default _default;
@@ -1,12 +1,24 @@
1
- import { map } from "./module.f.js";
2
- export default () => {
3
- const optionSq = map((v) => v * v);
4
- const sq3 = optionSq(3);
5
- if (sq3 !== 9) {
6
- throw sq3;
1
+ import { map, toOption } from "./module.f.js";
2
+ export default [
3
+ () => {
4
+ const optionSq = map((v) => v * v);
5
+ const sq3 = optionSq(3);
6
+ if (sq3 !== 9) {
7
+ throw sq3;
8
+ }
9
+ const sqNull = optionSq(null);
10
+ if (sqNull !== null) {
11
+ throw sqNull;
12
+ }
13
+ },
14
+ () => {
15
+ const opt1 = toOption(5);
16
+ if (opt1.length !== 1 || opt1[0] !== 5) {
17
+ throw opt1;
18
+ }
19
+ const opt2 = toOption(null);
20
+ if (opt2.length !== 0) {
21
+ throw opt2;
22
+ }
7
23
  }
8
- const sqNull = optionSq(null);
9
- if (sqNull !== null) {
10
- throw sqNull;
11
- }
12
- };
24
+ ];
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Optional tuple-based value representation.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * Represents an optional value as an empty tuple or a tuple with one value.
8
+ */
9
+ export type Option<T> = readonly [T] | readonly [];
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Optional tuple-based value representation.
3
+ *
4
+ * @module
5
+ */
6
+ export {};
@@ -0,0 +1,11 @@
1
+ import { type Vec } from "../bit_vec/module.f.ts";
2
+ /**
3
+ * Converts a Uint8Array into an MSB-first bit vector.
4
+ */
5
+ export declare const toVec: (input: Uint8Array) => Vec;
6
+ /**
7
+ * Converts an MSB-first bit vector into a Uint8Array.
8
+ */
9
+ export declare const fromVec: (input: Vec) => Uint8Array;
10
+ export declare const decodeUtf8: (input: Uint8Array) => string;
11
+ export declare const encodeUtf8: (input: string) => Uint8Array;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Conversions between Uint8Array values and bit vectors.
3
+ *
4
+ * @module
5
+ */
6
+ import { utf8, utf8ToString } from "../../text/module.f.js";
7
+ import { msb, u8List, u8ListToVec } from "../bit_vec/module.f.js";
8
+ import { compose } from "../function/module.f.js";
9
+ import { fromArrayLike, iterable } from "../list/module.f.js";
10
+ const u8ListToVecMsb = u8ListToVec(msb);
11
+ const u8ListMsb = u8List(msb);
12
+ /**
13
+ * Converts a Uint8Array into an MSB-first bit vector.
14
+ */
15
+ export const toVec = (input) => u8ListToVecMsb(fromArrayLike(input));
16
+ /**
17
+ * Converts an MSB-first bit vector into a Uint8Array.
18
+ */
19
+ export const fromVec = (input) => Uint8Array.from(iterable(u8ListMsb(input)));
20
+ export const decodeUtf8 = compose(toVec)(utf8ToString);
21
+ export const encodeUtf8 = compose(utf8)(fromVec);
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ empty: () => void;
3
+ roundTrip: () => void;
4
+ unalignedLength: () => void;
5
+ encodeUtf8Empty: () => void;
6
+ encodeUtf8Ascii: () => void;
7
+ encodeUtf8Multibyte: () => void;
8
+ decodeUtf8Ascii: () => void;
9
+ decodeUtf8Multibyte: () => void;
10
+ utf8RoundTrip: () => void;
11
+ };
12
+ export default _default;
@@ -0,0 +1,58 @@
1
+ import { vec } from "../bit_vec/module.f.js";
2
+ import { toVec, fromVec, decodeUtf8, encodeUtf8 } from "./module.f.js";
3
+ import { strictEqual } from "../function/operator/module.f.js";
4
+ import { equal, fromArrayLike } from "../list/module.f.js";
5
+ const assertEq = (a, b) => {
6
+ if (a !== b) {
7
+ throw [a, b];
8
+ }
9
+ };
10
+ const assertArrayEq = (a, b) => {
11
+ if (!equal(strictEqual)(fromArrayLike(a))(fromArrayLike(b))) {
12
+ throw [a, b];
13
+ }
14
+ };
15
+ export default {
16
+ empty: () => {
17
+ const input = new Uint8Array();
18
+ const vec = toVec(input);
19
+ const output = fromVec(vec);
20
+ assertArrayEq(output, input);
21
+ },
22
+ roundTrip: () => {
23
+ const input = Uint8Array.from([0, 1, 2, 3, 255]);
24
+ const vec = toVec(input);
25
+ const output = fromVec(vec);
26
+ assertArrayEq(output, input);
27
+ },
28
+ unalignedLength: () => {
29
+ const input = vec(4n)(0xfn);
30
+ const output = fromVec(input);
31
+ assertArrayEq(output, Uint8Array.from([0xF0]));
32
+ },
33
+ encodeUtf8Empty: () => {
34
+ const output = encodeUtf8('');
35
+ assertArrayEq(output, new Uint8Array());
36
+ },
37
+ encodeUtf8Ascii: () => {
38
+ const output = encodeUtf8('Hi!');
39
+ assertArrayEq(output, Uint8Array.from([72, 105, 33]));
40
+ },
41
+ encodeUtf8Multibyte: () => {
42
+ const output = encodeUtf8('✓');
43
+ assertArrayEq(output, Uint8Array.from([0xE2, 0x9C, 0x93]));
44
+ },
45
+ decodeUtf8Ascii: () => {
46
+ const output = decodeUtf8(Uint8Array.from([102, 115]));
47
+ assertEq(output, 'fs');
48
+ },
49
+ decodeUtf8Multibyte: () => {
50
+ const output = decodeUtf8(Uint8Array.from([0xE2, 0x9C, 0x93]));
51
+ assertEq(output, '✓');
52
+ },
53
+ utf8RoundTrip: () => {
54
+ const input = 'FunctionalScript 🐝';
55
+ const output = decodeUtf8(encodeUtf8(input));
56
+ assertEq(output, input);
57
+ }
58
+ };
package/fsc/module.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/fsc/module.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- import node from "../io/module.js";
3
- import { compile } from "../djs/module.f.js";
4
- await node(compile);
File without changes