functionalscript 0.6.9 → 0.6.11
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 +2 -2
- package/bnf/data/module.f.d.ts +3 -1
- package/bnf/data/module.f.js +4 -2
- package/bnf/data/test.f.d.ts +3 -1
- package/bnf/data/test.f.js +71 -3
- package/bnf/module.f.d.ts +8 -0
- package/bnf/module.f.js +1 -1
- package/bnf/testlib.f.js +1 -0
- package/crypto/hmac/module.f.js +9 -4
- package/crypto/sha2/module.f.d.ts +1 -1
- package/crypto/sign/module.f.d.ts +5 -0
- package/crypto/sign/module.f.js +53 -0
- package/crypto/sign/test.f.d.ts +2 -0
- package/crypto/sign/test.f.js +1 -0
- package/deno/module.d.ts +8 -0
- package/deno/module.js +53 -0
- package/deno/test.d.ts +1 -0
- package/deno/test.js +2 -0
- package/dev/module.f.d.ts +1 -1
- package/dev/module.f.js +7 -4
- package/dev/test/module.f.d.ts +3 -1
- package/dev/test/module.f.js +12 -12
- package/djs/module.f.js +2 -1
- package/djs/parser/module.f.d.ts +7 -2
- package/djs/parser/module.f.js +80 -52
- package/djs/parser/test.f.d.ts +1 -0
- package/djs/parser/test.f.js +104 -76
- package/djs/tokenizer/module.f.d.ts +6 -2
- package/djs/tokenizer/module.f.js +12 -7
- package/djs/tokenizer/test.f.d.ts +1 -0
- package/djs/tokenizer/test.f.js +103 -87
- package/djs/transpiler/module.f.d.ts +3 -2
- package/djs/transpiler/module.f.js +3 -3
- package/djs/transpiler/test.f.js +2 -2
- package/io/module.f.d.ts +7 -0
- package/io/module.js +5 -1
- package/io/virtual/module.f.js +3 -0
- package/issues/31-json.f.d.ts +1 -1
- package/issues/31-json.f.js +1 -1
- package/issues/demo/data/data.f.js +12 -0
- package/issues/demo/data/shared.f.js +3 -0
- package/issues/demo/fs/app.js +4 -0
- package/issues/demo/fs/math.f.js +4 -0
- package/issues/demo/test/test.f.js +13 -0
- package/js/tokenizer/module.f.d.ts +14 -2
- package/js/tokenizer/module.f.js +30 -17
- package/js/tokenizer/test.f.d.ts +1 -0
- package/js/tokenizer/test.f.js +159 -149
- package/json/parser/module.f.js +18 -9
- package/json/parser/test.f.js +16 -16
- package/json/tokenizer/module.f.d.ts +1 -1
- package/json/tokenizer/module.f.js +7 -6
- package/json/tokenizer/test.f.js +68 -68
- package/package.json +10 -11
- package/text/sgr/module.f.d.ts +5 -0
- package/text/sgr/module.f.js +10 -1
- package/types/bit_vec/module.f.d.ts +1 -0
- package/types/bit_vec/module.f.js +1 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ FunctionalScript is a safe, purely functional programming language and a strict
|
|
|
8
8
|
|
|
9
9
|
- [JSON](https://en.wikipedia.org/wiki/JSON) and [JSON5](https://json5.org/) as subsets of JavaScript.
|
|
10
10
|
JSON is also a subset of FunctionalScript.
|
|
11
|
-
- [asm.JS](https://en.wikipedia.org/wiki/Asm.js)
|
|
11
|
+
- [asm.JS](https://en.wikipedia.org/wiki/Asm.js) (a precursor of [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly)),
|
|
12
12
|
as a subset of JavaScript.
|
|
13
13
|
- [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
|
|
14
14
|
|
|
@@ -19,7 +19,7 @@ Learn more about
|
|
|
19
19
|
- [Purely Functional Programming in JavaScript](https://blog.bitsrc.io/purely-functional-programming-in-javascript-91114b1b2dff?sk=5f7132e56902f38fcf4c6164bfa681ed),
|
|
20
20
|
- [FunctionalScript and I/O](https://medium.com/@sergeyshandar/functionalscript-5cf817345376?sk=30b32189a81d1a2dad16c2244f32328d).
|
|
21
21
|
|
|
22
|
-
This repository is a [monorepo](https://en.wikipedia.org/wiki/Monorepo) and
|
|
22
|
+
This repository is a [monorepo](https://en.wikipedia.org/wiki/Monorepo) and distributed under [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.en.html#license-text). Let us know if you need another license by sending an [email](mailto:sergey.oss@proton.me).
|
|
23
23
|
|
|
24
24
|
## Getting Started
|
|
25
25
|
|
package/bnf/data/module.f.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Rule as FRule } from '../module.f.ts';
|
|
2
2
|
export type TerminalRange = number;
|
|
3
3
|
export type Sequence = readonly string[];
|
|
4
|
+
/** A variant of rule names. */
|
|
4
5
|
export type Variant = {
|
|
5
6
|
readonly [k in string]: string;
|
|
6
7
|
};
|
|
7
8
|
export type Rule = Variant | Sequence | TerminalRange;
|
|
9
|
+
/** The full grammar */
|
|
8
10
|
export type RuleSet = Readonly<Record<string, Rule>>;
|
|
9
11
|
export declare const toData: (fr: FRule) => readonly [RuleSet, string];
|
|
10
12
|
/**
|
package/bnf/data/module.f.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { stringToCodePointList } from "../../text/utf16/module.f.js";
|
|
2
|
-
import { toArray } from "../../types/list/module.f.js";
|
|
2
|
+
import { map, toArray } from "../../types/list/module.f.js";
|
|
3
|
+
import { oneEncode, } from "../module.f.js";
|
|
3
4
|
const { entries } = Object;
|
|
4
5
|
const find = (map) => (fr) => {
|
|
5
6
|
for (const [k, v] of entries(map)) {
|
|
@@ -40,10 +41,11 @@ const variant = (fr) => map => {
|
|
|
40
41
|
}
|
|
41
42
|
return [map, set, rule];
|
|
42
43
|
};
|
|
44
|
+
const mapOneEncode = map(oneEncode);
|
|
43
45
|
const data = (dr) => {
|
|
44
46
|
switch (typeof dr) {
|
|
45
47
|
case 'string': {
|
|
46
|
-
return sequence(toArray(stringToCodePointList(dr)));
|
|
48
|
+
return sequence(toArray(mapOneEncode(stringToCodePointList(dr))));
|
|
47
49
|
}
|
|
48
50
|
case 'number':
|
|
49
51
|
return m => [m, {}, dr];
|
package/bnf/data/test.f.d.ts
CHANGED
package/bnf/data/test.f.js
CHANGED
|
@@ -1,8 +1,76 @@
|
|
|
1
|
+
import { stringify } from "../../json/module.f.js";
|
|
2
|
+
import { sort } from "../../types/object/module.f.js";
|
|
3
|
+
import { range } from "../module.f.js";
|
|
1
4
|
import { classic, deterministic } from "../testlib.f.js";
|
|
2
5
|
import { toData } from "./module.f.js";
|
|
3
6
|
export default {
|
|
4
|
-
toData:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
toData: [
|
|
8
|
+
() => {
|
|
9
|
+
const c = toData(classic());
|
|
10
|
+
const d = toData(deterministic());
|
|
11
|
+
},
|
|
12
|
+
() => {
|
|
13
|
+
const stringRule = 'true';
|
|
14
|
+
const result = stringify(sort)(toData(stringRule));
|
|
15
|
+
if (result != '[{"":["0","1","2","3"],"0":1946157172,"1":1912602738,"2":1962934389,"3":1694498917},""]') {
|
|
16
|
+
throw result;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
() => {
|
|
20
|
+
const terminalRangeRule = range('AF');
|
|
21
|
+
const result = stringify(sort)(toData(terminalRangeRule));
|
|
22
|
+
if (result != '[{"":1090519110},""]') {
|
|
23
|
+
throw result;
|
|
24
|
+
} //1090519110 = 65 * 2^24 + 70
|
|
25
|
+
},
|
|
26
|
+
() => {
|
|
27
|
+
const sequenceRangeRule = [range('AF'), range('af')];
|
|
28
|
+
const result = stringify(sort)(toData(sequenceRangeRule));
|
|
29
|
+
if (result != '[{"":["0","1"],"0":1090519110,"1":1627390054},""]') {
|
|
30
|
+
throw result;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
() => {
|
|
34
|
+
const lazyRule = () => 'true';
|
|
35
|
+
const result = stringify(sort)(toData(lazyRule));
|
|
36
|
+
if (result != '[{"":1946157172,"0":1912602738,"1":1962934389,"2":1694498917,"lazyRule":["","0","1","2"]},"lazyRule"]') {
|
|
37
|
+
throw result;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
() => {
|
|
41
|
+
const varintRule = { true: 'true', false: 'false' };
|
|
42
|
+
const result = stringify(sort)(toData(varintRule));
|
|
43
|
+
const expected = '[{"":{"false":"5","true":"0"},"0":["1","2","3","4"],"1":1946157172,"2":1912602738,"3":1962934389,"4":1694498917,"5":["6","7","8","9","4"],"6":1711276134,"7":1627390049,"8":1811939436,"9":1929379955},""]';
|
|
44
|
+
if (result != expected) {
|
|
45
|
+
throw [result, expected];
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
() => {
|
|
49
|
+
const lazyRule = () => 'true';
|
|
50
|
+
const lazyRule0 = () => 'false';
|
|
51
|
+
const result = stringify(sort)(toData([lazyRule, lazyRule0]));
|
|
52
|
+
const expected = '[{"":["lazyRule","lazyRule0"],"0":1946157172,"1":1912602738,"2":1962934389,"3":1694498917,"4":1711276134,"5":1627390049,"6":1811939436,"7":1929379955,"lazyRule":["0","1","2","3"],"lazyRule0":["4","5","6","7","3"]},""]';
|
|
53
|
+
if (result != expected) {
|
|
54
|
+
throw [result, expected];
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
variantTest: () => {
|
|
59
|
+
const varintRule = { a: 'a', b: 'b' };
|
|
60
|
+
const result = stringify(sort)(toData(varintRule));
|
|
61
|
+
if (result != '[{"":{"a":"0","b":"2"},"0":["1"],"1":1627390049,"2":["3"],"3":1644167266},""]') {
|
|
62
|
+
throw result;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
example: () => {
|
|
66
|
+
const grammar = {
|
|
67
|
+
space: 0x000020_000020,
|
|
68
|
+
digit: 0x000030_000039,
|
|
69
|
+
sequence: ['space', 'digit'],
|
|
70
|
+
spaceOrDigit: {
|
|
71
|
+
'whiteSpace': 'space',
|
|
72
|
+
'digit': 'digit',
|
|
73
|
+
}
|
|
74
|
+
};
|
|
7
75
|
}
|
|
8
76
|
};
|
package/bnf/module.f.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { type Array2 } from '../types/array/module.f.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A range of symbols (48 bits)
|
|
4
|
+
* For example: 0xBBBBBB_EEEEEE
|
|
5
|
+
* - 0xBBBBBB is the first symbol
|
|
6
|
+
* - 0xEEEEEE is the last symbol
|
|
7
|
+
*/
|
|
2
8
|
export type TerminalRange = number;
|
|
9
|
+
/** A sequence of rules. */
|
|
3
10
|
export type Sequence = readonly Rule[];
|
|
11
|
+
/** A variant */
|
|
4
12
|
export type Variant = {
|
|
5
13
|
readonly [k in string]: Rule;
|
|
6
14
|
};
|
package/bnf/module.f.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { codePointListToString, stringToCodePointList } from "../text/utf16/module.f.js";
|
|
2
2
|
import { isArray2 } from "../types/array/module.f.js";
|
|
3
3
|
import { map, toArray, repeat as listRepeat } from "../types/list/module.f.js";
|
|
4
|
-
//
|
|
4
|
+
// Internals:
|
|
5
5
|
const { fromEntries, values } = Object;
|
|
6
6
|
const { fromCodePoint } = String;
|
|
7
7
|
/**
|
package/bnf/testlib.f.js
CHANGED
package/crypto/hmac/module.f.js
CHANGED
|
@@ -48,13 +48,18 @@ export const hmac = (sha2) => {
|
|
|
48
48
|
const op = p(oPad);
|
|
49
49
|
const c = computeSync(sha2);
|
|
50
50
|
const vbl = vec(blockLength);
|
|
51
|
+
// a and b should have the same size
|
|
51
52
|
const xor = (a) => (b) => vbl(a ^ b);
|
|
52
|
-
return k =>
|
|
53
|
+
return k => {
|
|
53
54
|
const k1 = length(k) > blockLength ? c([k]) : k;
|
|
54
55
|
const k2 = concat(k1)(vec(blockLength - length(k1))(0n));
|
|
55
56
|
const xk2 = xor(k2);
|
|
56
|
-
const f = (p
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const f = (p) => {
|
|
58
|
+
const x = xk2(p);
|
|
59
|
+
return (msg) => c([x, msg]);
|
|
60
|
+
};
|
|
61
|
+
const fip = f(ip);
|
|
62
|
+
const fop = f(op);
|
|
63
|
+
return m => fop(fip(m));
|
|
59
64
|
};
|
|
60
65
|
};
|
|
@@ -37,7 +37,7 @@ export type Base = {
|
|
|
37
37
|
* const s = msbUtf8("The quick brown fox jumps over the lazy dog.")
|
|
38
38
|
* let state = sha224.init
|
|
39
39
|
* state = sha224.append(state)(s)
|
|
40
|
-
* const h = sha224.end(state) //
|
|
40
|
+
* const h = sha224.end(state) // 0x1_619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4cn
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
43
|
export type Sha2 = {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Vec } from '../../types/bit_vec/module.f.ts';
|
|
2
|
+
import { type Init } from '../secp/module.f.ts';
|
|
3
|
+
import type { Sha2 } from '../sha2/module.f.ts';
|
|
4
|
+
export declare const newPrivateKey: (i: Init) => (random: Vec) => Vec;
|
|
5
|
+
export declare const sign: (sha2: Sha2) => (curveInit: Init) => (privateKey: Vec) => (messageHash: Vec) => readonly [bigint, bigint];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { listToVec, msb, uint, vec, vec8, length } from "../../types/bit_vec/module.f.js";
|
|
2
|
+
import { hmac } from "../hmac/module.f.js";
|
|
3
|
+
import { curve } from "../secp/module.f.js";
|
|
4
|
+
const concat = listToVec(msb);
|
|
5
|
+
const v00 = vec8(0x00n);
|
|
6
|
+
const v01 = vec8(0x01n);
|
|
7
|
+
/**
|
|
8
|
+
* The size of the result equals the size of the hash.
|
|
9
|
+
*
|
|
10
|
+
* @param sha2 SHA2 hash function
|
|
11
|
+
* @returns A function that accepts a private key, a message hash and returns `k`.
|
|
12
|
+
*/
|
|
13
|
+
const createK = (sha2) => {
|
|
14
|
+
const h = hmac(sha2);
|
|
15
|
+
let vs = vec(sha2.hashLength);
|
|
16
|
+
let k0 = vs(0x00n);
|
|
17
|
+
let v0 = vs(0x01n);
|
|
18
|
+
return (privateKey) => (messageHash) => {
|
|
19
|
+
const pm = concat([privateKey, messageHash]);
|
|
20
|
+
let k = k0;
|
|
21
|
+
let v = v0;
|
|
22
|
+
k = h(k)(concat([v, v00, pm]));
|
|
23
|
+
v = h(k)(v);
|
|
24
|
+
k = h(k)(concat([v, v01, pm]));
|
|
25
|
+
v = h(k)(v);
|
|
26
|
+
return uint(h(k)(v));
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export const newPrivateKey = (i) => (random) => {
|
|
30
|
+
const { nf } = curve(i);
|
|
31
|
+
if (length(nf.max) < length(random)) {
|
|
32
|
+
throw "need more random bits";
|
|
33
|
+
}
|
|
34
|
+
return uint(random) % nf.p;
|
|
35
|
+
};
|
|
36
|
+
export const sign = (sha2) => (curveInit) => (privateKey) => (messageHash) => {
|
|
37
|
+
const { mul, pf } = curve(curveInit);
|
|
38
|
+
// const curveVec = vec(length(pf.max))
|
|
39
|
+
//`k` is a unique for each `z` and secret.
|
|
40
|
+
const k = createK(sha2)(privateKey)(messageHash) % pf.p;
|
|
41
|
+
// `R = G * k`.
|
|
42
|
+
const rp = mul(curveInit.g)(k);
|
|
43
|
+
// `r = R.x`
|
|
44
|
+
const r = rp === null ? 0n : rp[0];
|
|
45
|
+
// `s = ((z + r * d) / k)`.
|
|
46
|
+
const d = uint(privateKey);
|
|
47
|
+
const z = uint(messageHash);
|
|
48
|
+
const rd = pf.mul(r)(d);
|
|
49
|
+
const zrd = pf.add(z)(rd);
|
|
50
|
+
const kn1 = pf.reciprocal(k);
|
|
51
|
+
const s = pf.mul(zrd)(kn1);
|
|
52
|
+
return [r, s];
|
|
53
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
package/deno/module.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type DenoTestStep = {
|
|
2
|
+
readonly step: (name: string, f: () => void | Promise<void>) => Promise<void>;
|
|
3
|
+
};
|
|
4
|
+
type DenoFunc = (t: DenoTestStep) => void | Promise<void>;
|
|
5
|
+
type DenoArg = readonly [string, DenoFunc];
|
|
6
|
+
export type DenoTest = (...arg: DenoArg) => void;
|
|
7
|
+
declare const _default: () => Promise<void>;
|
|
8
|
+
export default _default;
|
package/deno/module.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { io } from "../io/module.js";
|
|
2
|
+
import { loadModuleMap } from "../dev/module.f.js";
|
|
3
|
+
import { isTest } from "../dev/test/module.f.js";
|
|
4
|
+
const denoTest = (x) => async (t) => {
|
|
5
|
+
let subTests = [x];
|
|
6
|
+
while (true) {
|
|
7
|
+
const [first, ...rest] = subTests;
|
|
8
|
+
if (first === undefined) {
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
subTests = rest;
|
|
12
|
+
//
|
|
13
|
+
const [name, value] = first;
|
|
14
|
+
if (value === null) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
switch (typeof value) {
|
|
18
|
+
case "function": {
|
|
19
|
+
if (value.length === 0) {
|
|
20
|
+
const g = value.name === 'throw'
|
|
21
|
+
? () => {
|
|
22
|
+
try {
|
|
23
|
+
value();
|
|
24
|
+
throw new Error(`Expected ${name} to throw, but it did not.`);
|
|
25
|
+
}
|
|
26
|
+
catch { }
|
|
27
|
+
}
|
|
28
|
+
: () => {
|
|
29
|
+
const r = value();
|
|
30
|
+
subTests = [...subTests, [`${name}()`, r]];
|
|
31
|
+
};
|
|
32
|
+
await t.step(name, g);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case "object": {
|
|
37
|
+
for (const [j, y] of Object.entries(value)) {
|
|
38
|
+
const pr = `${name}/${j}`;
|
|
39
|
+
subTests = [...subTests, [pr, y]];
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export default async () => {
|
|
47
|
+
const x = await loadModuleMap(io);
|
|
48
|
+
for (const [i, v] of Object.entries(x)) {
|
|
49
|
+
if (isTest(i)) {
|
|
50
|
+
Deno.test(i, denoTest(['', v.default]));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
package/deno/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/deno/test.js
ADDED
package/dev/module.f.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ export type ModuleMap = {
|
|
|
7
7
|
readonly [k in string]: Module;
|
|
8
8
|
};
|
|
9
9
|
export declare const env: (io: Io) => (v: string) => string | undefined;
|
|
10
|
-
export declare const allFiles: (
|
|
10
|
+
export declare const allFiles: (io: Io) => (s: string) => Promise<readonly string[]>;
|
|
11
11
|
export declare const loadModuleMap: (io: Io) => Promise<ModuleMap>;
|
|
12
12
|
export declare const index: (io: Io) => Promise<number>;
|
package/dev/module.f.js
CHANGED
|
@@ -7,7 +7,8 @@ export const env = ({ process: { env } }) => a => {
|
|
|
7
7
|
typeof r.get === 'function' ? r.get() :
|
|
8
8
|
r.value;
|
|
9
9
|
};
|
|
10
|
-
export const allFiles = (
|
|
10
|
+
export const allFiles = (io) => (s) => {
|
|
11
|
+
const { fs: { promises: { readdir } }, process: { cwd } } = io;
|
|
11
12
|
const load = async (p) => {
|
|
12
13
|
let result = [];
|
|
13
14
|
for (const i of await readdir(p, { withFileTypes: true })) {
|
|
@@ -29,12 +30,14 @@ export const allFiles = ({ fs: { promises: { readdir } } }) => {
|
|
|
29
30
|
}
|
|
30
31
|
return result;
|
|
31
32
|
};
|
|
32
|
-
return load(
|
|
33
|
+
return load(s);
|
|
33
34
|
};
|
|
34
35
|
export const loadModuleMap = async (io) => {
|
|
35
36
|
const { fs: { existsSync }, asyncImport } = io;
|
|
36
37
|
let map = [];
|
|
37
|
-
|
|
38
|
+
const initCwd = env(io)('INIT_CWD');
|
|
39
|
+
const s = initCwd === undefined ? '.' : `${initCwd.replaceAll('\\', '/')}`;
|
|
40
|
+
for (const f of await allFiles(io)(s)) {
|
|
38
41
|
if (f.endsWith('.f.js') ||
|
|
39
42
|
(f.endsWith('.f.ts') && !existsSync(f.substring(0, f.length - 3) + '.js'))) {
|
|
40
43
|
const source = await asyncImport(f);
|
|
@@ -47,7 +50,7 @@ export const index = async (io) => {
|
|
|
47
50
|
updateVersion(io);
|
|
48
51
|
const jj = './deno.json';
|
|
49
52
|
const jsr_json = JSON.parse(await io.fs.promises.readFile(jj, 'utf8'));
|
|
50
|
-
const list = (await allFiles(io)).filter(v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'));
|
|
53
|
+
const list = (await allFiles(io)('.')).filter(v => v.endsWith('/module.f.ts') || v.endsWith('/module.ts'));
|
|
51
54
|
//console.log(list)
|
|
52
55
|
const exportsA = list.map(v => [v, `./${v.substring(2)}`]);
|
|
53
56
|
// console.log(exportsA)
|
package/dev/test/module.f.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type CsiConsole } from '../../text/sgr/module.f.ts';
|
|
1
2
|
import type * as Result from '../../types/result/module.f.ts';
|
|
2
3
|
import type { Io, Performance } from '../../io/module.f.ts';
|
|
3
4
|
import { type ModuleMap } from '../module.f.ts';
|
|
4
|
-
type Log<T> =
|
|
5
|
+
type Log<T> = CsiConsole;
|
|
5
6
|
type Measure<T> = <R>(f: () => R) => (state: T) => readonly [R, number, T];
|
|
6
7
|
type Input<T> = {
|
|
7
8
|
readonly moduleMap: ModuleMap;
|
|
@@ -12,6 +13,7 @@ type Input<T> = {
|
|
|
12
13
|
readonly tryCatch: <R>(f: () => R) => Result.Result<R, unknown>;
|
|
13
14
|
readonly env: (n: string) => string | undefined;
|
|
14
15
|
};
|
|
16
|
+
export declare const isTest: (s: string) => boolean;
|
|
15
17
|
export declare const test: <T>(input: Input<T>) => readonly [number, T];
|
|
16
18
|
export declare const anyLog: (f: (s: string) => void) => (s: string) => <T>(state: T) => T;
|
|
17
19
|
export declare const measure: (p: Performance) => <R>(f: () => R) => <T>(state: T) => readonly [R, number, T];
|
package/dev/test/module.f.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { entries, fold } from "../../types/list/module.f.js";
|
|
2
|
-
import { reset, fgGreen, fgRed, bold } from "../../text/sgr/module.f.js";
|
|
2
|
+
import { reset, fgGreen, fgRed, bold, stdio, stderr } from "../../text/sgr/module.f.js";
|
|
3
3
|
import { env, loadModuleMap } from "../module.f.js";
|
|
4
|
-
const isTest = (s) => s.endsWith('test.f.js') || s.endsWith('test.f.ts');
|
|
4
|
+
export const isTest = (s) => s.endsWith('test.f.js') || s.endsWith('test.f.ts');
|
|
5
5
|
const addPass = (delta) => (ts) => ({ ...ts, time: ts.time + delta, pass: ts.pass + 1 });
|
|
6
6
|
const addFail = (delta) => (ts) => ({ ...ts, time: ts.time + delta, fail: ts.fail + 1 });
|
|
7
7
|
const timeFormat = (a) => {
|
|
@@ -30,16 +30,16 @@ export const test = (input) => {
|
|
|
30
30
|
if (isGitHub) {
|
|
31
31
|
// https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions
|
|
32
32
|
// https://github.com/OndraM/ci-detector/blob/main/src/Ci/GitHubActions.php
|
|
33
|
-
|
|
33
|
+
error(`::error file=${k},line=1,title=[3]['a']()::${r}`);
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
error(`${i}() ${fgRed}error${reset}, ${timeFormat(delta)}`);
|
|
37
|
+
error(`${fgRed}${r}${reset}`);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
41
|
ts = addPass(delta)(ts);
|
|
42
|
-
|
|
42
|
+
log(`${i}() ${fgGreen}ok${reset}, ${timeFormat(delta)}`);
|
|
43
43
|
}
|
|
44
44
|
[ts, state] = next(r)([ts, state]);
|
|
45
45
|
}
|
|
@@ -48,7 +48,7 @@ export const test = (input) => {
|
|
|
48
48
|
case 'object': {
|
|
49
49
|
if (v !== null) {
|
|
50
50
|
const f = ([k, v]) => ([time, state]) => {
|
|
51
|
-
|
|
51
|
+
log(`${i}${k}:`);
|
|
52
52
|
[time, state] = next(v)([time, state]);
|
|
53
53
|
return [time, state];
|
|
54
54
|
};
|
|
@@ -61,7 +61,7 @@ export const test = (input) => {
|
|
|
61
61
|
};
|
|
62
62
|
return ([ts, state]) => {
|
|
63
63
|
if (isTest(k)) {
|
|
64
|
-
|
|
64
|
+
log(`testing ${k}`);
|
|
65
65
|
[ts, state] = test('| ')(v.default)([ts, state]);
|
|
66
66
|
}
|
|
67
67
|
return [ts, state];
|
|
@@ -70,8 +70,8 @@ export const test = (input) => {
|
|
|
70
70
|
let ts = { time: 0, pass: 0, fail: 0 };
|
|
71
71
|
[ts, state] = fold(f)([ts, state])(Object.entries(moduleMap));
|
|
72
72
|
const fgFail = ts.fail === 0 ? fgGreen : fgRed;
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
log(`${bold}Number of tests: pass: ${fgGreen}${ts.pass}${reset}${bold}, fail: ${fgFail}${ts.fail}${reset}${bold}, total: ${ts.pass + ts.fail}${reset}`);
|
|
74
|
+
log(`${bold}Time: ${timeFormat(ts.time)}${reset}`);
|
|
75
75
|
return [ts.fail !== 0 ? 1 : 0, state];
|
|
76
76
|
};
|
|
77
77
|
export const anyLog = (f) => (s) => (state) => {
|
|
@@ -86,8 +86,8 @@ export const measure = (p) => (f) => (state) => {
|
|
|
86
86
|
};
|
|
87
87
|
export const main = async (io) => test({
|
|
88
88
|
moduleMap: await loadModuleMap(io),
|
|
89
|
-
log: anyLog(io.console.log),
|
|
90
|
-
error: anyLog(io.console.error),
|
|
89
|
+
log: stdio(io), // anyLog(io.console.log),
|
|
90
|
+
error: stderr(io), // anyLog(io.console.error),
|
|
91
91
|
measure: measure(io.performance),
|
|
92
92
|
tryCatch: io.tryCatch,
|
|
93
93
|
env: env(io),
|
package/djs/module.f.js
CHANGED
|
@@ -22,7 +22,8 @@ export const compile = ({ console: { error }, fs, process: { argv } }) => {
|
|
|
22
22
|
break;
|
|
23
23
|
}
|
|
24
24
|
case 'error': {
|
|
25
|
-
|
|
25
|
+
const metadata = result[1].metadata;
|
|
26
|
+
error(`${metadata?.path}:${metadata?.line}:${metadata?.column} - error: ${result[1].message}`);
|
|
26
27
|
break;
|
|
27
28
|
}
|
|
28
29
|
}
|
package/djs/parser/module.f.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import * as result from '../../types/result/module.f.ts';
|
|
2
2
|
import { type List } from '../../types/list/module.f.ts';
|
|
3
|
-
import type {
|
|
3
|
+
import type { DjsTokenWithMetadata } from '../tokenizer/module.f.ts';
|
|
4
4
|
import { type OrderedMap } from '../../types/ordered_map/module.f.ts';
|
|
5
5
|
import type { Fs } from '../../io/module.f.ts';
|
|
6
6
|
import type { AstModule } from '../ast/module.f.ts';
|
|
7
|
+
import type { TokenMetadata } from '../../js/tokenizer/module.f.ts';
|
|
7
8
|
export type ParseContext = {
|
|
8
9
|
readonly fs: Fs;
|
|
9
10
|
readonly complete: OrderedMap<result.Result<AstModule, string>>;
|
|
10
11
|
readonly stack: List<string>;
|
|
11
12
|
};
|
|
12
|
-
export
|
|
13
|
+
export type ParseError = {
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly metadata: TokenMetadata | null;
|
|
16
|
+
};
|
|
17
|
+
export declare const parseFromTokens: (tokenList: List<DjsTokenWithMetadata>) => result.Result<AstModule, ParseError>;
|