functionalscript 0.7.0 → 0.8.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 (125) hide show
  1. package/LICENSE +21 -661
  2. package/README.md +3 -2
  3. package/bnf/data/module.f.d.ts +16 -6
  4. package/bnf/data/module.f.js +115 -23
  5. package/bnf/data/test.f.d.ts +4 -0
  6. package/bnf/data/test.f.js +389 -14
  7. package/bnf/module.f.d.ts +5 -4
  8. package/bnf/module.f.js +1 -1
  9. package/bnf/testlib.f.js +1 -1
  10. package/ci/module.f.d.ts +3 -0
  11. package/ci/module.f.js +169 -0
  12. package/ci/module.js +3 -0
  13. package/crypto/hmac/module.f.d.ts +5 -4
  14. package/crypto/hmac/module.f.js +9 -18
  15. package/crypto/hmac/test.f.d.ts +1 -0
  16. package/crypto/hmac/test.f.js +16 -8
  17. package/crypto/prime_field/module.f.d.ts +1 -1
  18. package/crypto/prime_field/module.f.js +4 -3
  19. package/crypto/prime_field/test.f.js +13 -13
  20. package/crypto/rfc6979/module.f.d.ts +15 -0
  21. package/crypto/rfc6979/module.f.js +98 -0
  22. package/crypto/rfc6979/test.f.d.ts +10 -0
  23. package/crypto/rfc6979/test.f.js +490 -0
  24. package/crypto/secp/module.f.d.ts +4 -4
  25. package/crypto/secp/module.f.js +1 -1
  26. package/crypto/secp/test.f.js +8 -8
  27. package/crypto/sha2/module.f.d.ts +11 -5
  28. package/crypto/sha2/module.f.js +4 -3
  29. package/crypto/sha2/test.f.d.ts +4 -1
  30. package/crypto/sha2/test.f.js +41 -31
  31. package/crypto/sign/module.f.d.ts +1 -1
  32. package/crypto/sign/module.f.js +3 -2
  33. package/dev/tf/all.test.js +9 -1
  34. package/djs/ast/module.f.d.ts +3 -3
  35. package/djs/ast/test.f.js +7 -8
  36. package/djs/parser/module.f.d.ts +3 -3
  37. package/djs/parser/module.f.js +4 -4
  38. package/djs/parser/test.f.js +76 -77
  39. package/djs/serializer/module.f.d.ts +8 -8
  40. package/djs/serializer/module.f.js +4 -7
  41. package/djs/serializer/test.f.js +8 -9
  42. package/djs/tokenizer/module.f.d.ts +2 -2
  43. package/djs/tokenizer/module.f.js +3 -5
  44. package/djs/tokenizer/test.f.js +8 -10
  45. package/djs/transpiler/module.f.d.ts +3 -3
  46. package/djs/transpiler/module.f.js +2 -0
  47. package/fsc/bnf.f.d.ts +1 -1
  48. package/fsc/bnf.f.js +39 -51
  49. package/fsc/json.f.d.ts +1 -1
  50. package/fsc/json.f.js +56 -81
  51. package/fsc/test.f.d.ts +5 -0
  52. package/fsc/test.f.js +69 -7
  53. package/fsm/module.f.js +3 -3
  54. package/fsm/test.f.js +21 -25
  55. package/html/module.f.js +17 -4
  56. package/html/test.f.d.ts +7 -0
  57. package/html/test.f.js +37 -0
  58. package/issues/031-json.f.d.ts +1 -0
  59. package/js/tokenizer/module.f.d.ts +4 -4
  60. package/js/tokenizer/module.f.js +12 -17
  61. package/js/tokenizer/test.f.js +9 -11
  62. package/json/module.f.d.ts +6 -6
  63. package/json/module.f.js +5 -10
  64. package/json/parser/module.f.d.ts +4 -4
  65. package/json/parser/module.f.js +7 -4
  66. package/json/parser/test.f.js +47 -49
  67. package/json/serializer/module.f.d.ts +6 -6
  68. package/json/serializer/module.f.js +3 -2
  69. package/json/serializer/test.f.js +13 -13
  70. package/json/test.f.js +13 -15
  71. package/json/tokenizer/module.f.d.ts +4 -4
  72. package/json/tokenizer/module.f.js +6 -7
  73. package/json/tokenizer/test.f.js +7 -9
  74. package/nanvm-lib/tests/vm/test.f.d.ts +25 -0
  75. package/nanvm-lib/tests/vm/test.f.js +105 -0
  76. package/package.json +8 -8
  77. package/text/ascii/test.f.js +2 -2
  78. package/text/module.f.d.ts +3 -2
  79. package/text/module.f.js +2 -2
  80. package/text/test.f.js +3 -3
  81. package/text/utf16/test.f.js +2 -2
  82. package/text/utf8/test.f.js +2 -2
  83. package/types/array/test.f.js +2 -2
  84. package/types/bigint/module.f.d.ts +6 -3
  85. package/types/bigint/module.f.js +12 -11
  86. package/types/bigint/test.f.d.ts +2 -0
  87. package/types/bigint/test.f.js +21 -2
  88. package/types/bit_vec/module.f.d.ts +66 -34
  89. package/types/bit_vec/module.f.js +97 -32
  90. package/types/bit_vec/test.f.d.ts +7 -0
  91. package/types/bit_vec/test.f.js +283 -62
  92. package/types/btree/find/test.f.js +9 -8
  93. package/types/btree/remove/test.f.js +4 -4
  94. package/types/btree/set/test.f.js +4 -4
  95. package/types/btree/test.f.js +7 -7
  96. package/types/byte_set/test.f.js +2 -2
  97. package/types/function/compare/module.f.d.ts +15 -1
  98. package/types/function/compare/module.f.js +1 -1
  99. package/types/function/compare/test.f.js +37 -4
  100. package/types/list/test.f.js +93 -93
  101. package/types/monoid/module.f.d.ts +4 -4
  102. package/types/monoid/module.f.js +3 -3
  103. package/types/monoid/test.f.js +3 -3
  104. package/types/nominal/module.f.d.ts +5 -0
  105. package/types/nominal/module.f.js +4 -0
  106. package/types/nominal/test.f.d.ts +5 -0
  107. package/types/nominal/test.f.js +53 -0
  108. package/types/number/module.f.js +2 -2
  109. package/types/range_map/test.f.js +21 -21
  110. package/types/sorted_list/test.f.js +10 -10
  111. package/types/sorted_set/test.f.js +14 -14
  112. package/types/string/module.f.js +2 -2
  113. package/types/string_set/module.f.js +3 -3
  114. package/bnf/djs/module.f.d.ts +0 -77
  115. package/bnf/djs/module.f.js +0 -207
  116. package/bnf/djs/test.f.d.ts +0 -8
  117. package/bnf/djs/test.f.js +0 -277
  118. package/bnf/func/module.f.d.ts +0 -148
  119. package/bnf/func/module.f.js +0 -132
  120. package/bnf/func/test.f.d.ts +0 -12
  121. package/bnf/func/test.f.js +0 -171
  122. package/bnf/func/testlib.f.d.ts +0 -25
  123. package/bnf/func/testlib.f.js +0 -150
  124. /package/{issues/31-json.f.d.ts → ci/module.d.ts} +0 -0
  125. /package/issues/{31-json.f.js → 031-json.f.js} +0 -0
