functionalscript 0.44.0 → 0.45.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/fjs/asn.1/proof.f.d.mts +5 -0
- package/fjs/asn.1/proof.f.mjs +15 -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/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/proof.f.mjs +0 -1
- package/fjs/bnf/descent/module.f.d.mts +17 -2
- package/fjs/bnf/descent/module.f.mjs +118 -41
- package/fjs/bnf/descent/proof.f.d.mts +1 -0
- package/fjs/bnf/descent/proof.f.mjs +77 -1
- package/fjs/bnf/descent/types.d.ts +12 -4
- package/fjs/bnf/ll1/module.f.d.mts +28 -2
- package/fjs/bnf/ll1/module.f.mjs +180 -38
- package/fjs/bnf/ll1/proof.f.d.mts +2 -0
- package/fjs/bnf/ll1/proof.f.mjs +62 -1
- package/fjs/bnf/ll1/types.d.ts +14 -8
- 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/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/proof.f.d.mts +3 -1
- package/fjs/cas/cli/proof.f.mjs +3 -1
- package/fjs/cas/evo/module.f.d.mts +7 -13
- package/fjs/cas/evo/module.f.mjs +103 -96
- package/fjs/cas/evo/proof.f.mjs +6 -3
- package/fjs/cas/module.f.mjs +96 -109
- 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 +2 -2
- package/fjs/ci/config/module.f.mjs +2 -2
- package/fjs/ci/nix/proof.f.d.mts +2 -0
- package/fjs/ci/nix/proof.f.mjs +2 -2
- package/fjs/ci/proof.f.d.mts +4 -2
- package/fjs/ci/proof.f.mjs +4 -3
- package/fjs/cli/proof.f.d.mts +4 -2
- package/fjs/cli/proof.f.mjs +4 -2
- 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/secp/proof.f.d.mts +3 -1
- package/fjs/crypto/secp/proof.f.mjs +3 -1
- package/fjs/crypto/sha2/proof.f.d.mts +3 -1
- package/fjs/crypto/sha2/proof.f.mjs +3 -1
- 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 +5 -2
- package/fjs/dev/module.f.mjs +5 -4
- package/fjs/dev/package_json/module.f.d.mts +7 -0
- package/fjs/dev/package_json/module.f.mjs +10 -7
- package/fjs/dev/update/module.f.d.mts +3 -0
- package/fjs/dev/update/module.f.mjs +3 -2
- package/fjs/dev/update/proof.f.d.mts +3 -0
- package/fjs/dev/update/proof.f.mjs +1 -2
- package/fjs/djs/parser/module.f.d.mts +3 -0
- package/fjs/djs/parser/module.f.mjs +18 -0
- package/fjs/djs/parser/proof.f.d.mts +3 -0
- package/fjs/djs/parser/proof.f.mjs +13 -1
- package/fjs/djs/proof.f.d.mts +3 -0
- package/fjs/djs/proof.f.mjs +4 -1
- package/fjs/djs/serializer/module.f.mjs +5 -4
- package/fjs/djs/tokenizer/module.f.mjs +21 -13
- package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
- package/fjs/djs/tokenizer/proof.f.mjs +14 -2
- package/fjs/djs/transpiler/module.f.d.mts +1 -12
- package/fjs/djs/transpiler/module.f.mjs +1 -20
- package/fjs/djs/transpiler/types.d.ts +25 -0
- package/fjs/effects/eff/module.f.d.mts +10 -0
- package/fjs/effects/eff/module.f.mjs +4 -2
- package/fjs/effects/eff/proof.f.d.mts +3 -0
- package/fjs/effects/eff/proof.f.mjs +4 -1
- package/fjs/effects/list/module.f.d.mts +10 -2
- package/fjs/effects/list/module.f.mjs +4 -2
- package/fjs/effects/memory/module.f.d.mts +4 -2
- package/fjs/effects/memory/module.f.mjs +4 -3
- package/fjs/effects/memory/proof.f.d.mts +4 -0
- package/fjs/effects/memory/proof.f.mjs +5 -2
- package/fjs/effects/mock/module.f.d.mts +10 -2
- package/fjs/effects/mock/module.f.mjs +4 -2
- package/fjs/effects/module.d.mts +8 -0
- package/fjs/effects/module.f.d.mts +6 -4
- package/fjs/effects/module.f.mjs +6 -5
- package/fjs/effects/module.mjs +9 -1
- package/fjs/effects/node/memory/module.d.mts +3 -0
- package/fjs/effects/node/memory/module.mjs +3 -2
- package/fjs/effects/node/memory/proof.d.mts +2 -0
- package/fjs/effects/node/memory/proof.mjs +2 -1
- package/fjs/effects/node/module.d.mts +5 -0
- package/fjs/effects/node/module.f.d.mts +17 -12
- package/fjs/effects/node/module.f.mjs +6 -12
- package/fjs/effects/node/module.mjs +5 -17
- package/fjs/effects/node/virtual/module.f.d.mts +6 -3
- package/fjs/effects/node/virtual/module.f.mjs +6 -5
- package/fjs/effects/node/virtual/proof.f.d.mts +4 -1
- package/fjs/effects/node/virtual/proof.f.mjs +13 -1
- package/fjs/effects/proof.f.d.mts +3 -0
- package/fjs/effects/proof.f.mjs +4 -1
- 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 +6 -1
- package/fjs/emergent_testing/module.f.mjs +40 -66
- package/fjs/emergent_testing/proof.f.mjs +5 -5
- 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/proof.f.d.mts +3 -0
- package/fjs/fsm/proof.f.mjs +4 -1
- package/fjs/js/tokenizer/module.f.d.mts +7 -0
- package/fjs/js/tokenizer/module.f.mjs +19 -55
- package/fjs/mcp/module.f.d.mts +36 -1
- package/fjs/mcp/module.f.mjs +9 -7
- package/fjs/mcp/proof.f.d.mts +11 -1
- package/fjs/mcp/proof.f.mjs +11 -18
- package/fjs/media/html/module.f.d.mts +12 -0
- package/fjs/media/html/module.f.mjs +6 -4
- package/fjs/media/html/proof.f.d.mts +3 -0
- package/fjs/media/html/proof.f.mjs +4 -1
- package/fjs/media/json/parser/module.f.d.mts +1 -1
- package/fjs/media/json/parser/module.f.mjs +25 -8
- package/fjs/media/json/parser/types.d.ts +5 -0
- package/fjs/media/json/rtti/proof.f.d.mts +3 -0
- package/fjs/media/json/rtti/proof.f.mjs +3 -3
- package/fjs/media/json/schema/module.f.d.mts +61 -27
- package/fjs/media/json/schema/module.f.mjs +228 -63
- package/fjs/media/json/schema/proof.f.d.mts +41 -0
- package/fjs/media/json/schema/proof.f.mjs +219 -7
- package/fjs/media/json/serializer/module.f.d.mts +13 -0
- package/fjs/media/json/serializer/module.f.mjs +7 -7
- package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
- package/fjs/media/json/tokenizer/module.f.mjs +24 -5
- 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/revision/module.f.d.mts +5 -0
- package/fjs/media/revision/module.f.mjs +8 -11
- package/fjs/media/revision/proof.f.d.mts +4 -0
- package/fjs/media/revision/proof.f.mjs +5 -2
- package/fjs/media/type/module.f.d.mts +28 -11
- package/fjs/media/type/module.f.mjs +69 -85
- package/fjs/media/type/proof.f.d.mts +16 -0
- package/fjs/media/type/proof.f.mjs +44 -4
- package/fjs/module.d.mts +5 -0
- package/fjs/module.f.d.mts +8 -0
- package/fjs/module.f.mjs +4 -2
- package/fjs/module.mjs +6 -0
- package/fjs/path/module.f.d.mts +8 -0
- package/fjs/path/module.f.mjs +4 -2
- package/fjs/proof.f.d.mts +4 -0
- package/fjs/proof.f.mjs +5 -2
- package/fjs/protocol/json_rpc/module.f.d.mts +1 -1
- package/fjs/protocol/json_rpc/module.f.mjs +7 -4
- package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
- package/fjs/protocol/json_rpc/proof.f.mjs +22 -1
- package/fjs/protocol/mcp/proof.f.d.mts +4 -0
- package/fjs/protocol/mcp/proof.f.mjs +47 -24
- package/fjs/protocol/mcp/stdio/module.f.d.mts +2 -4
- package/fjs/protocol/mcp/stdio/module.f.mjs +1 -8
- package/fjs/protocol/mcp/stdio/proof.f.d.mts +1 -1
- package/fjs/protocol/mcp/stdio/proof.f.mjs +1 -1
- package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
- package/fjs/sul/id/module.f.d.mts +5 -0
- package/fjs/sul/id/module.f.mjs +5 -4
- package/fjs/sul/level/hash/module.f.d.mts +4 -1
- package/fjs/sul/level/hash/module.f.mjs +4 -3
- package/fjs/sul/level/hash/proof.f.d.mts +4 -0
- package/fjs/sul/level/hash/proof.f.mjs +5 -2
- 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 +5 -4
- 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 +21 -3
- package/fjs/text/code_point/module.f.mjs +24 -8
- package/fjs/text/code_point/proof.f.d.mts +1 -0
- package/fjs/text/code_point/proof.f.mjs +28 -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 +4 -1
- package/fjs/text/sgr/module.f.mjs +4 -3
- 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 +31 -33
- package/fjs/text/utf16/proof.f.d.mts +3 -1
- package/fjs/text/utf16/proof.f.mjs +18 -1
- package/fjs/text/utf8/module.f.d.mts +9 -5
- package/fjs/text/utf8/module.f.mjs +16 -18
- package/fjs/types/array/module.f.d.mts +2 -1
- package/fjs/types/array/module.f.mjs +2 -2
- 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 -14
- package/fjs/types/bit_vec/module.f.mjs +61 -71
- package/fjs/types/bit_vec/proof.f.d.mts +6 -0
- package/fjs/types/bit_vec/proof.f.mjs +29 -3
- 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 +9 -9
- 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 +5 -6
- package/fjs/types/btree/set/proof.f.d.mts +3 -0
- package/fjs/types/btree/set/proof.f.mjs +4 -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 +10 -1
- package/fjs/types/byte_set/module.f.mjs +5 -3
- package/fjs/types/byte_set/proof.f.d.mts +3 -1
- package/fjs/types/byte_set/proof.f.mjs +3 -1
- package/fjs/types/function/compare/module.f.d.mts +3 -2
- package/fjs/types/function/compare/module.f.mjs +3 -2
- 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 +9 -2
- package/fjs/types/list/module.f.mjs +5 -3
- 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 +8 -2
- package/fjs/types/nullable/module.f.mjs +4 -2
- 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 +14 -2
- package/fjs/types/object/module.f.mjs +15 -6
- 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 +2 -2
- 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 +35 -2
- package/fjs/types/rtti/common/module.f.mjs +9 -7
- package/fjs/types/rtti/common/proof.f.d.mts +4 -0
- package/fjs/types/rtti/common/proof.f.mjs +5 -2
- package/fjs/types/rtti/data/module.f.d.mts +120 -0
- package/fjs/types/rtti/data/module.f.mjs +1030 -0
- package/fjs/types/rtti/data/proof.f.d.mts +75 -0
- package/fjs/types/rtti/data/proof.f.mjs +566 -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 +38 -0
- package/fjs/types/rtti/parse/module.f.mjs +9 -7
- package/fjs/types/rtti/parse/proof.f.mjs +18 -38
- package/fjs/types/rtti/proof.f.d.mts +3 -1
- package/fjs/types/rtti/proof.f.mjs +3 -1
- package/fjs/types/rtti/ts/module.f.d.mts +68 -9
- package/fjs/types/rtti/ts/module.f.mjs +262 -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 +11 -0
- package/fjs/types/rtti/types.d.ts +40 -0
- package/fjs/types/rtti/validate/module.f.d.mts +36 -1
- package/fjs/types/rtti/validate/module.f.mjs +6 -4
- 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 +31 -1
- package/fjs/types/sorted_set/module.f.mjs +4 -2
- package/fjs/types/sorted_set/proof.f.d.mts +3 -1
- package/fjs/types/sorted_set/proof.f.mjs +3 -1
- 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 +3 -0
- package/fjs/website/module.f.mjs +3 -2
- 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/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/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.d.ts +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/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
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
|
|
9
9
|
import { map, toArray } from '../../types/list/module.f.mjs'
|
|
10
|
-
import { commaJoin0Plus, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
10
|
+
import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
11
11
|
import { emptyTagMap, toData } from '../data/module.f.mjs'
|
|
12
12
|
import { descentParser } from './module.f.mjs'
|
|
13
13
|
import { assertEq, assertNotNullish } from '../../asserts/module.f.mjs'
|
|
@@ -323,6 +323,82 @@ export const proof = {
|
|
|
323
323
|
if (result !== `{"ast":{"sequence":[{"tag":"minus","sequence":[[${cp1('-')},"minus"]]},{"sequence":[[${cp1('2')},"two"]]}]},"success":true,"idx":2}`) { throw result }
|
|
324
324
|
},
|
|
325
325
|
],
|
|
326
|
+
logicalEof: [
|
|
327
|
+
() => {
|
|
328
|
+
// The matcher synthesizes one EOF after the physical input, so the
|
|
329
|
+
// `eof` terminal matches empty input. It contributes no AST leaf,
|
|
330
|
+
// and the public index stays physical.
|
|
331
|
+
const m = descentParser(eof)
|
|
332
|
+
const mr = m('', [])
|
|
333
|
+
assertEq(JSON.stringify(mr), '{"ast":{"sequence":[]},"success":true,"idx":0}')
|
|
334
|
+
},
|
|
335
|
+
() => {
|
|
336
|
+
// Callers pass physical symbols only, so EOF is not available
|
|
337
|
+
// before the end of the input.
|
|
338
|
+
const m = descentParser(eof)
|
|
339
|
+
const mr = descentParserCpOnly(m, '', toArray(stringToCodePointList('A')))
|
|
340
|
+
assertEq(mr.success, false)
|
|
341
|
+
const f = assertNotNullish(mr.failure)
|
|
342
|
+
assertEq(f.idx, 0)
|
|
343
|
+
assertEq(f.expected.length, 1)
|
|
344
|
+
assertEq(f.expected[0], eof)
|
|
345
|
+
},
|
|
346
|
+
() => {
|
|
347
|
+
// Non-empty input: the terminal consumes the synthesized EOF after
|
|
348
|
+
// the last code point, and `idx` still reports `input.length`.
|
|
349
|
+
const m = descentParser([range('AA'), eof])
|
|
350
|
+
const cp = toArray(stringToCodePointList('A'))
|
|
351
|
+
const mr = descentParserCpOnly(m, '', cp)
|
|
352
|
+
assertEq(mr.success, true)
|
|
353
|
+
assertEq(mr.idx, cp.length)
|
|
354
|
+
assertEq(JSON.stringify(mr.ast), `{"sequence":[{"sequence":[[${cp1('A')},null]]},{"sequence":[]}]}`)
|
|
355
|
+
},
|
|
356
|
+
() => {
|
|
357
|
+
// Exactly one EOF is synthesized: a second `eof` terminal has
|
|
358
|
+
// nothing left to consume, and its failure points at `input.length`.
|
|
359
|
+
const m = descentParser([eof, eof])
|
|
360
|
+
const mr = m('', [])
|
|
361
|
+
assertEq(mr.success, false)
|
|
362
|
+
const f = assertNotNullish(mr.failure)
|
|
363
|
+
assertEq(f.idx, 0)
|
|
364
|
+
assertEq(f.expected.length, 1)
|
|
365
|
+
assertEq(f.expected[0], eof)
|
|
366
|
+
},
|
|
367
|
+
() => {
|
|
368
|
+
// EOF as one alternative among ordinary terminals.
|
|
369
|
+
const m = descentParser({ a: range('AA'), e: eof })
|
|
370
|
+
assertEq(JSON.stringify(m('', [])), '{"ast":{"tag":"e","sequence":[]},"success":true,"idx":0}')
|
|
371
|
+
const mr = descentParserCpOnly(m, '', toArray(stringToCodePointList('A')))
|
|
372
|
+
assertEq(mr.success, true)
|
|
373
|
+
assertEq(mr.idx, 1)
|
|
374
|
+
},
|
|
375
|
+
() => {
|
|
376
|
+
// Repetition terminates on EOF: consuming it moves the complete
|
|
377
|
+
// cursor, so the repeat makes exactly one round and then takes its
|
|
378
|
+
// empty branch — with `idx` alone this would never stop.
|
|
379
|
+
const m = descentParser(repeat0Plus(eof))
|
|
380
|
+
const mr = m('', [])
|
|
381
|
+
assertEq(JSON.stringify(mr), '{"ast":{"sequence":[{"sequence":[]},{"tag":"none","sequence":[]}]},"success":true,"idx":0}')
|
|
382
|
+
},
|
|
383
|
+
() => {
|
|
384
|
+
// Backtracking restores the complete cursor: `x` consumes EOF and
|
|
385
|
+
// then fails, so `y` must still find EOF available.
|
|
386
|
+
const m = descentParser({ x: [eof, range('AA')], y: eof })
|
|
387
|
+
assertEq(JSON.stringify(m('', [])), '{"ast":{"tag":"y","sequence":[]},"success":true,"idx":0}')
|
|
388
|
+
},
|
|
389
|
+
() => {
|
|
390
|
+
// Diagnostic ordering by the complete cursor: `y` got further than
|
|
391
|
+
// `x` — the same physical index, but past the EOF it consumed — so
|
|
392
|
+
// only its expectation is reported, and at the physical end.
|
|
393
|
+
const m = descentParser({ x: range('AA'), y: [eof, range('BB')] })
|
|
394
|
+
const mr = m('', [])
|
|
395
|
+
assertEq(mr.success, false)
|
|
396
|
+
const f = assertNotNullish(mr.failure)
|
|
397
|
+
assertEq(f.idx, 0)
|
|
398
|
+
assertEq(f.expected.length, 1)
|
|
399
|
+
assertEq(f.expected[0], range('BB'))
|
|
400
|
+
},
|
|
401
|
+
],
|
|
326
402
|
furthestFailure: [
|
|
327
403
|
() => {
|
|
328
404
|
// A branch rejected *before* the high-water mark must not pull it back:
|
|
@@ -7,9 +7,11 @@ import type { CodePoint } from '../../text/utf16/types.ts';
|
|
|
7
7
|
import type { TerminalRange } from '../types.ts';
|
|
8
8
|
export type AstTag = string | true | undefined;
|
|
9
9
|
/**
|
|
10
|
-
* Recursive descent matcher for a single named rule
|
|
10
|
+
* Recursive descent matcher for a single named rule, starting from `startPos` —
|
|
11
|
+
* a position that counts the synthesized end-of-input symbol, unlike the public
|
|
12
|
+
* `idx` of the result.
|
|
11
13
|
*/
|
|
12
|
-
export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePointMeta<T>[],
|
|
14
|
+
export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePointMeta<T>[], startPos: number) => DescentMatchResult<T>;
|
|
13
15
|
/**
|
|
14
16
|
* Where a match ran out of road, for diagnostics.
|
|
15
17
|
*
|
|
@@ -24,6 +26,11 @@ export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePo
|
|
|
24
26
|
*
|
|
25
27
|
* `idx` is `0` with an empty `expected` when the match failed without ever
|
|
26
28
|
* rejecting a terminal, as an empty variant does.
|
|
29
|
+
*
|
|
30
|
+
* `idx` is physical, so a terminal rejected at — or past — the synthesized
|
|
31
|
+
* end-of-input symbol reports `input.length`. The high-water mark itself is
|
|
32
|
+
* kept on the complete cursor, so those two are still ordered against each
|
|
33
|
+
* other and their expected terminals do not merge.
|
|
27
34
|
*/
|
|
28
35
|
export type DescentFailure = {
|
|
29
36
|
readonly idx: number;
|
|
@@ -41,8 +48,9 @@ export type DescentFailure = {
|
|
|
41
48
|
* On failure `idx` has rewound to the start of the enclosing sequence and
|
|
42
49
|
* locates nothing; read `failure.idx` instead.
|
|
43
50
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
51
|
+
* `idx` is physical — `0 <= idx <= input.length` — so a match that consumed the
|
|
52
|
+
* synthesized end-of-input symbol reports `input.length`, the same as one that
|
|
53
|
+
* stopped just before it.
|
|
46
54
|
*/
|
|
47
55
|
export type DescentMatchResult<T> = {
|
|
48
56
|
readonly ast: AstRuleMeta<T>;
|
|
@@ -8,19 +8,24 @@
|
|
|
8
8
|
* grammar is not LL(1) — a first/first conflict. Nullability is looked up from
|
|
9
9
|
* {@link emptyTagMap} in `fjs/bnf/data` rather than re-derived here.
|
|
10
10
|
*
|
|
11
|
+
* The caller passes physical symbols only; the matcher synthesizes the one
|
|
12
|
+
* logical EOF ({@link eofSymbol}) after them, so a grammar can dispatch on the
|
|
13
|
+
* end of input with the `eof` terminal.
|
|
14
|
+
*
|
|
11
15
|
* See `./types.ts` for the type-level API.
|
|
12
16
|
*
|
|
13
17
|
* @module
|
|
14
18
|
*
|
|
19
|
+
* @import { CodePoint } from '../../text/utf16/types.ts'
|
|
15
20
|
* @import { Properties } from '../../types/range_map/types.ts'
|
|
16
21
|
* @import { StringSet } from '../../types/string_set/types.ts'
|
|
17
22
|
* @import { EmptyTag, RuleSet } from '../data/types.ts'
|
|
18
23
|
* @import { Rule as FRule } from '../types.ts'
|
|
19
|
-
* @import { AstSequence, AstTag, Match, MatchResult,
|
|
24
|
+
* @import { AstSequence, AstTag, Match, MatchResult, Remainder, _AstRule, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
|
|
20
25
|
*/
|
|
21
26
|
import type { RuleSet } from '../data/types.ts';
|
|
22
27
|
import type { Rule as FRule } from '../types.ts';
|
|
23
|
-
import type { Match, _DispatchMap } from './types.ts';
|
|
28
|
+
import type { AstSequence, AstTag, Match, _AstRule, _DispatchMap, _DispatchRule } from './types.ts';
|
|
24
29
|
/**
|
|
25
30
|
* Builds a dispatch map for a {@link RuleSet} to enable predictive parsing.
|
|
26
31
|
*
|
|
@@ -33,6 +38,27 @@ export declare const dispatchMap: (ruleSet: RuleSet) => _DispatchMap;
|
|
|
33
38
|
* @type {(fr: FRule) => Match}
|
|
34
39
|
*/
|
|
35
40
|
export declare const parser: (fr: FRule) => Match;
|
|
41
|
+
export type _Cursor = number;
|
|
42
|
+
export type _Position = _Cursor | null;
|
|
43
|
+
export type _Result = {
|
|
44
|
+
readonly ast: _AstRule;
|
|
45
|
+
readonly success: boolean;
|
|
46
|
+
readonly pos: _Position;
|
|
47
|
+
};
|
|
48
|
+
export type _Frame = {
|
|
49
|
+
readonly tag: AstTag;
|
|
50
|
+
readonly rules: readonly string[];
|
|
51
|
+
readonly ruleIndex: number;
|
|
52
|
+
readonly seq: AstSequence;
|
|
53
|
+
};
|
|
54
|
+
export type _Stack = null | {
|
|
55
|
+
readonly top: _Frame;
|
|
56
|
+
readonly rest: _Stack;
|
|
57
|
+
};
|
|
58
|
+
export type _Task = {
|
|
59
|
+
readonly rule: _DispatchRule;
|
|
60
|
+
readonly pos: _Cursor;
|
|
61
|
+
};
|
|
36
62
|
/**
|
|
37
63
|
* Creates an LL(1) parser from an already materialized {@link RuleSet}.
|
|
38
64
|
*
|
package/fjs/bnf/ll1/module.f.mjs
CHANGED
|
@@ -8,22 +8,27 @@
|
|
|
8
8
|
* grammar is not LL(1) — a first/first conflict. Nullability is looked up from
|
|
9
9
|
* {@link emptyTagMap} in `fjs/bnf/data` rather than re-derived here.
|
|
10
10
|
*
|
|
11
|
+
* The caller passes physical symbols only; the matcher synthesizes the one
|
|
12
|
+
* logical EOF ({@link eofSymbol}) after them, so a grammar can dispatch on the
|
|
13
|
+
* end of input with the `eof` terminal.
|
|
14
|
+
*
|
|
11
15
|
* See `./types.ts` for the type-level API.
|
|
12
16
|
*
|
|
13
17
|
* @module
|
|
14
18
|
*
|
|
19
|
+
* @import { CodePoint } from '../../text/utf16/types.ts'
|
|
15
20
|
* @import { Properties } from '../../types/range_map/types.ts'
|
|
16
21
|
* @import { StringSet } from '../../types/string_set/types.ts'
|
|
17
22
|
* @import { EmptyTag, RuleSet } from '../data/types.ts'
|
|
18
23
|
* @import { Rule as FRule } from '../types.ts'
|
|
19
|
-
* @import { AstSequence, AstTag, Match, MatchResult,
|
|
24
|
+
* @import { AstSequence, AstTag, Match, MatchResult, Remainder, _AstRule, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
|
|
20
25
|
*/
|
|
21
26
|
|
|
22
27
|
import { strictEqual } from '../../types/function/operator/module.f.mjs'
|
|
23
28
|
import { toArray } from '../../types/list/module.f.mjs'
|
|
24
29
|
import { rangeMap } from '../../types/range_map/module.f.mjs'
|
|
25
30
|
import { contains, set } from '../../types/string_set/module.f.mjs'
|
|
26
|
-
import { rangeDecode } from '../module.f.mjs'
|
|
31
|
+
import { eofSymbol, rangeDecode } from '../module.f.mjs'
|
|
27
32
|
import { definedEntries } from '../../types/object/module.f.mjs'
|
|
28
33
|
import { emptyTagMap, toData } from '../data/module.f.mjs'
|
|
29
34
|
|
|
@@ -145,13 +150,101 @@ export const parser = fr => {
|
|
|
145
150
|
return parserRuleSet(data[0])
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
/**
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
/**
|
|
154
|
+
* A match position over the physical input: `0 .. cp.length` are the physical
|
|
155
|
+
* positions, and `cp.length + 1` is where the one synthesized EOF has been
|
|
156
|
+
* consumed.
|
|
157
|
+
*
|
|
158
|
+
* This is the `(idx, eofConsumed)` cursor written as one number: `eofConsumed`
|
|
159
|
+
* can only be true at the physical end, so the pair and the extended position
|
|
160
|
+
* hold the same information.
|
|
161
|
+
*
|
|
162
|
+
* @typedef {number} _Cursor
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Where a match stopped: a {@link _Cursor}, or `null` when it ran out of input
|
|
167
|
+
* — the `null` {@link Remainder} this backend reports for that.
|
|
168
|
+
*
|
|
169
|
+
* @typedef {_Cursor|null} _Position
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The machine's own result: a {@link MatchResult} positioned by a cursor
|
|
174
|
+
* instead of by a materialized remainder.
|
|
175
|
+
*
|
|
176
|
+
* @typedef {{
|
|
177
|
+
* readonly ast: _AstRule
|
|
178
|
+
* readonly success: boolean
|
|
179
|
+
* readonly pos: _Position
|
|
180
|
+
* }} _Result
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* A suspended rules-chain match: `rules[ruleIndex]` is being matched by the
|
|
185
|
+
* current task, and `seq` holds the ASTs matched so far — starting with the
|
|
186
|
+
* dispatched symbol's leaf, empty when that symbol was the synthesized EOF.
|
|
187
|
+
*
|
|
188
|
+
* @typedef {{
|
|
189
|
+
* readonly tag: AstTag
|
|
190
|
+
* readonly rules: readonly string[]
|
|
191
|
+
* readonly ruleIndex: number
|
|
192
|
+
* readonly seq: AstSequence
|
|
193
|
+
* }} _Frame
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Immutable cons-cell stack: O(1) push/pop, no array copying per step.
|
|
198
|
+
*
|
|
199
|
+
* @typedef {null | {
|
|
200
|
+
* readonly top: _Frame
|
|
201
|
+
* readonly rest: _Stack
|
|
202
|
+
* }} _Stack
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The rule invocation about to be evaluated, or `null` when a result is ready
|
|
207
|
+
* to resume the innermost frame instead.
|
|
208
|
+
*
|
|
209
|
+
* @typedef {{
|
|
210
|
+
* readonly rule: _DispatchRule
|
|
211
|
+
* readonly pos: _Cursor
|
|
212
|
+
* }} _Task
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
/** @type {(tag: AstTag, sequence: AstSequence, pos: _Position) => _Result} */
|
|
216
|
+
const mrSuccess = (tag, sequence, pos) =>
|
|
217
|
+
({ast: {tag, sequence}, success: true, pos})
|
|
151
218
|
|
|
152
|
-
/** @type {(tag: AstTag, sequence: AstSequence,
|
|
153
|
-
const mrFail = (tag, sequence,
|
|
154
|
-
|
|
219
|
+
/** @type {(tag: AstTag, sequence: AstSequence, pos: _Position) => _Result} */
|
|
220
|
+
const mrFail = (tag, sequence, pos) =>
|
|
221
|
+
({ast: {tag, sequence}, success: false, pos})
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* The semantic symbol a cursor points at: a code point inside the physical
|
|
225
|
+
* input, and the synthesized {@link eofSymbol} at its end. Only meaningful
|
|
226
|
+
* where the cursor still has a symbol, `pos <= cp.length`.
|
|
227
|
+
*
|
|
228
|
+
* @type {(cp: readonly CodePoint[], pos: _Cursor) => number}
|
|
229
|
+
*/
|
|
230
|
+
const symbolAt = (cp, pos) => pos < cp.length ? cp[pos] : eofSymbol
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* What consuming the symbol at a cursor contributes to the AST: the code point
|
|
234
|
+
* itself, and nothing for the synthesized EOF — it has no physical source
|
|
235
|
+
* element.
|
|
236
|
+
*
|
|
237
|
+
* @type {(cp: readonly CodePoint[], pos: _Cursor) => AstSequence}
|
|
238
|
+
*/
|
|
239
|
+
const leafAt = (cp, pos) => pos < cp.length ? [cp[pos]] : []
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The public remainder of a position. It stays physical, so consuming EOF
|
|
243
|
+
* leaves it empty; the slice is materialized once, at the end of a match.
|
|
244
|
+
*
|
|
245
|
+
* @type {(cp: readonly CodePoint[], pos: _Position) => Remainder}
|
|
246
|
+
*/
|
|
247
|
+
const remainderAt = (cp, pos) => pos === null ? null : cp.slice(Math.min(pos, cp.length))
|
|
155
248
|
|
|
156
249
|
/**
|
|
157
250
|
* Creates an LL(1) parser from an already materialized {@link RuleSet}.
|
|
@@ -161,39 +254,88 @@ const mrFail = (tag, sequence, r) =>
|
|
|
161
254
|
export const parserRuleSet = ruleSet => {
|
|
162
255
|
const map = dispatchMap(ruleSet)
|
|
163
256
|
|
|
164
|
-
/** @type {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
|
|
257
|
+
/** @type {(name: string) => _DispatchRule} */
|
|
258
|
+
const dispatched = name => /** @type {_DispatchRule} */ (map[name])
|
|
259
|
+
|
|
260
|
+
// The matcher as an explicit-stack machine: each iteration either starts the
|
|
261
|
+
// current task (dispatching one rule and pushing a frame for the rules chain
|
|
262
|
+
// that symbol selected) or feeds the pending result into the innermost frame.
|
|
263
|
+
// Semantics are identical to the former recursive matcher, but the JS call
|
|
264
|
+
// stack stays O(1) however deep the grammar recurses: a right-recursive rule
|
|
265
|
+
// (e.g. a `repeat0Plus` chain) descends once per consumed code point, so the
|
|
266
|
+
// depth used to grow with input length and overflow (see the longInput proof
|
|
267
|
+
// group). Positions are cursors into the shared input array for the same
|
|
268
|
+
// reason: re-slicing the remainder per step made a match quadratic.
|
|
269
|
+
/** @type {(dr0: _DispatchRule, cp: readonly CodePoint[]) => MatchResult} */
|
|
270
|
+
const f = (dr0, cp) => {
|
|
271
|
+
/** @type {_Stack} */
|
|
272
|
+
let stack = null
|
|
273
|
+
/** @type {_Task|null} */
|
|
274
|
+
let task = {rule: dr0, pos: 0}
|
|
275
|
+
/** @type {_Result} */
|
|
276
|
+
let result = mrFail(undefined, [], 0)
|
|
277
|
+
|
|
278
|
+
while (true) {
|
|
279
|
+
if (task !== null) {
|
|
280
|
+
// The explicit annotation cuts a control-flow inference cycle
|
|
281
|
+
// (TS7022): `task`'s narrowed type feeds `pos`, which feeds the
|
|
282
|
+
// `task` assignment below that the narrowing depends on.
|
|
283
|
+
/** @type {_Task} */
|
|
284
|
+
const current = task
|
|
285
|
+
const {rule: {emptyTag, rangeMap}, pos} = current
|
|
286
|
+
task = null
|
|
287
|
+
// The one logical EOF is available at the physical end, and only
|
|
288
|
+
// there: a rule that dispatches on it consumes it, once. Past it
|
|
289
|
+
// no symbol is left to dispatch on.
|
|
290
|
+
const dr = pos > cp.length ? null : dispatchOp.get(rangeMap)(symbolAt(cp, pos))
|
|
291
|
+
if (dr === null) {
|
|
292
|
+
if (emptyTag !== undefined) {
|
|
293
|
+
result = mrSuccess(emptyTag, [], pos)
|
|
294
|
+
} else if (pos >= cp.length) {
|
|
295
|
+
// Nothing left to reject: the match ran out of input.
|
|
296
|
+
result = mrSuccess(emptyTag, [], null)
|
|
297
|
+
} else {
|
|
298
|
+
result = mrFail(emptyTag, [], pos)
|
|
299
|
+
}
|
|
300
|
+
continue
|
|
301
|
+
}
|
|
302
|
+
const {tag, rules} = dr
|
|
303
|
+
const seq = leafAt(cp, pos)
|
|
304
|
+
const next = pos + 1
|
|
305
|
+
if (rules.length === 0) {
|
|
306
|
+
result = mrSuccess(tag, seq, next)
|
|
307
|
+
} else {
|
|
308
|
+
stack = {top: {tag, rules, ruleIndex: 0, seq}, rest: stack}
|
|
309
|
+
task = {rule: dispatched(rules[0]), pos: next}
|
|
310
|
+
}
|
|
311
|
+
continue
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (stack === null) {
|
|
315
|
+
const {ast, success, pos} = result
|
|
316
|
+
return [ast, success, remainderAt(cp, pos)]
|
|
317
|
+
}
|
|
318
|
+
const frame = stack.top
|
|
319
|
+
stack = stack.rest
|
|
320
|
+
|
|
321
|
+
const {ast, success, pos} = result
|
|
322
|
+
// A failing item's own result propagates unchanged, exactly as the
|
|
323
|
+
// recursive version returned it through the chain.
|
|
324
|
+
if (success === false) { continue }
|
|
325
|
+
const seq = [...frame.seq, ast]
|
|
326
|
+
if (pos === null) {
|
|
327
|
+
result = mrSuccess(frame.tag, seq, null)
|
|
328
|
+
continue
|
|
188
329
|
}
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
|
|
330
|
+
const ruleIndex = frame.ruleIndex + 1
|
|
331
|
+
if (ruleIndex < frame.rules.length) {
|
|
332
|
+
stack = {top: {...frame, ruleIndex, seq}, rest: stack}
|
|
333
|
+
task = {rule: dispatched(frame.rules[ruleIndex]), pos}
|
|
334
|
+
} else {
|
|
335
|
+
result = mrSuccess(frame.tag, seq, pos)
|
|
192
336
|
}
|
|
193
|
-
r = newR
|
|
194
337
|
}
|
|
195
|
-
return mrSuccess(tag, seq, r)
|
|
196
338
|
}
|
|
197
339
|
|
|
198
|
-
return (name, cp) => f(
|
|
340
|
+
return (name, cp) => f(dispatched(name), cp)
|
|
199
341
|
}
|
package/fjs/bnf/ll1/proof.f.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
|
|
9
9
|
import { toArray } from '../../types/list/module.f.mjs'
|
|
10
|
-
import { commaJoin0Plus, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
10
|
+
import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
|
|
11
11
|
import { toData } from '../data/module.f.mjs'
|
|
12
12
|
import { dispatchMap, parser, parserRuleSet } from './module.f.mjs'
|
|
13
13
|
import { assertEq } from '../../asserts/module.f.mjs'
|
|
@@ -274,6 +274,67 @@ export const proof = {
|
|
|
274
274
|
expect(' [{ "q": [ 12, false, [}], "a"] }] ', false)
|
|
275
275
|
}
|
|
276
276
|
],
|
|
277
|
+
longInput: [
|
|
278
|
+
() => {
|
|
279
|
+
// Long right-recursive repetition: one `repeat0Plus` chain across the
|
|
280
|
+
// whole input. This is the shape that overflowed the JS call stack
|
|
281
|
+
// when the matcher recursed once per consumed code point.
|
|
282
|
+
const m = parser(repeat0Plus(set(' \n\r\t')))
|
|
283
|
+
const [, success, remainder] = m('', toArray(stringToCodePointList(' '.repeat(10000))))
|
|
284
|
+
assertEq(success, true)
|
|
285
|
+
assertEq(remainder?.length, 0)
|
|
286
|
+
},
|
|
287
|
+
() => {
|
|
288
|
+
// Deep non-repetition nesting: 5000 bracket levels in the JSON-like
|
|
289
|
+
// test grammar — a shape a repetition-specific fix would not cover.
|
|
290
|
+
const m = parser(deterministic())
|
|
291
|
+
const n = 5000
|
|
292
|
+
const cp = toArray(stringToCodePointList('['.repeat(n) + ']'.repeat(n)))
|
|
293
|
+
const [, success, remainder] = m('', cp)
|
|
294
|
+
assertEq(success, true)
|
|
295
|
+
assertEq(remainder?.length, 0)
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
logicalEof: [
|
|
299
|
+
() => {
|
|
300
|
+
// EOF dispatches below every ordinary symbol, so its cut point is
|
|
301
|
+
// `-2` — the stored endpoint codes never reach the dispatch map.
|
|
302
|
+
const dm = dispatchMap(toData(eof)[0])
|
|
303
|
+
assertEq(JSON.stringify(dm), '{"":{"rangeMap":[[null,-2],[{"rules":[]},-1]]}}')
|
|
304
|
+
},
|
|
305
|
+
() => {
|
|
306
|
+
// The matcher synthesizes one EOF after the physical input, so an
|
|
307
|
+
// `eof` terminal matches empty input. It adds no AST leaf, and the
|
|
308
|
+
// remainder stays physical: empty, not `null`.
|
|
309
|
+
const m = parser(eof)
|
|
310
|
+
assertEq(JSON.stringify(m('', [])), '[{"sequence":[]},true,[]]')
|
|
311
|
+
},
|
|
312
|
+
() => {
|
|
313
|
+
// Callers pass physical symbols only, so EOF is not available
|
|
314
|
+
// before the end of the input.
|
|
315
|
+
const m = parser(eof)
|
|
316
|
+
assertEq(JSON.stringify(m('', [65])), '[{"sequence":[]},false,[65]]')
|
|
317
|
+
},
|
|
318
|
+
() => {
|
|
319
|
+
// Non-empty input: the terminal consumes the synthesized EOF after
|
|
320
|
+
// the last code point.
|
|
321
|
+
const m = parser([range('AA'), eof])
|
|
322
|
+
assertEq(JSON.stringify(m('', [65])), '[{"sequence":[65,{"sequence":[]}]},true,[]]')
|
|
323
|
+
},
|
|
324
|
+
() => {
|
|
325
|
+
// Exactly one EOF is synthesized: the second `eof` terminal has
|
|
326
|
+
// nothing to consume, so the match runs out of input — the `null`
|
|
327
|
+
// remainder this backend reports for that.
|
|
328
|
+
const m = parser([eof, eof])
|
|
329
|
+
assertEq(JSON.stringify(m('', [])), '[{"sequence":[{"sequence":[]}]},true,null]')
|
|
330
|
+
},
|
|
331
|
+
() => {
|
|
332
|
+
// EOF as one alternative among ordinary terminals.
|
|
333
|
+
const m = parser({ a: range('AA'), e: eof })
|
|
334
|
+
assertEq(JSON.stringify(m('', [])), '[{"tag":"e","sequence":[]},true,[]]')
|
|
335
|
+
assertEq(JSON.stringify(m('', [65])), '[{"tag":"a","sequence":[65]},true,[]]')
|
|
336
|
+
},
|
|
337
|
+
],
|
|
277
338
|
repeat: [
|
|
278
339
|
() => {
|
|
279
340
|
/** @type {readonly [RuleSet, string]} */
|
package/fjs/bnf/ll1/types.d.ts
CHANGED
|
@@ -16,12 +16,16 @@ export type _DispatchRule = {
|
|
|
16
16
|
export type _Dispatch = RangeMapArray<_DispatchResult>;
|
|
17
17
|
/** @internal */
|
|
18
18
|
export type _DispatchResult = _DispatchRuleCollection | null;
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/**
|
|
20
|
+
* The rules a dispatched symbol selects, to be matched one after another. They
|
|
21
|
+
* are names into the {@link _DispatchMap}: the builder only ever appends rule
|
|
22
|
+
* names, so the matcher resolves each one there.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
22
26
|
export type _DispatchRuleCollection = {
|
|
23
27
|
readonly tag: string | undefined;
|
|
24
|
-
readonly rules:
|
|
28
|
+
readonly rules: readonly string[];
|
|
25
29
|
};
|
|
26
30
|
/** @internal */
|
|
27
31
|
export type _DispatchMap = StringMap<_DispatchRule>;
|
|
@@ -41,6 +45,9 @@ export type AstSequence = readonly (_AstRule | CodePoint)[];
|
|
|
41
45
|
export type AstTag = string | true | undefined;
|
|
42
46
|
/**
|
|
43
47
|
* Represents the remaining input after a match attempt, or `null` if no match is possible.
|
|
48
|
+
*
|
|
49
|
+
* The remainder is physical: consuming the synthesized end-of-input symbol
|
|
50
|
+
* leaves it empty rather than making it `null`.
|
|
44
51
|
*/
|
|
45
52
|
export type Remainder = readonly CodePoint[] | null;
|
|
46
53
|
/**
|
|
@@ -51,9 +58,8 @@ export type Remainder = readonly CodePoint[] | null;
|
|
|
51
58
|
export type MatchResult = readonly [_AstRule, boolean, Remainder];
|
|
52
59
|
/**
|
|
53
60
|
* LL(1) parser function for matching by rule name.
|
|
61
|
+
*
|
|
62
|
+
* `s` holds physical symbols only; the matcher synthesizes the one logical
|
|
63
|
+
* end-of-input symbol after them.
|
|
54
64
|
*/
|
|
55
65
|
export type Match = (name: string, s: readonly CodePoint[]) => MatchResult;
|
|
56
|
-
/**
|
|
57
|
-
* Internal match function signature used by compiled dispatch rules.
|
|
58
|
-
*/
|
|
59
|
-
export type MatchRule = (dr: _DispatchRule, s: readonly CodePoint[]) => MatchResult;
|
package/fjs/bnf/module.f.d.mts
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import type { Tuple } from '../types/array/types.ts';
|
|
14
14
|
import type { TerminalRange, Sequence, Rule, RangeVariant, None, Option, Repeat0Plus, Repeat1Plus, Join1Plus, Repeat } from './types.ts';
|
|
15
|
+
/**
|
|
16
|
+
* The logical end-of-input symbol.
|
|
17
|
+
*
|
|
18
|
+
* `-1` is outside the non-negative physical-symbol domain, so no alphabet
|
|
19
|
+
* adapter can produce it and no ordinary symbol has to be reserved for it.
|
|
20
|
+
* Parser backends synthesize it exactly once, after the physical input.
|
|
21
|
+
*/
|
|
22
|
+
export declare const eofSymbol = -1;
|
|
15
23
|
/** @type {(a: number, b: number) => TerminalRange} */
|
|
16
24
|
export declare const rangeEncode: (a: number, b: number) => TerminalRange;
|
|
17
25
|
/**
|
|
@@ -21,16 +29,17 @@ export declare const rangeEncode: (a: number, b: number) => TerminalRange;
|
|
|
21
29
|
*/
|
|
22
30
|
export declare const oneEncode: (a: number) => TerminalRange;
|
|
23
31
|
/**
|
|
24
|
-
* End-of-file marker:
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* real code point.
|
|
32
|
+
* End-of-file marker: the singleton range of {@link eofSymbol}. Deliberately
|
|
33
|
+
* outside the ordinary symbol domain — and so outside Unicode — so it can
|
|
34
|
+
* never collide with a real code point.
|
|
28
35
|
*
|
|
29
36
|
* @type {TerminalRange}
|
|
30
37
|
*/
|
|
31
38
|
export declare const eof: TerminalRange;
|
|
32
39
|
/**
|
|
33
|
-
*
|
|
40
|
+
* Every ordinary symbol packed into a single {@link TerminalRange}. EOF is not
|
|
41
|
+
* one of them, so complements over this range never include it.
|
|
42
|
+
*
|
|
34
43
|
* @type {TerminalRange}
|
|
35
44
|
*/
|
|
36
45
|
export declare const fullRange: TerminalRange;
|
|
@@ -44,7 +53,7 @@ export declare const unicodeRange: TerminalRange;
|
|
|
44
53
|
*/
|
|
45
54
|
export declare const unicodeMax: string;
|
|
46
55
|
/**
|
|
47
|
-
* Decodes a packed range into `[start, end]` symbols.
|
|
56
|
+
* Decodes a packed range into `[start, end]` semantic symbols.
|
|
48
57
|
*
|
|
49
58
|
* @type {(r: number) => Tuple<2, number>}
|
|
50
59
|
*/
|