functionalscript 0.8.1 → 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.
- package/README.md +4 -4
- package/bnf/data/module.f.d.ts +10 -1
- package/bnf/data/module.f.js +58 -19
- package/bnf/data/test.f.d.ts +2 -0
- package/bnf/data/test.f.js +244 -3
- package/cas/module.f.d.ts +17 -0
- package/cas/module.f.js +77 -0
- package/cas/test.f.d.ts +2 -0
- package/cas/test.f.js +1 -0
- package/ci/module.f.js +8 -6
- package/crypto/secp/module.f.d.ts +10 -7
- package/crypto/secp/module.f.js +32 -12
- package/crypto/secp/test.f.js +4 -5
- package/crypto/sha2/module.f.js +0 -1
- package/crypto/sign/module.f.d.ts +17 -4
- package/crypto/sign/module.f.js +141 -47
- package/crypto/sign/test.f.d.ts +11 -1
- package/crypto/sign/test.f.js +631 -1
- package/dev/module.f.js +3 -2
- package/dev/version/module.f.d.ts +2 -2
- package/dev/version/module.f.js +4 -3
- package/dev/version/test.f.js +3 -2
- package/djs/module.f.d.ts +1 -1
- package/djs/module.f.js +4 -4
- package/djs/transpiler/module.f.js +3 -2
- package/djs/transpiler/test.f.js +12 -11
- package/fjs/module.f.d.ts +2 -0
- package/fjs/module.f.js +24 -0
- package/{dev/tf → fjs}/module.js +1 -1
- package/io/module.f.d.ts +4 -9
- package/io/virtual/module.f.d.ts +1 -1
- package/io/virtual/module.f.js +3 -3
- package/js/tokenizer/module.f.d.ts +1 -1
- package/js/tokenizer/module.f.js +0 -1
- package/nanvm-lib/tests/test.f.d.ts +1 -1
- package/nanvm-lib/tests/test.f.js +114 -104
- package/nanvm-lib/tests/vm/test.f.js +1 -1
- package/package.json +5 -7
- package/path/module.f.d.ts +3 -2
- package/types/btree/find/module.f.d.ts +7 -8
- package/types/btree/set/module.f.js +21 -0
- package/types/cbase32/module.f.d.ts +6 -0
- package/types/cbase32/module.f.js +71 -0
- package/types/cbase32/test.f.d.ts +7 -0
- package/types/cbase32/test.f.js +74 -0
- package/types/list/module.f.d.ts +1 -0
- package/types/list/module.f.js +2 -2
- package/types/nullable/module.f.d.ts +2 -0
- package/types/nullable/module.f.js +1 -0
- package/types/nullable/test.f.d.ts +1 -1
- package/types/nullable/test.f.js +23 -11
- package/types/option/module.f.d.ts +9 -0
- package/types/option/module.f.js +6 -0
- package/{crypto → types}/prime_field/module.f.d.ts +1 -1
- package/{crypto → types}/prime_field/module.f.js +1 -1
- package/types/uint8array/module.f.d.ts +11 -0
- package/types/uint8array/module.f.js +21 -0
- package/types/uint8array/test.f.d.ts +12 -0
- package/types/uint8array/test.f.js +58 -0
- package/crypto/rfc6979/module.f.d.ts +0 -15
- package/crypto/rfc6979/module.f.js +0 -98
- package/crypto/rfc6979/test.f.d.ts +0 -10
- package/crypto/rfc6979/test.f.js +0 -490
- package/fsc/module.d.ts +0 -2
- package/fsc/module.js +0 -4
- /package/{dev/tf → fjs}/module.d.ts +0 -0
- /package/{crypto → types}/prime_field/test.f.d.ts +0 -0
- /package/{crypto → types}/prime_field/test.f.js +0 -0
package/README.md
CHANGED
|
@@ -29,19 +29,19 @@ Install FunctionalScript via npm:
|
|
|
29
29
|
npm install functionalscript
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
The FunctionalScript compiler (`
|
|
32
|
+
The FunctionalScript compiler command (`fjs compile`) currently supports:
|
|
33
33
|
|
|
34
34
|
* `import` statements
|
|
35
35
|
* `const` declarations
|
|
36
36
|
|
|
37
37
|
It does **not** yet support functions or complex expressions.
|
|
38
38
|
|
|
39
|
-
Example usage with `
|
|
39
|
+
Example usage with `fjs`:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npx
|
|
42
|
+
npx fjs compile example.f.js output.json
|
|
43
43
|
# or
|
|
44
|
-
npx
|
|
44
|
+
npx fjs compile example.f.js output.f.js
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
FunctionalScript code can be compiled directly into either JSON or JavaScript without imports.
|
package/bnf/data/module.f.d.ts
CHANGED
|
@@ -29,7 +29,15 @@ type DispatchMap = {
|
|
|
29
29
|
type EmptyTagMap = {
|
|
30
30
|
readonly [id in string]: EmptyTagEntry;
|
|
31
31
|
};
|
|
32
|
-
export type DescentMatchRule = (
|
|
32
|
+
export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePointMeta<T>[], idx: number) => DescentMatchResult<T>;
|
|
33
|
+
export type DescentMatchResult<T> = readonly [AstRuleMeta<T>, boolean, number];
|
|
34
|
+
export type DescentMatch<T> = (name: string, s: readonly CodePointMeta<T>[]) => DescentMatchResult<T>;
|
|
35
|
+
export type CodePointMeta<T> = readonly [CodePoint, T];
|
|
36
|
+
export type AstSequenceMeta<T> = readonly (AstRuleMeta<T> | CodePointMeta<T>)[];
|
|
37
|
+
export type AstRuleMeta<T> = {
|
|
38
|
+
readonly tag: AstTag;
|
|
39
|
+
readonly sequence: AstSequenceMeta<T>;
|
|
40
|
+
};
|
|
33
41
|
/**
|
|
34
42
|
* Represents a parsed Abstract Syntax Tree (AST) sequence.
|
|
35
43
|
*/
|
|
@@ -58,6 +66,7 @@ export type MatchRule = (dr: DispatchRule, s: readonly CodePoint[]) => MatchResu
|
|
|
58
66
|
export declare const toData: (fr: FRule) => readonly [RuleSet, string];
|
|
59
67
|
export declare const dispatchMap: (ruleSet: RuleSet) => DispatchMap;
|
|
60
68
|
export declare const createEmptyTagMap: (data: readonly [RuleSet, string]) => EmptyTagMap;
|
|
69
|
+
export declare const descentParser: <T>(fr: FRule) => DescentMatch<T>;
|
|
61
70
|
export declare const parser: (fr: FRule) => Match;
|
|
62
71
|
export declare const parserRuleSet: (ruleSet: RuleSet) => Match;
|
|
63
72
|
export {};
|
package/bnf/data/module.f.js
CHANGED
|
@@ -3,6 +3,7 @@ import { strictEqual } from "../../types/function/operator/module.f.js";
|
|
|
3
3
|
import { map, toArray } from "../../types/list/module.f.js";
|
|
4
4
|
import { rangeMap } from "../../types/range_map/module.f.js";
|
|
5
5
|
import { contains, set } from "../../types/string_set/module.f.js";
|
|
6
|
+
import { contains as rangeContains } from "../../types/range/module.f.js";
|
|
6
7
|
import { oneEncode, rangeDecode, } from "../module.f.js";
|
|
7
8
|
const { entries } = Object;
|
|
8
9
|
const find = (map) => (fr) => {
|
|
@@ -198,25 +199,63 @@ const emptyTagMapAdd = (ruleSet) => (map) => (name) => {
|
|
|
198
199
|
export const createEmptyTagMap = (data) => {
|
|
199
200
|
return emptyTagMapAdd(data[0])({})(data[1])[1];
|
|
200
201
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
202
|
+
export const descentParser = (fr) => {
|
|
203
|
+
const data = toData(fr);
|
|
204
|
+
const emptyTagMap = createEmptyTagMap(data);
|
|
205
|
+
const getEmptyTag = (name) => {
|
|
206
|
+
const res = emptyTagMap[name];
|
|
207
|
+
return res === false ? undefined : res;
|
|
208
|
+
};
|
|
209
|
+
const f = (name, tag, cp, idx) => {
|
|
210
|
+
const mrSuccess = (tag, sequence, idx) => [{ tag, sequence }, true, idx];
|
|
211
|
+
const mrFail = (tag, sequence, idx) => [{ tag, sequence }, false, idx];
|
|
212
|
+
const rule = data[0][name];
|
|
213
|
+
if (typeof rule === 'number') {
|
|
214
|
+
const emptyTag = getEmptyTag(name);
|
|
215
|
+
if (idx >= cp.length) {
|
|
216
|
+
return emptyTag === undefined ? mrFail(emptyTag, [], idx) : mrSuccess(emptyTag, [], idx);
|
|
217
|
+
}
|
|
218
|
+
const cpi = cp[idx];
|
|
219
|
+
const range = rangeDecode(rule);
|
|
220
|
+
if (rangeContains(range)(cpi[0])) {
|
|
221
|
+
return mrSuccess(tag, [cpi], idx + 1);
|
|
222
|
+
}
|
|
223
|
+
return mrFail(emptyTag, [], idx);
|
|
224
|
+
}
|
|
225
|
+
else if (rule instanceof Array) {
|
|
226
|
+
let seq = [];
|
|
227
|
+
let tidx = idx;
|
|
228
|
+
for (const item of rule) {
|
|
229
|
+
const m = f(item, undefined, cp, tidx);
|
|
230
|
+
const [astRule, success, nidx] = m;
|
|
231
|
+
tidx = nidx;
|
|
232
|
+
if (success === false) {
|
|
233
|
+
return mrFail(tag, [], idx);
|
|
234
|
+
}
|
|
235
|
+
seq = [...seq, astRule];
|
|
236
|
+
}
|
|
237
|
+
return mrSuccess(tag, seq, tidx);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
const entries = Object.entries(rule);
|
|
241
|
+
const emptyTag = getEmptyTag(name);
|
|
242
|
+
let emptyResult = mrFail(emptyTag, [], idx);
|
|
243
|
+
for (const [tag, item] of entries) {
|
|
244
|
+
const m = f(item, tag, cp, idx);
|
|
245
|
+
if (m[1]) {
|
|
246
|
+
if (idx !== m[2])
|
|
247
|
+
return m;
|
|
248
|
+
emptyResult = m;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return emptyResult;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const match = (name, cp) => {
|
|
255
|
+
return f(name, undefined, cp, 0);
|
|
256
|
+
};
|
|
257
|
+
return match;
|
|
258
|
+
};
|
|
220
259
|
export const parser = (fr) => {
|
|
221
260
|
const data = toData(fr);
|
|
222
261
|
return parserRuleSet(data[0]);
|
package/bnf/data/test.f.d.ts
CHANGED
package/bnf/data/test.f.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { stringify } from "../../json/module.f.js";
|
|
2
2
|
import { stringToCodePointList } from "../../text/utf16/module.f.js";
|
|
3
3
|
import { identity } from "../../types/function/module.f.js";
|
|
4
|
-
import { toArray } from "../../types/list/module.f.js";
|
|
4
|
+
import { map, toArray } from "../../types/list/module.f.js";
|
|
5
5
|
import { sort } from "../../types/object/module.f.js";
|
|
6
|
-
import { join0Plus,
|
|
6
|
+
import { join0Plus, option, range, repeat0Plus, set } from "../module.f.js";
|
|
7
7
|
import { classic, deterministic } from "../testlib.f.js";
|
|
8
|
-
import { dispatchMap, parser, parserRuleSet, toData, createEmptyTagMap } from "./module.f.js";
|
|
8
|
+
import { dispatchMap, parser, parserRuleSet, toData, createEmptyTagMap, descentParser } from "./module.f.js";
|
|
9
|
+
const mapCodePoint = (cp) => [cp, undefined];
|
|
10
|
+
const descentParserCpOnly = (m, name, cp) => {
|
|
11
|
+
const cpm = toArray(map(mapCodePoint)(cp));
|
|
12
|
+
return m(name, cpm);
|
|
13
|
+
};
|
|
9
14
|
export default {
|
|
10
15
|
toData: [
|
|
11
16
|
() => {
|
|
@@ -366,6 +371,19 @@ export default {
|
|
|
366
371
|
throw result;
|
|
367
372
|
}
|
|
368
373
|
},
|
|
374
|
+
() => {
|
|
375
|
+
const emptyRule = '';
|
|
376
|
+
const minusRule = range('--');
|
|
377
|
+
const optionalMinusRule = { 'none': emptyRule, 'minus': minusRule };
|
|
378
|
+
const digitRule = range('09');
|
|
379
|
+
const numberRule = [optionalMinusRule, digitRule];
|
|
380
|
+
const m = parser(numberRule);
|
|
381
|
+
const mr = m("", []);
|
|
382
|
+
const result = JSON.stringify(mr);
|
|
383
|
+
if (result !== '[{"sequence":[]},true,null]') {
|
|
384
|
+
throw result;
|
|
385
|
+
} //if remainder is null it means failed
|
|
386
|
+
},
|
|
369
387
|
() => {
|
|
370
388
|
const m = parser(option('a'));
|
|
371
389
|
const isSuccess = (mr) => mr[1] && mr[2]?.length === 0;
|
|
@@ -401,6 +419,7 @@ export default {
|
|
|
401
419
|
throw mr;
|
|
402
420
|
}
|
|
403
421
|
};
|
|
422
|
+
expect('', false);
|
|
404
423
|
expect('[]', true);
|
|
405
424
|
expect('[a]', true);
|
|
406
425
|
expect('[a, a]', true);
|
|
@@ -437,6 +456,228 @@ export default {
|
|
|
437
456
|
expect(' [{ "q": [ 12, false, [}], "a"] }] ', false);
|
|
438
457
|
}
|
|
439
458
|
],
|
|
459
|
+
descentParser: [
|
|
460
|
+
() => {
|
|
461
|
+
const emptyRule = '';
|
|
462
|
+
const m = descentParser(emptyRule);
|
|
463
|
+
const mr = m("", []);
|
|
464
|
+
const result = JSON.stringify(mr);
|
|
465
|
+
if (result !== '[{"sequence":[]},true,0]') {
|
|
466
|
+
throw result;
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
() => {
|
|
470
|
+
const emptyRule = '';
|
|
471
|
+
const m = descentParser(emptyRule);
|
|
472
|
+
const mr = descentParserCpOnly(m, "", [65, 70]);
|
|
473
|
+
const result = JSON.stringify(mr);
|
|
474
|
+
if (result !== '[{"sequence":[]},true,0]') {
|
|
475
|
+
throw result;
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
() => {
|
|
479
|
+
const terminalRangeRule = range('AF');
|
|
480
|
+
const m = descentParser(terminalRangeRule);
|
|
481
|
+
const mr = descentParserCpOnly(m, "", [65]);
|
|
482
|
+
const result = JSON.stringify(mr);
|
|
483
|
+
if (result !== '[{"sequence":[[65,null]]},true,1]') {
|
|
484
|
+
throw result;
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
() => {
|
|
488
|
+
const terminalRangeRule = range('AF');
|
|
489
|
+
const m = descentParser(terminalRangeRule);
|
|
490
|
+
const mr = descentParserCpOnly(m, "", [64]);
|
|
491
|
+
const result = JSON.stringify(mr);
|
|
492
|
+
if (result !== '[{"sequence":[]},false,0]') {
|
|
493
|
+
throw result;
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
() => {
|
|
497
|
+
const variantRule = { 'a': range('AA'), 'b': range('BB') };
|
|
498
|
+
const m = descentParser(variantRule);
|
|
499
|
+
const mr = descentParserCpOnly(m, "", [65]);
|
|
500
|
+
const result = JSON.stringify(mr);
|
|
501
|
+
if (result !== '[{"tag":"a","sequence":[[65,null]]},true,1]') {
|
|
502
|
+
throw result;
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
() => {
|
|
506
|
+
const variantRule = { 'a': range('AA'), 'b': range('BB') };
|
|
507
|
+
const m = descentParser(variantRule);
|
|
508
|
+
const mr = descentParserCpOnly(m, "", [64]);
|
|
509
|
+
const result = JSON.stringify(mr);
|
|
510
|
+
if (result !== '[{"sequence":[]},false,0]') {
|
|
511
|
+
throw result;
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
() => {
|
|
515
|
+
const emptyRule = '';
|
|
516
|
+
const variantRule = { 'e': emptyRule, 'a': range('AA') };
|
|
517
|
+
const m = descentParser(variantRule);
|
|
518
|
+
const mr = m("", []);
|
|
519
|
+
const result = JSON.stringify(mr);
|
|
520
|
+
if (result !== '[{"tag":"e","sequence":[]},true,0]') {
|
|
521
|
+
throw result;
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
() => {
|
|
525
|
+
const emptyRule = '';
|
|
526
|
+
const variantRule = { 'e': emptyRule, 'a': range('AA') };
|
|
527
|
+
const m = descentParser(variantRule);
|
|
528
|
+
const mr = descentParserCpOnly(m, "", [64]);
|
|
529
|
+
const result = JSON.stringify(mr);
|
|
530
|
+
if (result !== '[{"tag":"e","sequence":[]},true,0]') {
|
|
531
|
+
throw result;
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
() => {
|
|
535
|
+
const stringRule = 'AB';
|
|
536
|
+
const m = descentParser(stringRule);
|
|
537
|
+
const mr = descentParserCpOnly(m, "", [65, 66]);
|
|
538
|
+
const result = JSON.stringify(mr);
|
|
539
|
+
if (result !== '[{"sequence":[{"sequence":[[65,null]]},{"sequence":[[66,null]]}]},true,2]') {
|
|
540
|
+
throw result;
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
() => {
|
|
544
|
+
const stringRule = 'AB';
|
|
545
|
+
const m = descentParser(stringRule);
|
|
546
|
+
const mr = descentParserCpOnly(m, "", [65, 67]);
|
|
547
|
+
const result = JSON.stringify(mr);
|
|
548
|
+
if (result !== '[{"sequence":[]},false,0]') {
|
|
549
|
+
throw result;
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
() => {
|
|
553
|
+
const emptyRule = '';
|
|
554
|
+
const minursRule = range('--');
|
|
555
|
+
const optionalMinusRule = { 'none': emptyRule, 'minus': minursRule };
|
|
556
|
+
const digitRule = range('09');
|
|
557
|
+
const numberRule = [optionalMinusRule, digitRule];
|
|
558
|
+
const m = descentParser(numberRule);
|
|
559
|
+
const mr = descentParserCpOnly(m, "", [50]);
|
|
560
|
+
const result = JSON.stringify(mr);
|
|
561
|
+
if (result !== '[{"sequence":[{"tag":"none","sequence":[]},{"sequence":[[50,null]]}]},true,1]') {
|
|
562
|
+
throw result;
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
() => {
|
|
566
|
+
const emptyRule = '';
|
|
567
|
+
const minusRule = range('--');
|
|
568
|
+
const optionalMinusRule = { 'none': emptyRule, 'minus': minusRule };
|
|
569
|
+
const digitRule = range('09');
|
|
570
|
+
const numberRule = [optionalMinusRule, digitRule];
|
|
571
|
+
const m = descentParser(numberRule);
|
|
572
|
+
const mr = descentParserCpOnly(m, "", [45, 50]);
|
|
573
|
+
const result = JSON.stringify(mr);
|
|
574
|
+
if (result !== '[{"sequence":[{"tag":"minus","sequence":[[45,null]]},{"sequence":[[50,null]]}]},true,2]') {
|
|
575
|
+
throw result;
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
() => {
|
|
579
|
+
const emptyRule = '';
|
|
580
|
+
const minursRule = range('--');
|
|
581
|
+
const optionalMinusRule = { 'none': emptyRule, 'minus': minursRule };
|
|
582
|
+
const digitRule = range('09');
|
|
583
|
+
const numberRule = [optionalMinusRule, digitRule];
|
|
584
|
+
const m = descentParser(numberRule);
|
|
585
|
+
const mr = m("", []);
|
|
586
|
+
const result = JSON.stringify(mr);
|
|
587
|
+
if (result !== '[{"sequence":[]},false,0]') {
|
|
588
|
+
throw result;
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
() => {
|
|
592
|
+
const m = descentParser(option('a'));
|
|
593
|
+
const expect = (s, expected) => {
|
|
594
|
+
const cp = toArray(stringToCodePointList(s));
|
|
595
|
+
const mr = descentParserCpOnly(m, '', cp);
|
|
596
|
+
const success = mr[1] && mr[2] === cp.length;
|
|
597
|
+
if (success !== expected) {
|
|
598
|
+
throw mr;
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
expect('a', true);
|
|
602
|
+
expect('', true);
|
|
603
|
+
expect('aa', false);
|
|
604
|
+
expect('b', false);
|
|
605
|
+
},
|
|
606
|
+
() => {
|
|
607
|
+
const ws = repeat0Plus(set(' \n\r\t'));
|
|
608
|
+
const commaJoin0Plus = ([open, close], a) => [
|
|
609
|
+
open,
|
|
610
|
+
ws,
|
|
611
|
+
join0Plus([a, ws], [',', ws]),
|
|
612
|
+
close,
|
|
613
|
+
];
|
|
614
|
+
const value = () => ({
|
|
615
|
+
object: commaJoin0Plus('{}', 'a'),
|
|
616
|
+
array: commaJoin0Plus('[]', 'a')
|
|
617
|
+
});
|
|
618
|
+
value.name; //bun will fail if no usage of name found
|
|
619
|
+
const m = descentParser(value);
|
|
620
|
+
const expect = (s, expected) => {
|
|
621
|
+
const cp = toArray(stringToCodePointList(s));
|
|
622
|
+
const mr = descentParserCpOnly(m, 'value', cp);
|
|
623
|
+
const success = mr[1] && mr[2] === cp.length;
|
|
624
|
+
if (success !== expected) {
|
|
625
|
+
throw mr;
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
expect('', false);
|
|
629
|
+
expect('[]', true);
|
|
630
|
+
expect('[a]', true);
|
|
631
|
+
expect('[a, a]', true);
|
|
632
|
+
expect('{a}', true);
|
|
633
|
+
},
|
|
634
|
+
() => {
|
|
635
|
+
const m = descentParser(deterministic());
|
|
636
|
+
const expect = (s, expected) => {
|
|
637
|
+
const cp = toArray(stringToCodePointList(s));
|
|
638
|
+
const mr = descentParserCpOnly(m, '', cp);
|
|
639
|
+
const success = mr[1] && mr[2] === cp.length;
|
|
640
|
+
if (success !== expected) {
|
|
641
|
+
throw mr;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
expect(' true ', true);
|
|
645
|
+
expect(' tr2ue ', false);
|
|
646
|
+
expect(' true" ', false);
|
|
647
|
+
expect(' "Hello" ', true);
|
|
648
|
+
expect(' "Hello ', false);
|
|
649
|
+
expect(' "Hello\\n\\r\\"" ', true);
|
|
650
|
+
expect(' -56.7e+5 ', true);
|
|
651
|
+
expect(' h-56.7e+5 ', false);
|
|
652
|
+
expect(' -56.7e+5 3', false);
|
|
653
|
+
expect(' [] ', true);
|
|
654
|
+
expect(' {} ', true);
|
|
655
|
+
expect(' [[[]]] ', true);
|
|
656
|
+
expect(' [1] ', true);
|
|
657
|
+
expect(' [ 12, false, "a"] ', true);
|
|
658
|
+
expect(' [ 12, false2, "a"] ', false);
|
|
659
|
+
expect(' { "q": [ 12, false, [{"b" : "c"}], "a"] } ', true);
|
|
660
|
+
expect(' { "q": [ 12, false, [{}], "a"] } ', true);
|
|
661
|
+
expect(' { "q": [ 12, false, [}], "a"] } ', false);
|
|
662
|
+
expect(' [{ "q": [ 12, false, [{}], "a"] }] ', true);
|
|
663
|
+
expect(' [{ "q": [ 12, false, [}], "a"] }] ', false);
|
|
664
|
+
}
|
|
665
|
+
],
|
|
666
|
+
descentParserWithMeta: [
|
|
667
|
+
() => {
|
|
668
|
+
const emptyRule = '';
|
|
669
|
+
const minusRule = range('--');
|
|
670
|
+
const optionalMinusRule = { 'none': emptyRule, 'minus': minusRule };
|
|
671
|
+
const digitRule = range('09');
|
|
672
|
+
const numberRule = [optionalMinusRule, digitRule];
|
|
673
|
+
const m = descentParser(numberRule);
|
|
674
|
+
const mr = m("", [[45, 'minus'], [50, 'two']]);
|
|
675
|
+
const result = JSON.stringify(mr);
|
|
676
|
+
if (result !== '[{"sequence":[{"tag":"minus","sequence":[[45,"minus"]]},{"sequence":[[50,"two"]]}]},true,2]') {
|
|
677
|
+
throw result;
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
],
|
|
440
681
|
repeat: [
|
|
441
682
|
() => {
|
|
442
683
|
const repeatData = [{ "": ["ws", "repa"], "ws": [], "repa": ["a", ""], "a": 1090519105 }, ""];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Sha2 } from "../crypto/sha2/module.f.ts";
|
|
2
|
+
import type { Io } from "../io/module.f.ts";
|
|
3
|
+
import { type Vec } from "../types/bit_vec/module.f.ts";
|
|
4
|
+
export type KvStore = {
|
|
5
|
+
readonly read: (key: Vec) => Promise<Vec | undefined>;
|
|
6
|
+
readonly write: (key: Vec, value: Vec) => Promise<KvStore>;
|
|
7
|
+
readonly list: () => Promise<Iterable<Vec>>;
|
|
8
|
+
};
|
|
9
|
+
export type Kv = readonly [Vec, Vec];
|
|
10
|
+
export declare const memKvStore: () => KvStore;
|
|
11
|
+
export declare const fileKvStore: (io: Io) => (path: string) => KvStore;
|
|
12
|
+
export type Cas = {
|
|
13
|
+
readonly read: (key: Vec) => Promise<Vec | undefined>;
|
|
14
|
+
readonly write: (value: Vec) => Promise<readonly [Cas, Vec]>;
|
|
15
|
+
readonly list: () => Promise<Iterable<Vec>>;
|
|
16
|
+
};
|
|
17
|
+
export declare const cas: (sha2: Sha2) => (s: KvStore) => Cas;
|
package/cas/module.f.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { computeSync } from "../crypto/sha2/module.f.js";
|
|
2
|
+
import { todo } from "../dev/module.f.js";
|
|
3
|
+
import {} from "../types/bit_vec/module.f.js";
|
|
4
|
+
import { cBase32ToVec, vecToCBase32 } from "../types/cbase32/module.f.js";
|
|
5
|
+
import { compose } from "../types/function/module.f.js";
|
|
6
|
+
import { toOption } from "../types/nullable/module.f.js";
|
|
7
|
+
import { fromVec, toVec } from "../types/uint8array/module.f.js";
|
|
8
|
+
export const memKvStore = () => {
|
|
9
|
+
const create = (...i) => {
|
|
10
|
+
const store = new Map(i);
|
|
11
|
+
return {
|
|
12
|
+
read: async (key) => store.get(key),
|
|
13
|
+
write: async (...kv) => create(...store, kv),
|
|
14
|
+
list: async () => store.keys(),
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
return create();
|
|
18
|
+
};
|
|
19
|
+
const o = { withFileTypes: true };
|
|
20
|
+
const split = (s) => [s.substring(0, 2), s.substring(2)];
|
|
21
|
+
const toPath = (key) => {
|
|
22
|
+
const s = vecToCBase32(key);
|
|
23
|
+
const [a, bc] = split(s);
|
|
24
|
+
const [b, c] = split(bc);
|
|
25
|
+
return `${a}/${b}/${c}`;
|
|
26
|
+
};
|
|
27
|
+
export const fileKvStore = (io) => (path) => {
|
|
28
|
+
const { readdir, readFile, writeFile } = io.fs.promises;
|
|
29
|
+
const { asyncTryCatch } = io;
|
|
30
|
+
const result = {
|
|
31
|
+
read: async (key) => {
|
|
32
|
+
const p = toPath(key);
|
|
33
|
+
const [s, v] = await asyncTryCatch(() => readFile(`${path}/${p}`));
|
|
34
|
+
if (s === 'error') {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return toVec(v);
|
|
38
|
+
},
|
|
39
|
+
write: async (key, value) => {
|
|
40
|
+
const p = toPath(key);
|
|
41
|
+
await writeFile(`${path}/${p}`, fromVec(value));
|
|
42
|
+
return result;
|
|
43
|
+
},
|
|
44
|
+
list: async () => {
|
|
45
|
+
const f = async (p) => {
|
|
46
|
+
const dir = await readdir(p, o);
|
|
47
|
+
let result = [];
|
|
48
|
+
for (const entry of dir) {
|
|
49
|
+
const { name } = entry;
|
|
50
|
+
if (entry.isFile()) {
|
|
51
|
+
result = [...result, name];
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
// directory
|
|
55
|
+
const sub = await f(`${p}/${name}`);
|
|
56
|
+
result = [...result, ...sub.map(x => `${name}${x}`)];
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
};
|
|
60
|
+
const all = await f(path);
|
|
61
|
+
return all.flatMap(compose(cBase32ToVec)(toOption));
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
66
|
+
export const cas = (sha2) => {
|
|
67
|
+
const compute = computeSync(sha2);
|
|
68
|
+
const f = ({ read, list, write }) => ({
|
|
69
|
+
read,
|
|
70
|
+
write: async (value) => {
|
|
71
|
+
const hash = compute([value]);
|
|
72
|
+
return [f(await write(hash, value)), hash];
|
|
73
|
+
},
|
|
74
|
+
list,
|
|
75
|
+
});
|
|
76
|
+
return f;
|
|
77
|
+
};
|
package/cas/test.f.d.ts
ADDED
package/cas/test.f.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default () => { };
|
package/ci/module.f.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encodeUtf8 } from "../types/uint8array/module.f.js";
|
|
1
2
|
const os = ['ubuntu', 'macos', 'windows'];
|
|
2
3
|
const architecture = ['intel', 'arm'];
|
|
3
4
|
// https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories
|
|
@@ -73,7 +74,7 @@ const toSteps = (m) => {
|
|
|
73
74
|
...(rust ? [{
|
|
74
75
|
// wasm32-wasip1-threads doesn't work on Rust 1.91 in the release mode.
|
|
75
76
|
// See https://github.com/sergey-shandar/wasmtime-crash
|
|
76
|
-
uses: 'dtolnay/rust-toolchain@1.
|
|
77
|
+
uses: 'dtolnay/rust-toolchain@1.92.0',
|
|
77
78
|
with: {
|
|
78
79
|
components: 'rustfmt,clippy',
|
|
79
80
|
targets
|
|
@@ -128,8 +129,8 @@ const steps = (v) => (a) => {
|
|
|
128
129
|
// publishing
|
|
129
130
|
test({ run: 'npm pack' }),
|
|
130
131
|
test({ run: `npm install -g ${findTgz(v)}` }),
|
|
131
|
-
test({ run: '
|
|
132
|
-
test({ run: '
|
|
132
|
+
test({ run: 'fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
133
|
+
test({ run: 'fjs t' }),
|
|
133
134
|
test({ run: 'npm uninstall functionalscript -g' }),
|
|
134
135
|
]),
|
|
135
136
|
// Deno
|
|
@@ -137,14 +138,15 @@ const steps = (v) => (a) => {
|
|
|
137
138
|
installDeno(v)(a),
|
|
138
139
|
test({ run: 'deno install' }),
|
|
139
140
|
test({ run: 'deno task test' }),
|
|
140
|
-
test({ run: 'deno task
|
|
141
|
+
test({ run: 'deno task fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
142
|
+
test({ run: 'deno task fjs t' }),
|
|
141
143
|
test({ run: 'deno publish --dry-run' }),
|
|
142
144
|
]),
|
|
143
145
|
// Bun
|
|
144
146
|
...clean([
|
|
145
147
|
installBun(v)(a),
|
|
146
148
|
test({ run: 'bun test --timeout 20000' }),
|
|
147
|
-
test({ run: 'bun ./
|
|
149
|
+
test({ run: 'bun ./fjs/module.ts t' }),
|
|
148
150
|
]),
|
|
149
151
|
];
|
|
150
152
|
return toSteps(result);
|
|
@@ -164,6 +166,6 @@ const gha = {
|
|
|
164
166
|
jobs,
|
|
165
167
|
};
|
|
166
168
|
export default async (io) => {
|
|
167
|
-
io.fs.writeFileSync('.github/workflows/ci.yml', JSON.stringify(gha, null, ' '));
|
|
169
|
+
io.fs.writeFileSync('.github/workflows/ci.yml', encodeUtf8(JSON.stringify(gha, null, ' ')));
|
|
168
170
|
return 0;
|
|
169
171
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Equal, Fold, Reduce } from '../../types/function/operator/module.f.ts';
|
|
2
|
-
import { type PrimeField } from '
|
|
2
|
+
import { type PrimeField } from '../../types/prime_field/module.f.ts';
|
|
3
3
|
/**
|
|
4
4
|
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
|
5
5
|
*/
|
|
@@ -24,6 +24,7 @@ export type Init = {
|
|
|
24
24
|
export type Curve = {
|
|
25
25
|
readonly pf: PrimeField;
|
|
26
26
|
readonly nf: PrimeField;
|
|
27
|
+
readonly g: Point;
|
|
27
28
|
readonly y2: (x: bigint) => bigint;
|
|
28
29
|
readonly y: (x: bigint) => bigint | null;
|
|
29
30
|
readonly neg: (a: Point) => Point;
|
|
@@ -50,27 +51,29 @@ export type Curve = {
|
|
|
50
51
|
* const mulPoint = curveInstance.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
51
52
|
* ```
|
|
52
53
|
*/
|
|
53
|
-
export declare const curve: ({ p, a: [a0, a1], n }: Init) => Curve;
|
|
54
|
+
export declare const curve: ({ p, a: [a0, a1], n, g }: Init) => Curve;
|
|
54
55
|
export declare const eq: Equal<Point>;
|
|
55
56
|
/**
|
|
56
57
|
* https://neuromancer.sk/std/secg/secp192r1
|
|
58
|
+
* NIST P-192
|
|
57
59
|
*/
|
|
58
|
-
export declare const secp192r1:
|
|
60
|
+
export declare const secp192r1: Curve;
|
|
59
61
|
/**
|
|
60
62
|
* https://en.bitcoin.it/wiki/Secp256k1
|
|
61
63
|
* https://neuromancer.sk/std/secg/secp256k1
|
|
62
64
|
*/
|
|
63
|
-
export declare const secp256k1:
|
|
65
|
+
export declare const secp256k1: Curve;
|
|
64
66
|
/**
|
|
65
67
|
* https://neuromancer.sk/std/secg/secp256r1
|
|
68
|
+
* NIST P-256
|
|
66
69
|
*/
|
|
67
|
-
export declare const secp256r1:
|
|
70
|
+
export declare const secp256r1: Curve;
|
|
68
71
|
/**
|
|
69
72
|
* https://neuromancer.sk/std/secg/secp384r1
|
|
70
73
|
*/
|
|
71
|
-
export declare const secp384r1:
|
|
74
|
+
export declare const secp384r1: Curve;
|
|
72
75
|
/**
|
|
73
76
|
* https://neuromancer.sk/std/secg/secp521r1
|
|
74
77
|
*/
|
|
75
|
-
export declare const secp521r1:
|
|
78
|
+
export declare const secp521r1: Curve;
|
|
76
79
|
export {};
|