@@ -1,12 +1,11 @@
1
- import { msbUtf8 } from "../../text/module.f.js";
2
- import { empty, msb, vec } from "../../types/bit_vec/module.f.js";
1
+ import { utf8 } from "../../text/module.f.js";
2
+ import { repeat, uint, vec } from "../../types/bit_vec/module.f.js";
3
+ import { flip } from "../../types/function/module.f.js";
3
4
  import { map } from "../../types/list/module.f.js";
4
- import { repeat } from "../../types/monoid/module.f.js";
5
5
  import { base32, base64, computeSync, sha224, sha256, sha384, sha512, sha512x224, sha512x256, } from "./module.f.js";
6
- const { concat: beConcat } = msb;
7
- const checkEmpty = ({ init, end }) => (x) => {
6
+ const checkEmpty = ({ init, end, hashLength }) => (x) => {
8
7
  const result = end(init);
9
- if (result !== x) {
8
+ if (result !== vec(hashLength)(x)) {
10
9
  throw [result, x];
11
10
  }
12
11
  };
@@ -46,7 +45,7 @@ export default {
46
45
  throw [result, x];
47
46
  }
48
47
  },
49
- s385: () => {
48
+ s384: () => {
50
49
  const result = fromV8(compress(sha384.init.hash)(e)) >> 128n;
51
50
  const x = 0x38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bn;
52
51
  if (result !== x) {
@@ -71,72 +70,83 @@ export default {
71
70
  }
72
71
  },
73
72
  sha2: {
74
- sha256: () => checkEmpty(sha256)(0x1e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n),
75
- sha224: () => checkEmpty(sha224)(0x1d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42fn),
76
- sha512: () => checkEmpty(sha512)(0x1cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3en),
77
- sha384: () => checkEmpty(sha384)(0x138b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bn),
78
- sha512x256: () => checkEmpty(sha512x256)(0x1c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967an),
79
- sha512x224: () => checkEmpty(sha512x224)(0x16ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4n),
73
+ sha256: () => checkEmpty(sha256)(0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n),
74
+ sha224: () => checkEmpty(sha224)(0xd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42fn),
75
+ sha512: () => checkEmpty(sha512)(0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3en),
76
+ sha384: () => checkEmpty(sha384)(0x38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bn),
77
+ sha512x256: () => checkEmpty(sha512x256)(0xc672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967an),
78
+ sha512x224: () => checkEmpty(sha512x224)(0x6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4n),
80
79
  },
81
80
  utf8: [
82
81
  () => {
83
- const e = 0x1730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525n;
82
+ const e = 0x730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525n;
84
83
  {
85
- const s = msbUtf8("The quick brown fox jumps over the lazy dog");
84
+ const s = utf8("The quick brown fox jumps over the lazy dog");
86
85
  const h = computeSync(sha224)([s]);
87
- if (h !== e) {
86
+ if (uint(h) !== e) {
88
87
  throw h;
89
88
  }
90
89
  }
91
90
  {
92
91
  const s = ['The', ' quick', ' brown', ' fox', ' jumps', ' over', ' the', ' lazy', ' dog'];
93
- const h = computeSync(sha224)(map(msbUtf8)(s));
94
- if (h !== e) {
92
+ const h = computeSync(sha224)(map(utf8)(s));
93
+ if (uint(h) !== e) {
95
94
  throw h;
96
95
  }
97
96
  }
98
97
  },
99
98
  () => {
100
- const s = msbUtf8("The quick brown fox jumps over the lazy dog.");
99
+ const s = utf8("The quick brown fox jumps over the lazy dog.");
101
100
  const h = computeSync(sha224)([s]);
102
- if (h !== 0x1619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4cn) {
101
+ if (uint(h) !== 0x619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4cn) {
103
102
  throw h;
104
103
  }
105
104
  },
106
105
  () => {
107
- const s = msbUtf8("hello world");
108
- if (s !== 0x168656c6c6f20776f726c64n) {
106
+ const s = utf8("hello world");
107
+ if (uint(s) !== 0x68656c6c6f20776f726c64n) {
109
108
  throw s;
110
109
  }
111
110
  let state = sha256.init;
112
- state = sha256.append(state)(s);
111
+ state = sha256.append(s)(state);
113
112
  const h = sha256.end(state);
114
- if (h !== 0x1b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9n) {
113
+ if (uint(h) !== 0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9n) {
115
114
  throw h;
116
115
  }
117
116
  }
118
117
  ],
119
118
  fill: () => {
120
- const times = repeat({ identity: empty, operation: beConcat })(vec(32n)(0x31313131n));
119
+ const times = flip(repeat)(vec(32n)(0x31313131n));
121
120
  return {
122
121
  8: () => {
123
122
  const r = times(8n);
124
123
  let state = sha256.init;
125
- state = sha256.append(state)(r);
126
- const h = sha256.end(state);
127
- if (h >> 224n !== 0x18a83665fn) {
124
+ state = sha256.append(r)(state);
125
+ const h = uint(sha256.end(state));
126
+ if (h >> 224n !== 0x8a83665fn) {
128
127
  throw h;
129
128
  }
130
129
  },
131
130
  16: () => {
132
131
  const r = times(16n);
133
132
  let state = sha256.init;
134
- state = sha256.append(state)(r);
133
+ state = sha256.append(r)(state);
135
134
  const h = sha256.end(state);
136
- if (h !== 0x13138bb9bc78df27c473ecfd1410f7bd45ebac1f59cf3ff9cfe4db77aab7aedd3n) {
135
+ if (uint(h) !== 0x3138bb9bc78df27c473ecfd1410f7bd45ebac1f59cf3ff9cfe4db77aab7aedd3n) {
137
136
  throw h;
138
137
  }
139
138
  }
140
139
  };
141
- }
140
+ },
141
+ padding: {
142
+ overflow: () => {
143
+ const zero = vec(8n)(0n);
144
+ const msg = flip(repeat)(zero)(113n);
145
+ const h = computeSync(sha384)([msg]);
146
+ const x = 0x6be9af2cf3cd5dd12c8d9399ec2b34e66034fbd699d4e0221d39074172a380656089caafe8f39963f94cc7c0a07e3d21n;
147
+ if (uint(h) !== x) {
148
+ throw h;
149
+ }
150
+ },
151
+ },
142
152
  };
@@ -1,5 +1,5 @@
1
1
  import { type Vec } from '../../types/bit_vec/module.f.ts';
2
2
  import { type Init } from '../secp/module.f.ts';
3
3
  import type { Sha2 } from '../sha2/module.f.ts';
4
- export declare const newPrivateKey: (i: Init) => (random: Vec) => Vec;
4
+ export declare const newPrivateKey: (i: Init) => (random: Vec) => bigint;
5
5
  export declare const sign: (sha2: Sha2) => (curveInit: Init) => (privateKey: Vec) => (messageHash: Vec) => readonly [bigint, bigint];
@@ -1,3 +1,4 @@
1
+ import { bitLength } from "../../types/bigint/module.f.js";
1
2
  import { listToVec, msb, uint, vec, vec8, length } from "../../types/bit_vec/module.f.js";
2
3
  import { hmac } from "../hmac/module.f.js";
3
4
  import { curve } from "../secp/module.f.js";
@@ -28,7 +29,7 @@ const createK = (sha2) => {
28
29
  };
29
30
  export const newPrivateKey = (i) => (random) => {
30
31
  const { nf } = curve(i);
31
- if (length(nf.max) < length(random)) {
32
+ if (bitLength(nf.max) < length(random)) {
32
33
  throw "need more random bits";
33
34
  }
34
35
  return uint(random) % nf.p;
@@ -39,7 +40,7 @@ export const sign = (sha2) => (curveInit) => (privateKey) => (messageHash) => {
39
40
  //`k` is a unique for each `z` and secret.
40
41
  const k = createK(sha2)(privateKey)(messageHash) % pf.p;
41
42
  // `R = G * k`.
42
- const rp = mul(curveInit.g)(k);
43
+ const rp = mul(k)(curveInit.g);
43
44
  // `r = R.x`
44
45
  const r = rp === null ? 0n : rp[0];
45
46
  // `s = ((z + r * d) / k)`.
@@ -3,9 +3,17 @@ import { loadModuleMap } from "../module.f.js";
3
3
  import { isTest, parseTestSet } from "./module.f.js";
4
4
  import * as nodeTest from 'node:test';
5
5
  const isBun = typeof Bun !== 'undefined';
6
+ const isPlaywright = typeof process !== 'undefined' && process?.env?.PLAYWRIGHT_TEST !== undefined;
6
7
  const createFramework = (fw) => (prefix, f) => fw.test(prefix, t => f((name, v) => t.test(name, v)));
8
+ // Bun doesn't support nested tests yet.
7
9
  const createBunFramework = (fw) => (prefix, f) => f((name, v) => fw.test(`${prefix}: ${name}`, v));
8
- const framework = isBun ? createBunFramework(nodeTest) : createFramework(nodeTest);
10
+ const createPlaywrihtFramework = async () => {
11
+ const pwTest = (await import('@playwright/test')).test;
12
+ return (prefix, f) => f((name, v) => pwTest(`${prefix}: ${name}`, v));
13
+ };
14
+ const framework = isPlaywright ? await createPlaywrihtFramework() :
15
+ isBun ? createBunFramework(nodeTest) :
16
+ createFramework(nodeTest);
9
17
  const parse = parseTestSet(io.tryCatch);
10
18
  const scanModule = (x) => async (subTestRunner) => {
11
19
  let subTests = [x];
@@ -1,10 +1,10 @@
1
- import type * as djs from '../module.f.ts';
1
+ import type { Primitive, Array, Unknown } from '../module.f.ts';
2
2
  export type AstModule = [readonly string[], AstBody];
3
- export type AstConst = djs.Primitive | AstModuleRef | AstArray | AstObject;
3
+ export type AstConst = Primitive | AstModuleRef | AstArray | AstObject;
4
4
  export type AstModuleRef = ['aref' | 'cref', number];
5
5
  export type AstArray = ['array', readonly AstConst[]];
6
6
  export type AstObject = {
7
7
  readonly [k in string]: AstConst;
8
8
  };
9
9
  export type AstBody = readonly AstConst[];
10
- export declare const run: (body: AstBody) => (args: djs.Array) => djs.Unknown;
10
+ export declare const run: (body: AstBody) => (args: Array) => Unknown;
package/djs/ast/test.f.js CHANGED
@@ -1,38 +1,37 @@
1
- import * as list from "../../types/object/module.f.js";
2
- const { sort } = list;
3
- import * as shared from "./module.f.js";
1
+ import { sort } from "../../types/object/module.f.js";
2
+ import { run } from "./module.f.js";
4
3
  import { stringifyAsTree } from "../serializer/module.f.js";
5
4
  export default {
6
5
  test: () => {
7
- const djs = shared.run([1])([]);
6
+ const djs = run([1])([]);
8
7
  const result = stringifyAsTree(sort)(djs);
9
8
  if (result !== '1') {
10
9
  throw result;
11
10
  }
12
11
  },
13
12
  testCref: () => {
14
- const djs = shared.run([1, 2, 3, 4, 5, ['cref', 3]])([11, 12, 13, 14, 15]);
13
+ const djs = run([1, 2, 3, 4, 5, ['cref', 3]])([11, 12, 13, 14, 15]);
15
14
  const result = stringifyAsTree(sort)(djs);
16
15
  if (result !== '4') {
17
16
  throw result;
18
17
  }
19
18
  },
20
19
  testAref: () => {
21
- const djs = shared.run([1, 2, 3, 4, 5, ['aref', 3]])([11, 12, 13, 14, 15]);
20
+ const djs = run([1, 2, 3, 4, 5, ['aref', 3]])([11, 12, 13, 14, 15]);
22
21
  const result = stringifyAsTree(sort)(djs);
23
22
  if (result !== '14') {
24
23
  throw result;
25
24
  }
26
25
  },
27
26
  testArray: () => {
28
- const djs = shared.run([1, 2, 3, 4, 5, ['array', [['aref', 3], ['cref', 3]]]])([11, 12, 13, 14, 15]);
27
+ const djs = run([1, 2, 3, 4, 5, ['array', [['aref', 3], ['cref', 3]]]])([11, 12, 13, 14, 15]);
29
28
  const result = stringifyAsTree(sort)(djs);
30
29
  if (result !== '[14,4]') {
31
30
  throw result;
32
31
  }
33
32
  },
34
33
  testObj: () => {
35
- const djs = shared.run([1, 2, 3, 4, 5, { "key": { "key2": ['array', [['aref', 3], ['cref', 3]]] } }])([11, 12, 13, 14, 15]);
34
+ const djs = run([1, 2, 3, 4, 5, { "key": { "key2": ['array', [['aref', 3], ['cref', 3]]] } }])([11, 12, 13, 14, 15]);
36
35
  const result = stringifyAsTree(sort)(djs);
37
36
  if (result !== '{"key":{"key2":[14,4]}}') {
38
37
  throw result;
@@ -1,4 +1,4 @@
1
- import * as result from '../../types/result/module.f.ts';
1
+ import { type Result } from '../../types/result/module.f.ts';
2
2
  import { type List } from '../../types/list/module.f.ts';
3
3
  import type { DjsTokenWithMetadata } from '../tokenizer/module.f.ts';
4
4
  import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
@@ -7,11 +7,11 @@ import type { AstModule } from '../ast/module.f.ts';
7
7
  import type { TokenMetadata } from '../../js/tokenizer/module.f.ts';
8
8
  export type ParseContext = {
9
9
  readonly fs: Fs;
10
- readonly complete: OrderedMap<result.Result<AstModule, string>>;
10
+ readonly complete: OrderedMap<Result<AstModule, string>>;
11
11
  readonly stack: List<string>;
12
12
  };
13
13
  export type ParseError = {
14
14
  readonly message: string;
15
15
  readonly metadata: TokenMetadata | null;
16
16
  };
17
- export declare const parseFromTokens: (tokenList: List<DjsTokenWithMetadata>) => result.Result<AstModule, ParseError>;
17
+ export declare const parseFromTokens: (tokenList: List<DjsTokenWithMetadata>) => Result<AstModule, ParseError>;
@@ -1,4 +1,4 @@
1
- import * as result from "../../types/result/module.f.js";
1
+ import { error, ok } from "../../types/result/module.f.js";
2
2
  import { fold, first, drop, toArray, length, concat } from "../../types/list/module.f.js";
3
3
  import { setReplace, at } from "../../types/ordered_map/module.f.js";
4
4
  import { fromMap } from "../../types/object/module.f.js";
@@ -351,8 +351,8 @@ const foldOp = token => state => {
351
351
  export const parseFromTokens = (tokenList) => {
352
352
  const state = fold(foldOp)({ state: '', module: { refs: null, modules: null, consts: null } })(tokenList);
353
353
  switch (state.state) {
354
- case 'result': return result.ok([toArray(state.module.modules), toArray(state.module.consts)]);
355
- case 'error': return result.error(state.error);
356
- default: return result.error({ message: 'unexpected end', metadata: null });
354
+ case 'result': return ok([toArray(state.module.modules), toArray(state.module.consts)]);
355
+ case 'error': return error(state.error);
356
+ default: return error({ message: 'unexpected end', metadata: null });
357
357
  }
358
358
  };