semantifold 0.1.1 → 0.3.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 +42 -10
- package/build/index.d.ts +32 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +99 -4
- package/build/src/acceptance.d.ts +32 -0
- package/build/src/acceptance.d.ts.map +1 -0
- package/build/src/acceptance.js +358 -0
- package/build/src/array.d.ts +7 -0
- package/build/src/array.d.ts.map +1 -0
- package/build/src/array.js +18 -0
- package/build/src/artifact-path.d.ts +13 -0
- package/build/src/artifact-path.d.ts.map +1 -0
- package/build/src/artifact-path.js +30 -0
- package/build/src/artifacts.d.ts +7 -0
- package/build/src/artifacts.d.ts.map +1 -0
- package/build/src/artifacts.js +389 -0
- package/build/src/backends/c-runtime.d.ts +3 -0
- package/build/src/backends/c-runtime.d.ts.map +1 -0
- package/build/src/backends/c-runtime.js +151 -0
- package/build/src/backends/c-validation.d.ts +12 -0
- package/build/src/backends/c-validation.d.ts.map +1 -0
- package/build/src/backends/c-validation.js +85 -0
- package/build/src/backends/c.d.ts +31 -0
- package/build/src/backends/c.d.ts.map +1 -0
- package/build/src/backends/c.js +308 -0
- package/build/src/backends/cpp-runtime.d.ts +3 -0
- package/build/src/backends/cpp-runtime.d.ts.map +1 -0
- package/build/src/backends/cpp-runtime.js +99 -0
- package/build/src/backends/cpp-validation.d.ts +9 -0
- package/build/src/backends/cpp-validation.d.ts.map +1 -0
- package/build/src/backends/cpp-validation.js +74 -0
- package/build/src/backends/cpp.d.ts +16 -0
- package/build/src/backends/cpp.d.ts.map +1 -0
- package/build/src/backends/cpp.js +285 -0
- package/build/src/backends/csharp.d.ts +20 -0
- package/build/src/backends/csharp.d.ts.map +1 -0
- package/build/src/backends/csharp.js +259 -0
- package/build/src/backends/go.d.ts +20 -0
- package/build/src/backends/go.d.ts.map +1 -0
- package/build/src/backends/go.js +374 -0
- package/build/src/backends/identifiers.d.ts +12 -0
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +79 -2
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -37
- package/build/src/backends/native-validation.d.ts +9 -0
- package/build/src/backends/native-validation.d.ts.map +1 -0
- package/build/src/backends/native-validation.js +59 -0
- package/build/src/backends/ordered-expressions.d.ts +74 -0
- package/build/src/backends/ordered-expressions.d.ts.map +1 -0
- package/build/src/backends/ordered-expressions.js +159 -0
- package/build/src/backends/python.d.ts +8 -0
- package/build/src/backends/python.d.ts.map +1 -0
- package/build/src/backends/python.js +162 -0
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +8 -2
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +67 -19
- package/build/src/binary-mapping.d.ts +32 -0
- package/build/src/binary-mapping.d.ts.map +1 -0
- package/build/src/binary-mapping.js +285 -0
- package/build/src/diagnostic.d.ts +36 -4
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +42 -3
- package/build/src/frontends/c-parser.d.ts +20 -0
- package/build/src/frontends/c-parser.d.ts.map +1 -0
- package/build/src/frontends/c-parser.js +14 -0
- package/build/src/frontends/c.d.ts +220 -0
- package/build/src/frontends/c.d.ts.map +1 -0
- package/build/src/frontends/c.js +750 -0
- package/build/src/frontends/cpp-parser.d.ts +11 -0
- package/build/src/frontends/cpp-parser.d.ts.map +1 -0
- package/build/src/frontends/cpp-parser.js +15 -0
- package/build/src/frontends/cpp.d.ts +227 -0
- package/build/src/frontends/cpp.d.ts.map +1 -0
- package/build/src/frontends/cpp.js +784 -0
- package/build/src/frontends/csharp.d.ts +14 -0
- package/build/src/frontends/csharp.d.ts.map +1 -0
- package/build/src/frontends/csharp.js +708 -0
- package/build/src/frontends/go.d.ts +15 -0
- package/build/src/frontends/go.d.ts.map +1 -0
- package/build/src/frontends/go.js +712 -0
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +5 -23
- package/build/src/frontends/python.d.ts +14 -0
- package/build/src/frontends/python.d.ts.map +1 -0
- package/build/src/frontends/python.js +615 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +21 -1
- package/build/src/language-registry.d.ts +113 -0
- package/build/src/language-registry.d.ts.map +1 -0
- package/build/src/language-registry.js +421 -0
- package/build/src/mapping.js +3 -2
- package/build/src/semantic/location.d.ts +7 -0
- package/build/src/semantic/location.d.ts.map +1 -1
- package/build/src/semantic/location.js +10 -1
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +399 -2
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +110 -2
- package/build/src/subprocess.d.ts +38 -0
- package/build/src/subprocess.d.ts.map +1 -0
- package/build/src/subprocess.js +233 -0
- package/build/src/timeout.d.ts +8 -0
- package/build/src/timeout.d.ts.map +1 -0
- package/build/src/timeout.js +11 -0
- package/build/src/toolchains.d.ts +107 -0
- package/build/src/toolchains.d.ts.map +1 -0
- package/build/src/toolchains.js +417 -0
- package/docs/architecture.md +23 -5
- package/docs/c.md +60 -0
- package/docs/cpp.md +61 -0
- package/docs/goals.md +4 -2
- package/docs/language-support.md +46 -6
- package/docs/parser-qualification.md +219 -0
- package/docs/plans/2026-09-05-standard-library-portability.md +46 -0
- package/docs/source-maps.md +38 -5
- package/docs/standard-library-portability.md +190 -0
- package/docs/testing.md +131 -3
- package/index.js +109 -4
- package/node_modules/node-addon-api/LICENSE.md +9 -0
- package/node_modules/node-addon-api/README.md +95 -0
- package/node_modules/node-addon-api/common.gypi +21 -0
- package/node_modules/node-addon-api/except.gypi +25 -0
- package/node_modules/node-addon-api/index.js +14 -0
- package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
- package/node_modules/node-addon-api/napi-inl.h +7250 -0
- package/node_modules/node-addon-api/napi.h +3463 -0
- package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
- package/node_modules/node-addon-api/node_api.gyp +9 -0
- package/node_modules/node-addon-api/noexcept.gypi +26 -0
- package/node_modules/node-addon-api/nothing.c +0 -0
- package/node_modules/node-addon-api/package-support.json +21 -0
- package/node_modules/node-addon-api/package.json +481 -0
- package/node_modules/node-addon-api/tools/README.md +73 -0
- package/node_modules/node-addon-api/tools/check-napi.js +99 -0
- package/node_modules/node-addon-api/tools/clang-format.js +71 -0
- package/node_modules/node-addon-api/tools/conversion.js +301 -0
- package/node_modules/node-gyp-build/LICENSE +21 -0
- package/node_modules/node-gyp-build/README.md +58 -0
- package/node_modules/node-gyp-build/SECURITY.md +5 -0
- package/node_modules/node-gyp-build/bin.js +84 -0
- package/node_modules/node-gyp-build/build-test.js +19 -0
- package/node_modules/node-gyp-build/index.js +6 -0
- package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
- package/node_modules/node-gyp-build/optional.js +7 -0
- package/node_modules/node-gyp-build/package.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/LICENSE +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +7 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/README.md +90 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/binding.gyp +79 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/index.js +895 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/package.json +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.cc +106 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.cc +1056 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.cc +298 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.cc +383 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.h +39 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.cc +307 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/README.md +18 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/binding.gyp +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/grammar.js +1470 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/package.json +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/tags.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/grammar.json +9735 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/node-types.json +4614 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/parser.c +119615 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter-c.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/README.md +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/grammar.js +1436 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/package.json +61 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/highlights.scm +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/injections.scm +3 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/tags.scm +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/grammar.json +17084 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/node-types.json +7997 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/parser.c +530368 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/scanner.c +148 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter-cpp.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter.json +55 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +152 -0
- package/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/tree-sitter/README.md +128 -0
- package/node_modules/tree-sitter/binding.gyp +88 -0
- package/node_modules/tree-sitter/index.js +950 -0
- package/node_modules/tree-sitter/package.json +76 -0
- package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/tree-sitter/src/language.cc +105 -0
- package/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/tree-sitter/src/node.cc +1088 -0
- package/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/tree-sitter/src/parser.cc +332 -0
- package/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/tree-sitter/src/query.cc +425 -0
- package/node_modules/tree-sitter/src/query.h +40 -0
- package/node_modules/tree-sitter/src/tree.cc +316 -0
- package/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/tree-sitter/tree-sitter.d.ts +1083 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1478 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +523 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +483 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +54 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +875 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2297 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +286 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +241 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4347 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +912 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1034 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +716 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +75 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +137 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1314 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1937 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/package.json +24 -6
- package/src/acceptance.js +380 -0
- package/src/array.js +19 -0
- package/src/artifact-path.js +34 -0
- package/src/artifacts.js +420 -0
- package/src/backends/c-runtime.js +151 -0
- package/src/backends/c-validation.js +83 -0
- package/src/backends/c.js +308 -0
- package/src/backends/cpp-runtime.js +99 -0
- package/src/backends/cpp-validation.js +70 -0
- package/src/backends/cpp.js +285 -0
- package/src/backends/csharp.js +270 -0
- package/src/backends/go.js +383 -0
- package/src/backends/identifiers.js +80 -1
- package/src/backends/index.js +23 -32
- package/src/backends/native-validation.js +64 -0
- package/src/backends/ordered-expressions.js +161 -0
- package/src/backends/python.js +175 -0
- package/src/backends/scalars.js +8 -1
- package/src/backends/shared.js +64 -17
- package/src/binary-mapping.js +305 -0
- package/src/diagnostic.js +34 -2
- package/src/frontends/c-parser.js +17 -0
- package/src/frontends/c.js +780 -0
- package/src/frontends/cpp-parser.js +18 -0
- package/src/frontends/cpp.js +816 -0
- package/src/frontends/csharp.js +759 -0
- package/src/frontends/go.js +770 -0
- package/src/frontends/index.js +5 -20
- package/src/frontends/python.js +689 -0
- package/src/frontends/scalars.js +20 -0
- package/src/language-registry.js +454 -0
- package/src/mapping.js +2 -1
- package/src/semantic/location.js +10 -0
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +124 -1
- package/src/subprocess.js +232 -0
- package/src/timeout.js +12 -0
- package/src/toolchains.js +448 -0
- package/tsconfig.json +1 -0
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {generateCpp} from "../backends/cpp.js"
|
|
4
|
+
import {OrderedExpressionPlanner} from "../backends/ordered-expressions.js"
|
|
5
|
+
import {maximumCppSourceLength} from "../backends/cpp-validation.js"
|
|
6
|
+
import {validateNativeGraph} from "../backends/native-validation.js"
|
|
7
|
+
import {cppRuntime} from "../backends/cpp-runtime.js"
|
|
8
|
+
import {validateBackendModule} from "../backends/shared.js"
|
|
9
|
+
import {isCppIdentifier} from "../backends/identifiers.js"
|
|
10
|
+
import {parseCppCst} from "./cpp-parser.js"
|
|
11
|
+
import {missingType, SemantifoldDiagnostic, unsupportedSyntax} from "../diagnostic.js"
|
|
12
|
+
import {createCoordinateIndex, indexedPointAt} from "../semantic/location.js"
|
|
13
|
+
import {withAdaptedOperation} from "../semantic/operators.js"
|
|
14
|
+
import {withParserRanges} from "../semantic/provenance.js"
|
|
15
|
+
import {hasOnlyUnicodeScalars} from "../semantic/scalars.js"
|
|
16
|
+
import {validateParsedModule} from "../semantic/validate.js"
|
|
17
|
+
import {sourceScalarType} from "./scalars.js"
|
|
18
|
+
|
|
19
|
+
/** @typedef {import("./cpp-parser.js").CstNode} CstNode */
|
|
20
|
+
/** @typedef {import("../semantic/types.js").Expression} Expression */
|
|
21
|
+
/** @typedef {import("../semantic/types.js").Statement} Statement */
|
|
22
|
+
|
|
23
|
+
const binaryOperations = new Map([
|
|
24
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
25
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
26
|
+
["&&", "And"], ["||", "Or"]
|
|
27
|
+
])
|
|
28
|
+
const helpers = new Map([
|
|
29
|
+
["semantifold_integer_add", "PhpAdd"], ["semantifold_integer_subtract", "Subtract"],
|
|
30
|
+
["semantifold_integer_multiply", "Multiply"], ["semantifold_string_concat", "StringConcat"],
|
|
31
|
+
["semantifold_string_equal", "StringEqual"], ["semantifold_string_not_equal", "StringNotEqual"]
|
|
32
|
+
])
|
|
33
|
+
|
|
34
|
+
/** Strict field-and-token consumer for the private frozen CPP CST. */
|
|
35
|
+
export class CppReader {
|
|
36
|
+
/**
|
|
37
|
+
* Owns source content and its coordinate index, never native parser handles.
|
|
38
|
+
* @param {string} filename - Original filename.
|
|
39
|
+
* @param {string} source - Exact original source.
|
|
40
|
+
*/
|
|
41
|
+
constructor(filename, source) {
|
|
42
|
+
this.filename = filename
|
|
43
|
+
this.source = source
|
|
44
|
+
this.coordinates = createCoordinateIndex(source)
|
|
45
|
+
this.generated = false
|
|
46
|
+
/** @type {Map<string, Expression> | undefined} */
|
|
47
|
+
this.temporaryExpressions = undefined
|
|
48
|
+
/** @type {Set<string> | undefined} */
|
|
49
|
+
this.temporaryNames = undefined
|
|
50
|
+
/** @type {Map<Statement, {node: CstNode, type: string}>} */
|
|
51
|
+
this.printTypes = new Map()
|
|
52
|
+
/** @type {Set<string>} */
|
|
53
|
+
this.declaredFunctions = new Set()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Locates one parser-owned range in UTF-16 coordinates.
|
|
58
|
+
* @param {CstNode} node - Parser node.
|
|
59
|
+
* @returns {import("../semantic/types.js").SourceLocation} Verified location.
|
|
60
|
+
*/
|
|
61
|
+
location(node) {
|
|
62
|
+
return {filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex)}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Reads only the spelling of an already recognized parser node.
|
|
67
|
+
* @param {CstNode} node - Parser node.
|
|
68
|
+
* @returns {string} Exact token spelling.
|
|
69
|
+
*/
|
|
70
|
+
text(node) {
|
|
71
|
+
return this.source.slice(node.startIndex, node.endIndex)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Rejects a located source-profile violation.
|
|
76
|
+
* @param {CstNode} node - Rejected node.
|
|
77
|
+
* @param {string} [detail] - Profile violation.
|
|
78
|
+
* @returns {never} Always throws.
|
|
79
|
+
*/
|
|
80
|
+
fail(node, detail = node.type) {
|
|
81
|
+
unsupportedSyntax("cpp", detail, this.location(node))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Traverses all edges before interpreting any source meaning.
|
|
86
|
+
* @param {CstNode} node - Current parser node.
|
|
87
|
+
* @param {number} [depth] - Bounded CST traversal depth.
|
|
88
|
+
* @returns {void}
|
|
89
|
+
*/
|
|
90
|
+
validateTree(node, depth = 0) {
|
|
91
|
+
if (depth > 512) this.fail(node, "CPP CST exceeds the 512-level traversal limit")
|
|
92
|
+
for (const {node: child} of node.children) this.validateTree(child, depth + 1)
|
|
93
|
+
if (node.error || node.missing || node.hasError) {
|
|
94
|
+
throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "cpp", location: this.location(node), message: `CPP parser recovery at '${node.type}'.`})
|
|
95
|
+
}
|
|
96
|
+
if (node.extra && node.type != "comment") this.fail(node, "unexpected extra parser child")
|
|
97
|
+
if ((node.type == "comment" || node.type == "string_content") && /\?\?[=/'()!<>-]/u.test(this.text(node))) {
|
|
98
|
+
this.fail(node, "trigraph preprocessing")
|
|
99
|
+
}
|
|
100
|
+
if (node.type == "comment") {
|
|
101
|
+
const text = this.text(node)
|
|
102
|
+
|
|
103
|
+
// A terminal CR belongs to ordinary CRLF; content after a bare CR is not a CPP line comment.
|
|
104
|
+
if (/\\(?:\r\n?|\n)/u.test(text) || text.startsWith("//") && /\r(?!\n|$)/u.test(text)) {
|
|
105
|
+
this.fail(node, "preprocessing-sensitive comment")
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Separates harmless comments after every child has been validated.
|
|
112
|
+
* @param {CstNode} node - Parent node.
|
|
113
|
+
* @returns {CstNode[]} Ordered structural children.
|
|
114
|
+
*/
|
|
115
|
+
parts(node) {
|
|
116
|
+
return node.children.map(({node: child}) => child).filter((child) => child.type != "comment")
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Requires one exact field rather than searching descendants.
|
|
121
|
+
* @param {CstNode} node - Field owner.
|
|
122
|
+
* @param {string} name - Field name.
|
|
123
|
+
* @returns {CstNode} Sole field child.
|
|
124
|
+
*/
|
|
125
|
+
field(node, name) {
|
|
126
|
+
const matches = node.children.filter(({field}) => field == name)
|
|
127
|
+
|
|
128
|
+
if (matches.length != 1) return this.fail(node, `expected one '${name}' field`)
|
|
129
|
+
return matches[0].node
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Consumes every structural child, including punctuation.
|
|
134
|
+
* @param {CstNode} node - Shape owner.
|
|
135
|
+
* @param {(CstNode | string)[]} expected - Ordered nodes or token kinds.
|
|
136
|
+
* @returns {void}
|
|
137
|
+
*/
|
|
138
|
+
shape(node, expected) {
|
|
139
|
+
const children = this.parts(node)
|
|
140
|
+
|
|
141
|
+
if (children.length != expected.length || children.some((child, index) =>
|
|
142
|
+
typeof expected[index] == "string" ? child.type != expected[index] : child !== expected[index])) this.fail(node, `${node.type} child shape`)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Requires an ordinary caller identifier outside the protected namespace.
|
|
147
|
+
* @param {CstNode} node - Identifier token.
|
|
148
|
+
* @returns {string} Accepted spelling.
|
|
149
|
+
*/
|
|
150
|
+
identifier(node) {
|
|
151
|
+
const name = this.text(node)
|
|
152
|
+
|
|
153
|
+
if (node.type != "identifier" || !isCppIdentifier(name)) this.fail(node, "reserved or unsupported identifier")
|
|
154
|
+
return name
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Converts only the canonical scalar type spellings.
|
|
159
|
+
* @param {CstNode} node - Type token.
|
|
160
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic scalar.
|
|
161
|
+
*/
|
|
162
|
+
type(node) {
|
|
163
|
+
const spelling = node.type == "qualified_identifier" ? this.qualified(node) : this.text(node)
|
|
164
|
+
|
|
165
|
+
if (node.type != "qualified_identifier" && (node.type != "primitive_type" || spelling != "bool")) this.fail(node, "scalar type shape")
|
|
166
|
+
const type = sourceScalarType("cpp", spelling, this.location(node))
|
|
167
|
+
|
|
168
|
+
if (!type) return this.fail(node, "unsupported scalar type")
|
|
169
|
+
return type
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Reads exactly one std-qualified scalar name from CPP fields and punctuation.
|
|
174
|
+
* @param {CstNode} node - Qualified grammar node.
|
|
175
|
+
* @returns {string} Canonical qualified scalar spelling.
|
|
176
|
+
*/
|
|
177
|
+
qualified(node) {
|
|
178
|
+
const scope = this.field(node, "scope")
|
|
179
|
+
const name = this.field(node, "name")
|
|
180
|
+
|
|
181
|
+
this.shape(node, [scope, "::", name])
|
|
182
|
+
if (scope.type != "namespace_identifier" || this.text(scope) != "std" ||
|
|
183
|
+
!["type_identifier", "identifier"].includes(name.type) || !["int64_t", "string"].includes(this.text(name))) this.fail(node, "qualified scalar name")
|
|
184
|
+
return "std::" + this.text(name)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Converts a direct function call's exact argument list.
|
|
189
|
+
* @param {CstNode} node - Call node.
|
|
190
|
+
* @returns {{name: CstNode, arguments: CstNode[]}} Parsed call shape.
|
|
191
|
+
*/
|
|
192
|
+
call(node) {
|
|
193
|
+
if (node.type != "call_expression") return this.fail(node, "direct call required")
|
|
194
|
+
const name = this.field(node, "function")
|
|
195
|
+
const list = this.field(node, "arguments")
|
|
196
|
+
|
|
197
|
+
this.shape(node, [name, list])
|
|
198
|
+
if (!["identifier", "qualified_identifier"].includes(name.type) || list.type != "argument_list") this.fail(node, "direct call shape")
|
|
199
|
+
const parts = this.parts(list)
|
|
200
|
+
const args = parts.slice(1, -1).filter((_part, index) => index % 2 == 0)
|
|
201
|
+
|
|
202
|
+
this.shape(list, ["(", ...args.flatMap((arg, index) => index == 0 ? [arg] : [",", arg]), ")"])
|
|
203
|
+
return {arguments: args, name}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Decodes a parser-backed ordinary CPP string token as UTF-8 bytes.
|
|
208
|
+
* @param {CstNode} node - String literal.
|
|
209
|
+
* @returns {string} Complete Unicode scalar value.
|
|
210
|
+
*/
|
|
211
|
+
string(node) {
|
|
212
|
+
if (node.type != "string_literal") return this.fail(node, "ordinary string literal required")
|
|
213
|
+
const parts = this.parts(node)
|
|
214
|
+
|
|
215
|
+
if (parts[0]?.type != '"' || parts.at(-1)?.type != '"') this.fail(node, "prefixed string literal")
|
|
216
|
+
const bytes = []
|
|
217
|
+
|
|
218
|
+
for (let index = 1; index < parts.length - 1; index++) {
|
|
219
|
+
const child = parts[index]
|
|
220
|
+
const text = this.text(child)
|
|
221
|
+
|
|
222
|
+
if (child.type == "string_content") {
|
|
223
|
+
if (/[\r\n]/u.test(text)) this.fail(child, "raw line terminator in string literal")
|
|
224
|
+
for (const byte of new TextEncoder().encode(text)) bytes.push(byte)
|
|
225
|
+
}
|
|
226
|
+
else if (child.type == "escape_sequence") {
|
|
227
|
+
const simple = new Map([["a", 7], ["b", 8], ["f", 12], ["n", 10], ["r", 13], ["t", 9], ["v", 11], ["\\", 92], ['"', 34], ["'", 39], ["?", 63]])
|
|
228
|
+
const value = text.slice(1)
|
|
229
|
+
|
|
230
|
+
if (text[0] != "\\") this.fail(child, "invalid escape")
|
|
231
|
+
if (simple.has(value)) bytes.push(/** @type {number} */ (simple.get(value)))
|
|
232
|
+
else if (/^[0-7]{1,3}$/u.test(value) || /^x[0-9a-fA-F]+$/u.test(value)) {
|
|
233
|
+
const next = parts[index + 1]
|
|
234
|
+
|
|
235
|
+
// CPP consumes every adjacent hex digit; the frozen grammar caps each escape node at four.
|
|
236
|
+
if (value.startsWith("x") && next.type == "string_content" && next.startIndex == child.endIndex && /^[0-9a-fA-F]/u.test(this.text(next))) {
|
|
237
|
+
this.fail(child, "hexadecimal escape split by parser boundary")
|
|
238
|
+
}
|
|
239
|
+
const number = Number.parseInt(value[0] == "x" ? value.slice(1) : value, value[0] == "x" ? 16 : 8)
|
|
240
|
+
|
|
241
|
+
if (number > 255) this.fail(child, "escape outside byte range")
|
|
242
|
+
bytes.push(number)
|
|
243
|
+
} else this.fail(child, "unsupported escape")
|
|
244
|
+
} else this.fail(child, "string child")
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
return new TextDecoder("utf-8", {fatal: true, ignoreBOM: true}).decode(new Uint8Array(bytes))
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error instanceof TypeError) return this.fail(node, "invalid UTF-8 literal bytes")
|
|
250
|
+
throw error
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Converts supported expressions without assuming CPP argument evaluation order.
|
|
256
|
+
* @param {CstNode} node - Expression node.
|
|
257
|
+
* @param {boolean} [nested] - Whether a semantic call would have unspecified order.
|
|
258
|
+
* @returns {Expression} Semantic expression.
|
|
259
|
+
*/
|
|
260
|
+
expression(node, nested = false) {
|
|
261
|
+
const location = this.location(node)
|
|
262
|
+
|
|
263
|
+
if (node.type == "condition_clause") {
|
|
264
|
+
const value = this.field(node, "value")
|
|
265
|
+
|
|
266
|
+
this.shape(node, ["(", value, ")"])
|
|
267
|
+
return this.expression(value, nested)
|
|
268
|
+
}
|
|
269
|
+
if (node.type == "parenthesized_expression") {
|
|
270
|
+
const parts = this.parts(node)
|
|
271
|
+
|
|
272
|
+
this.shape(node, ["(", parts[1], ")"])
|
|
273
|
+
return this.expression(parts[1], nested)
|
|
274
|
+
}
|
|
275
|
+
if (node.type == "identifier") {
|
|
276
|
+
const temporary = this.temporaryExpressions?.get(this.text(node))
|
|
277
|
+
|
|
278
|
+
if (temporary) {
|
|
279
|
+
this.temporaryExpressions?.delete(this.text(node))
|
|
280
|
+
return temporary
|
|
281
|
+
}
|
|
282
|
+
return withParserRanges({kind: "IdentifierExpression", location, name: this.identifier(node)}, {name: location})
|
|
283
|
+
}
|
|
284
|
+
if (node.type == "true" || node.type == "false") {
|
|
285
|
+
if (this.text(node) != node.type) this.fail(node, "noncanonical Boolean literal spelling")
|
|
286
|
+
return withParserRanges({kind: "BooleanLiteral", location, value: node.type == "true"}, {literal: location})
|
|
287
|
+
}
|
|
288
|
+
if (node.type == "number_literal") this.fail(node, "integer literal requires exact std::int64_t construction")
|
|
289
|
+
if (node.type == "binary_expression") {
|
|
290
|
+
const left = this.field(node, "left")
|
|
291
|
+
const right = this.field(node, "right")
|
|
292
|
+
const operator = this.field(node, "operator")
|
|
293
|
+
const intent = binaryOperations.get(operator.type)
|
|
294
|
+
|
|
295
|
+
this.shape(node, [left, operator, right])
|
|
296
|
+
if (!intent) return this.fail(operator, "unsupported binary operator")
|
|
297
|
+
return this.binary(node, intent, this.expression(left, true), this.expression(right, true), operator)
|
|
298
|
+
}
|
|
299
|
+
if (node.type == "unary_expression") {
|
|
300
|
+
const operator = this.field(node, "operator")
|
|
301
|
+
const argument = this.field(node, "argument")
|
|
302
|
+
|
|
303
|
+
this.shape(node, [operator, argument])
|
|
304
|
+
if (!["-", "!"].includes(operator.type)) this.fail(operator, "unsupported unary operator")
|
|
305
|
+
return this.unary(node, operator.type == "-" ? "Negate" : "Not", this.expression(argument, true), operator)
|
|
306
|
+
}
|
|
307
|
+
if (node.type == "call_expression") {
|
|
308
|
+
const call = this.call(node)
|
|
309
|
+
const name = this.text(call.name)
|
|
310
|
+
|
|
311
|
+
if (call.name.type == "qualified_identifier") {
|
|
312
|
+
const qualified = this.qualified(call.name)
|
|
313
|
+
|
|
314
|
+
if (qualified == "std::int64_t") {
|
|
315
|
+
if (call.arguments.length != 1 || call.arguments[0].type != "number_literal") this.fail(node, "exact integer literal construction")
|
|
316
|
+
const spelling = this.text(call.arguments[0])
|
|
317
|
+
|
|
318
|
+
if (!/^(?:0|[1-9][0-9]*)$/u.test(spelling) || !Number.isSafeInteger(Number(spelling))) this.fail(call.arguments[0], "non-safe or noncanonical integer")
|
|
319
|
+
return withParserRanges({kind: "IntegerLiteral", location, value: Number(spelling)}, {literal: location})
|
|
320
|
+
}
|
|
321
|
+
if (qualified == "std::string") {
|
|
322
|
+
if (call.arguments.length != 2 || call.arguments[1].type != "number_literal") this.fail(node, "byte-counted string literal construction")
|
|
323
|
+
const value = this.string(call.arguments[0])
|
|
324
|
+
const length = this.text(call.arguments[1])
|
|
325
|
+
|
|
326
|
+
if (length != String(Buffer.byteLength(value, "utf8"))) this.fail(node, "string literal byte count")
|
|
327
|
+
return withParserRanges({kind: "StringLiteral", location, value}, {literal: location})
|
|
328
|
+
}
|
|
329
|
+
this.fail(call.name, "qualified user call")
|
|
330
|
+
}
|
|
331
|
+
// Generated operations are separate temporary initializers; only exact scalar literal constructions may nest as calls.
|
|
332
|
+
if (nested) this.fail(node, "caller call in unspecified-order expression")
|
|
333
|
+
if (name == "semantifold_integer_negate") {
|
|
334
|
+
if (call.arguments.length != 1) this.fail(node, "negation helper arity")
|
|
335
|
+
return this.unary(node, "Negate", this.expression(call.arguments[0], true), call.name)
|
|
336
|
+
}
|
|
337
|
+
const intent = helpers.get(name)
|
|
338
|
+
|
|
339
|
+
if (intent) {
|
|
340
|
+
if (call.arguments.length != 2) this.fail(node, "scalar helper arity")
|
|
341
|
+
return this.binary(node, intent, this.expression(call.arguments[0], true), this.expression(call.arguments[1], true), call.name)
|
|
342
|
+
}
|
|
343
|
+
if (call.arguments.length != 2) this.fail(node, "semantic call arity")
|
|
344
|
+
const callee = this.identifier(call.name)
|
|
345
|
+
|
|
346
|
+
if (!this.generated && !this.declaredFunctions.has(callee)) this.fail(call.name, "implicit function declaration")
|
|
347
|
+
return withParserRanges({kind: "CallExpression", location, callee,
|
|
348
|
+
arguments: call.arguments.map((argument) => this.expression(argument, true))}, {callee: this.location(call.name)})
|
|
349
|
+
}
|
|
350
|
+
return this.fail(node)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Records parser intent before shared type resolution.
|
|
355
|
+
* @param {CstNode} node - Owning expression.
|
|
356
|
+
* @param {string} intent - Adapted operation.
|
|
357
|
+
* @param {Expression} left - Left operand.
|
|
358
|
+
* @param {Expression} right - Right operand.
|
|
359
|
+
* @param {CstNode} operator - Operator token.
|
|
360
|
+
* @returns {Expression} Pending binary expression.
|
|
361
|
+
*/
|
|
362
|
+
binary(node, intent, left, right, operator) {
|
|
363
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({kind: "BinaryExpression", location: this.location(node), left, right},
|
|
364
|
+
{operator: this.location(operator)}), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)))
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Records parser intent for a unary operation.
|
|
369
|
+
* @param {CstNode} node - Owning expression.
|
|
370
|
+
* @param {"Negate" | "Not"} intent - Adapted operation.
|
|
371
|
+
* @param {Expression} operand - Operand.
|
|
372
|
+
* @param {CstNode} operator - Operator token.
|
|
373
|
+
* @returns {Expression} Pending unary expression.
|
|
374
|
+
*/
|
|
375
|
+
unary(node, intent, operand, operator) {
|
|
376
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({kind: "UnaryExpression", location: this.location(node), operand},
|
|
377
|
+
{operator: this.location(operator)}), intent))
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Converts one initialized declaration or executable statement.
|
|
382
|
+
* @param {CstNode} node - Statement node.
|
|
383
|
+
* @returns {Statement} Semantic statement.
|
|
384
|
+
*/
|
|
385
|
+
statement(node) {
|
|
386
|
+
const location = this.location(node)
|
|
387
|
+
|
|
388
|
+
if (node.type == "declaration") {
|
|
389
|
+
const typeNode = node.children.find(({field}) => field == "type")?.node
|
|
390
|
+
|
|
391
|
+
if (!typeNode) return missingType("cpp", "local", location)
|
|
392
|
+
const declarator = this.field(node, "declarator")
|
|
393
|
+
const parts = this.parts(node)
|
|
394
|
+
const immutable = parts[0].type == "type_qualifier"
|
|
395
|
+
|
|
396
|
+
this.shape(node, [...(immutable ? [parts[0]] : []), typeNode, declarator, ";"])
|
|
397
|
+
if (immutable && this.text(parts[0]) != "const") this.fail(parts[0], "local qualifier")
|
|
398
|
+
if (declarator.type != "init_declarator") this.fail(declarator, "initialized simple local required")
|
|
399
|
+
const name = this.field(declarator, "declarator")
|
|
400
|
+
const value = this.field(declarator, "value")
|
|
401
|
+
|
|
402
|
+
this.shape(declarator, [name, "=", value])
|
|
403
|
+
return withParserRanges({kind: "LocalDeclaration", location, name: this.identifier(name), type: this.type(typeNode), mutable: !immutable,
|
|
404
|
+
initializer: this.expression(value)}, {name: this.location(name), operator: this.location(this.parts(declarator)[1])})
|
|
405
|
+
}
|
|
406
|
+
if (node.type == "return_statement") {
|
|
407
|
+
const parts = this.parts(node)
|
|
408
|
+
|
|
409
|
+
this.shape(node, ["return", parts[1], ";"])
|
|
410
|
+
return {kind: "ReturnStatement", location, expression: this.expression(parts[1])}
|
|
411
|
+
}
|
|
412
|
+
if (node.type == "if_statement") {
|
|
413
|
+
const condition = this.field(node, "condition")
|
|
414
|
+
const consequence = this.field(node, "consequence")
|
|
415
|
+
const alternative = node.children.find(({field}) => field == "alternative")?.node
|
|
416
|
+
|
|
417
|
+
this.shape(node, ["if", condition, consequence, ...(alternative ? [alternative] : [])])
|
|
418
|
+
const statement = {kind: /** @type {const} */ ("IfStatement"), location, condition: this.expression(condition), consequent: this.block(consequence)}
|
|
419
|
+
|
|
420
|
+
if (!alternative) return statement
|
|
421
|
+
const branch = this.parts(alternative)[1]
|
|
422
|
+
|
|
423
|
+
this.shape(alternative, ["else", branch])
|
|
424
|
+
return {...statement, alternate: branch.type == "if_statement"
|
|
425
|
+
? {kind: "Block", location: this.location(branch), statements: [this.statement(branch)]} : this.block(branch)}
|
|
426
|
+
}
|
|
427
|
+
if (node.type == "expression_statement") {
|
|
428
|
+
const expression = this.parts(node)[0]
|
|
429
|
+
|
|
430
|
+
this.shape(node, [expression, ";"])
|
|
431
|
+
if (expression.type == "assignment_expression") {
|
|
432
|
+
const left = this.field(expression, "left")
|
|
433
|
+
const right = this.field(expression, "right")
|
|
434
|
+
const operator = this.field(expression, "operator")
|
|
435
|
+
|
|
436
|
+
this.shape(expression, [left, "=", right])
|
|
437
|
+
const target = withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), name: this.identifier(left), location: this.location(left)}, {name: this.location(left)})
|
|
438
|
+
|
|
439
|
+
return withParserRanges({kind: "AssignmentStatement", location, target, expression: this.expression(right)}, {operator: this.location(operator)})
|
|
440
|
+
}
|
|
441
|
+
const call = this.call(expression)
|
|
442
|
+
|
|
443
|
+
if (!/^semantifold_print_(?:integer|boolean|string)$/u.test(this.text(call.name)) || call.arguments.length != 1) this.fail(node, "print scaffold")
|
|
444
|
+
const value = this.expression(call.arguments[0])
|
|
445
|
+
|
|
446
|
+
const statement = {kind: /** @type {const} */ ("PrintStatement"), location, expression: value}
|
|
447
|
+
|
|
448
|
+
this.printTypes.set(statement, {node: call.name, type: this.text(call.name).slice("semantifold_print_".length)})
|
|
449
|
+
return statement
|
|
450
|
+
}
|
|
451
|
+
return this.fail(node)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Converts one lexical braced block in source order.
|
|
456
|
+
* @param {CstNode} node - Block node.
|
|
457
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
458
|
+
*/
|
|
459
|
+
block(node) {
|
|
460
|
+
if (node.type != "compound_statement") this.fail(node, "braced block required")
|
|
461
|
+
const parts = this.parts(node)
|
|
462
|
+
|
|
463
|
+
this.shape(node, ["{", ...parts.slice(1, -1), "}"])
|
|
464
|
+
return {kind: "Block", location: this.location(node), statements: this.generated
|
|
465
|
+
? this.generatedStatements(node.children.map(({node: child}) => child).slice(1, -1))
|
|
466
|
+
: parts.slice(1, -1).map((child) => this.statement(child))}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Converts one namespace-scope semantic function.
|
|
471
|
+
* @param {CstNode} node - Function definition.
|
|
472
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
473
|
+
*/
|
|
474
|
+
function(node) {
|
|
475
|
+
const type = this.field(node, "type")
|
|
476
|
+
const declarator = this.field(node, "declarator")
|
|
477
|
+
const body = this.field(node, "body")
|
|
478
|
+
|
|
479
|
+
this.shape(node, [type, declarator, body])
|
|
480
|
+
if (declarator.type != "function_declarator") this.fail(node, "namespace-scope function required")
|
|
481
|
+
const name = this.field(declarator, "declarator")
|
|
482
|
+
const parameters = this.field(declarator, "parameters")
|
|
483
|
+
|
|
484
|
+
this.shape(declarator, [name, parameters])
|
|
485
|
+
const parts = this.parts(parameters)
|
|
486
|
+
|
|
487
|
+
this.shape(parameters, ["(", "parameter_declaration", ",", "parameter_declaration", ")"])
|
|
488
|
+
const converted = [parts[1], parts[3]].map((parameter) => {
|
|
489
|
+
const typeNode = this.field(parameter, "type")
|
|
490
|
+
const nameNode = this.field(parameter, "declarator")
|
|
491
|
+
|
|
492
|
+
this.shape(parameter, [typeNode, nameNode])
|
|
493
|
+
return withParserRanges({kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(nameNode), type: this.type(typeNode)}, {name: this.location(nameNode)})
|
|
494
|
+
})
|
|
495
|
+
|
|
496
|
+
this.declaredFunctions.add(this.identifier(name))
|
|
497
|
+
return withParserRanges({kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
|
|
498
|
+
returnType: this.type(type), body: this.block(body)}, {name: this.location(name)})
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Removes only the exact parameterless main and zero-status scaffolding.
|
|
503
|
+
* @param {CstNode} node - Entry definition.
|
|
504
|
+
* @returns {import("../semantic/types.js").EntryPoint} Semantic entry.
|
|
505
|
+
*/
|
|
506
|
+
main(node) {
|
|
507
|
+
const type = this.field(node, "type")
|
|
508
|
+
const declarator = this.field(node, "declarator")
|
|
509
|
+
const body = this.field(node, "body")
|
|
510
|
+
|
|
511
|
+
this.shape(node, [type, declarator, body])
|
|
512
|
+
const name = this.field(declarator, "declarator")
|
|
513
|
+
const parameters = this.field(declarator, "parameters")
|
|
514
|
+
|
|
515
|
+
this.shape(declarator, [name, parameters])
|
|
516
|
+
if (this.text(type) != "int" || this.text(name) != "main") this.fail(node, "main signature")
|
|
517
|
+
this.shape(parameters, ["(", ")"])
|
|
518
|
+
if (body.type != "compound_statement") this.fail(body, "braced main required")
|
|
519
|
+
const parts = this.parts(body)
|
|
520
|
+
const status = parts.at(-2)
|
|
521
|
+
|
|
522
|
+
if (!status) this.fail(body, "main status")
|
|
523
|
+
this.shape(body, ["{", ...parts.slice(1, -1), "}"])
|
|
524
|
+
this.shape(status, ["return", "number_literal", ";"])
|
|
525
|
+
if (this.text(this.parts(status)[1]) != "0") this.fail(status, "entry status")
|
|
526
|
+
return {kind: "EntryPoint", location: this.location(node), body: {kind: "Block", location: this.location(body),
|
|
527
|
+
statements: this.generated ? this.generatedStatements(body.children.map(({node: child}) => child).filter((child) =>
|
|
528
|
+
child.startIndex > body.startIndex && child.endIndex <= status.startIndex))
|
|
529
|
+
: parts.slice(1, -2).map((child) => this.statement(child))}}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Converts one complete translation unit after exhaustive recovery rejection.
|
|
534
|
+
* @param {CstNode} root - Frozen translation unit.
|
|
535
|
+
* @returns {import("../semantic/types.js").SemanticModule} Validated semantic module.
|
|
536
|
+
*/
|
|
537
|
+
module(root) {
|
|
538
|
+
this.validateTree(root)
|
|
539
|
+
this.generated = root.children.some(({node}) => node.type == "comment" && this.text(node) == "/* semantifold:program:cpp:v1 */")
|
|
540
|
+
if (root.type != "translation_unit") this.fail(root, "translation unit required")
|
|
541
|
+
const runtime = new CppReader(this.filename, cppRuntime)
|
|
542
|
+
const expected = runtime.significant(parseCppCst(cppRuntime).root)
|
|
543
|
+
const actual = this.significant(root).filter((node) => !(node.type == "comment" && this.text(node) == "/* semantifold:program:cpp:v1 */"))
|
|
544
|
+
|
|
545
|
+
if (actual.length < expected.length) this.fail(root, "complete CPP runtime required")
|
|
546
|
+
expected.forEach((node, index) => this.compareTree(actual[index], node, runtime))
|
|
547
|
+
const remaining = actual.slice(expected.length)
|
|
548
|
+
|
|
549
|
+
if (!this.generated) for (const node of remaining) this.rejectScaffoldComments(node)
|
|
550
|
+
const definitions = remaining.filter((node) => node.type != "comment" && (!this.generated || node.type != "declaration"))
|
|
551
|
+
|
|
552
|
+
if (definitions.some((node) => node.type != "function_definition")) this.fail(root, "translation unit members")
|
|
553
|
+
if (definitions.length < 2) this.fail(root, "semantic function and main required")
|
|
554
|
+
const module = {kind: /** @type {const} */ ("Module"), location: this.location(root), functions: definitions.slice(0, -1).map((node) => this.function(node)),
|
|
555
|
+
entryPoint: this.main(definitions[definitions.length - 1])}
|
|
556
|
+
|
|
557
|
+
if (this.generated) validateNativeGraph(module, "cpp")
|
|
558
|
+
const validated = validateParsedModule(module, "cpp")
|
|
559
|
+
|
|
560
|
+
this.validatePrintTypes(validated)
|
|
561
|
+
if (this.generated) {
|
|
562
|
+
validateBackendModule(validated, "cpp")
|
|
563
|
+
const canonical = generateCpp(validated)
|
|
564
|
+
|
|
565
|
+
if (typeof canonical != "string") throw new Error("CPP backend returned a nontext entry artifact.")
|
|
566
|
+
this.compareTree(root, parseCppCst(canonical).root, new CppReader(this.filename, canonical))
|
|
567
|
+
}
|
|
568
|
+
return validated
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Checks native print helper selection after semantic scalar resolution.
|
|
573
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Resolved module.
|
|
574
|
+
* @returns {void}
|
|
575
|
+
*/
|
|
576
|
+
validatePrintTypes(module) {
|
|
577
|
+
const planner = new OrderedExpressionPlanner(module, "cpp")
|
|
578
|
+
/**
|
|
579
|
+
* Checks one lexical block with its visible scalar bindings.
|
|
580
|
+
* @param {import("../semantic/types.js").Block} block - Semantic block.
|
|
581
|
+
* @param {Map<string, import("../semantic/types.js").SemanticTypeName>} inherited - Visible bindings.
|
|
582
|
+
* @returns {void}
|
|
583
|
+
*/
|
|
584
|
+
const visit = (block, inherited) => {
|
|
585
|
+
const bindings = new Map(inherited)
|
|
586
|
+
|
|
587
|
+
for (const statement of block.statements) {
|
|
588
|
+
if (statement.kind == "LocalDeclaration") bindings.set(statement.name, statement.type.name)
|
|
589
|
+
if (statement.kind == "PrintStatement") {
|
|
590
|
+
const expected = this.printTypes.get(statement)
|
|
591
|
+
|
|
592
|
+
if (!expected) throw new Error("CPP print statement lost its parser helper identity.")
|
|
593
|
+
if (planner.type(statement.expression, bindings) != expected.type) this.fail(expected.node, "print helper scalar mismatch")
|
|
594
|
+
}
|
|
595
|
+
if (statement.kind == "IfStatement") {
|
|
596
|
+
visit(statement.consequent, bindings)
|
|
597
|
+
if (statement.alternate) visit(statement.alternate, bindings)
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
for (const declaration of module.functions) visit(declaration.body, new Map(declaration.parameters.map((parameter) => [parameter.name, parameter.type.name])))
|
|
603
|
+
visit(module.entryPoint.body, new Map())
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Rejects profile-looking comments outside a complete canonical generated program.
|
|
608
|
+
* @param {CstNode} node - Current node.
|
|
609
|
+
* @returns {void}
|
|
610
|
+
*/
|
|
611
|
+
rejectScaffoldComments(node) {
|
|
612
|
+
if (node.type == "comment" && /semantifold:|@semantifold/u.test(this.text(node))) this.fail(node, "unrecognized scaffold comment")
|
|
613
|
+
for (const {node: child} of node.children) this.rejectScaffoldComments(child)
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Retains every scaffold comment and structural edge, ignoring only ordinary comments.
|
|
618
|
+
* @param {CstNode} node - CST parent.
|
|
619
|
+
* @returns {CstNode[]} Complete significant child list.
|
|
620
|
+
*/
|
|
621
|
+
significant(node) {
|
|
622
|
+
return node.children.map(({node: child}) => child).filter((child) =>
|
|
623
|
+
child.type != "comment" || /semantifold:|@semantifold/u.test(this.text(child)))
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Verifies every token, field, type, use, ordering edge and consumer against the canonical plan.
|
|
628
|
+
* This checks the original CST; it never recovers meaning from generated source text.
|
|
629
|
+
* @param {CstNode} actual - Original tree node.
|
|
630
|
+
* @param {CstNode} expected - Canonical tree node for the reconstructed semantics.
|
|
631
|
+
* @param {CppReader} canonical - Canonical token reader.
|
|
632
|
+
* @returns {void}
|
|
633
|
+
*/
|
|
634
|
+
compareTree(actual, expected, canonical) {
|
|
635
|
+
if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra) this.fail(actual, "generated scaffold node shape")
|
|
636
|
+
const left = this.significant(actual)
|
|
637
|
+
const right = canonical.significant(expected)
|
|
638
|
+
|
|
639
|
+
if (left.length != right.length) this.fail(actual, "generated scaffold child count")
|
|
640
|
+
if (!left.length && this.text(actual) != canonical.text(expected)) this.fail(actual, "generated scaffold token, type, order or consumer")
|
|
641
|
+
left.forEach((child, index) => {
|
|
642
|
+
if (actual.children.find((edge) => edge.node === child)?.field != expected.children.find((edge) => edge.node === right[index])?.field) this.fail(child, "generated scaffold field")
|
|
643
|
+
this.compareTree(child, right[index], canonical)
|
|
644
|
+
})
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Recognizes the shape of an inert generated unused-binding cast; canonical comparison checks its exact target and placement.
|
|
649
|
+
* @param {CstNode} node - Candidate statement.
|
|
650
|
+
* @returns {boolean} Whether this is a discard-shaped candidate.
|
|
651
|
+
*/
|
|
652
|
+
discard(node) {
|
|
653
|
+
return node.type == "expression_statement" && this.parts(node)[0]?.type == "cast_expression"
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Reconstructs paired statement regions before mandatory whole-CST canonical verification.
|
|
658
|
+
* @param {CstNode[]} children - Ordered block children without braces or main cleanup.
|
|
659
|
+
* @returns {Statement[]} Candidate semantic statements.
|
|
660
|
+
*/
|
|
661
|
+
generatedStatements(children) {
|
|
662
|
+
const nodes = children.filter((node) => node.type != "comment" || /semantifold:|@semantifold/u.test(this.text(node)))
|
|
663
|
+
/** @type {Statement[]} */
|
|
664
|
+
const statements = []
|
|
665
|
+
let cursor = 0
|
|
666
|
+
|
|
667
|
+
while (cursor < nodes.length && this.discard(nodes[cursor])) cursor++
|
|
668
|
+
while (cursor < nodes.length) {
|
|
669
|
+
const begin = nodes[cursor++]
|
|
670
|
+
const match = begin.type == "comment" && /^\/\* semantifold:ordered-expression:cpp:v1 begin ([0-9]{6}) ([0-9a-f]{64}) \*\/$/u.exec(this.text(begin))
|
|
671
|
+
|
|
672
|
+
if (!match) this.fail(begin, "complete ordered statement region required")
|
|
673
|
+
const outer = this.temporaryExpressions
|
|
674
|
+
const outerNames = this.temporaryNames
|
|
675
|
+
|
|
676
|
+
this.temporaryExpressions = new Map()
|
|
677
|
+
this.temporaryNames = new Set()
|
|
678
|
+
while (cursor < nodes.length && this.temporaryDeclaration(nodes[cursor])) cursor = this.readTemporary(nodes, cursor)
|
|
679
|
+
const consumer = nodes[cursor++]
|
|
680
|
+
|
|
681
|
+
if (!consumer) this.fail(begin, "missing ordered consumer")
|
|
682
|
+
const statement = this.statement(consumer)
|
|
683
|
+
|
|
684
|
+
if (this.temporaryExpressions.size != 0) this.fail(consumer, "unconsumed ordered temporary")
|
|
685
|
+
if (statement.kind == "LocalDeclaration" && nodes[cursor] && this.discard(nodes[cursor])) cursor++
|
|
686
|
+
const end = nodes[cursor++]
|
|
687
|
+
|
|
688
|
+
if (!end || end.type != "comment" || this.text(end) != `/* semantifold:ordered-expression:cpp:v1 end ${match[1]} ${match[2]} */`) this.fail(end ?? begin, "ordered marker pair")
|
|
689
|
+
this.temporaryExpressions = outer
|
|
690
|
+
this.temporaryNames = outerNames
|
|
691
|
+
statements.push(statement)
|
|
692
|
+
}
|
|
693
|
+
return statements
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Identifies only a declaration at the current region level, without descendant searching.
|
|
698
|
+
* @param {CstNode} node - Candidate node.
|
|
699
|
+
* @returns {boolean} Whether the direct initialized name uses the reserved prefix.
|
|
700
|
+
*/
|
|
701
|
+
temporaryDeclaration(node) {
|
|
702
|
+
if (node.type != "declaration") return false
|
|
703
|
+
const declarator = node.children.find(({field}) => field == "declarator")?.node
|
|
704
|
+
const name = declarator?.children.find(({field}) => field == "declarator")?.node
|
|
705
|
+
|
|
706
|
+
return name?.type == "identifier" && this.text(name).startsWith("semantifold_ordered_")
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Expands one candidate temporary, including its conditional RHS, retaining original operation tokens.
|
|
711
|
+
* @param {CstNode[]} nodes - Current lexical sequence.
|
|
712
|
+
* @param {number} cursor - Declaration position.
|
|
713
|
+
* @returns {number} Next unconsumed position.
|
|
714
|
+
*/
|
|
715
|
+
readTemporary(nodes, cursor) {
|
|
716
|
+
const node = nodes[cursor++]
|
|
717
|
+
const declarator = this.field(node, "declarator")
|
|
718
|
+
const nameNode = this.field(declarator, "declarator")
|
|
719
|
+
const name = this.text(nameNode)
|
|
720
|
+
const type = this.field(node, "type")
|
|
721
|
+
const value = this.field(declarator, "value")
|
|
722
|
+
|
|
723
|
+
this.shape(node, [type, declarator, ";"])
|
|
724
|
+
this.shape(declarator, [nameNode, "=", value])
|
|
725
|
+
this.type(type)
|
|
726
|
+
if (!/^semantifold_ordered_[0-9]{6}$/u.test(name) || this.temporaryNames?.has(name)) this.fail(nameNode, "ordered temporary declaration")
|
|
727
|
+
this.temporaryNames?.add(name)
|
|
728
|
+
let expression = this.expression(value)
|
|
729
|
+
const branch = nodes[cursor]
|
|
730
|
+
|
|
731
|
+
if (branch?.type == "if_statement" && ["identifier", "true", "false"].includes(value.type)) {
|
|
732
|
+
const condition = this.field(branch, "condition")
|
|
733
|
+
const body = this.field(branch, "consequence")
|
|
734
|
+
|
|
735
|
+
this.shape(branch, ["if", condition, body])
|
|
736
|
+
this.shape(condition, ["(", this.parts(condition)[1], ")"])
|
|
737
|
+
const test = this.parts(condition)[1]
|
|
738
|
+
const isOr = test.type == "unary_expression"
|
|
739
|
+
const target = isOr ? this.field(test, "argument") : test
|
|
740
|
+
|
|
741
|
+
if (target.type != "identifier" || this.text(target) != name) this.fail(target, "short-circuit temporary test")
|
|
742
|
+
if (isOr) this.shape(test, ["!", target])
|
|
743
|
+
if (body.type != "compound_statement") this.fail(body, "short-circuit block")
|
|
744
|
+
const inside = this.significant(body).slice(1, -1)
|
|
745
|
+
let offset = 0
|
|
746
|
+
|
|
747
|
+
while (offset < inside.length && this.temporaryDeclaration(inside[offset])) offset = this.readTemporary(inside, offset)
|
|
748
|
+
if (offset != inside.length - 1) this.fail(body, "short-circuit final write")
|
|
749
|
+
const assignment = inside[offset]
|
|
750
|
+
|
|
751
|
+
this.shape(assignment, ["assignment_expression", ";"])
|
|
752
|
+
const assigned = this.parts(assignment)[0]
|
|
753
|
+
const left = this.field(assigned, "left")
|
|
754
|
+
const right = this.field(assigned, "right")
|
|
755
|
+
|
|
756
|
+
this.shape(assigned, [left, "=", right])
|
|
757
|
+
if (left.type != "identifier" || this.text(left) != name) this.fail(left, "short-circuit result write")
|
|
758
|
+
this.shape(right, ["(", "binary_expression", ")"])
|
|
759
|
+
const binary = this.parts(right)[1]
|
|
760
|
+
const repeated = this.field(binary, "left")
|
|
761
|
+
const operand = this.field(binary, "right")
|
|
762
|
+
const operator = this.field(binary, "operator")
|
|
763
|
+
|
|
764
|
+
this.shape(binary, [repeated, isOr ? "||" : "&&", operand])
|
|
765
|
+
if (repeated.type != "identifier" || this.text(repeated) != name) this.fail(repeated, "short-circuit consumed value")
|
|
766
|
+
expression = this.binary(node, isOr ? "Or" : "And", expression, this.expression(operand), operator)
|
|
767
|
+
cursor++
|
|
768
|
+
}
|
|
769
|
+
this.temporaryExpressions?.set(name, expression)
|
|
770
|
+
return cursor
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Parses only the frozen legacy CST, with no source-text recovery path.
|
|
776
|
+
* @param {{filename: string, source: string}} input - Exact caller source.
|
|
777
|
+
* @returns {import("../semantic/types.js").SemanticModule} Parsed C++ semantics.
|
|
778
|
+
*/
|
|
779
|
+
export function parseCpp({filename, source}) {
|
|
780
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
781
|
+
const coordinates = createCoordinateIndex(source)
|
|
782
|
+
const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u)
|
|
783
|
+
|
|
784
|
+
throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "cpp", message: "CPP source contains a lone UTF-16 surrogate.",
|
|
785
|
+
location: {filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1)}})
|
|
786
|
+
}
|
|
787
|
+
if (source.length > maximumCppSourceLength) {
|
|
788
|
+
const coordinates = createCoordinateIndex(source)
|
|
789
|
+
|
|
790
|
+
return unsupportedSyntax("cpp", "source exceeds the frozen CPP parser's 32767 UTF-16 input limit", {
|
|
791
|
+
filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length)
|
|
792
|
+
})
|
|
793
|
+
}
|
|
794
|
+
let snapshot
|
|
795
|
+
|
|
796
|
+
try {
|
|
797
|
+
snapshot = parseCppCst(source)
|
|
798
|
+
} catch (error) {
|
|
799
|
+
const coordinates = createCoordinateIndex(source)
|
|
800
|
+
|
|
801
|
+
throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "cpp",
|
|
802
|
+
cause: error instanceof Error ? error : undefined, message: "The qualified CPP parser could not produce a complete CST.",
|
|
803
|
+
location: {filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length)}})
|
|
804
|
+
}
|
|
805
|
+
const reader = new CppReader(filename, source)
|
|
806
|
+
|
|
807
|
+
try {
|
|
808
|
+
return reader.module(snapshot.root)
|
|
809
|
+
} catch (error) {
|
|
810
|
+
if (reader.generated && error instanceof SemantifoldDiagnostic && error.language == "cpp" &&
|
|
811
|
+
error.code != "PARSE_ERROR" && error.code != "UNSUPPORTED_SYNTAX") {
|
|
812
|
+
return unsupportedSyntax("cpp", `invalid generated ordered scaffold: ${error.code}`, error.location ?? reader.location(snapshot.root))
|
|
813
|
+
}
|
|
814
|
+
throw error
|
|
815
|
+
}
|
|
816
|
+
}
|