functionalscript 0.44.0 → 0.46.0
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 +15 -0
- package/fjs/asn.1/proof.f.mjs +31 -3
- package/fjs/asserts/module.f.d.mts +14 -0
- package/fjs/asserts/module.f.mjs +20 -0
- package/fjs/asserts/proof.f.d.mts +3 -0
- package/fjs/asserts/proof.f.mjs +15 -1
- package/fjs/basen/base128/module.f.mjs +22 -5
- package/fjs/basen/base128/proof.f.d.mts +3 -1
- package/fjs/basen/base128/proof.f.mjs +3 -1
- package/fjs/basen/base64/module.f.mjs +7 -3
- package/fjs/basen/base64/proof.f.d.mts +3 -1
- package/fjs/basen/base64/proof.f.mjs +7 -4
- package/fjs/basen/cbase32/proof.f.d.mts +3 -1
- package/fjs/basen/cbase32/proof.f.mjs +3 -1
- 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 -4
- package/fjs/bnf/data/types.d.ts +20 -2
- package/fjs/bnf/descent/module.f.d.mts +34 -5
- package/fjs/bnf/descent/module.f.mjs +176 -54
- package/fjs/bnf/descent/proof.f.d.mts +3 -0
- package/fjs/bnf/descent/proof.f.mjs +189 -27
- package/fjs/bnf/descent/types.d.ts +24 -18
- package/fjs/bnf/ll1/module.f.d.mts +74 -6
- package/fjs/bnf/ll1/module.f.mjs +297 -95
- package/fjs/bnf/ll1/proof.f.d.mts +17 -2
- package/fjs/bnf/ll1/proof.f.mjs +372 -137
- package/fjs/bnf/ll1/types.d.ts +25 -27
- 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/module.f.d.mts +15 -6
- package/fjs/bnf/module.f.mjs +52 -11
- package/fjs/bnf/proof.f.d.mts +2 -0
- package/fjs/bnf/proof.f.mjs +79 -3
- package/fjs/bnf/testlib.f.d.mts +31 -0
- package/fjs/bnf/testlib.f.mjs +80 -0
- package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
- package/fjs/bnf/token_symbol/module.f.mjs +7 -6
- package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
- package/fjs/bnf/token_symbol/types.d.ts +2 -2
- package/fjs/bnf/types.d.ts +10 -3
- 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 +4 -4
- package/fjs/cas/cli/proof.f.mjs +47 -34
- package/fjs/cas/evo/module.f.d.mts +71 -31
- package/fjs/cas/evo/module.f.mjs +223 -138
- package/fjs/cas/evo/proof.f.d.mts +10 -1
- package/fjs/cas/evo/proof.f.mjs +311 -226
- package/fjs/cas/evo/types.d.ts +45 -9
- package/fjs/cas/module.f.d.mts +18 -32
- package/fjs/cas/module.f.mjs +164 -176
- 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/common/module.f.d.mts +1 -1
- package/fjs/ci/common/module.f.mjs +1 -0
- package/fjs/ci/config/module.f.d.mts +3 -3
- package/fjs/ci/config/module.f.mjs +3 -3
- 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.d.mts +2 -0
- package/fjs/ci/nix/proof.f.mjs +4 -4
- package/fjs/ci/proof.f.d.mts +4 -2
- package/fjs/ci/proof.f.mjs +13 -8
- package/fjs/cli/module.f.d.mts +4 -6
- package/fjs/cli/module.f.mjs +4 -8
- package/fjs/cli/proof.f.d.mts +4 -2
- package/fjs/cli/proof.f.mjs +21 -18
- package/fjs/cli/types.d.ts +2 -3
- package/fjs/common/monoid/module.f.d.mts +70 -12
- package/fjs/common/monoid/module.f.mjs +177 -14
- package/fjs/common/monoid/proof.f.d.mts +12 -1
- package/fjs/common/monoid/proof.f.mjs +88 -4
- package/fjs/common/monoid/types.d.ts +23 -0
- package/fjs/crypto/hmac/module.f.mjs +2 -2
- package/fjs/crypto/secp/proof.f.d.mts +3 -1
- package/fjs/crypto/secp/proof.f.mjs +3 -1
- package/fjs/crypto/sha2/module.f.mjs +3 -1
- package/fjs/crypto/sha2/proof.f.d.mts +4 -1
- package/fjs/crypto/sha2/proof.f.mjs +27 -1
- package/fjs/crypto/sha2/types.d.ts +11 -0
- package/fjs/crypto/sign/module.f.mjs +2 -2
- package/fjs/crypto/vdf/module.f.d.mts +23 -4
- package/fjs/crypto/vdf/module.f.mjs +6 -4
- package/fjs/dev/module.f.d.mts +17 -5
- package/fjs/dev/module.f.mjs +60 -30
- package/fjs/dev/update/module.f.d.mts +11 -3
- package/fjs/dev/update/module.f.mjs +16 -11
- package/fjs/dev/update/proof.f.d.mts +4 -3
- package/fjs/dev/update/proof.f.mjs +11 -7
- 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 +16 -3
- package/fjs/djs/parser/module.f.mjs +135 -16
- package/fjs/djs/parser/proof.f.d.mts +8 -1
- package/fjs/djs/parser/proof.f.mjs +287 -13
- package/fjs/djs/parser/types.d.ts +7 -1
- package/fjs/djs/proof.f.d.mts +20 -1
- package/fjs/djs/proof.f.mjs +190 -12
- package/fjs/djs/serializer/module.f.d.mts +25 -8
- package/fjs/djs/serializer/module.f.mjs +66 -19
- 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 +120 -73
- package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
- package/fjs/djs/tokenizer/proof.f.mjs +86 -67
- package/fjs/djs/transpiler/module.f.d.mts +13 -19
- package/fjs/djs/transpiler/module.f.mjs +79 -72
- package/fjs/djs/transpiler/types.d.ts +29 -0
- package/fjs/djs/types.d.ts +7 -1
- package/fjs/effects/list/module.f.d.mts +23 -12
- package/fjs/effects/list/module.f.mjs +16 -12
- package/fjs/effects/list/types.d.ts +27 -7
- package/fjs/effects/memory/module.f.d.mts +6 -3
- package/fjs/effects/memory/module.f.mjs +7 -7
- package/fjs/effects/memory/proof.f.d.mts +4 -0
- package/fjs/effects/memory/proof.f.mjs +18 -9
- package/fjs/effects/memory/types.d.ts +4 -3
- package/fjs/effects/mock/module.f.d.mts +28 -4
- package/fjs/effects/mock/module.f.mjs +39 -5
- package/fjs/effects/mock/types.d.ts +10 -1
- package/fjs/effects/module.d.mts +12 -2
- package/fjs/effects/module.f.d.mts +469 -281
- package/fjs/effects/module.f.mjs +538 -299
- package/fjs/effects/module.mjs +11 -2
- package/fjs/effects/node/memory/module.d.mts +7 -2
- package/fjs/effects/node/memory/module.mjs +9 -5
- package/fjs/effects/node/memory/proof.d.mts +2 -0
- package/fjs/effects/node/memory/proof.mjs +12 -5
- package/fjs/effects/node/module.d.mts +8 -2
- package/fjs/effects/node/module.f.d.mts +183 -43
- package/fjs/effects/node/module.f.mjs +260 -62
- package/fjs/effects/node/module.mjs +61 -50
- 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 +21 -4
- package/fjs/effects/node/virtual/module.f.mjs +113 -70
- package/fjs/effects/node/virtual/proof.f.d.mts +31 -2
- package/fjs/effects/node/virtual/proof.f.mjs +201 -8
- package/fjs/effects/proof.f.d.mts +69 -34
- package/fjs/effects/proof.f.mjs +413 -130
- package/fjs/effects/types.d.ts +161 -33
- package/fjs/emergent_testing/all.test.d.mts +8 -0
- package/fjs/emergent_testing/all.test.mjs +14 -0
- package/fjs/emergent_testing/module.f.d.mts +22 -10
- package/fjs/emergent_testing/module.f.mjs +119 -85
- package/fjs/emergent_testing/proof.f.d.mts +21 -7
- package/fjs/emergent_testing/proof.f.mjs +169 -35
- package/fjs/emergent_testing/types.d.ts +22 -4
- package/fjs/fsc/bnf.f.d.mts +3 -0
- package/fjs/fsc/bnf.f.mjs +4 -1
- package/fjs/fsc/json.f.d.mts +3 -0
- package/fjs/fsc/json.f.mjs +4 -1
- package/fjs/fsc/module.f.d.mts +9 -0
- package/fjs/fsc/module.f.mjs +5 -3
- package/fjs/fsm/module.f.d.mts +14 -4
- package/fjs/fsm/module.f.mjs +54 -37
- package/fjs/fsm/proof.f.d.mts +5 -0
- package/fjs/fsm/proof.f.mjs +87 -115
- package/fjs/js/keywords/module.f.d.mts +52 -0
- package/fjs/js/keywords/module.f.mjs +72 -0
- package/fjs/{emergent_testing/scenarios/return-value.pass.d.ts → js/keywords/proof.f.d.mts} +1 -1
- package/fjs/js/keywords/proof.f.mjs +13 -0
- package/fjs/js/tokenizer/module.f.d.mts +30 -3
- package/fjs/js/tokenizer/module.f.mjs +161 -211
- 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 +39 -4
- package/fjs/mcp/module.f.mjs +14 -12
- package/fjs/mcp/proof.f.d.mts +13 -1
- package/fjs/mcp/proof.f.mjs +120 -61
- package/fjs/media/html/module.f.d.mts +12 -0
- package/fjs/media/html/module.f.mjs +7 -5
- package/fjs/media/html/proof.f.d.mts +3 -0
- package/fjs/media/html/proof.f.mjs +4 -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 +133 -72
- 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 +38 -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.d.mts +3 -0
- package/fjs/media/json/rtti/proof.f.mjs +12 -12
- package/fjs/media/json/schema/module.f.d.mts +61 -27
- package/fjs/media/json/schema/module.f.mjs +218 -63
- package/fjs/media/json/schema/proof.f.d.mts +41 -1
- package/fjs/media/json/schema/proof.f.mjs +220 -9
- package/fjs/media/json/serializer/module.f.d.mts +44 -0
- package/fjs/media/json/serializer/module.f.mjs +71 -9
- package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
- package/fjs/media/json/tokenizer/module.f.mjs +31 -8
- 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/nix/module.f.d.mts +13 -0
- package/fjs/media/nix/module.f.mjs +4 -2
- package/fjs/media/nix/proof.f.d.mts +3 -0
- package/fjs/media/nix/proof.f.mjs +4 -1
- 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 +83 -7
- package/fjs/media/revision/module.f.mjs +127 -23
- package/fjs/media/revision/proof.f.d.mts +14 -0
- package/fjs/media/revision/proof.f.mjs +93 -2
- package/fjs/media/revision/types.d.ts +34 -5
- package/fjs/media/type/module.f.d.mts +53 -18
- package/fjs/media/type/module.f.mjs +87 -97
- package/fjs/media/type/proof.f.d.mts +17 -0
- package/fjs/media/type/proof.f.mjs +73 -13
- package/fjs/module.d.mts +5 -0
- package/fjs/module.f.d.mts +8 -0
- package/fjs/module.f.mjs +33 -10
- package/fjs/module.mjs +6 -0
- 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/path/module.f.d.mts +8 -0
- package/fjs/path/module.f.mjs +4 -2
- package/fjs/proof.f.d.mts +7 -3
- package/fjs/proof.f.mjs +41 -12
- package/fjs/protocol/json_rpc/module.f.d.mts +3 -3
- package/fjs/protocol/json_rpc/module.f.mjs +10 -7
- package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
- package/fjs/protocol/json_rpc/proof.f.mjs +26 -5
- 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 +16 -3
- package/fjs/protocol/mcp/proof.f.mjs +224 -69
- package/fjs/protocol/mcp/stdio/module.f.d.mts +17 -11
- package/fjs/protocol/mcp/stdio/module.f.mjs +39 -33
- package/fjs/protocol/mcp/stdio/proof.f.d.mts +5 -3
- package/fjs/protocol/mcp/stdio/proof.f.mjs +46 -13
- package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
- package/fjs/protocol/mcp/types.d.ts +17 -6
- package/fjs/sul/id/module.f.d.mts +4 -0
- package/fjs/sul/id/module.f.mjs +6 -6
- package/fjs/sul/level/hash/module.f.d.mts +4 -1
- package/fjs/sul/level/hash/module.f.mjs +6 -4
- package/fjs/sul/level/hash/proof.f.d.mts +4 -0
- package/fjs/sul/level/hash/proof.f.mjs +7 -4
- package/fjs/sul/level/literal/module.f.d.mts +4 -1
- package/fjs/sul/level/literal/module.f.mjs +4 -3
- package/fjs/sul/level/literal/proof.f.d.mts +3 -0
- package/fjs/sul/level/literal/proof.f.mjs +4 -1
- package/fjs/sul/module.f.d.mts +5 -3
- package/fjs/sul/module.f.mjs +23 -17
- package/fjs/sul/proof.f.d.mts +4 -0
- package/fjs/sul/proof.f.mjs +5 -2
- package/fjs/text/ascii/module.f.d.mts +26 -0
- package/fjs/text/ascii/module.f.mjs +49 -1
- package/fjs/text/ascii/proof.f.d.mts +10 -0
- package/fjs/text/ascii/proof.f.mjs +33 -1
- package/fjs/text/code_point/module.f.d.mts +29 -3
- package/fjs/text/code_point/module.f.mjs +32 -9
- package/fjs/text/code_point/proof.f.d.mts +2 -0
- package/fjs/text/code_point/proof.f.mjs +39 -0
- package/fjs/text/module.f.d.mts +4 -2
- package/fjs/text/module.f.mjs +4 -3
- package/fjs/text/proof.f.d.mts +3 -0
- package/fjs/text/proof.f.mjs +4 -1
- package/fjs/text/sgr/module.f.d.mts +6 -5
- package/fjs/text/sgr/module.f.mjs +8 -8
- package/fjs/text/sgr/proof.f.d.mts +3 -0
- package/fjs/text/sgr/proof.f.mjs +4 -1
- package/fjs/text/utf16/module.f.d.mts +5 -1
- package/fjs/text/utf16/module.f.mjs +38 -35
- package/fjs/text/utf16/proof.f.d.mts +3 -1
- package/fjs/text/utf16/proof.f.mjs +19 -2
- package/fjs/text/utf8/module.f.d.mts +9 -5
- package/fjs/text/utf8/module.f.mjs +20 -20
- package/fjs/types/array/module.f.d.mts +2 -1
- package/fjs/types/array/module.f.mjs +16 -4
- package/fjs/types/bigfloat/module.f.d.mts +21 -1
- package/fjs/types/bigfloat/module.f.mjs +33 -7
- package/fjs/types/bigfloat/proof.f.d.mts +1 -0
- package/fjs/types/bigfloat/proof.f.mjs +46 -0
- package/fjs/types/bigint/module.f.d.mts +4 -0
- package/fjs/types/bigint/module.f.mjs +4 -3
- package/fjs/types/bit_vec/module.f.d.mts +10 -16
- package/fjs/types/bit_vec/module.f.mjs +99 -95
- package/fjs/types/bit_vec/proof.f.d.mts +6 -0
- package/fjs/types/bit_vec/proof.f.mjs +31 -5
- package/fjs/types/btree/find/module.f.d.mts +5 -1
- package/fjs/types/btree/find/module.f.mjs +5 -5
- package/fjs/types/btree/find/proof.f.d.mts +5 -1
- package/fjs/types/btree/find/proof.f.mjs +5 -3
- package/fjs/types/btree/module.f.d.mts +3 -0
- package/fjs/types/btree/module.f.mjs +3 -2
- package/fjs/types/btree/proof.f.d.mts +5 -1
- package/fjs/types/btree/proof.f.mjs +5 -3
- package/fjs/types/btree/remove/module.f.d.mts +11 -0
- package/fjs/types/btree/remove/module.f.mjs +10 -10
- package/fjs/types/btree/remove/proof.f.d.mts +3 -0
- package/fjs/types/btree/remove/proof.f.mjs +4 -1
- package/fjs/types/btree/set/module.f.d.mts +9 -0
- package/fjs/types/btree/set/module.f.mjs +14 -17
- package/fjs/types/btree/set/proof.f.d.mts +3 -0
- package/fjs/types/btree/set/proof.f.mjs +16 -1
- package/fjs/types/btree/types/module.f.d.mts +2 -1
- package/fjs/types/btree/types/module.f.mjs +2 -1
- package/fjs/types/byte_set/module.f.d.mts +20 -4
- package/fjs/types/byte_set/module.f.mjs +18 -8
- package/fjs/types/byte_set/proof.f.d.mts +3 -1
- package/fjs/types/byte_set/proof.f.mjs +10 -8
- package/fjs/types/function/compare/module.f.d.mts +3 -2
- package/fjs/types/function/compare/module.f.mjs +13 -5
- package/fjs/types/function/module.f.d.mts +8 -1
- package/fjs/types/function/module.f.mjs +8 -1
- package/fjs/types/function/operator/module.f.d.mts +2 -1
- package/fjs/types/function/operator/module.f.mjs +2 -2
- package/fjs/types/list/module.f.d.mts +10 -3
- package/fjs/types/list/module.f.mjs +6 -4
- package/fjs/types/list/proof.f.d.mts +4 -1
- package/fjs/types/list/proof.f.mjs +4 -2
- package/fjs/types/nibble_set/module.f.d.mts +2 -1
- package/fjs/types/nibble_set/module.f.mjs +2 -2
- package/fjs/types/nominal/module.f.d.mts +2 -1
- package/fjs/types/nominal/module.f.mjs +2 -1
- package/fjs/types/nullable/module.f.d.mts +26 -6
- package/fjs/types/nullable/module.f.mjs +25 -6
- package/fjs/types/nullable/proof.f.d.mts +4 -0
- package/fjs/types/nullable/proof.f.mjs +15 -0
- package/fjs/types/number/module.f.d.mts +4 -0
- package/fjs/types/number/module.f.mjs +4 -3
- package/fjs/types/object/module.f.d.mts +26 -4
- package/fjs/types/object/module.f.mjs +26 -7
- package/fjs/types/object/proof.f.d.mts +5 -2
- package/fjs/types/object/proof.f.mjs +6 -3
- package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
- package/fjs/types/object/structurally_same/module.f.mjs +59 -0
- package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
- package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
- package/fjs/types/ordered_map/module.f.d.mts +5 -0
- package/fjs/types/ordered_map/module.f.mjs +5 -4
- package/fjs/types/ordered_map/proof.f.d.mts +3 -0
- package/fjs/types/ordered_map/proof.f.mjs +4 -1
- package/fjs/types/patricia_trie/module.f.d.mts +2 -1
- package/fjs/types/patricia_trie/module.f.mjs +27 -12
- package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
- package/fjs/types/patricia_trie/proof.f.mjs +4 -1
- package/fjs/types/prime_field/module.f.d.mts +3 -1
- package/fjs/types/prime_field/module.f.mjs +3 -2
- package/fjs/types/range/module.f.d.mts +2 -1
- package/fjs/types/range/module.f.mjs +2 -2
- package/fjs/types/range_map/module.f.d.mts +6 -0
- package/fjs/types/range_map/module.f.mjs +6 -9
- package/fjs/types/range_map/proof.f.d.mts +5 -1
- package/fjs/types/range_map/proof.f.mjs +5 -3
- package/fjs/types/range_set/module.f.d.mts +5 -0
- package/fjs/types/range_set/module.f.mjs +1 -0
- package/fjs/types/range_set/proof.f.d.mts +3 -0
- package/fjs/types/range_set/proof.f.mjs +4 -1
- package/fjs/types/result/module.d.mts +8 -0
- package/fjs/types/result/module.f.d.mts +37 -7
- package/fjs/types/result/module.f.mjs +38 -8
- package/fjs/types/result/module.mjs +9 -1
- package/fjs/types/result/proof.f.d.mts +5 -0
- package/fjs/types/result/proof.f.mjs +22 -2
- package/fjs/types/rtti/common/module.f.d.mts +44 -14
- package/fjs/types/rtti/common/module.f.mjs +42 -36
- package/fjs/types/rtti/common/proof.f.d.mts +4 -0
- package/fjs/types/rtti/common/proof.f.mjs +10 -7
- package/fjs/types/rtti/data/module.f.d.mts +134 -0
- package/fjs/types/rtti/data/module.f.mjs +1053 -0
- package/fjs/types/rtti/data/proof.f.d.mts +76 -0
- package/fjs/types/rtti/data/proof.f.mjs +589 -0
- package/fjs/types/rtti/data/types.d.ts +83 -0
- package/fjs/types/rtti/module.f.d.mts +12 -5
- package/fjs/types/rtti/module.f.mjs +7 -5
- package/fjs/types/rtti/parse/module.f.d.mts +48 -0
- package/fjs/types/rtti/parse/module.f.mjs +45 -34
- package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
- package/fjs/types/rtti/parse/proof.f.mjs +51 -52
- package/fjs/types/rtti/proof.f.d.mts +3 -1
- package/fjs/types/rtti/proof.f.mjs +6 -2
- package/fjs/types/rtti/ts/module.f.d.mts +68 -9
- package/fjs/types/rtti/ts/module.f.mjs +258 -30
- package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
- package/fjs/types/rtti/ts/proof.f.mjs +152 -4
- package/fjs/types/rtti/ts/types.d.ts +25 -1
- package/fjs/types/rtti/types.d.ts +40 -0
- package/fjs/types/sorted_list/module.f.d.mts +4 -1
- package/fjs/types/sorted_list/module.f.mjs +21 -12
- package/fjs/types/sorted_list/proof.f.d.mts +3 -1
- package/fjs/types/sorted_list/proof.f.mjs +3 -1
- package/fjs/types/sorted_set/module.f.d.mts +49 -1
- package/fjs/types/sorted_set/module.f.mjs +26 -2
- package/fjs/types/sorted_set/proof.f.d.mts +4 -1
- package/fjs/types/sorted_set/proof.f.mjs +19 -2
- package/fjs/types/string/module.f.d.mts +4 -0
- package/fjs/types/string/module.f.mjs +4 -3
- package/fjs/types/string_set/module.f.d.mts +3 -1
- package/fjs/types/string_set/module.f.mjs +3 -2
- package/fjs/types/ts/module.f.d.mts +2 -0
- package/fjs/types/ts/module.f.mjs +3 -3
- package/fjs/types/ts/proof.f.d.mts +1 -0
- package/fjs/types/ts/proof.f.mjs +5 -0
- package/fjs/types/ts/types.d.ts +6 -1
- package/fjs/types/uint8array/module.f.d.mts +13 -2
- package/fjs/types/uint8array/module.f.mjs +20 -15
- package/fjs/website/module.f.d.mts +5 -2
- package/fjs/website/module.f.mjs +6 -8
- package/fjs/website/proof.f.mjs +2 -1
- package/package.json +3 -3
- package/fjs/asn.1/types.js +0 -6
- package/fjs/asserts/types.js +0 -6
- package/fjs/basen/types.js +0 -6
- package/fjs/bnf/data/types.js +0 -6
- package/fjs/bnf/descent/types.js +0 -6
- package/fjs/bnf/ll1/types.js +0 -6
- package/fjs/bnf/token_symbol/types.js +0 -6
- package/fjs/bnf/types.js +0 -6
- package/fjs/cas/evo/types.js +0 -7
- package/fjs/cas/types.js +0 -6
- package/fjs/ci/common/types.js +0 -1
- package/fjs/ci/nix/types.js +0 -6
- package/fjs/ci/types.js +0 -6
- package/fjs/cli/types.js +0 -6
- package/fjs/common/monoid/types.js +0 -6
- package/fjs/crypto/pow/types.js +0 -6
- package/fjs/crypto/secp/types.js +0 -6
- package/fjs/crypto/sha2/types.js +0 -6
- package/fjs/crypto/sign/types.js +0 -6
- package/fjs/crypto/vdf/types.js +0 -6
- package/fjs/dev/package_json/module.f.d.mts +0 -32
- package/fjs/dev/package_json/module.f.mjs +0 -37
- package/fjs/dev/package_json/proof.f.d.mts +0 -6
- package/fjs/dev/package_json/proof.f.mjs +0 -32
- package/fjs/dev/types.js +0 -6
- package/fjs/djs/ast/types.js +0 -8
- package/fjs/djs/parser/types.js +0 -7
- package/fjs/djs/tokenizer/types.js +0 -7
- package/fjs/djs/types.js +0 -7
- package/fjs/effects/eff/module.f.d.mts +0 -10
- package/fjs/effects/eff/module.f.mjs +0 -68
- package/fjs/effects/eff/proof.f.d.mts +0 -12
- package/fjs/effects/eff/proof.f.mjs +0 -66
- package/fjs/effects/eff/types.d.ts +0 -71
- package/fjs/effects/eff/types.js +0 -6
- package/fjs/effects/list/types.js +0 -6
- package/fjs/effects/memory/types.js +0 -6
- package/fjs/effects/mock/types.js +0 -6
- package/fjs/effects/node/types.js +0 -6
- package/fjs/effects/node/virtual/types.js +0 -7
- package/fjs/effects/types.js +0 -6
- package/fjs/emergent_testing/all.test.d.ts +0 -1
- package/fjs/emergent_testing/all.test.js +0 -5
- package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
- package/fjs/emergent_testing/scenarios/all.js +0 -1
- package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
- package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
- package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
- package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
- package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
- package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
- package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
- package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
- package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
- package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
- package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
- package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
- package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
- package/fjs/emergent_testing/types.js +0 -6
- package/fjs/js/tokenizer/types.js +0 -6
- package/fjs/media/html/types.js +0 -6
- package/fjs/media/json/parser/types.js +0 -6
- package/fjs/media/json/tokenizer/types.js +0 -6
- package/fjs/media/json/types.js +0 -13
- package/fjs/media/nix/types.js +0 -6
- package/fjs/media/revision/types.js +0 -8
- package/fjs/media/type/types.js +0 -6
- package/fjs/media/types.js +0 -7
- package/fjs/nanvm/types.js +0 -11
- package/fjs/protocol/json_rpc/types.js +0 -8
- package/fjs/protocol/mcp/types.js +0 -8
- package/fjs/sul/id/types.js +0 -6
- package/fjs/sul/level/hash/types.js +0 -6
- package/fjs/sul/level/literal/types.js +0 -6
- package/fjs/sul/types.js +0 -6
- package/fjs/text/sgr/types.js +0 -6
- package/fjs/text/types.js +0 -6
- package/fjs/text/utf16/types.js +0 -6
- package/fjs/text/utf8/types.js +0 -6
- package/fjs/types/array/types.js +0 -6
- package/fjs/types/bigfloat/types.js +0 -6
- package/fjs/types/bigint/types.js +0 -6
- package/fjs/types/bit_vec/types.js +0 -6
- package/fjs/types/btree/find/types.js +0 -6
- package/fjs/types/btree/types/types.js +0 -6
- package/fjs/types/byte_set/types.js +0 -6
- package/fjs/types/function/compare/types.js +0 -6
- package/fjs/types/function/operator/types.js +0 -6
- package/fjs/types/function/types.js +0 -6
- package/fjs/types/list/types.js +0 -6
- package/fjs/types/nibble_set/types.js +0 -6
- package/fjs/types/nominal/types.js +0 -6
- package/fjs/types/nullable/types.js +0 -6
- package/fjs/types/object/types.js +0 -8
- package/fjs/types/option/types.js +0 -6
- package/fjs/types/ordered_map/types.js +0 -6
- package/fjs/types/patricia_trie/types.js +0 -6
- package/fjs/types/phantom/types.js +0 -11
- package/fjs/types/prime_field/types.js +0 -6
- package/fjs/types/range/types.js +0 -6
- package/fjs/types/range_map/types.js +0 -6
- package/fjs/types/result/types.js +0 -6
- package/fjs/types/rtti/common/types.js +0 -1
- package/fjs/types/rtti/parse/types.js +0 -1
- package/fjs/types/rtti/ts/types.js +0 -1
- package/fjs/types/rtti/types.js +0 -1
- package/fjs/types/rtti/validate/module.f.d.mts +0 -6
- package/fjs/types/rtti/validate/module.f.mjs +0 -169
- package/fjs/types/rtti/validate/proof.f.d.mts +0 -125
- package/fjs/types/rtti/validate/proof.f.mjs +0 -437
- package/fjs/types/rtti/validate/types.d.ts +0 -6
- package/fjs/types/rtti/validate/types.js +0 -1
- package/fjs/types/sorted_list/types.js +0 -6
- package/fjs/types/sorted_set/types.js +0 -6
- package/fjs/types/string_set/types.js +0 -6
- package/fjs/types/ts/types.js +0 -8
package/fjs/bnf/ll1/proof.f.mjs
CHANGED
|
@@ -1,64 +1,88 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
3
|
-
*
|
|
2
|
+
* @import { CodePoint } from '../../text/utf16/types.ts'
|
|
4
3
|
* @import { RuleSet } from '../data/types.ts'
|
|
4
|
+
* @import { CodePointMeta } from '../descent/types.ts'
|
|
5
|
+
* @import { Rule as FRule } from '../types.ts'
|
|
5
6
|
* @import { MatchResult } from './types.ts'
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
|
|
9
|
-
import { toArray } from '../../types/list/module.f.mjs'
|
|
10
|
-
import { commaJoin0Plus, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
10
|
+
import { map, toArray } from '../../types/list/module.f.mjs'
|
|
11
|
+
import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
11
12
|
import { toData } from '../data/module.f.mjs'
|
|
13
|
+
import { descentParser } from '../descent/module.f.mjs'
|
|
12
14
|
import { dispatchMap, parser, parserRuleSet } from './module.f.mjs'
|
|
13
|
-
import { assertEq } from '../../asserts/module.f.mjs'
|
|
14
|
-
import { deterministic } from '../testlib.f.mjs'
|
|
15
|
+
import { assertEq, assertNotNullish } from '../../asserts/module.f.mjs'
|
|
16
|
+
import { deterministic, showAst } from '../testlib.f.mjs'
|
|
17
|
+
|
|
18
|
+
/** @type {(cp: CodePoint) => CodePointMeta<unknown>} */
|
|
19
|
+
const mapCodePoint = cp => [cp, undefined]
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* One grammar matched by both backends, which must build the same AST for it:
|
|
23
|
+
* the shape is pinned once and asserted against each backend, so neither can
|
|
24
|
+
* drift from the shared contract without this failing.
|
|
25
|
+
*
|
|
26
|
+
* @type {(rule: FRule, s: string, expected: string) => () => void}
|
|
27
|
+
*/
|
|
28
|
+
const bothBackends = (rule, s, expected) => () => {
|
|
29
|
+
const [, entry] = toData(rule)
|
|
30
|
+
const cp = toArray(stringToCodePointList(s))
|
|
31
|
+
const dm = descentParser(rule)(entry, toArray(map(mapCodePoint)(cp)))
|
|
32
|
+
assertEq(showAst(dm.ast), expected, s)
|
|
33
|
+
assertEq(showAst(parser(rule)(entry, cp)[0]), expected, s)
|
|
34
|
+
}
|
|
15
35
|
|
|
16
36
|
export const proof = {
|
|
17
37
|
dispatch: [
|
|
18
38
|
() => {
|
|
19
39
|
const terminalRangeRule = range('AF')
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
const dm = dispatchMap(toData(terminalRangeRule)[0])
|
|
41
|
+
assertEq(
|
|
42
|
+
JSON.stringify(dm),
|
|
43
|
+
'{"":{"rangeMap":[[null,64],[{"name":""},70]]}}')
|
|
24
44
|
},
|
|
25
45
|
() => {
|
|
46
|
+
// The sequence's own entry holds its first set only — the first
|
|
47
|
+
// item's, because that item cannot match empty. Nothing is
|
|
48
|
+
// consumed by dispatch, so no chain of follow-up rules is stored.
|
|
26
49
|
const stringRule = 'AB'
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
50
|
+
const dm = dispatchMap(toData(stringRule)[0])
|
|
51
|
+
assertEq(
|
|
52
|
+
JSON.stringify(dm),
|
|
53
|
+
'{"0":{"rangeMap":[[null,64],[{"name":"0"},65]]},"1":{"rangeMap":[[null,65],[{"name":"1"},66]]},"":{"rangeMap":[[null,64],[{"name":"0"},65]]}}')
|
|
31
54
|
},
|
|
32
55
|
() => {
|
|
33
56
|
const a = range('AA')
|
|
34
57
|
const b = range('BB')
|
|
35
58
|
const ab = [a, b]
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
const dm = dispatchMap(toData(ab)[0])
|
|
60
|
+
assertEq(
|
|
61
|
+
JSON.stringify(dm),
|
|
62
|
+
'{"0":{"rangeMap":[[null,64],[{"name":"0"},65]]},"1":{"rangeMap":[[null,65],[{"name":"1"},66]]},"":{"rangeMap":[[null,64],[{"name":"0"},65]]}}')
|
|
40
63
|
},
|
|
41
64
|
() => {
|
|
42
65
|
const emptyRule = ''
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const result = JSON.stringify(dm)
|
|
46
|
-
if (result !== '{"":{"emptyTag":true,"rangeMap":[]}}') { throw result }
|
|
66
|
+
const dm = dispatchMap(toData(emptyRule)[0])
|
|
67
|
+
assertEq(JSON.stringify(dm), '{"":{"rangeMap":[]}}')
|
|
47
68
|
},
|
|
48
69
|
() => {
|
|
70
|
+
// A variant's entry is the one whose values are read: the branch
|
|
71
|
+
// each lookahead selects, entered before the symbol is consumed.
|
|
49
72
|
const variantRule = { 'a': range('AA'), 'b': range('BB')}
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
73
|
+
const dm = dispatchMap(toData(variantRule)[0])
|
|
74
|
+
assertEq(
|
|
75
|
+
JSON.stringify(dm),
|
|
76
|
+
'{"0":{"rangeMap":[[null,64],[{"name":"0"},65]]},"1":{"rangeMap":[[null,65],[{"name":"1"},66]]},"":{"rangeMap":[[null,64],[{"tag":"a","name":"0"},65],[{"tag":"b","name":"1"},66]]}}')
|
|
54
77
|
},
|
|
55
78
|
() => {
|
|
79
|
+
// `empty` is the nullable branch a dispatch miss selects.
|
|
56
80
|
const emptyRule = ''
|
|
57
81
|
const variantRule = { 'e': emptyRule, 'a': range('AA')}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
82
|
+
const dm = dispatchMap(toData(variantRule)[0])
|
|
83
|
+
assertEq(
|
|
84
|
+
JSON.stringify(dm),
|
|
85
|
+
'{"0":{"rangeMap":[]},"1":{"rangeMap":[[null,64],[{"name":"1"},65]]},"":{"empty":{"tag":"e","name":"0"},"rangeMap":[[null,64],[{"tag":"a","name":"1"},65]]}}')
|
|
62
86
|
},
|
|
63
87
|
() => {
|
|
64
88
|
const emptyRule = ''
|
|
@@ -66,12 +90,14 @@ export const proof = {
|
|
|
66
90
|
const optionalMinusRule = { 'none': emptyRule, 'minus': minursRule}
|
|
67
91
|
const digitRule = range('09')
|
|
68
92
|
const numberRule = [optionalMinusRule, digitRule]
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
93
|
+
const dm = dispatchMap(toData(numberRule)[0])
|
|
94
|
+
assertEq(
|
|
95
|
+
JSON.stringify(dm),
|
|
96
|
+
'{"0":{"empty":{"tag":"none","name":"1"},"rangeMap":[[null,44],[{"tag":"minus","name":"2"},45]]},"1":{"rangeMap":[]},"2":{"rangeMap":[[null,44],[{"name":"2"},45]]},"3":{"rangeMap":[[null,47],[{"name":"3"},57]]},"":{"rangeMap":[[null,44],[{"tag":"minus","name":"2"},45],[null,47],[{"name":"3"},57]]}}')
|
|
73
97
|
},
|
|
74
98
|
() => {
|
|
99
|
+
// A nullable prefix merges each item's first set into the
|
|
100
|
+
// sequence's, up to and including the first non-nullable item.
|
|
75
101
|
const emptyRule = ''
|
|
76
102
|
const spaceRule = range(' ')
|
|
77
103
|
const optionalSpaceRule = { 'none': emptyRule, 'space': spaceRule}
|
|
@@ -79,113 +105,126 @@ export const proof = {
|
|
|
79
105
|
const optionalMinusRule = { 'none': emptyRule, 'minus': minusRule}
|
|
80
106
|
const digitRule = range('09')
|
|
81
107
|
const numberRule = [optionalSpaceRule, optionalMinusRule, digitRule]
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
108
|
+
const dm = dispatchMap(toData(numberRule)[0])
|
|
109
|
+
assertEq(
|
|
110
|
+
JSON.stringify(dm),
|
|
111
|
+
'{"0":{"empty":{"tag":"none","name":"1"},"rangeMap":[[null,31],[{"tag":"space","name":"2"},32]]},"1":{"rangeMap":[]},"2":{"rangeMap":[[null,31],[{"name":"2"},32]]},"3":{"empty":{"tag":"none","name":"1"},"rangeMap":[[null,44],[{"tag":"minus","name":"4"},45]]},"4":{"rangeMap":[[null,44],[{"name":"4"},45]]},"5":{"rangeMap":[[null,47],[{"name":"5"},57]]},"":{"rangeMap":[[null,31],[{"tag":"space","name":"2"},32],[null,44],[{"tag":"minus","name":"4"},45],[null,47],[{"name":"5"},57]]}}')
|
|
112
|
+
},
|
|
113
|
+
() => {
|
|
114
|
+
// A sequence of nullable items only: the first-set loop runs off
|
|
115
|
+
// the end instead of stopping at a non-nullable item.
|
|
116
|
+
/** @type {RuleSet} */
|
|
117
|
+
const ruleSet = {
|
|
118
|
+
s: ['o1', 'o2'],
|
|
119
|
+
o1: { some: 'm', none: 'e' },
|
|
120
|
+
o2: { some: 'a', none: 'e' },
|
|
121
|
+
m: range('--'),
|
|
122
|
+
a: range('AA'),
|
|
123
|
+
e: [],
|
|
124
|
+
}
|
|
125
|
+
assertEq(
|
|
126
|
+
JSON.stringify(dispatchMap(ruleSet)),
|
|
127
|
+
'{"m":{"rangeMap":[[null,44],[{"name":"m"},45]]},"e":{"rangeMap":[]},"o1":{"empty":{"tag":"none","name":"e"},"rangeMap":[[null,44],[{"tag":"some","name":"m"},45]]},"a":{"rangeMap":[[null,64],[{"name":"a"},65]]},"o2":{"empty":{"tag":"none","name":"e"},"rangeMap":[[null,64],[{"tag":"some","name":"a"},65]]},"s":{"rangeMap":[[null,44],[{"tag":"some","name":"m"},45],[null,64],[{"tag":"some","name":"a"},65]]}}')
|
|
128
|
+
assertEq(
|
|
129
|
+
JSON.stringify(parserRuleSet(ruleSet)('s', [45, 65])),
|
|
130
|
+
'[{"sequence":[{"tag":"some","sequence":[45]},{"tag":"some","sequence":[65]}]},true,[]]')
|
|
86
131
|
}
|
|
87
132
|
],
|
|
88
133
|
parser: [
|
|
89
134
|
() => {
|
|
90
135
|
const emptyRule = ''
|
|
91
136
|
const m = parser(emptyRule)
|
|
92
|
-
|
|
93
|
-
const result = JSON.stringify(mr)
|
|
94
|
-
if (result !== '[{"tag":true,"sequence":[]},true,[]]') { throw result }
|
|
137
|
+
assertEq(JSON.stringify(m("", [])), '[{"sequence":[]},true,[]]')
|
|
95
138
|
},
|
|
96
139
|
() => {
|
|
97
140
|
const emptyRule = ''
|
|
98
141
|
const m = parser(emptyRule)
|
|
99
|
-
|
|
100
|
-
const result = JSON.stringify(mr)
|
|
101
|
-
if (result !== '[{"tag":true,"sequence":[]},true,[65,70]]') { throw result }
|
|
142
|
+
assertEq(JSON.stringify(m("", [65, 70])), '[{"sequence":[]},true,[65,70]]')
|
|
102
143
|
},
|
|
103
144
|
() => {
|
|
104
145
|
const terminalRangeRule = range('AF')
|
|
105
146
|
const m = parser(terminalRangeRule)
|
|
106
|
-
|
|
107
|
-
const result = JSON.stringify(mr)
|
|
108
|
-
if (result !== '[{"sequence":[65]},true,[]]') { throw result }
|
|
147
|
+
assertEq(JSON.stringify(m("", [65])), '[{"sequence":[65]},true,[]]')
|
|
109
148
|
},
|
|
110
149
|
() => {
|
|
111
150
|
const terminalRangeRule = 0x000079_000087
|
|
112
151
|
const m = parser(terminalRangeRule)
|
|
113
|
-
|
|
114
|
-
const result = JSON.stringify(mr)
|
|
115
|
-
if (result !== '[{"sequence":[]},false,[64]]') { throw result }
|
|
152
|
+
assertEq(JSON.stringify(m("", [64])), '[{"sequence":[]},false,[64]]')
|
|
116
153
|
},
|
|
117
154
|
() => {
|
|
118
155
|
const terminalRangeRule = 0x000080_000087 //broken range
|
|
119
156
|
const m = parser(terminalRangeRule)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
157
|
+
assertEq(JSON.stringify(m("", [64])), '[{"sequence":[]},false,[64]]')
|
|
158
|
+
},
|
|
159
|
+
() => {
|
|
160
|
+
const variantRule = { 'a': range('AA'), 'b': range('BB')}
|
|
161
|
+
const m = parser(variantRule)
|
|
162
|
+
assertEq(JSON.stringify(m("", [65])), '[{"tag":"a","sequence":[65]},true,[]]')
|
|
123
163
|
},
|
|
124
164
|
() => {
|
|
125
165
|
const variantRule = { 'a': range('AA'), 'b': range('BB')}
|
|
126
166
|
const m = parser(variantRule)
|
|
127
|
-
|
|
128
|
-
const result = JSON.stringify(mr)
|
|
129
|
-
if (result !== '[{"tag":"a","sequence":[65]},true,[]]') { throw result }
|
|
167
|
+
assertEq(JSON.stringify(m("", [64])), '[{"sequence":[]},false,[64]]')
|
|
130
168
|
},
|
|
131
169
|
() => {
|
|
170
|
+
// No branch dispatches on the end of input and none is nullable:
|
|
171
|
+
// the match ran out of input, the `null` remainder.
|
|
132
172
|
const variantRule = { 'a': range('AA'), 'b': range('BB')}
|
|
133
173
|
const m = parser(variantRule)
|
|
134
|
-
|
|
135
|
-
const result = JSON.stringify(mr)
|
|
136
|
-
if (result !== '[{"sequence":[]},false,[64]]') { throw result }
|
|
174
|
+
assertEq(JSON.stringify(m("", [])), '[{"sequence":[]},true,null]')
|
|
137
175
|
},
|
|
138
176
|
() => {
|
|
139
177
|
const emptyRule = ''
|
|
140
178
|
const variantRule = { 'e': emptyRule, 'a': range('AA')}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const result = JSON.stringify(mr)
|
|
144
|
-
if (result !== '[{"tag":"e","sequence":[]},true,[]]') { throw result }
|
|
179
|
+
const m = parser(variantRule)
|
|
180
|
+
assertEq(JSON.stringify(m("", [])), '[{"tag":"e","sequence":[]},true,[]]')
|
|
145
181
|
},
|
|
146
182
|
() => {
|
|
147
183
|
const emptyRule = ''
|
|
148
184
|
const variantRule = { 'e': emptyRule, 'a': range('AA')}
|
|
149
185
|
const m = parser(variantRule)
|
|
150
|
-
|
|
151
|
-
const result = JSON.stringify(mr)
|
|
152
|
-
if (result !== '[{"tag":"e","sequence":[]},true,[64]]') { throw result }
|
|
186
|
+
assertEq(JSON.stringify(m("", [64])), '[{"tag":"e","sequence":[]},true,[64]]')
|
|
153
187
|
},
|
|
154
188
|
() => {
|
|
189
|
+
// Every item of a sequence owns a node — the leading one included.
|
|
155
190
|
const stringRule = 'AB'
|
|
156
191
|
const m = parser(stringRule)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
192
|
+
assertEq(
|
|
193
|
+
JSON.stringify(m("", [65,66])),
|
|
194
|
+
'[{"sequence":[{"sequence":[65]},{"sequence":[66]}]},true,[]]')
|
|
160
195
|
},
|
|
161
196
|
() => {
|
|
197
|
+
// LL(1) never backtracks, so a failure keeps the position where
|
|
198
|
+
// matching stopped: on the rejected `C`.
|
|
162
199
|
const stringRule = 'AB'
|
|
163
200
|
const m = parser(stringRule)
|
|
164
|
-
|
|
165
|
-
const result = JSON.stringify(mr)
|
|
166
|
-
if (result !== '[{"sequence":[]},false,[67]]') { throw result }
|
|
201
|
+
assertEq(JSON.stringify(m("", [65,67])), '[{"sequence":[]},false,[67]]')
|
|
167
202
|
},
|
|
168
203
|
() => {
|
|
204
|
+
// An option that matched empty still owns a node, so the AST says
|
|
205
|
+
// the option was considered.
|
|
169
206
|
const emptyRule = ''
|
|
170
207
|
const minursRule = range('--')
|
|
171
208
|
const optionalMinusRule = { 'none': emptyRule, 'minus': minursRule}
|
|
172
209
|
const digitRule = range('09')
|
|
173
210
|
const numberRule = [optionalMinusRule, digitRule]
|
|
174
211
|
const m = parser(numberRule)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
assertEq(
|
|
213
|
+
JSON.stringify(m("", [50])),
|
|
214
|
+
'[{"sequence":[{"tag":"none","sequence":[]},{"sequence":[50]}]},true,[]]')
|
|
178
215
|
},
|
|
179
216
|
() => {
|
|
217
|
+
// Taken, the option's tag lands on its own node, not the
|
|
218
|
+
// enclosing sequence's.
|
|
180
219
|
const emptyRule = ''
|
|
181
220
|
const minusRule = range('--')
|
|
182
221
|
const optionalMinusRule = { 'none': emptyRule, 'minus': minusRule}
|
|
183
222
|
const digitRule = range('09')
|
|
184
223
|
const numberRule = [optionalMinusRule, digitRule]
|
|
185
224
|
const m = parser(numberRule)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
225
|
+
assertEq(
|
|
226
|
+
JSON.stringify(m("", [45,50])),
|
|
227
|
+
'[{"sequence":[{"tag":"minus","sequence":[45]},{"sequence":[50]}]},true,[]]')
|
|
189
228
|
},
|
|
190
229
|
() => {
|
|
191
230
|
const emptyRule = ''
|
|
@@ -194,9 +233,11 @@ export const proof = {
|
|
|
194
233
|
const digitRule = range('09')
|
|
195
234
|
const numberRule = [optionalMinusRule, digitRule]
|
|
196
235
|
const m = parser(numberRule)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
236
|
+
// The `null` remainder means the match ran out of input; the AST
|
|
237
|
+
// keeps what had matched by then.
|
|
238
|
+
assertEq(
|
|
239
|
+
JSON.stringify(m("", [])),
|
|
240
|
+
'[{"sequence":[{"tag":"none","sequence":[]},{"sequence":[]}]},true,null]')
|
|
200
241
|
},
|
|
201
242
|
() => {
|
|
202
243
|
const m = parser(option('a'))
|
|
@@ -242,87 +283,281 @@ export const proof = {
|
|
|
242
283
|
expect('{a}', true)
|
|
243
284
|
},
|
|
244
285
|
() => {
|
|
245
|
-
const
|
|
286
|
+
const rule = deterministic()
|
|
287
|
+
const [, entry] = toData(rule)
|
|
288
|
+
const md = descentParser(rule)
|
|
289
|
+
const ml = parser(rule)
|
|
246
290
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
291
|
+
// The same inputs as `bnf/descent`'s copy of this group, which
|
|
292
|
+
// pins the AST each one builds. Both backends produce the same
|
|
293
|
+
// AST for the same grammar, so this side asserts equality with
|
|
294
|
+
// `bnf/descent` instead of restating the expectations.
|
|
295
|
+
/** @type {(s: string) => void} */
|
|
296
|
+
const expectSameAst = s => {
|
|
297
|
+
const cp = toArray(stringToCodePointList(s))
|
|
298
|
+
const dm = md(entry, toArray(map(mapCodePoint)(cp)))
|
|
299
|
+
const mr = ml(entry, cp)
|
|
300
|
+
assertEq(mr[1], true, s)
|
|
301
|
+
assertEq(mr[2]?.length, 0, s)
|
|
302
|
+
assertEq(showAst(mr[0]), showAst(dm.ast), s)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** @type {(s: string) => void} */
|
|
306
|
+
const expectNoMatch = s => {
|
|
307
|
+
const mr = ml(entry, toArray(stringToCodePointList(s)))
|
|
308
|
+
assertEq(mr[1] && mr[2]?.length === 0, false, s)
|
|
253
309
|
}
|
|
254
310
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
311
|
+
expectSameAst(' true ')
|
|
312
|
+
expectSameAst(' "Hello" ')
|
|
313
|
+
expectSameAst(' "Hello\\n\\r\\"" ')
|
|
314
|
+
expectSameAst(' -56.7e+5 ')
|
|
315
|
+
expectSameAst(' [] ')
|
|
316
|
+
expectSameAst(' {} ')
|
|
317
|
+
expectSameAst(' [[[]]] ')
|
|
318
|
+
expectSameAst(' [1] ')
|
|
319
|
+
expectSameAst(' [ 12, false, "a"] ')
|
|
320
|
+
expectSameAst(' { "q": [ 12, false, [{"b" : "c"}], "a"] } ')
|
|
321
|
+
expectSameAst(' { "q": [ 12, false, [{}], "a"] } ')
|
|
322
|
+
expectSameAst(' [{ "q": [ 12, false, [{}], "a"] }] ')
|
|
323
|
+
|
|
324
|
+
expectNoMatch(' tr2ue ')
|
|
325
|
+
expectNoMatch(' true" ')
|
|
326
|
+
expectNoMatch(' "Hello ')
|
|
327
|
+
expectNoMatch(' h-56.7e+5 ')
|
|
328
|
+
expectNoMatch(' -56.7e+5 3')
|
|
329
|
+
expectNoMatch(' [ 12, false2, "a"] ')
|
|
330
|
+
expectNoMatch(' { "q": [ 12, false, [}], "a"] } ')
|
|
331
|
+
|
|
332
|
+
// The invalid input in detail. This backend never backtracks, so
|
|
333
|
+
// the remainder is where matching stopped: on the `}` that closes
|
|
334
|
+
// nothing, the same position the descent backend reports as its
|
|
335
|
+
// furthest failure.
|
|
336
|
+
const bad = ' [{ "q": [ 12, false, [}], "a"] }] '
|
|
337
|
+
const badMr = ml(entry, toArray(stringToCodePointList(bad)))
|
|
338
|
+
assertEq(badMr[1], false, bad)
|
|
339
|
+
const remainder = assertNotNullish(badMr[2])
|
|
340
|
+
assertEq(bad.length - remainder.length, 25, bad)
|
|
341
|
+
assertEq(bad[25], '}', bad)
|
|
275
342
|
}
|
|
276
343
|
],
|
|
277
|
-
|
|
344
|
+
longInput: [
|
|
278
345
|
() => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
346
|
+
// Long repetition across the whole input: matched iteratively, so
|
|
347
|
+
// neither the JS call stack nor the frame stack grows with it.
|
|
348
|
+
const rule = repeat0Plus(set(' \n\r\t'))
|
|
349
|
+
const m = parser(rule)
|
|
350
|
+
const [, success, remainder] = m(toData(rule)[1], toArray(stringToCodePointList(' '.repeat(10000))))
|
|
351
|
+
assertEq(success, true)
|
|
352
|
+
assertEq(remainder?.length, 0)
|
|
353
|
+
},
|
|
354
|
+
() => {
|
|
355
|
+
// Deep non-repetition nesting: 5000 bracket levels in the
|
|
356
|
+
// JSON-like test grammar. The frame stack grows on the heap, so
|
|
357
|
+
// depth is bounded by memory rather than the JS call stack.
|
|
358
|
+
const m = parser(deterministic())
|
|
359
|
+
const n = 5000
|
|
360
|
+
const cp = toArray(stringToCodePointList('['.repeat(n) + ']'.repeat(n)))
|
|
361
|
+
const [, success, remainder] = m('', cp)
|
|
362
|
+
assertEq(success, true)
|
|
363
|
+
assertEq(remainder?.length, 0)
|
|
364
|
+
},
|
|
285
365
|
],
|
|
286
|
-
|
|
366
|
+
logicalEof: [
|
|
287
367
|
() => {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
const result = JSON.stringify(mr)
|
|
293
|
-
if (result !== '[{"sequence":[]},true,null]') { throw result }
|
|
368
|
+
// EOF dispatches below every ordinary symbol, so its cut point is
|
|
369
|
+
// `-2` — the stored endpoint codes never reach the dispatch map.
|
|
370
|
+
const dm = dispatchMap(toData(eof)[0])
|
|
371
|
+
assertEq(JSON.stringify(dm), '{"":{"rangeMap":[[null,-2],[{"name":""},-1]]}}')
|
|
294
372
|
},
|
|
295
373
|
() => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
374
|
+
// The matcher synthesizes one EOF after the physical input, so an
|
|
375
|
+
// `eof` terminal matches empty input. It adds no AST leaf, and the
|
|
376
|
+
// remainder stays physical: empty, not `null`.
|
|
377
|
+
const m = parser(eof)
|
|
378
|
+
assertEq(JSON.stringify(m('', [])), '[{"sequence":[]},true,[]]')
|
|
379
|
+
},
|
|
380
|
+
() => {
|
|
381
|
+
// Callers pass physical symbols only, so EOF is not available
|
|
382
|
+
// before the end of the input.
|
|
383
|
+
const m = parser(eof)
|
|
384
|
+
assertEq(JSON.stringify(m('', [65])), '[{"sequence":[]},false,[65]]')
|
|
385
|
+
},
|
|
386
|
+
() => {
|
|
387
|
+
// Non-empty input: the terminal consumes the synthesized EOF after
|
|
388
|
+
// the last code point.
|
|
389
|
+
const m = parser([range('AA'), eof])
|
|
390
|
+
assertEq(JSON.stringify(m('', [65])), '[{"sequence":[{"sequence":[65]},{"sequence":[]}]},true,[]]')
|
|
391
|
+
},
|
|
392
|
+
() => {
|
|
393
|
+
// Exactly one EOF is synthesized: the second `eof` terminal has
|
|
394
|
+
// nothing to consume, so the match runs out of input — the `null`
|
|
395
|
+
// remainder this backend reports for that.
|
|
396
|
+
const m = parser([eof, eof])
|
|
397
|
+
assertEq(JSON.stringify(m('', [])), '[{"sequence":[{"sequence":[]},{"sequence":[]}]},true,null]')
|
|
398
|
+
},
|
|
399
|
+
() => {
|
|
400
|
+
// A variant past the consumed EOF has no symbol to dispatch on:
|
|
401
|
+
// the match runs out of input there too.
|
|
402
|
+
const m = parser([eof, { a: range('AA') }])
|
|
403
|
+
assertEq(JSON.stringify(m('', [])), '[{"sequence":[{"sequence":[]},{"sequence":[]}]},true,null]')
|
|
404
|
+
},
|
|
405
|
+
() => {
|
|
406
|
+
// EOF as one alternative among ordinary terminals.
|
|
407
|
+
const m = parser({ a: range('AA'), e: eof })
|
|
408
|
+
assertEq(JSON.stringify(m('', [])), '[{"tag":"e","sequence":[]},true,[]]')
|
|
409
|
+
assertEq(JSON.stringify(m('', [65])), '[{"tag":"a","sequence":[65]},true,[]]')
|
|
302
410
|
},
|
|
303
411
|
() => {
|
|
412
|
+
// Repetition terminates on EOF: consuming it moves the cursor, so
|
|
413
|
+
// the repeat makes exactly one round and then stops — its second
|
|
414
|
+
// round has no symbol left to dispatch on.
|
|
415
|
+
const rule = repeat0Plus(eof)
|
|
416
|
+
const m = parser(rule)
|
|
417
|
+
assertEq(JSON.stringify(m(toData(rule)[1], [])), '[{"sequence":[{"sequence":[]}]},true,[]]')
|
|
418
|
+
},
|
|
419
|
+
() => {
|
|
420
|
+
// Running out of input inside a repetition round ends the whole
|
|
421
|
+
// match, keeping the rounds collected so far.
|
|
422
|
+
const rule = repeat0Plus([eof, eof])
|
|
423
|
+
const m = parser(rule)
|
|
424
|
+
assertEq(
|
|
425
|
+
JSON.stringify(m(toData(rule)[1], [])),
|
|
426
|
+
'[{"sequence":[{"sequence":[{"sequence":[]},{"sequence":[]}]}]},true,null]')
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
repeat: [
|
|
430
|
+
() => {
|
|
431
|
+
// A `repeat` rule's entry is its item's first set: the matcher
|
|
432
|
+
// starts one more round exactly while the lookahead is in it, and
|
|
433
|
+
// matches the repetition iteratively into one flat node.
|
|
434
|
+
const rule = repeat0Plus(range('AF'))
|
|
435
|
+
const [ruleSet, entry] = toData(rule)
|
|
436
|
+
assertEq(JSON.stringify(ruleSet[entry]), '"0"')
|
|
437
|
+
assertEq(
|
|
438
|
+
JSON.stringify(dispatchMap(ruleSet)[entry]),
|
|
439
|
+
'{"rangeMap":[[null,64],[{"name":"0"},70]]}')
|
|
440
|
+
},
|
|
441
|
+
() => {
|
|
442
|
+
// A repetition of itself has no first set to dispatch on, and
|
|
443
|
+
// asking for one would not terminate. `toData` never folds such a
|
|
444
|
+
// rule; a hand-written rule set can still hold one, and it can
|
|
445
|
+
// only match zero rounds.
|
|
446
|
+
/** @type {RuleSet} */
|
|
447
|
+
const ruleSet = { repeated: 'repeated' }
|
|
448
|
+
assertEq(
|
|
449
|
+
JSON.stringify(dispatchMap(ruleSet)),
|
|
450
|
+
'{"repeated":{"rangeMap":[]}}')
|
|
451
|
+
const m = parserRuleSet(ruleSet)
|
|
452
|
+
assertEq(JSON.stringify(m('repeated', [])), '[{"sequence":[]},true,[]]')
|
|
453
|
+
assertEq(JSON.stringify(m('repeated', [65])), '[{"sequence":[]},true,[65]]')
|
|
454
|
+
},
|
|
455
|
+
() => {
|
|
456
|
+
// The right-recursive spelling `toData` folds away can still be
|
|
457
|
+
// hand-written; it then dispatches — and nests — as the grammar
|
|
458
|
+
// says, one recursion level per item.
|
|
304
459
|
/** @type {readonly [RuleSet, string]} */
|
|
305
460
|
const repeatData = [{"":["ws","repa"],"ws":[],"repa":["a",""],"a":1090519105},""]
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (result !== '[{"sequence":[65,{"sequence":[65,{"sequence":[65,{"sequence":[]}]}]}]},true,null]') { throw result }
|
|
461
|
+
assertEq(
|
|
462
|
+
JSON.stringify(dispatchMap(repeatData[0])),
|
|
463
|
+
'{"ws":{"rangeMap":[]},"a":{"rangeMap":[[null,64],[{"name":"a"},65]]},"repa":{"rangeMap":[[null,64],[{"name":"a"},65]]},"":{"rangeMap":[[null,64],[{"name":"a"},65]]}}')
|
|
310
464
|
},
|
|
465
|
+
],
|
|
466
|
+
repeatParser: [
|
|
311
467
|
() => {
|
|
468
|
+
// The hand-written right-recursive chain: `""` requires `repa`,
|
|
469
|
+
// which requires `a` and `""` again, so every input eventually
|
|
470
|
+
// runs out — the `null` remainder — and the AST nests one level
|
|
471
|
+
// per matched item because the *grammar* is right-recursive.
|
|
312
472
|
/** @type {readonly [RuleSet, string]} */
|
|
313
473
|
const repeatData = [{"":["ws","repa"],"ws":[],"repa":["a",""],"a":1090519105},""]
|
|
314
474
|
const m = parserRuleSet(repeatData[0])
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
475
|
+
assertEq(
|
|
476
|
+
JSON.stringify(m("", [])),
|
|
477
|
+
'[{"sequence":[{"sequence":[]},{"sequence":[{"sequence":[]}]}]},true,null]')
|
|
478
|
+
const mr1 = m("", [65])
|
|
479
|
+
assertEq(showAst(mr1[0]), '(() (("A") (() (()))))')
|
|
480
|
+
assertEq(mr1[1], true)
|
|
481
|
+
assertEq(mr1[2], null)
|
|
482
|
+
const mr3 = m("", [65,65,65])
|
|
483
|
+
assertEq(showAst(mr3[0]), '(() (("A") (() (("A") (() (("A") (() (()))))))))')
|
|
484
|
+
assertEq(mr3[1], true)
|
|
485
|
+
assertEq(mr3[2], null)
|
|
486
|
+
assertEq(JSON.stringify(m("", [66])), '[{"sequence":[]},false,[66]]')
|
|
487
|
+
},
|
|
319
488
|
],
|
|
489
|
+
// The two backends consume the same `RuleSet` and must agree about the AST
|
|
490
|
+
// it implies: `bnf/descent` builds a node per rule *invocation*, and so
|
|
491
|
+
// does this backend — a rule is entered before its first symbol is
|
|
492
|
+
// consumed, so the dispatch only selects and never absorbs a child's leaf,
|
|
493
|
+
// children or tag into the enclosing node.
|
|
494
|
+
//
|
|
495
|
+
// Each case below is one grammar matched by both backends against one
|
|
496
|
+
// pinned AST, so neither can drift from the shared contract unremarked.
|
|
497
|
+
// These are the cases that used to diverge (see the git history of
|
|
498
|
+
// `../ll1/README.md` for the old shapes); only `variant` always agreed.
|
|
499
|
+
descentEquivalence: {
|
|
500
|
+
// Every item of a sequence owns a node, the leading one included.
|
|
501
|
+
leadingItem: bothBackends(
|
|
502
|
+
[range('AA'), range('BB'), range('CC')], 'ABC',
|
|
503
|
+
'(("A") ("B") ("C"))'),
|
|
504
|
+
// A taken variant tags the branch's own node.
|
|
505
|
+
variant: bothBackends(
|
|
506
|
+
{ a: range('AA'), b: range('BB') }, 'A',
|
|
507
|
+
'"a"("A")'),
|
|
508
|
+
// A nullable item that matched empty still owns a node, so the AST
|
|
509
|
+
// says the option was considered.
|
|
510
|
+
skippedOption: bothBackends(
|
|
511
|
+
[option(range('--')), range('09')], '5',
|
|
512
|
+
'("none"() ("5"))'),
|
|
513
|
+
// Taken, the option's tag lands on its own node, not the enclosing one.
|
|
514
|
+
takenOption: bothBackends(
|
|
515
|
+
[option(range('--')), range('09')], '-5',
|
|
516
|
+
'("some"("-") ("5"))'),
|
|
517
|
+
// A repetition is one flat node of items in both backends.
|
|
518
|
+
repetition: bothBackends(
|
|
519
|
+
repeat0Plus(range('AA')), 'AAA',
|
|
520
|
+
'(("A") ("A") ("A"))'),
|
|
521
|
+
// Grouping survives: `[[A,B],C]` and `[A,B,C]` — the `leadingItem`
|
|
522
|
+
// case above — are distinguishable ASTs.
|
|
523
|
+
nesting: bothBackends(
|
|
524
|
+
[[range('AA'), range('BB')], range('CC')], 'ABC',
|
|
525
|
+
'((("A") ("B")) ("C"))'),
|
|
526
|
+
// A repetition leading a sequence: its first set is inlined into the
|
|
527
|
+
// sequence's dispatch entry at build time, yet it still matches as an
|
|
528
|
+
// iterative rule invocation with a flat node of its own.
|
|
529
|
+
repetitionInNullablePrefix: bothBackends(
|
|
530
|
+
[repeat0Plus(range('AA')), range('09')], 'AA5',
|
|
531
|
+
'((("A") ("A")) ("5"))'),
|
|
532
|
+
// The same repetition matching empty leaves an empty node, not nothing.
|
|
533
|
+
emptyRepetitionInNullablePrefix: bothBackends(
|
|
534
|
+
[repeat0Plus(range('AA')), range('09')], '5',
|
|
535
|
+
'(() ("5"))'),
|
|
536
|
+
},
|
|
320
537
|
throw: {
|
|
321
538
|
ambiguousVariantDispatch: () => {
|
|
322
539
|
// Two alternatives covering the same code point — dispatch merge throws.
|
|
323
540
|
const conflictRule = { 'a': range('AA'), 'b': range('AA') }
|
|
324
541
|
dispatchMap(toData(conflictRule)[0])
|
|
325
|
-
}
|
|
542
|
+
},
|
|
543
|
+
// Left recursion is not LL(1): no lookahead can decide it, and a match
|
|
544
|
+
// would loop at the same position forever, so building throws instead.
|
|
545
|
+
leftRecursiveSequence: () => {
|
|
546
|
+
// `s` reaches itself through its nullable first item.
|
|
547
|
+
/** @type {RuleSet} */
|
|
548
|
+
const ruleSet = {
|
|
549
|
+
s: ['o', 's'],
|
|
550
|
+
o: { some: 'm', none: 'e' },
|
|
551
|
+
m: range('--'),
|
|
552
|
+
e: [],
|
|
553
|
+
}
|
|
554
|
+
dispatchMap(ruleSet)
|
|
555
|
+
},
|
|
556
|
+
leftRecursiveVariant: () => {
|
|
557
|
+
/** @type {RuleSet} */
|
|
558
|
+
const ruleSet = { v: { x: 'v', a: 'a' }, a: range('AA') }
|
|
559
|
+
dispatchMap(ruleSet)
|
|
560
|
+
},
|
|
326
561
|
},
|
|
327
562
|
// Regression: `emptyTagMap` must stay correct for cyclic rule references.
|
|
328
563
|
// A naive single-pass, memoized derivation that marks a rule nullable as
|