functionalscript 0.45.0 → 0.46.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 +5 -3
- package/fjs/asn.1/module.f.mjs +8 -1
- package/fjs/asn.1/proof.f.d.mts +10 -0
- package/fjs/asn.1/proof.f.mjs +16 -0
- package/fjs/basen/base128/module.f.mjs +22 -5
- package/fjs/bnf/data/module.f.d.mts +32 -6
- package/fjs/bnf/data/module.f.mjs +112 -7
- package/fjs/bnf/data/proof.f.d.mts +2 -0
- package/fjs/bnf/data/proof.f.mjs +74 -3
- package/fjs/bnf/data/types.d.ts +20 -2
- package/fjs/bnf/descent/module.f.d.mts +28 -14
- package/fjs/bnf/descent/module.f.mjs +122 -77
- package/fjs/bnf/descent/proof.f.d.mts +2 -0
- package/fjs/bnf/descent/proof.f.mjs +117 -31
- package/fjs/bnf/descent/types.d.ts +12 -14
- package/fjs/bnf/ll1/module.f.d.mts +64 -22
- package/fjs/bnf/ll1/module.f.mjs +214 -154
- package/fjs/bnf/ll1/proof.f.d.mts +15 -2
- package/fjs/bnf/ll1/proof.f.mjs +323 -149
- package/fjs/bnf/ll1/types.d.ts +16 -24
- package/fjs/bnf/matcher/module.f.d.mts +66 -0
- package/fjs/bnf/matcher/module.f.mjs +81 -0
- package/fjs/bnf/matcher/proof.f.d.mts +10 -0
- package/fjs/bnf/matcher/proof.f.mjs +79 -0
- package/fjs/bnf/matcher/types.d.ts +54 -0
- package/fjs/bnf/testlib.f.d.mts +31 -0
- package/fjs/bnf/testlib.f.mjs +80 -0
- package/fjs/cas/cli/module.f.d.mts +1 -1
- package/fjs/cas/cli/module.f.mjs +14 -20
- package/fjs/cas/cli/proof.f.d.mts +1 -3
- package/fjs/cas/cli/proof.f.mjs +44 -33
- package/fjs/cas/evo/module.f.d.mts +64 -18
- package/fjs/cas/evo/module.f.mjs +148 -70
- package/fjs/cas/evo/proof.f.d.mts +10 -1
- package/fjs/cas/evo/proof.f.mjs +305 -223
- package/fjs/cas/evo/types.d.ts +45 -9
- package/fjs/cas/module.f.d.mts +18 -32
- package/fjs/cas/module.f.mjs +129 -128
- package/fjs/cas/proof.f.d.mts +11 -8
- package/fjs/cas/proof.f.mjs +259 -147
- package/fjs/cas/types.d.ts +24 -10
- package/fjs/ci/config/module.f.d.mts +2 -2
- package/fjs/ci/config/module.f.mjs +2 -2
- package/fjs/ci/module.f.d.mts +5 -5
- package/fjs/ci/module.f.mjs +8 -7
- package/fjs/ci/nix/module.f.d.mts +7 -5
- package/fjs/ci/nix/module.f.mjs +13 -12
- package/fjs/ci/nix/proof.f.mjs +2 -2
- package/fjs/ci/proof.f.mjs +9 -5
- package/fjs/cli/module.f.d.mts +4 -6
- package/fjs/cli/module.f.mjs +4 -8
- package/fjs/cli/proof.f.mjs +17 -16
- package/fjs/cli/types.d.ts +2 -3
- package/fjs/common/monoid/types.d.ts +1 -1
- package/fjs/crypto/hmac/module.f.mjs +2 -2
- package/fjs/crypto/sha2/module.f.mjs +3 -1
- package/fjs/crypto/sha2/proof.f.d.mts +1 -0
- package/fjs/crypto/sha2/proof.f.mjs +24 -0
- package/fjs/crypto/sha2/types.d.ts +11 -0
- package/fjs/crypto/sign/module.f.mjs +2 -2
- package/fjs/dev/module.f.d.mts +13 -4
- package/fjs/dev/module.f.mjs +56 -27
- package/fjs/dev/update/module.f.d.mts +9 -4
- package/fjs/dev/update/module.f.mjs +14 -10
- package/fjs/dev/update/proof.f.d.mts +1 -3
- package/fjs/dev/update/proof.f.mjs +10 -5
- package/fjs/djs/module.f.d.mts +13 -5
- package/fjs/djs/module.f.mjs +31 -16
- package/fjs/djs/parser/module.f.d.mts +13 -3
- package/fjs/djs/parser/module.f.mjs +117 -16
- package/fjs/djs/parser/proof.f.d.mts +5 -1
- package/fjs/djs/parser/proof.f.mjs +274 -12
- package/fjs/djs/parser/types.d.ts +7 -1
- package/fjs/djs/proof.f.d.mts +18 -2
- package/fjs/djs/proof.f.mjs +187 -12
- package/fjs/djs/serializer/module.f.d.mts +25 -8
- package/fjs/djs/serializer/module.f.mjs +61 -15
- package/fjs/djs/serializer/proof.f.d.mts +5 -0
- package/fjs/djs/serializer/proof.f.mjs +23 -1
- package/fjs/djs/tokenizer/module.f.d.mts +17 -5
- package/fjs/djs/tokenizer/module.f.mjs +99 -60
- package/fjs/djs/tokenizer/proof.f.d.mts +1 -1
- package/fjs/djs/tokenizer/proof.f.mjs +74 -67
- package/fjs/djs/transpiler/module.f.d.mts +12 -7
- package/fjs/djs/transpiler/module.f.mjs +82 -56
- package/fjs/djs/transpiler/types.d.ts +7 -3
- package/fjs/djs/types.d.ts +7 -1
- package/fjs/effects/list/module.f.d.mts +14 -11
- package/fjs/effects/list/module.f.mjs +13 -11
- package/fjs/effects/list/types.d.ts +27 -7
- package/fjs/effects/memory/module.f.d.mts +2 -1
- package/fjs/effects/memory/module.f.mjs +3 -4
- package/fjs/effects/memory/proof.f.mjs +13 -7
- package/fjs/effects/memory/types.d.ts +4 -3
- package/fjs/effects/mock/module.f.d.mts +20 -4
- package/fjs/effects/mock/module.f.mjs +37 -5
- package/fjs/effects/mock/types.d.ts +10 -1
- package/fjs/effects/module.d.mts +4 -2
- package/fjs/effects/module.f.d.mts +466 -280
- package/fjs/effects/module.f.mjs +537 -299
- package/fjs/effects/module.mjs +2 -1
- package/fjs/effects/node/memory/module.d.mts +4 -2
- package/fjs/effects/node/memory/module.mjs +6 -3
- package/fjs/effects/node/memory/proof.mjs +10 -4
- package/fjs/effects/node/module.d.mts +4 -3
- package/fjs/effects/node/module.f.d.mts +168 -33
- package/fjs/effects/node/module.f.mjs +256 -52
- package/fjs/effects/node/module.mjs +57 -34
- package/fjs/effects/node/proof.f.d.mts +28 -2
- package/fjs/effects/node/proof.f.mjs +161 -42
- package/fjs/effects/node/types.d.ts +106 -18
- package/fjs/effects/node/virtual/module.f.d.mts +18 -4
- package/fjs/effects/node/virtual/module.f.mjs +110 -68
- package/fjs/effects/node/virtual/proof.f.d.mts +28 -2
- package/fjs/effects/node/virtual/proof.f.mjs +190 -9
- package/fjs/effects/proof.f.d.mts +69 -37
- package/fjs/effects/proof.f.mjs +410 -130
- package/fjs/effects/types.d.ts +161 -33
- package/fjs/emergent_testing/module.f.d.mts +19 -12
- package/fjs/emergent_testing/module.f.mjs +93 -33
- package/fjs/emergent_testing/proof.f.d.mts +21 -7
- package/fjs/emergent_testing/proof.f.mjs +166 -32
- package/fjs/emergent_testing/types.d.ts +22 -4
- package/fjs/fsm/module.f.d.mts +14 -4
- package/fjs/fsm/module.f.mjs +54 -37
- package/fjs/fsm/proof.f.d.mts +2 -0
- package/fjs/fsm/proof.f.mjs +83 -114
- package/fjs/js/keywords/module.f.d.mts +52 -0
- package/fjs/js/keywords/module.f.mjs +72 -0
- package/fjs/js/keywords/proof.f.d.mts +3 -0
- package/fjs/js/keywords/proof.f.mjs +13 -0
- package/fjs/js/tokenizer/module.f.d.mts +26 -6
- package/fjs/js/tokenizer/module.f.mjs +145 -159
- package/fjs/js/tokenizer/proof.f.d.mts +1 -0
- package/fjs/js/tokenizer/proof.f.mjs +54 -24
- package/fjs/js/tokenizer/types.d.ts +33 -24
- package/fjs/mcp/cas/module.f.d.mts +1 -6
- package/fjs/mcp/cas/module.f.mjs +55 -51
- package/fjs/mcp/cas/proof.f.d.mts +15 -0
- package/fjs/mcp/cas/proof.f.mjs +174 -0
- package/fjs/mcp/evo/module.f.d.mts +19 -10
- package/fjs/mcp/evo/module.f.mjs +48 -27
- package/fjs/mcp/evo/proof.f.d.mts +6 -1
- package/fjs/mcp/evo/proof.f.mjs +115 -31
- package/fjs/mcp/module.f.d.mts +4 -4
- package/fjs/mcp/module.f.mjs +6 -6
- package/fjs/mcp/proof.f.d.mts +5 -3
- package/fjs/mcp/proof.f.mjs +112 -46
- package/fjs/media/html/module.f.mjs +1 -1
- package/fjs/media/json/extended/module.f.d.mts +82 -0
- package/fjs/media/json/extended/module.f.mjs +153 -0
- package/fjs/media/json/extended/proof.f.d.mts +42 -0
- package/fjs/media/json/extended/proof.f.mjs +127 -0
- package/fjs/media/json/extended/types.d.ts +23 -0
- package/fjs/media/json/module.f.d.mts +8 -2
- package/fjs/media/json/module.f.mjs +43 -41
- package/fjs/media/json/number/module.f.d.mts +59 -0
- package/fjs/media/json/number/module.f.mjs +136 -0
- package/fjs/media/json/number/proof.f.d.mts +24 -0
- package/fjs/media/json/number/proof.f.mjs +86 -0
- package/fjs/media/json/number/types.d.ts +28 -0
- package/fjs/media/json/parser/module.f.d.mts +25 -13
- package/fjs/media/json/parser/module.f.mjs +114 -70
- package/fjs/media/json/parser/proof.f.d.mts +5 -0
- package/fjs/media/json/parser/proof.f.mjs +31 -1
- package/fjs/media/json/parser/types.d.ts +33 -14
- package/fjs/media/json/rtti/module.f.d.mts +1 -1
- package/fjs/media/json/rtti/module.f.mjs +1 -1
- package/fjs/media/json/rtti/proof.f.mjs +9 -9
- package/fjs/media/json/schema/module.f.mjs +3 -13
- package/fjs/media/json/schema/proof.f.d.mts +0 -1
- package/fjs/media/json/schema/proof.f.mjs +1 -2
- package/fjs/media/json/serializer/module.f.d.mts +32 -1
- package/fjs/media/json/serializer/module.f.mjs +64 -2
- package/fjs/media/json/tokenizer/module.f.mjs +7 -3
- package/fjs/media/json/tokenizer/proof.f.d.mts +6 -0
- package/fjs/media/json/tokenizer/proof.f.mjs +62 -21
- package/fjs/media/json/types.d.ts +36 -10
- package/fjs/media/lock/module.f.d.mts +100 -0
- package/fjs/media/lock/module.f.mjs +125 -0
- package/fjs/media/lock/proof.f.d.mts +33 -0
- package/fjs/media/lock/proof.f.mjs +196 -0
- package/fjs/media/lock/types.d.ts +15 -0
- package/fjs/media/module.f.d.mts +6 -5
- package/fjs/media/module.f.mjs +8 -7
- package/fjs/media/note/module.f.d.mts +121 -0
- package/fjs/media/note/module.f.mjs +131 -0
- package/fjs/media/note/proof.f.d.mts +29 -0
- package/fjs/media/note/proof.f.mjs +150 -0
- package/fjs/media/note/types.d.ts +10 -0
- package/fjs/media/proof.f.d.mts +4 -1
- package/fjs/media/proof.f.mjs +40 -21
- package/fjs/media/revision/module.f.d.mts +78 -7
- package/fjs/media/revision/module.f.mjs +119 -12
- package/fjs/media/revision/proof.f.d.mts +10 -0
- package/fjs/media/revision/proof.f.mjs +88 -0
- package/fjs/media/revision/types.d.ts +34 -5
- package/fjs/media/type/module.f.d.mts +33 -15
- package/fjs/media/type/module.f.mjs +35 -29
- package/fjs/media/type/proof.f.d.mts +2 -1
- package/fjs/media/type/proof.f.mjs +30 -10
- package/fjs/module.f.mjs +29 -8
- package/fjs/nanvm/proof.f.mjs +3 -3
- package/fjs/nanvm/rust/module.f.mjs +1 -1
- package/fjs/nanvm/update/module.f.d.mts +4 -4
- package/fjs/nanvm/update/module.f.mjs +8 -9
- package/fjs/nanvm/update/proof.f.mjs +4 -3
- package/fjs/proof.f.d.mts +3 -3
- package/fjs/proof.f.mjs +36 -10
- package/fjs/protocol/json_rpc/module.f.d.mts +2 -2
- package/fjs/protocol/json_rpc/module.f.mjs +3 -3
- package/fjs/protocol/json_rpc/proof.f.mjs +4 -4
- package/fjs/protocol/mcp/module.f.d.mts +10 -13
- package/fjs/protocol/mcp/module.f.mjs +74 -58
- package/fjs/protocol/mcp/proof.f.d.mts +13 -4
- package/fjs/protocol/mcp/proof.f.mjs +193 -61
- package/fjs/protocol/mcp/stdio/module.f.d.mts +15 -7
- package/fjs/protocol/mcp/stdio/module.f.mjs +38 -25
- package/fjs/protocol/mcp/stdio/proof.f.d.mts +4 -2
- package/fjs/protocol/mcp/stdio/proof.f.mjs +45 -12
- package/fjs/protocol/mcp/stdio/types.d.ts +1 -1
- package/fjs/protocol/mcp/types.d.ts +17 -6
- package/fjs/sul/id/module.f.d.mts +0 -1
- package/fjs/sul/id/module.f.mjs +2 -3
- package/fjs/sul/level/hash/module.f.mjs +2 -1
- package/fjs/sul/level/hash/proof.f.mjs +2 -2
- package/fjs/sul/module.f.mjs +18 -13
- package/fjs/text/code_point/module.f.d.mts +8 -0
- package/fjs/text/code_point/module.f.mjs +8 -1
- package/fjs/text/code_point/proof.f.d.mts +1 -0
- package/fjs/text/code_point/proof.f.mjs +11 -0
- package/fjs/text/sgr/module.f.d.mts +4 -6
- package/fjs/text/sgr/module.f.mjs +6 -7
- package/fjs/text/utf16/module.f.mjs +7 -2
- package/fjs/text/utf16/proof.f.mjs +3 -3
- package/fjs/text/utf8/module.f.mjs +4 -2
- package/fjs/types/array/module.f.mjs +14 -2
- package/fjs/types/bit_vec/module.f.d.mts +0 -2
- package/fjs/types/bit_vec/module.f.mjs +46 -32
- package/fjs/types/bit_vec/proof.f.mjs +2 -2
- package/fjs/types/btree/remove/module.f.mjs +1 -1
- package/fjs/types/btree/set/module.f.mjs +9 -11
- package/fjs/types/btree/set/proof.f.mjs +12 -0
- package/fjs/types/byte_set/module.f.d.mts +11 -4
- package/fjs/types/byte_set/module.f.mjs +14 -6
- package/fjs/types/byte_set/proof.f.mjs +7 -7
- package/fjs/types/function/compare/module.f.mjs +10 -3
- package/fjs/types/list/module.f.d.mts +1 -1
- package/fjs/types/list/module.f.mjs +1 -1
- package/fjs/types/nullable/module.f.d.mts +18 -4
- package/fjs/types/nullable/module.f.mjs +21 -4
- package/fjs/types/nullable/proof.f.d.mts +4 -0
- package/fjs/types/nullable/proof.f.mjs +15 -0
- package/fjs/types/object/module.f.d.mts +12 -2
- package/fjs/types/object/module.f.mjs +11 -1
- package/fjs/types/patricia_trie/module.f.mjs +26 -11
- package/fjs/types/result/module.f.d.mts +3 -3
- package/fjs/types/result/module.f.mjs +3 -3
- package/fjs/types/rtti/common/module.f.d.mts +25 -28
- package/fjs/types/rtti/common/module.f.mjs +36 -32
- package/fjs/types/rtti/common/proof.f.mjs +5 -5
- package/fjs/types/rtti/data/module.f.d.mts +14 -0
- package/fjs/types/rtti/data/module.f.mjs +25 -2
- package/fjs/types/rtti/data/proof.f.d.mts +1 -0
- package/fjs/types/rtti/data/proof.f.mjs +25 -2
- package/fjs/types/rtti/parse/module.f.d.mts +24 -14
- package/fjs/types/rtti/parse/module.f.mjs +37 -28
- package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
- package/fjs/types/rtti/parse/proof.f.mjs +33 -14
- package/fjs/types/rtti/proof.f.mjs +3 -1
- package/fjs/types/rtti/ts/module.f.mjs +13 -17
- package/fjs/types/rtti/ts/types.d.ts +14 -1
- package/fjs/types/rtti/validate/module.f.d.mts +81 -19
- package/fjs/types/rtti/validate/module.f.mjs +107 -61
- package/fjs/types/rtti/validate/proof.f.d.mts +13 -10
- package/fjs/types/rtti/validate/proof.f.mjs +186 -197
- package/fjs/types/sorted_set/module.f.d.mts +18 -0
- package/fjs/types/sorted_set/module.f.mjs +22 -0
- package/fjs/types/sorted_set/proof.f.d.mts +1 -0
- package/fjs/types/sorted_set/proof.f.mjs +16 -1
- package/fjs/types/uint8array/module.f.d.mts +1 -1
- package/fjs/types/uint8array/module.f.mjs +1 -1
- package/fjs/website/module.f.d.mts +3 -3
- package/fjs/website/module.f.mjs +4 -7
- package/fjs/website/proof.f.mjs +2 -1
- package/package.json +2 -2
- package/fjs/dev/package_json/module.f.d.mts +0 -39
- package/fjs/dev/package_json/module.f.mjs +0 -40
- package/fjs/dev/package_json/proof.f.d.mts +0 -6
- package/fjs/dev/package_json/proof.f.mjs +0 -32
- package/fjs/effects/eff/module.f.d.mts +0 -20
- package/fjs/effects/eff/module.f.mjs +0 -70
- package/fjs/effects/eff/proof.f.d.mts +0 -15
- package/fjs/effects/eff/proof.f.mjs +0 -69
- package/fjs/effects/eff/types.d.ts +0 -71
- package/fjs/types/rtti/validate/types.d.ts +0 -6
package/fjs/djs/proof.f.mjs
CHANGED
|
@@ -1,55 +1,230 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @import {
|
|
2
|
+
* @import { Unknown } from './types.ts'
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { exitCode } from '../effects/node/module.f.mjs'
|
|
5
6
|
import { compile } from './module.f.mjs'
|
|
7
|
+
import { transpile } from './transpiler/module.f.mjs'
|
|
8
|
+
import { stringify } from './serializer/module.f.mjs'
|
|
6
9
|
import { virtual, emptyState } from '../effects/node/virtual/module.f.mjs'
|
|
7
10
|
import { utf8, utf8ToString } from '../text/module.f.mjs'
|
|
8
|
-
import {
|
|
11
|
+
import { fromEntries, isObject, sort } from '../types/object/module.f.mjs'
|
|
12
|
+
import { assert, assertEq, assertStructurallySame } from '../asserts/module.f.mjs'
|
|
9
13
|
|
|
10
14
|
/** @type {(root: typeof emptyState.root, path: string) => string} */
|
|
11
15
|
const readOutput = (root, path) => {
|
|
12
16
|
const file = root[path]
|
|
13
17
|
if (!Array.isArray(file) || file.length === 0) { throw `${path} is not a file` }
|
|
14
|
-
return utf8ToString(
|
|
18
|
+
return utf8ToString(file[0])
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
/** @type {(source: string) => (outputFileName: string) => string} */
|
|
22
|
+
const compileSource = source => outputFileName => {
|
|
23
|
+
const root = { 'input.f.js': [utf8(source)] }
|
|
24
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['input.f.js', outputFileName]))
|
|
25
|
+
assertEq(exitCode(code), 0, state.stderr)
|
|
26
|
+
return readOutput(state.root, outputFileName)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { getPrototypeOf, prototype: objectPrototype } = Object
|
|
30
|
+
|
|
31
|
+
/** The value every `protoKey` test below denotes. */
|
|
32
|
+
const protoValue = fromEntries([['__proto__', { a: 42 }]])
|
|
33
|
+
|
|
34
|
+
const sharedArray = [1, 2]
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Values the module emitter must be able to write as source that evaluates
|
|
38
|
+
* back to them. It covers every leaf type, both containers, the shared values
|
|
39
|
+
* that become a `const`, and the `__proto__` key in both positions — the key
|
|
40
|
+
* whose obvious spelling evaluates to something else entirely.
|
|
41
|
+
*
|
|
42
|
+
* @type {readonly Unknown[]}
|
|
43
|
+
*/
|
|
44
|
+
const roundTripCorpus = [
|
|
45
|
+
null,
|
|
46
|
+
true,
|
|
47
|
+
false,
|
|
48
|
+
undefined,
|
|
49
|
+
0,
|
|
50
|
+
-1.5,
|
|
51
|
+
42n,
|
|
52
|
+
'a"b\n\\',
|
|
53
|
+
[],
|
|
54
|
+
{},
|
|
55
|
+
[1, [2, [3, []]]],
|
|
56
|
+
{ a: 1, 'b c': [true, undefined, 3n], d: {} },
|
|
57
|
+
[sharedArray, sharedArray],
|
|
58
|
+
{ a: 'dup', b: 'dup' },
|
|
59
|
+
protoValue,
|
|
60
|
+
fromEntries([['__proto__', 3]]),
|
|
61
|
+
[protoValue, protoValue],
|
|
62
|
+
{ a: protoValue },
|
|
63
|
+
]
|
|
64
|
+
|
|
17
65
|
export const proof = {
|
|
18
66
|
tooFewArgs: {
|
|
19
67
|
noArgs: () => {
|
|
20
68
|
const [state, code] = virtual(emptyState)(compile([]))
|
|
21
|
-
assertEq(code, 1)
|
|
69
|
+
assertEq(exitCode(code), 1)
|
|
22
70
|
assert(state.stderr.includes('Requires 2 or more arguments'), state.stderr)
|
|
23
71
|
},
|
|
24
72
|
oneArg: () => {
|
|
25
73
|
const [state, code] = virtual(emptyState)(compile(['input.f.js']))
|
|
26
|
-
assertEq(code, 1)
|
|
74
|
+
assertEq(exitCode(code), 1)
|
|
27
75
|
assert(state.stderr.includes('Requires 2 or more arguments'), state.stderr)
|
|
28
76
|
},
|
|
29
77
|
},
|
|
30
78
|
success: () => {
|
|
31
79
|
const root = { 'input.f.js': [utf8('export default 42')] }
|
|
32
80
|
const [state, code] = virtual({ ...emptyState, root })(compile(['input.f.js', 'output.f.js']))
|
|
33
|
-
assertEq(code, 0)
|
|
81
|
+
assertEq(exitCode(code), 0)
|
|
34
82
|
const content = readOutput(state.root, 'output.f.js')
|
|
35
83
|
assertEq(content, 'export default 42')
|
|
36
84
|
},
|
|
37
85
|
jsonOutput: () => {
|
|
38
86
|
const root = { 'input.f.js': [utf8('export default 42')] }
|
|
39
87
|
const [state, code] = virtual({ ...emptyState, root })(compile(['input.f.js', 'output.json']))
|
|
40
|
-
assertEq(code, 0)
|
|
88
|
+
assertEq(exitCode(code), 0)
|
|
41
89
|
const content = readOutput(state.root, 'output.json')
|
|
42
90
|
assertEq(content, '42')
|
|
43
91
|
},
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
92
|
+
// An error with no token to point at names the file being compiled, not
|
|
93
|
+
// `undefined:undefined:undefined`. Each language reports its own missing
|
|
94
|
+
// file: the module reader and the JSON reader read their inputs
|
|
95
|
+
// separately.
|
|
96
|
+
fileNotFound: {
|
|
97
|
+
module: () => {
|
|
98
|
+
const [state, code] = virtual(emptyState)(compile(['missing.f.js', 'output.f.js']))
|
|
99
|
+
assertEq(exitCode(code), 1)
|
|
100
|
+
assertEq(state.stderr.trim(), 'missing.f.js - error: file not found')
|
|
101
|
+
assertEq(state.root['output.f.js'], undefined)
|
|
102
|
+
},
|
|
103
|
+
json: () => {
|
|
104
|
+
const [state, code] = virtual(emptyState)(compile(['missing.json', 'output.f.js']))
|
|
105
|
+
assertEq(exitCode(code), 1)
|
|
106
|
+
assertEq(state.stderr.trim(), 'missing.json - error: file not found')
|
|
107
|
+
assertEq(state.root['output.f.js'], undefined)
|
|
108
|
+
},
|
|
48
109
|
},
|
|
49
110
|
parseError: () => {
|
|
50
111
|
const root = { 'bad.f.js': [utf8('export default @')] }
|
|
51
112
|
const [state, code] = virtual({ ...emptyState, root })(compile(['bad.f.js', 'output.f.js']))
|
|
52
|
-
assertEq(code,
|
|
113
|
+
assertEq(exitCode(code), 1)
|
|
53
114
|
assert(state.stderr !== '', 'expected error output')
|
|
115
|
+
assertEq(state.root['output.f.js'], undefined)
|
|
116
|
+
},
|
|
117
|
+
// serialize → evaluate → structurally the same, one test per corpus value.
|
|
118
|
+
// The emitter is only correct if its output is an input denoting the value
|
|
119
|
+
// it was given, which no assertion on the text alone can state.
|
|
120
|
+
roundTrip: roundTripCorpus.map(value => () => {
|
|
121
|
+
const source = stringify(sort)(value)
|
|
122
|
+
const root = { 'input.f.js': [utf8(source)] }
|
|
123
|
+
const [, result] = virtual({ ...emptyState, root })(transpile('input.f.js'))
|
|
124
|
+
assert(result[0] === 'ok', result[1])
|
|
125
|
+
assertStructurallySame(result[1], value, source)
|
|
126
|
+
}),
|
|
127
|
+
// The `__proto__` key end to end: one value, two output languages, and one
|
|
128
|
+
// spelling of the key in each (#2480).
|
|
129
|
+
protoKey: {
|
|
130
|
+
// The module output uses the computed form, which is also the only
|
|
131
|
+
// input spelling — so the emitter's output is an input that means the
|
|
132
|
+
// same value, and compiling it again is the identity.
|
|
133
|
+
moduleRoundTrip: () => {
|
|
134
|
+
const source = 'export default {["__proto__"]:{"a":42}}'
|
|
135
|
+
const output = compileSource(source)('output.f.js')
|
|
136
|
+
assertEq(output, source)
|
|
137
|
+
assertEq(compileSource(output)('output.f.js'), source)
|
|
138
|
+
},
|
|
139
|
+
// The JSON output keeps the plain key: the computed form is a
|
|
140
|
+
// JavaScript spelling that no JSON parser accepts.
|
|
141
|
+
jsonOutput: () => {
|
|
142
|
+
assertEq(
|
|
143
|
+
compileSource('export default {["__proto__"]:{"a":42}}')('output.json'),
|
|
144
|
+
'{"__proto__":{"a":42}}')
|
|
145
|
+
},
|
|
146
|
+
// `fjs compile proto.json a.js` — the two languages meeting. The input
|
|
147
|
+
// is a JSON document, where `"__proto__"` is an ordinary data key, and
|
|
148
|
+
// the output is a JavaScript module, where only the computed form
|
|
149
|
+
// denotes one. Each hop uses its own language's spelling of the key.
|
|
150
|
+
jsonInput: () => {
|
|
151
|
+
const root = { 'proto.json': [utf8('{"__proto__":5}')] }
|
|
152
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['proto.json', 'a.js']))
|
|
153
|
+
assertEq(exitCode(code), 0, state.stderr)
|
|
154
|
+
assertEq(readOutput(state.root, 'a.js'), 'export default {["__proto__"]:5}')
|
|
155
|
+
},
|
|
156
|
+
// …and back, byte for byte: a JSON document survives the loop
|
|
157
|
+
// `proto.json → a.js → out.json` with no `["__proto__"]:` artifact,
|
|
158
|
+
// which no JSON parser would accept.
|
|
159
|
+
jsonInputRoundTrip: () => {
|
|
160
|
+
const document = '{"__proto__":{"a":42}}'
|
|
161
|
+
const root = { 'proto.json': [utf8(document)] }
|
|
162
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['proto.json', 'a.js']))
|
|
163
|
+
assertEq(exitCode(code), 0, state.stderr)
|
|
164
|
+
const module = readOutput(state.root, 'a.js')
|
|
165
|
+
assertEq(module, 'export default {["__proto__"]:{"a":42}}')
|
|
166
|
+
assertEq(compileSource(module)('out.json'), document)
|
|
167
|
+
},
|
|
168
|
+
// The extension speaks for the file named on the command line and for
|
|
169
|
+
// no other: an import is resolved as a FunctionalScript module, and a
|
|
170
|
+
// JSON document is not one — a statement never begins with a value —
|
|
171
|
+
// so importing JSON fails until an import can say
|
|
172
|
+
// `with { type: "json" }` (spec/todo/2140).
|
|
173
|
+
jsonImportRejected: () => {
|
|
174
|
+
const root = {
|
|
175
|
+
'main.f.js': [utf8('import a from "./a.json"\nexport default [a]')],
|
|
176
|
+
'a.json': [utf8('{"a":42}')],
|
|
177
|
+
}
|
|
178
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['main.f.js', 'out.json']))
|
|
179
|
+
assertEq(exitCode(code), 1)
|
|
180
|
+
assert(state.stderr.includes('a.json:1:1 - error: unexpected token'), state.stderr)
|
|
181
|
+
assertEq(state.root['out.json'], undefined)
|
|
182
|
+
},
|
|
183
|
+
// A `.json` input is read as JSON, and an identifier key is no JSON
|
|
184
|
+
// document's key — so this one fails in the JSON reader, which has no
|
|
185
|
+
// position to report and is named by its file instead.
|
|
186
|
+
jsonInputIdKeyRejected: () => {
|
|
187
|
+
const root = { 'proto.json': [utf8('{__proto__:5}')] }
|
|
188
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['proto.json', 'a.js']))
|
|
189
|
+
assertEq(exitCode(code), 1)
|
|
190
|
+
assertEq(state.stderr.trim(), 'proto.json - error: unexpected token')
|
|
191
|
+
assertEq(state.root['a.js'], undefined)
|
|
192
|
+
},
|
|
193
|
+
// The `.json` reader is JSON, not DJS with a JSON flag: a bigint is
|
|
194
|
+
// not JSON, whatever DJS makes of it.
|
|
195
|
+
jsonInputRejectsDjsExtensions: () => {
|
|
196
|
+
const root = { 'a.json': [utf8('{"a":1n}')] }
|
|
197
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['a.json', 'a.js']))
|
|
198
|
+
assertEq(exitCode(code), 1)
|
|
199
|
+
assertEq(state.root['a.js'], undefined)
|
|
200
|
+
},
|
|
201
|
+
// The statement behind the textual assertions: the property is an
|
|
202
|
+
// ordinary own property and the prototype is untouched. A textual test
|
|
203
|
+
// alone would also pass for a spelling that merely looks right.
|
|
204
|
+
value: () => {
|
|
205
|
+
const root = { 'input.f.js': [utf8('export default {["__proto__"]:{"a":42}}')] }
|
|
206
|
+
const [, result] = virtual({ ...emptyState, root })(transpile('input.f.js'))
|
|
207
|
+
assert(result[0] === 'ok', result[1])
|
|
208
|
+
const value = result[1]
|
|
209
|
+
assert(isObject(value), value)
|
|
210
|
+
assertStructurallySame(value, protoValue)
|
|
211
|
+
assertEq(getPrototypeOf(value), objectPrototype)
|
|
212
|
+
},
|
|
213
|
+
// The two spellings JavaScript reads as a prototype assignment are
|
|
214
|
+
// compilation errors, not silently accepted properties.
|
|
215
|
+
idKeyRejected: () => {
|
|
216
|
+
const root = { 'input.f.js': [utf8('export default {__proto__:{"a":42}}')] }
|
|
217
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['input.f.js', 'output.f.js']))
|
|
218
|
+
assertEq(exitCode(code), 1)
|
|
219
|
+
assert(state.stderr.includes('__proto__ requires the computed key form'), state.stderr)
|
|
220
|
+
assertEq(state.root['output.f.js'], undefined)
|
|
221
|
+
},
|
|
222
|
+
stringKeyRejected: () => {
|
|
223
|
+
const root = { 'input.f.js': [utf8('export default {"__proto__":{"a":42}}')] }
|
|
224
|
+
const [state, code] = virtual({ ...emptyState, root })(compile(['input.f.js', 'output.f.js']))
|
|
225
|
+
assertEq(exitCode(code), 1)
|
|
226
|
+
assert(state.stderr.includes('__proto__ requires the computed key form'), state.stderr)
|
|
227
|
+
assertEq(state.root['output.f.js'], undefined)
|
|
228
|
+
},
|
|
54
229
|
},
|
|
55
230
|
}
|
|
@@ -1,30 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DJS serializer for formatting AST values back to source text.
|
|
3
3
|
*
|
|
4
|
+
* Two output formats share this one walk over the value: `stringify` emits a
|
|
5
|
+
* JavaScript module and `stringifyAsTree` a JSON tree. They differ in `const`
|
|
6
|
+
* hoisting and in how a property key is spelled — see `_KeySerialize`.
|
|
7
|
+
*
|
|
4
8
|
* @module
|
|
5
9
|
*
|
|
6
|
-
* @import { Unknown, Object } from '../types.ts'
|
|
10
|
+
* @import { Unknown, Object, _MapEntries } from '../types.ts'
|
|
7
11
|
* @import { Fold } from '../../types/function/operator/types.ts'
|
|
8
|
-
* @import { Entry as ObjectEntry } from '../../types/object/types.ts'
|
|
9
12
|
* @import { List } from '../../types/list/types.ts'
|
|
10
13
|
*/
|
|
11
|
-
import type { Unknown } from '../types.ts';
|
|
12
|
-
import type { Entry as ObjectEntry } from '../../types/object/types.ts';
|
|
14
|
+
import type { Unknown, _MapEntries } from '../types.ts';
|
|
13
15
|
import type { List } from '../../types/list/types.ts';
|
|
14
16
|
export declare const undefinedSerialize: string[];
|
|
15
17
|
export type _RefCounter = readonly [number, number];
|
|
16
|
-
export type _MapEntries = (entries: List<ObjectEntry<Unknown>>) => List<ObjectEntry<Unknown>>;
|
|
17
18
|
export type _Refs = ReadonlyMap<Unknown, _RefCounter>;
|
|
18
19
|
export type _GetConstsState = {
|
|
19
20
|
readonly added: ReadonlySet<Unknown>;
|
|
20
21
|
readonly consts: List<Unknown>;
|
|
21
22
|
};
|
|
22
23
|
export type _RefLookup = (value: Unknown) => List<string> | null;
|
|
23
|
-
|
|
24
|
+
export type _KeySerialize = (key: string) => List<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Serializes a value as a JSON tree — no `const` hoisting, and JSON's key
|
|
27
|
+
* spelling.
|
|
28
|
+
*
|
|
29
|
+
* @type {(mapEntries: _MapEntries) => (value: Unknown) => List<string>}
|
|
30
|
+
*/
|
|
24
31
|
export declare const serializeWithoutConst: (mapEntries: _MapEntries) => (value: Unknown) => List<string>;
|
|
25
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Serializes a value as a JavaScript module: a shared value becomes a `const`,
|
|
34
|
+
* and a `__proto__` key is written in the computed form the language requires.
|
|
35
|
+
*
|
|
36
|
+
* @type {(sort: _MapEntries) => (djs: Unknown) => string}
|
|
37
|
+
*/
|
|
26
38
|
export declare const stringify: (sort: _MapEntries) => (djs: Unknown) => string;
|
|
27
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Serializes a value as a JSON tree: shared values are expanded, and keys keep
|
|
41
|
+
* JSON's plain spelling.
|
|
42
|
+
*
|
|
43
|
+
* @type {(mapEntries: _MapEntries) => (value: Unknown) => string}
|
|
44
|
+
*/
|
|
28
45
|
export declare const stringifyAsTree: (mapEntries: _MapEntries) => (value: Unknown) => string;
|
|
29
46
|
/** @type {(djs: Unknown) => _Refs} */
|
|
30
47
|
export declare const countRefs: (djs: Unknown) => _Refs;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DJS serializer for formatting AST values back to source text.
|
|
3
3
|
*
|
|
4
|
+
* Two output formats share this one walk over the value: `stringify` emits a
|
|
5
|
+
* JavaScript module and `stringifyAsTree` a JSON tree. They differ in `const`
|
|
6
|
+
* hoisting and in how a property key is spelled — see `_KeySerialize`.
|
|
7
|
+
*
|
|
4
8
|
* @module
|
|
5
9
|
*
|
|
6
|
-
* @import { Unknown, Object } from '../types.ts'
|
|
10
|
+
* @import { Unknown, Object, _MapEntries } from '../types.ts'
|
|
7
11
|
* @import { Fold } from '../../types/function/operator/types.ts'
|
|
8
|
-
* @import { Entry as ObjectEntry } from '../../types/object/types.ts'
|
|
9
12
|
* @import { List } from '../../types/list/types.ts'
|
|
10
13
|
*/
|
|
11
14
|
|
|
@@ -15,17 +18,13 @@ import { flat, flatMap, map, concat as listConcat } from '../../types/list/modul
|
|
|
15
18
|
const { entries } = Object
|
|
16
19
|
import { compose, fn } from '../../types/function/module.f.mjs'
|
|
17
20
|
import { serialize as bigintSerialize } from '../../types/bigint/module.f.mjs'
|
|
18
|
-
import { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from '../../media/json/serializer/module.f.mjs'
|
|
21
|
+
import { objectWrap, arrayWrap, colon, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from '../../media/json/serializer/module.f.mjs'
|
|
19
22
|
import { assertNotNullish } from '../../asserts/module.f.mjs'
|
|
20
23
|
|
|
21
|
-
const colon = [':']
|
|
22
|
-
|
|
23
24
|
export const undefinedSerialize = ['undefined']
|
|
24
25
|
|
|
25
26
|
/** @typedef {readonly [number, number]} _RefCounter */
|
|
26
27
|
|
|
27
|
-
/** @typedef {(entries: List<ObjectEntry<Unknown>>) => List<ObjectEntry<Unknown>>} _MapEntries */
|
|
28
|
-
|
|
29
28
|
/** @typedef {ReadonlyMap<Unknown, _RefCounter>} _Refs */
|
|
30
29
|
|
|
31
30
|
/**
|
|
@@ -93,11 +92,43 @@ const entryValue = kv => kv[1]
|
|
|
93
92
|
/** @type {_RefLookup} */
|
|
94
93
|
const noRef = () => null
|
|
95
94
|
|
|
96
|
-
/**
|
|
97
|
-
|
|
95
|
+
/**
|
|
96
|
+
* How one output format spells a property key. The two formats disagree about
|
|
97
|
+
* exactly one key, `__proto__`, so the spelling is a parameter of
|
|
98
|
+
* `buildSerialize` rather than a property of the shared JSON helper.
|
|
99
|
+
*
|
|
100
|
+
* @typedef {(key: string) => List<string>} _KeySerialize
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
const protoKey = '__proto__'
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* JSON spells every key as a quoted string. `"__proto__"` included: `JSON.parse`
|
|
107
|
+
* has no prototype special case, so the plain spelling already round-trips, and
|
|
108
|
+
* the computed form below is not JSON at all.
|
|
109
|
+
*
|
|
110
|
+
* @type {_KeySerialize}
|
|
111
|
+
*/
|
|
112
|
+
const jsonKeySerialize = stringSerialize
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* JavaScript reads `{"__proto__": v}` as a prototype assignment, so a module
|
|
116
|
+
* emitting that spelling would not read back the value it was given. The
|
|
117
|
+
* computed form is the only spelling whose evaluation reproduces the property,
|
|
118
|
+
* which makes it a requirement of round-tripping rather than a style choice.
|
|
119
|
+
* See [spec: the `__proto__` key](../../../spec/README.md#the-__proto__-key).
|
|
120
|
+
*
|
|
121
|
+
* @type {_KeySerialize}
|
|
122
|
+
*/
|
|
123
|
+
const jsKeySerialize = key => key === protoKey
|
|
124
|
+
? flat([['['], stringSerialize(key), [']']])
|
|
125
|
+
: stringSerialize(key)
|
|
126
|
+
|
|
127
|
+
/** @type {(keySerialize: _KeySerialize) => (refLookup: _RefLookup) => (sort: _MapEntries) => (value: Unknown) => List<string>} */
|
|
128
|
+
const buildSerialize = keySerialize => refLookup => sort => {
|
|
98
129
|
/** @type {(kv: readonly [string, Unknown]) => List<string>} */
|
|
99
130
|
const propertySerialize = ([k, v]) => flat([
|
|
100
|
-
|
|
131
|
+
keySerialize(k),
|
|
101
132
|
colon,
|
|
102
133
|
f(v)
|
|
103
134
|
])
|
|
@@ -129,13 +160,18 @@ const buildSerialize = refLookup => sort => {
|
|
|
129
160
|
return f
|
|
130
161
|
}
|
|
131
162
|
|
|
132
|
-
/**
|
|
133
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Serializes a value as a JSON tree — no `const` hoisting, and JSON's key
|
|
165
|
+
* spelling.
|
|
166
|
+
*
|
|
167
|
+
* @type {(mapEntries: _MapEntries) => (value: Unknown) => List<string>}
|
|
168
|
+
*/
|
|
169
|
+
export const serializeWithoutConst = buildSerialize(jsonKeySerialize)(noRef)
|
|
134
170
|
|
|
135
171
|
/** @type {(sort: _MapEntries) => (refs: _Refs) => (root: Unknown) => (djs: Unknown) => List<string>} */
|
|
136
172
|
const serializeWithConst = sort => refs => {
|
|
137
173
|
const shared = sharedRef(refs)
|
|
138
|
-
return root => buildSerialize(value => {
|
|
174
|
+
return root => buildSerialize(jsKeySerialize)(value => {
|
|
139
175
|
if (value === root) { return null }
|
|
140
176
|
const rc = shared(value)
|
|
141
177
|
if (rc !== undefined) { return [`c${rc[0]}`] }
|
|
@@ -180,7 +216,12 @@ const addRef = djs => refs => {
|
|
|
180
216
|
return new Map([...refs, [djs, newCounter]])
|
|
181
217
|
}
|
|
182
218
|
|
|
183
|
-
/**
|
|
219
|
+
/**
|
|
220
|
+
* Serializes a value as a JavaScript module: a shared value becomes a `const`,
|
|
221
|
+
* and a `__proto__` key is written in the computed form the language requires.
|
|
222
|
+
*
|
|
223
|
+
* @type {(sort: _MapEntries) => (djs: Unknown) => string}
|
|
224
|
+
*/
|
|
184
225
|
export const stringify = sort => djs => {
|
|
185
226
|
const refs = countRefs(djs)
|
|
186
227
|
const consts = getConstants(refs)(djs)
|
|
@@ -197,7 +238,12 @@ export const stringify = sort => djs => {
|
|
|
197
238
|
return concat(listConcat(constStrings)(rootStrings))
|
|
198
239
|
}
|
|
199
240
|
|
|
200
|
-
/**
|
|
241
|
+
/**
|
|
242
|
+
* Serializes a value as a JSON tree: shared values are expanded, and keys keep
|
|
243
|
+
* JSON's plain spelling.
|
|
244
|
+
*
|
|
245
|
+
* @type {(mapEntries: _MapEntries) => (value: Unknown) => string}
|
|
246
|
+
*/
|
|
201
247
|
export const stringifyAsTree = sort => compose(serializeWithoutConst(sort))(concat)
|
|
202
248
|
|
|
203
249
|
|
|
@@ -12,6 +12,11 @@ export declare const proof: {
|
|
|
12
12
|
testSort: () => void;
|
|
13
13
|
testIdentity: () => void;
|
|
14
14
|
})[];
|
|
15
|
+
protoKey: {
|
|
16
|
+
module: () => void;
|
|
17
|
+
moduleShared: () => void;
|
|
18
|
+
json: () => void;
|
|
19
|
+
};
|
|
15
20
|
stringifyAsTree: ({
|
|
16
21
|
sort: () => void;
|
|
17
22
|
identity: () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { countRefs, stringify, stringifyAsTree } from './module.f.mjs'
|
|
2
|
-
import { sort } from '../../types/object/module.f.mjs'
|
|
2
|
+
import { fromEntries, sort } from '../../types/object/module.f.mjs'
|
|
3
3
|
import { identity } from '../../types/function/module.f.mjs'
|
|
4
4
|
import { setProperty } from '../../media/json/module.f.mjs'
|
|
5
5
|
import { assertEq } from '../../asserts/module.f.mjs'
|
|
@@ -55,6 +55,28 @@ export const proof = {
|
|
|
55
55
|
},
|
|
56
56
|
}
|
|
57
57
|
],
|
|
58
|
+
// The one key the two output formats spell differently. A `__proto__`
|
|
59
|
+
// property is built with `fromEntries` because an object literal cannot
|
|
60
|
+
// hold one: `{__proto__: 3}` assigns a prototype instead (#2480).
|
|
61
|
+
protoKey: {
|
|
62
|
+
// JavaScript output: only the computed form evaluates back to the
|
|
63
|
+
// property, so the module emitter must use it.
|
|
64
|
+
module: () => {
|
|
65
|
+
const res = stringify(sort)(fromEntries([['__proto__', 3]]))
|
|
66
|
+
assertEq(res, 'export default {["__proto__"]:3}')
|
|
67
|
+
},
|
|
68
|
+
moduleShared: () => {
|
|
69
|
+
const shared = fromEntries([['__proto__', 3]])
|
|
70
|
+
const res = stringify(sort)([shared, shared])
|
|
71
|
+
assertEq(res, 'const c0 = {["__proto__"]:3}\nexport default [c0,c0]')
|
|
72
|
+
},
|
|
73
|
+
// JSON output: `JSON.parse` has no prototype special case, so the plain
|
|
74
|
+
// spelling already round-trips — and the computed form is not JSON.
|
|
75
|
+
json: () => {
|
|
76
|
+
const res = stringifyAsTree(sort)(fromEntries([['__proto__', 3]]))
|
|
77
|
+
assertEq(res, '{"__proto__":3}')
|
|
78
|
+
},
|
|
79
|
+
},
|
|
58
80
|
stringifyAsTree: [
|
|
59
81
|
{
|
|
60
82
|
sort: () => {
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*
|
|
6
|
+
* @import { Ast, AstSequence, AstTag } from '../../bnf/matcher/types.ts'
|
|
6
7
|
* @import {
|
|
7
|
-
* AstRuleMeta,
|
|
8
|
-
* AstSequenceMeta,
|
|
9
|
-
* AstTag,
|
|
10
8
|
* CodePointMeta,
|
|
11
9
|
* DescentMatch,
|
|
12
|
-
* DescentMatchResult
|
|
10
|
+
* DescentMatchResult,
|
|
13
11
|
* } from '../../bnf/descent/types.ts'
|
|
14
12
|
* @import { DataRule, Rule } from '../../bnf/types.ts'
|
|
15
13
|
* @import {
|
|
@@ -29,8 +27,9 @@
|
|
|
29
27
|
* @import { CodePoint } from '../../text/utf16/types.ts'
|
|
30
28
|
* @import { StateScan } from '../../types/function/operator/types.ts'
|
|
31
29
|
* @import { List } from '../../types/list/types.ts'
|
|
32
|
-
* @import { Unknown } from '../types.ts'
|
|
33
30
|
* @import { DjsToken, DjsTokenWithMetadata } from './types.ts'
|
|
31
|
+
* @import { TriviaKind } from '../../js/tokenizer/types.ts'
|
|
32
|
+
* @import { Nullable } from '../../types/nullable/types.ts'
|
|
34
33
|
*/
|
|
35
34
|
import type { CodePointMeta, DescentMatch, DescentMatchResult } from '../../bnf/descent/types.ts';
|
|
36
35
|
import type { Rule } from '../../bnf/types.ts';
|
|
@@ -40,6 +39,16 @@ import type { List } from '../../types/list/types.ts';
|
|
|
40
39
|
import type { DjsTokenWithMetadata } from './types.ts';
|
|
41
40
|
/** @type {() => Rule} */
|
|
42
41
|
export declare const jsGrammar: () => Rule;
|
|
42
|
+
/**
|
|
43
|
+
* The whole-file matcher together with the name of the rule to start it at.
|
|
44
|
+
*
|
|
45
|
+
* `toData` generates rule names, so the entry name belongs to the conversion
|
|
46
|
+
* rather than to the grammar's spelling and is read back from it here. Building
|
|
47
|
+
* both from one conversion also keeps the grammar built once per matcher.
|
|
48
|
+
*
|
|
49
|
+
* @type {<T>() => readonly [DescentMatch<T>, string]}
|
|
50
|
+
*/
|
|
51
|
+
export declare const jsMatcher: <T>() => readonly [DescentMatch<T>, string];
|
|
43
52
|
/** @type {(m: DescentMatch<unknown>, name: string, cp: readonly CodePoint[]) => DescentMatchResult<unknown>} */
|
|
44
53
|
export declare const descentParserCpOnly: (m: DescentMatch<unknown>, name: string, cp: readonly CodePoint[]) => DescentMatchResult<unknown>;
|
|
45
54
|
export type _Token = [string, TokenMetadata, readonly number[]];
|
|
@@ -63,3 +72,6 @@ export type _DjsScanState = {
|
|
|
63
72
|
};
|
|
64
73
|
/** @type {(input: List<number>) => (path: string) => List<DjsTokenWithMetadata>} */
|
|
65
74
|
export declare const tokenize: (input: List<number>) => (path: string) => List<DjsTokenWithMetadata>;
|
|
75
|
+
export declare const proof: {
|
|
76
|
+
tagToTokenTrueTag: () => void;
|
|
77
|
+
};
|