semantifold 0.5.0 → 0.7.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.
Files changed (201) hide show
  1. package/README.md +15 -9
  2. package/build/index.d.ts +8 -8
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +6 -6
  5. package/build/src/backends/android.js +8 -4
  6. package/build/src/backends/dart.d.ts +19 -0
  7. package/build/src/backends/dart.d.ts.map +1 -1
  8. package/build/src/backends/dart.js +28 -16
  9. package/build/src/backends/flutter.d.ts +51 -0
  10. package/build/src/backends/flutter.d.ts.map +1 -0
  11. package/build/src/backends/flutter.js +1362 -0
  12. package/build/src/backends/identifiers.d.ts +6 -0
  13. package/build/src/backends/identifiers.d.ts.map +1 -1
  14. package/build/src/backends/identifiers.js +28 -5
  15. package/build/src/backends/ios.js +2 -2
  16. package/build/src/backends/native-validation.d.ts +2 -2
  17. package/build/src/backends/native-validation.d.ts.map +1 -1
  18. package/build/src/backends/native-validation.js +2 -2
  19. package/build/src/backends/program.d.ts +4 -4
  20. package/build/src/backends/program.d.ts.map +1 -1
  21. package/build/src/backends/program.js +4 -4
  22. package/build/src/backends/scalars.d.ts.map +1 -1
  23. package/build/src/backends/scalars.js +2 -1
  24. package/build/src/backends/shared.d.ts +7 -0
  25. package/build/src/backends/shared.d.ts.map +1 -1
  26. package/build/src/backends/shared.js +14 -9
  27. package/build/src/backends/zig-runtime.d.ts +5 -0
  28. package/build/src/backends/zig-runtime.d.ts.map +1 -0
  29. package/build/src/backends/zig-runtime.js +92 -0
  30. package/build/src/backends/zig-validation.d.ts +9 -0
  31. package/build/src/backends/zig-validation.d.ts.map +1 -0
  32. package/build/src/backends/zig-validation.js +73 -0
  33. package/build/src/backends/zig.d.ts +42 -0
  34. package/build/src/backends/zig.d.ts.map +1 -0
  35. package/build/src/backends/zig.js +584 -0
  36. package/build/src/frontends/scalars.d.ts.map +1 -1
  37. package/build/src/frontends/scalars.js +2 -1
  38. package/build/src/frontends/zig-parser.d.ts +31 -0
  39. package/build/src/frontends/zig-parser.d.ts.map +1 -0
  40. package/build/src/frontends/zig-parser.js +17 -0
  41. package/build/src/frontends/zig.d.ts +14 -0
  42. package/build/src/frontends/zig.d.ts.map +1 -0
  43. package/build/src/frontends/zig.js +970 -0
  44. package/build/src/language-registry.d.ts.map +1 -1
  45. package/build/src/language-registry.js +40 -1
  46. package/build/src/mapping.js +2 -2
  47. package/build/src/semantic/provenance.js +3 -3
  48. package/build/src/semantic/types.d.ts +154 -4
  49. package/build/src/semantic/types.d.ts.map +1 -1
  50. package/build/src/semantic/types.js +39 -3
  51. package/build/src/semantic/validate.js +2 -2
  52. package/build/src/toolchains.d.ts +6 -0
  53. package/build/src/toolchains.d.ts.map +1 -1
  54. package/build/src/toolchains.js +2 -1
  55. package/build/src/zig-bindings.d.ts +10 -0
  56. package/build/src/zig-bindings.d.ts.map +1 -0
  57. package/build/src/zig-bindings.js +54 -0
  58. package/docs/android.md +7 -3
  59. package/docs/architecture.md +13 -5
  60. package/docs/flutter.md +47 -0
  61. package/docs/goals.md +1 -1
  62. package/docs/language-support.md +16 -5
  63. package/docs/parser-qualification.md +31 -1
  64. package/docs/source-maps.md +7 -3
  65. package/docs/testing.md +47 -4
  66. package/docs/zig.md +33 -0
  67. package/index.js +5 -5
  68. package/node_modules/semantifold-tree-sitter-zig-internal/LICENSE +15 -0
  69. package/node_modules/semantifold-tree-sitter-zig-internal/README.md +5 -0
  70. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/LICENSE +21 -0
  71. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/README.md +21 -0
  72. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/binding.gyp +29 -0
  73. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding.cc +20 -0
  74. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding_test.js +9 -0
  75. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.d.ts +28 -0
  76. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.js +11 -0
  77. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/grammar.js +900 -0
  78. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/package.json +57 -0
  79. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  80. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  81. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  82. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  83. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  84. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
  85. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/folds.scm +23 -0
  86. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/highlights.scm +291 -0
  87. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/indents.scm +22 -0
  88. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/injections.scm +10 -0
  89. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/grammar.json +6570 -0
  90. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/node-types.json +3178 -0
  91. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/parser.c +169829 -0
  92. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/alloc.h +54 -0
  93. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/array.h +291 -0
  94. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/parser.h +266 -0
  95. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter-zig.wasm +0 -0
  96. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter.json +38 -0
  97. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/LICENSE +21 -0
  98. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/README.md +128 -0
  99. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/binding.gyp +80 -0
  100. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/index.js +916 -0
  101. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/package.json +76 -0
  102. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
  103. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
  104. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
  105. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
  106. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
  107. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
  108. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
  109. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/binding.cc +35 -0
  110. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
  111. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.h +22 -0
  112. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.cc +106 -0
  113. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.h +17 -0
  114. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.cc +70 -0
  115. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.h +19 -0
  116. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
  117. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
  118. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.cc +1088 -0
  119. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.h +30 -0
  120. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.cc +306 -0
  121. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.h +35 -0
  122. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.cc +397 -0
  123. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.h +40 -0
  124. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.cc +316 -0
  125. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.h +45 -0
  126. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
  127. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
  128. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/tree-sitter.d.ts +1042 -0
  129. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1318 -0
  130. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
  131. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
  132. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
  133. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
  134. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
  135. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
  136. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
  137. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
  138. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
  139. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +223 -0
  140. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +297 -0
  141. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
  142. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +435 -0
  143. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
  144. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
  145. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +920 -0
  146. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2165 -0
  147. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +266 -0
  148. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
  149. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +206 -0
  150. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4187 -0
  151. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
  152. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
  153. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
  154. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +130 -0
  155. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1066 -0
  156. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
  157. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
  158. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
  159. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +712 -0
  160. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
  161. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
  162. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
  163. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
  164. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
  165. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
  166. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
  167. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
  168. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
  169. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
  170. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
  171. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +83 -0
  172. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
  173. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
  174. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1302 -0
  175. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1859 -0
  176. package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
  177. package/node_modules/semantifold-tree-sitter-zig-internal/package.json +21 -0
  178. package/node_modules/semantifold-tree-sitter-zig-internal/src/zig.js +134 -0
  179. package/package.json +11 -6
  180. package/src/backends/android.js +7 -3
  181. package/src/backends/dart.js +28 -15
  182. package/src/backends/flutter.js +1465 -0
  183. package/src/backends/identifiers.js +28 -4
  184. package/src/backends/ios.js +1 -1
  185. package/src/backends/native-validation.js +1 -1
  186. package/src/backends/program.js +3 -3
  187. package/src/backends/scalars.js +1 -0
  188. package/src/backends/shared.js +15 -11
  189. package/src/backends/zig-runtime.js +93 -0
  190. package/src/backends/zig-validation.js +68 -0
  191. package/src/backends/zig.js +579 -0
  192. package/src/frontends/scalars.js +1 -0
  193. package/src/frontends/zig-parser.js +20 -0
  194. package/src/frontends/zig.js +994 -0
  195. package/src/language-registry.js +40 -0
  196. package/src/mapping.js +1 -1
  197. package/src/semantic/provenance.js +2 -2
  198. package/src/semantic/types.js +41 -2
  199. package/src/semantic/validate.js +1 -1
  200. package/src/toolchains.js +1 -0
  201. package/src/zig-bindings.js +46 -0
@@ -0,0 +1,994 @@
1
+ // @ts-check
2
+
3
+ import {isZigIdentifier} from "../backends/identifiers.js"
4
+ import {generateZigProject} from "../backends/zig.js"
5
+ import {zigRuntime} from "../backends/zig-runtime.js"
6
+ import {maximumZigSourceLength} from "../backends/zig-validation.js"
7
+ import {missingType, SemantifoldDiagnostic, unsupportedSyntax} from "../diagnostic.js"
8
+ import {createCoordinateIndex, indexedPointAt} from "../semantic/location.js"
9
+ import {withAdaptedOperation} from "../semantic/operators.js"
10
+ import {withParserRanges} from "../semantic/provenance.js"
11
+ import {hasOnlyUnicodeScalars} from "../semantic/scalars.js"
12
+ import {validateParsedModule} from "../semantic/validate.js"
13
+ import {sourceScalarType} from "./scalars.js"
14
+ import {parseZigCst} from "./zig-parser.js"
15
+ import {collectZigBindingUsage} from "../zig-bindings.js"
16
+
17
+ /** @typedef {import("./zig-parser.js").CstNode} CstNode */
18
+ /** @typedef {import("../semantic/types.js").Expression} Expression */
19
+ /** @typedef {import("../semantic/types.js").Statement} Statement */
20
+ /** @typedef {import("../semantic/types.js").FunctionReturnTypeName} Scalar */
21
+
22
+ const binaryOperations = new Map([
23
+ ["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
24
+ ["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
25
+ ["and", "And"], ["or", "Or"]
26
+ ])
27
+ const helperOperations = new Map([
28
+ ["semantifold_integer_add", "Add"], ["semantifold_integer_subtract", "Subtract"],
29
+ ["semantifold_integer_multiply", "Multiply"], ["semantifold_string_concat", "Add"],
30
+ ["semantifold_string_equal", "Equal"], ["semantifold_string_not_equal", "NotEqual"]
31
+ ])
32
+ const operationSpellings = new Map([
33
+ ["IntegerAdd", "semantifold_integer_add"], ["IntegerSubtract", "semantifold_integer_subtract"],
34
+ ["IntegerMultiply", "semantifold_integer_multiply"], ["IntegerNegate", "semantifold_integer_negate"],
35
+ ["IntegerEqual", "=="], ["IntegerNotEqual", "!="], ["IntegerLessThan", "<"],
36
+ ["IntegerLessThanOrEqual", "<="], ["IntegerGreaterThan", ">"], ["IntegerGreaterThanOrEqual", ">="],
37
+ ["BooleanEqual", "=="], ["BooleanNotEqual", "!="], ["BooleanAnd", "and"], ["BooleanOr", "or"], ["BooleanNot", "!"],
38
+ ["StringConcat", "semantifold_string_concat"], ["StringEqual", "semantifold_string_equal"],
39
+ ["StringNotEqual", "semantifold_string_not_equal"]
40
+ ])
41
+
42
+ /** Consumes the complete qualified Zig CST and retains exact generated-shell constraints. */
43
+ class ZigReader {
44
+ /**
45
+ * Creates a reader over one complete parser snapshot.
46
+ * @param {string} filename - Logical source filename.
47
+ * @param {string} source - Exact Zig source text.
48
+ */
49
+ constructor(filename, source) {
50
+ this.filename = filename
51
+ this.source = source
52
+ this.coordinates = createCoordinateIndex(source)
53
+ this.generated = false
54
+ /** @type {Map<string, Expression> | undefined} */
55
+ this.temporaryExpressions = undefined
56
+ /** @type {Set<string> | undefined} */
57
+ this.temporaryNames = undefined
58
+ /** @type {Map<Expression, {node: CstNode, spelling: string}>} */
59
+ this.operations = new Map()
60
+ /** @type {Map<Statement, {node: CstNode, type: string}>} */
61
+ this.prints = new Map()
62
+ /** @type {Map<string, Scalar>} */
63
+ this.functions = new Map()
64
+ /** @type {Map<import("../semantic/types.js").Parameter | import("../semantic/types.js").LocalDeclaration, "use" | "address" | "none">} */
65
+ this.scaffolds = new Map()
66
+ }
67
+
68
+ /**
69
+ * Converts a parser node boundary to a semantic location.
70
+ * @param {CstNode} node - Parser node.
71
+ * @returns {import("../semantic/types.js").SourceLocation} UTF-16 location.
72
+ */
73
+ location(node) {
74
+ return {filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex)}
75
+ }
76
+
77
+ /**
78
+ * Reads the exact source spelling owned by a parser node.
79
+ * @param {CstNode} node - Parser node.
80
+ * @returns {string} Node source text.
81
+ */
82
+ text(node) {
83
+ return this.source.slice(node.startIndex, node.endIndex)
84
+ }
85
+
86
+ /**
87
+ * Reads one generated line-comment marker independent of the source newline convention.
88
+ * @param {CstNode} node - Marker comment node.
89
+ * @returns {string} Marker spelling without a parser-owned trailing carriage return.
90
+ */
91
+ marker(node) {
92
+ return this.text(node).replace(/\r$/u, "")
93
+ }
94
+
95
+ /**
96
+ * Raises a located unsupported-syntax diagnostic.
97
+ * @param {CstNode} node - Rejected parser node.
98
+ * @param {string} [detail] - Diagnostic detail.
99
+ * @returns {never} This function always throws.
100
+ */
101
+ fail(node, detail = node.type) {
102
+ unsupportedSyntax("zig", detail, this.location(node))
103
+ }
104
+
105
+ /**
106
+ * Exhaustively rejects recovery, unexpected extras, directives, and excessive nesting.
107
+ * @param {CstNode} node - Current CST node.
108
+ * @param {number} [depth] - Current nesting depth.
109
+ */
110
+ validateTree(node, depth = 0) {
111
+ if (depth > 512) this.fail(node, "Zig CST exceeds the 512-level traversal limit")
112
+ for (const {node: child} of node.children) this.validateTree(child, depth + 1)
113
+ if (node.error || node.missing || node.hasError) {
114
+ throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "zig", location: this.location(node), message: `Zig parser recovery at '${node.type}'.`})
115
+ }
116
+ if (node.extra && node.type != "comment") this.fail(node, "unexpected extra parser child")
117
+ if (node.type == "comment" && (/^\s*\/\/[/!]/u.test(this.text(node)) || /^\s*\/\/\s*zig fmt:/u.test(this.text(node)))) {
118
+ this.fail(node, "doc or formatter-directive comment")
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Returns every non-comment child without hiding syntax edges.
124
+ * @param {CstNode} node - Parent parser node.
125
+ * @returns {CstNode[]} Ordered non-comment children.
126
+ */
127
+ parts(node) {
128
+ return node.children.map(({node: child}) => child).filter(child => child.type != "comment")
129
+ }
130
+
131
+ /**
132
+ * Retains compiler-owned scaffold markers while ignoring ordinary inert comments.
133
+ * @param {CstNode} node - Parent parser node.
134
+ * @returns {CstNode[]} Complete significant child list.
135
+ */
136
+ significant(node) {
137
+ return node.children.map(({node: child}) => child).filter(child =>
138
+ child.type != "comment" || /semantifold:/u.test(this.text(child)))
139
+ }
140
+
141
+ /**
142
+ * Requires exactly one parser field edge.
143
+ * @param {CstNode} node - Parent parser node.
144
+ * @param {string} name - Required field name.
145
+ * @returns {CstNode} Field child.
146
+ */
147
+ field(node, name) {
148
+ const edges = node.children.filter(({field}) => field == name)
149
+
150
+ if (edges.length != 1) this.fail(node, `expected one '${name}' field`)
151
+ return edges[0].node
152
+ }
153
+
154
+ /**
155
+ * Requires an exact ordered child/token shape.
156
+ * @param {CstNode} node - Parser node to check.
157
+ * @param {(CstNode | string)[]} expected - Expected node identities or token types.
158
+ */
159
+ shape(node, expected) {
160
+ const parts = this.parts(node)
161
+
162
+ if (parts.length != expected.length || parts.some((child, index) =>
163
+ typeof expected[index] == "string" ? child.type != expected[index] || !child.named && this.text(child) != expected[index] : child !== expected[index])) {
164
+ this.fail(node, `${node.type} child shape`)
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Validates and returns one ordinary Zig identifier.
170
+ * @param {CstNode} node - Candidate identifier node.
171
+ * @returns {string} Validated identifier.
172
+ */
173
+ identifier(node) {
174
+ const name = this.text(node)
175
+
176
+ if (node.type != "identifier" || !isZigIdentifier(name)) this.fail(node, "reserved or unsupported identifier")
177
+ return name
178
+ }
179
+
180
+ /**
181
+ * Converts an exact source scalar annotation.
182
+ * @param {CstNode} node - Type node.
183
+ * @param {boolean} [allowVoid] - Whether void is valid here.
184
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic type.
185
+ */
186
+ type(node, allowVoid = false) {
187
+ const spelling = this.text(node)
188
+
189
+ if (allowVoid && node.type == "builtin_type" && spelling == "void") {
190
+ this.shape(node, ["void"])
191
+ return withParserRanges({kind: "TypeReference", name: "void"}, {type: this.location(node)})
192
+ }
193
+ if (node.type == "builtin_type" && ["i64", "bool"].includes(spelling)) {
194
+ if (spelling == "bool") this.shape(node, ["bool"])
195
+ else if (node.children.length) this.fail(node, "scalar type shape")
196
+ } else if (node.type == "slice_type" && spelling == "[]const u8") {
197
+ this.shape(node, ["[", "]", "const", this.parts(node)[3]])
198
+ const child = this.parts(node)[3]
199
+
200
+ if (child.type != "builtin_type" || this.text(child) != "u8" || child.children.length) this.fail(child, "immutable UTF-8 slice element")
201
+ } else return missingType("zig", allowVoid ? "function return" : "scalar", this.location(node))
202
+ const type = sourceScalarType("zig", spelling, this.location(node))
203
+
204
+ if (!type) return missingType("zig", "scalar", this.location(node))
205
+ return type
206
+ }
207
+
208
+ /**
209
+ * Decomposes an exact direct call.
210
+ * @param {CstNode} node - Call expression node.
211
+ * @returns {{name: CstNode, arguments: CstNode[]}} Callee and ordered arguments.
212
+ */
213
+ call(node) {
214
+ if (node.type != "call_expression") this.fail(node, "direct call required")
215
+ const name = this.field(node, "function")
216
+ const parts = this.parts(node)
217
+ const argumentsAndCommas = parts.slice(2, -1)
218
+ const args = argumentsAndCommas.filter((_part, index) => index % 2 == 0)
219
+
220
+ this.shape(node, [name, "(", ...args.flatMap((argument, index) => index ? [",", argument] : [argument]), ")"])
221
+ return {name, arguments: args}
222
+ }
223
+
224
+ /**
225
+ * Decodes one bounded ordinary Zig string literal.
226
+ * @param {CstNode} node - String node.
227
+ * @returns {string} Unicode scalar value.
228
+ */
229
+ string(node) {
230
+ if (node.type != "string") this.fail(node, "ordinary UTF-8 string literal required")
231
+ const parts = this.parts(node)
232
+
233
+ this.shape(node, ['"', ...parts.slice(1, -1), '"'])
234
+ let value = ""
235
+
236
+ for (const part of parts.slice(1, -1)) {
237
+ const spelling = this.text(part)
238
+
239
+ if (part.type == "string_content") {
240
+ if (/[\r\n]/u.test(spelling)) this.fail(part, "raw string line terminator")
241
+ value += spelling
242
+ } else if (part.type == "escape_sequence") {
243
+ const simple = new Map([["\\n", "\n"], ["\\r", "\r"], ["\\t", "\t"], ["\\\\", "\\"], ['\\"', '"']])
244
+
245
+ if (simple.has(spelling)) value += simple.get(spelling)
246
+ else if (/^\\x[0-9a-fA-F]{2}$/u.test(spelling)) {
247
+ const scalar = Number.parseInt(spelling.slice(2), 16)
248
+
249
+ if (scalar > 127) this.fail(part, "non-ASCII byte escape")
250
+ value += String.fromCodePoint(scalar)
251
+ } else if (/^\\u\{[0-9a-fA-F]{1,6}\}$/u.test(spelling)) {
252
+ const scalar = Number.parseInt(spelling.slice(3, -1), 16)
253
+
254
+ if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF) this.fail(part, "non-scalar Unicode escape")
255
+ value += String.fromCodePoint(scalar)
256
+ } else this.fail(part, "unsupported string escape")
257
+ } else this.fail(part, "string child")
258
+ }
259
+ if (!hasOnlyUnicodeScalars(value)) this.fail(node, "non-scalar string value")
260
+ return value
261
+ }
262
+
263
+ /**
264
+ * Converts one supported scalar expression.
265
+ * @param {CstNode} node - Expression node.
266
+ * @returns {Expression} Semantic expression.
267
+ */
268
+ expression(node) {
269
+ const location = this.location(node)
270
+
271
+ if (node.type == "parenthesized_expression") {
272
+ const parts = this.parts(node)
273
+
274
+ this.shape(node, ["(", parts[1], ")"])
275
+ return this.expression(parts[1])
276
+ }
277
+ if (node.type == "identifier") {
278
+ const temporary = this.temporaryExpressions?.get(this.text(node))
279
+
280
+ if (temporary) {
281
+ this.temporaryExpressions?.delete(this.text(node))
282
+ return temporary
283
+ }
284
+ return withParserRanges({kind: "IdentifierExpression", location, name: this.identifier(node)}, {name: location})
285
+ }
286
+ if (node.type == "integer") {
287
+ const spelling = this.text(node)
288
+ const value = Number(spelling)
289
+
290
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(spelling) || !Number.isSafeInteger(value)) this.fail(node, "non-safe or noncanonical i64 literal")
291
+ return withParserRanges({kind: "IntegerLiteral", location, value}, {literal: location})
292
+ }
293
+ if (node.type == "boolean") {
294
+ const spelling = this.text(node)
295
+
296
+ if (spelling != "true" && spelling != "false") this.fail(node, "Boolean literal spelling")
297
+ this.shape(node, [spelling])
298
+ return withParserRanges({kind: "BooleanLiteral", location, value: spelling == "true"}, {literal: location})
299
+ }
300
+ if (node.type == "string") return withParserRanges({kind: "StringLiteral", location, value: this.string(node)}, {literal: location})
301
+ if (node.type == "unary_expression" || node.type == "error_union_type") {
302
+ const parts = this.parts(node)
303
+ const operator = node.type == "unary_expression" ? this.field(node, "operator") : parts[0]
304
+ const operand = node.type == "unary_expression" ? this.field(node, "argument") : this.field(node, "ok")
305
+
306
+ this.shape(node, [operator, operand])
307
+ if (operator.type != "-" && operator.type != "!") this.fail(operator, "unary operator")
308
+ return this.unary(node, operator.type == "-" ? "Negate" : "Not", this.expression(operand), operator)
309
+ }
310
+ if (node.type == "binary_expression") {
311
+ const left = this.field(node, "left")
312
+ const right = this.field(node, "right")
313
+ const operator = this.field(node, "operator")
314
+ const intent = binaryOperations.get(operator.type)
315
+
316
+ this.shape(node, [left, operator, right])
317
+ if (!intent) this.fail(operator, "unsupported binary operator")
318
+ return this.binary(node, intent, this.expression(left), this.expression(right), operator)
319
+ }
320
+ if (node.type == "call_expression") {
321
+ const call = this.call(node)
322
+
323
+ if (call.name.type != "identifier") this.fail(call.name, "direct function call required")
324
+ const name = this.text(call.name)
325
+
326
+ if (name == "semantifold_integer_negate") {
327
+ if (call.arguments.length != 1) this.fail(node, "negation helper arity")
328
+ return this.unary(node, "Negate", this.expression(call.arguments[0]), call.name)
329
+ }
330
+ const intent = helperOperations.get(name)
331
+
332
+ if (intent) {
333
+ if (call.arguments.length != 2) this.fail(node, "operator helper arity")
334
+ return this.binary(node, intent, this.expression(call.arguments[0]), this.expression(call.arguments[1]), call.name)
335
+ }
336
+ if (name.startsWith("semantifold_")) this.fail(call.name, "support helper outside its exact semantic role")
337
+ const callee = this.identifier(call.name)
338
+
339
+ return withParserRanges({kind: "CallExpression", location, callee, arguments: call.arguments.map(argument => this.expression(argument))}, {callee: this.location(call.name)})
340
+ }
341
+ return this.fail(node)
342
+ }
343
+
344
+ /**
345
+ * Adapts one typed binary operator.
346
+ * @param {CstNode} node - Whole expression node.
347
+ * @param {string} intent - Shared operator intent.
348
+ * @param {Expression} left - Left operand.
349
+ * @param {Expression} right - Right operand.
350
+ * @param {CstNode} operator - Source operator occurrence.
351
+ * @returns {Expression} Adapted semantic expression.
352
+ */
353
+ binary(node, intent, left, right, operator) {
354
+ const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({kind: "BinaryExpression", location: this.location(node), left, right},
355
+ {operator: this.location(operator)}), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)))
356
+
357
+ this.operations.set(expression, {node: operator, spelling: this.text(operator)})
358
+ return expression
359
+ }
360
+
361
+ /**
362
+ * Adapts one typed unary operator.
363
+ * @param {CstNode} node - Whole expression node.
364
+ * @param {"Negate" | "Not"} intent - Shared operator intent.
365
+ * @param {Expression} operand - Converted operand.
366
+ * @param {CstNode} operator - Source operator occurrence.
367
+ * @returns {Expression} Adapted semantic expression.
368
+ */
369
+ unary(node, intent, operand, operator) {
370
+ const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({kind: "UnaryExpression", location: this.location(node), operand},
371
+ {operator: this.location(operator)}), intent))
372
+
373
+ this.operations.set(expression, {node: operator, spelling: this.text(operator)})
374
+ return expression
375
+ }
376
+
377
+ /**
378
+ * Converts one supported statement.
379
+ * @param {CstNode} node - Statement node.
380
+ * @returns {Statement} Semantic statement.
381
+ */
382
+ statement(node) {
383
+ const location = this.location(node)
384
+ const parts = this.parts(node)
385
+
386
+ if (node.type == "variable_declaration") {
387
+ if (["const", "var"].includes(parts[0]?.type)) {
388
+ const typeNode = node.children.find(({field}) => field == "type")?.node
389
+
390
+ if (!typeNode) return missingType("zig", "local", location)
391
+ const name = parts[1]
392
+ const value = parts[5]
393
+
394
+ this.shape(node, [parts[0], name, ":", typeNode, "=", value, ";"])
395
+ return withParserRanges({kind: "LocalDeclaration", location, name: this.identifier(name), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(typeNode)), mutable: parts[0].type == "var",
396
+ initializer: this.expression(value)}, {name: this.location(name), operator: this.location(parts[4])})
397
+ }
398
+ const targetNode = parts[0]
399
+ const value = parts[2]
400
+
401
+ this.shape(node, [targetNode, "=", value, ";"])
402
+ const target = withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), location: this.location(targetNode), name: this.identifier(targetNode)}, {name: this.location(targetNode)})
403
+
404
+ return withParserRanges({kind: "AssignmentStatement", location, target, expression: this.expression(value)}, {operator: this.location(parts[1])})
405
+ }
406
+ if (node.type == "if_statement") return this.conditional(node)
407
+ if (node.type != "expression_statement") this.fail(node, "explicit statement required")
408
+ const expression = parts[0]
409
+
410
+ this.shape(node, [expression, ";"])
411
+ if (expression.type == "return_expression") {
412
+ const returned = this.parts(expression)
413
+
414
+ if (returned.length == 1) {
415
+ this.shape(expression, ["return"])
416
+ return {kind: "ReturnStatement", location}
417
+ }
418
+ this.shape(expression, ["return", returned[1]])
419
+ return {kind: "ReturnStatement", location, expression: this.expression(returned[1])}
420
+ }
421
+ if (expression.type != "call_expression") this.fail(expression, "direct void call statement required")
422
+ const call = this.call(expression)
423
+ const name = this.text(call.name)
424
+
425
+ if (/^semantifold_print_(?:integer|boolean|string)$/u.test(name)) {
426
+ if (call.name.type != "identifier" || call.arguments.length != 1) this.fail(expression, "exact print helper call required")
427
+ const statement = {kind: /** @type {const} */ ("PrintStatement"), location, expression: this.expression(call.arguments[0])}
428
+
429
+ this.prints.set(statement, {node: call.name, type: name.slice("semantifold_print_".length)})
430
+ return statement
431
+ }
432
+ const value = this.expression(expression)
433
+
434
+ if (value.kind != "CallExpression") this.fail(expression, "direct void call statement required")
435
+ return {kind: "ExpressionStatement", location, expression: value}
436
+ }
437
+
438
+ /**
439
+ * Converts one strict Boolean conditional.
440
+ * @param {CstNode} node - If-statement node.
441
+ * @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
442
+ */
443
+ conditional(node) {
444
+ const condition = this.field(node, "condition")
445
+ const body = this.field(node, "body")
446
+ const alternative = this.parts(node).find(child => child.type == "else_clause")
447
+
448
+ this.shape(node, ["if", "(", condition, ")", body, ...(alternative ? [alternative] : [])])
449
+ const statement = {kind: /** @type {const} */ ("IfStatement"), location: this.location(node), condition: this.expression(condition), consequent: this.blockExpression(body)}
450
+
451
+ if (!alternative) return statement
452
+ const branch = this.field(alternative, "alternative")
453
+
454
+ this.shape(alternative, ["else", branch])
455
+ if (branch.type != "labeled_statement") this.fail(branch, "braced else block required")
456
+ const block = this.parts(branch)[0]
457
+
458
+ this.shape(branch, [block])
459
+ return {...statement, alternate: this.block(block)}
460
+ }
461
+
462
+ /**
463
+ * Unwraps one braced conditional block expression.
464
+ * @param {CstNode} node - Block-expression node.
465
+ * @returns {import("../semantic/types.js").Block} Semantic block.
466
+ */
467
+ blockExpression(node) {
468
+ if (node.type != "block_expression") this.fail(node, "braced conditional block required")
469
+ const block = this.parts(node)[0]
470
+
471
+ this.shape(node, [block])
472
+ return this.block(block)
473
+ }
474
+
475
+ /**
476
+ * Converts one lexical block while consuming exact compiler scaffolds.
477
+ * @param {CstNode} node - Block node.
478
+ * @param {number} [skip] - Fixed leading generated statements to omit.
479
+ * @param {import("../semantic/types.js").Parameter[]} [parameters] - Parameters requiring scaffold checks.
480
+ * @returns {import("../semantic/types.js").Block} Semantic block.
481
+ */
482
+ block(node, skip = 0, parameters = []) {
483
+ if (node.type != "block") this.fail(node, "braced block required")
484
+ const parts = this.parts(node)
485
+
486
+ this.shape(node, ["{", ...parts.slice(1, -1), "}"])
487
+ const sourceStatements = this.significant(node).slice(1 + skip, -1)
488
+ return {kind: "Block", location: this.location(node), statements: this.generated
489
+ ? this.generatedStatements(sourceStatements, parameters)
490
+ : this.directStatements(sourceStatements, parameters)}
491
+ }
492
+
493
+ /**
494
+ * Converts the legacy direct statement shape when diagnosing a missing generated marker.
495
+ * @param {CstNode[]} sourceStatements - Ordered direct children.
496
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
497
+ * @returns {Statement[]} Semantic statements.
498
+ */
499
+ directStatements(sourceStatements, parameters) {
500
+ let cursor = 0
501
+
502
+ for (const parameter of parameters) {
503
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined
504
+
505
+ this.scaffolds.set(parameter, kind ?? "none")
506
+ if (kind) cursor += 1
507
+ }
508
+ /** @type {Statement[]} */
509
+ const statements = []
510
+
511
+ while (cursor < sourceStatements.length) {
512
+ const statement = this.statement(sourceStatements[cursor])
513
+
514
+ statements.push(statement)
515
+ cursor += 1
516
+ if (statement.kind == "LocalDeclaration") {
517
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined
518
+
519
+ this.scaffolds.set(statement, kind ?? "none")
520
+ if (kind) cursor += 1
521
+ }
522
+ }
523
+ return statements
524
+ }
525
+
526
+ /**
527
+ * Reconstructs complete generated statement regions before canonical whole-CST verification.
528
+ * @param {CstNode[]} sourceStatements - Significant direct block children.
529
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
530
+ * @returns {Statement[]} Reconstructed semantic statements.
531
+ */
532
+ generatedStatements(sourceStatements, parameters) {
533
+ /** @type {Statement[]} */
534
+ const statements = []
535
+ let cursor = 0
536
+
537
+ for (const parameter of parameters) {
538
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined
539
+
540
+ this.scaffolds.set(parameter, kind ?? "none")
541
+ if (kind) cursor += 1
542
+ }
543
+ while (cursor < sourceStatements.length) {
544
+ const begin = sourceStatements[cursor++]
545
+ const match = begin.type == "comment" &&
546
+ /^\/\/ semantifold:ordered-expression:zig:v1 begin ([0-9]{6}) ([0-9a-f]{64})$/u.exec(this.marker(begin))
547
+
548
+ if (!match) this.fail(begin, "complete generated ordered statement region required")
549
+ const outerExpressions = this.temporaryExpressions
550
+ const outerNames = this.temporaryNames
551
+
552
+ this.temporaryExpressions = new Map()
553
+ this.temporaryNames = new Set()
554
+ while (cursor < sourceStatements.length && this.temporaryDeclaration(sourceStatements[cursor])) {
555
+ cursor = this.readTemporary(sourceStatements, cursor)
556
+ }
557
+ const consumer = sourceStatements[cursor++]
558
+
559
+ if (!consumer) this.fail(begin, "missing generated ordered consumer")
560
+ const statement = this.statement(consumer)
561
+
562
+ if (this.temporaryExpressions.size != 0) this.fail(consumer, "unconsumed generated ordered temporary")
563
+ if (statement.kind == "LocalDeclaration") {
564
+ const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined
565
+
566
+ this.scaffolds.set(statement, kind ?? "none")
567
+ if (kind) cursor += 1
568
+ }
569
+ const end = sourceStatements[cursor++]
570
+
571
+ if (!end || end.type != "comment" || this.marker(end) !=
572
+ `// semantifold:ordered-expression:zig:v1 end ${match[1]} ${match[2]}`) this.fail(end ?? begin, "generated ordered marker pair")
573
+ this.temporaryExpressions = outerExpressions
574
+ this.temporaryNames = outerNames
575
+ statements.push(statement)
576
+ }
577
+ return statements
578
+ }
579
+
580
+ /**
581
+ * Identifies a reserved ordered temporary declaration at the current region level.
582
+ * @param {CstNode} node - Candidate direct child.
583
+ * @returns {boolean} Whether it declares a reserved ordered temporary.
584
+ */
585
+ temporaryDeclaration(node) {
586
+ const parts = this.parts(node)
587
+
588
+ return node.type == "variable_declaration" && ["const", "var"].includes(parts[0]?.type) &&
589
+ parts[1]?.type == "identifier" && this.text(parts[1]).startsWith("semantifold_ordered_")
590
+ }
591
+
592
+ /**
593
+ * Expands one typed ordered temporary and an optional conditional Boolean RHS.
594
+ * @param {CstNode[]} nodes - Current region children.
595
+ * @param {number} cursor - Temporary declaration position.
596
+ * @returns {number} Next unconsumed position.
597
+ */
598
+ readTemporary(nodes, cursor) {
599
+ const node = nodes[cursor++]
600
+ const parts = this.parts(node)
601
+ const nameNode = parts[1]
602
+ const name = this.text(nameNode)
603
+ const typeNode = this.field(node, "type")
604
+ const value = parts[5]
605
+
606
+ this.shape(node, [parts[0], nameNode, ":", typeNode, "=", value, ";"])
607
+ this.type(typeNode)
608
+ if (!/^semantifold_ordered_[0-9]{6}$/u.test(name) || this.temporaryNames?.has(name)) {
609
+ this.fail(nameNode, "generated ordered temporary declaration")
610
+ }
611
+ this.temporaryNames?.add(name)
612
+ let expression = this.expression(value)
613
+ const branch = nodes[cursor]
614
+
615
+ if (branch && this.shortCircuitBranch(branch, name)) {
616
+ const condition = this.field(branch, "condition")
617
+ const body = this.field(branch, "body")
618
+ const conditionParts = this.parts(condition)
619
+ const isOr = conditionParts[0]?.type == "!"
620
+ const target = isOr ? this.field(condition, condition.type == "unary_expression" ? "argument" : "ok") : condition
621
+
622
+ this.shape(branch, ["if", "(", condition, ")", body])
623
+ if (target.type != "identifier" || this.text(target) != name) this.fail(target, "generated short-circuit temporary test")
624
+ if (isOr) this.shape(condition, [conditionParts[0], target])
625
+ if (isOr && conditionParts[0]?.type != "!") this.fail(conditionParts[0] ?? condition, "generated short-circuit negation")
626
+ if (body.type != "block_expression") this.fail(body, "generated short-circuit block")
627
+ const block = this.parts(body)[0]
628
+
629
+ this.shape(body, [block])
630
+ if (block.type != "block") this.fail(block, "generated short-circuit block")
631
+ const inside = this.significant(block).slice(1, -1)
632
+ let offset = 0
633
+
634
+ while (offset < inside.length && this.temporaryDeclaration(inside[offset])) offset = this.readTemporary(inside, offset)
635
+ if (offset != inside.length - 1) this.fail(block, "generated short-circuit final assignment")
636
+ const assignment = inside[offset]
637
+ const assignmentParts = this.parts(assignment)
638
+ const left = assignmentParts[0]
639
+ const right = assignmentParts[2]
640
+
641
+ this.shape(assignment, [left, "=", right, ";"])
642
+ if (left.type != "identifier" || this.text(left) != name) this.fail(left, "generated short-circuit result write")
643
+ if (right.type != "binary_expression") this.fail(right, "generated short-circuit result expression")
644
+ const repeated = this.field(right, "left")
645
+ const operand = this.field(right, "right")
646
+ const operator = this.field(right, "operator")
647
+ const spelling = isOr ? "or" : "and"
648
+
649
+ this.shape(right, [repeated, spelling, operand])
650
+ if (repeated.type != "identifier" || this.text(repeated) != name) this.fail(repeated, "generated short-circuit consumed value")
651
+ expression = this.binary(right, isOr ? "Or" : "And", expression, this.expression(operand), operator)
652
+ cursor += 1
653
+ }
654
+ this.temporaryExpressions?.set(name, expression)
655
+ return cursor
656
+ }
657
+
658
+ /**
659
+ * Distinguishes an internal conditional RHS from the following semantic `if` consumer using only direct CST structure.
660
+ * @param {CstNode} node - Candidate conditional.
661
+ * @param {string} name - Ordered Boolean result name.
662
+ * @returns {boolean} Whether the node has the complete outer shape of a short-circuit update.
663
+ */
664
+ shortCircuitBranch(node, name) {
665
+ if (node.type != "if_statement" || this.parts(node).some(child => child.type == "else_clause")) return false
666
+ const body = node.children.find(({field}) => field == "body")?.node
667
+
668
+ if (body?.type != "block_expression") return false
669
+ const block = this.parts(body)[0]
670
+
671
+ if (block?.type != "block") return false
672
+ const inside = this.significant(block).slice(1, -1)
673
+ const final = inside.at(-1)
674
+ const finalParts = final ? this.parts(final) : []
675
+
676
+ return inside.length > 0 && !inside.some(child => child.type == "comment") && final?.type == "variable_declaration" &&
677
+ finalParts[0]?.type == "identifier" && this.text(finalParts[0]) == name && finalParts[1]?.type == "="
678
+ }
679
+
680
+ /**
681
+ * Recognizes one exact generated unused or unmutated binding scaffold.
682
+ * @param {CstNode} node - Candidate statement node.
683
+ * @param {string} name - Binding name.
684
+ * @returns {"use" | "address" | undefined} Scaffold form when matched.
685
+ */
686
+ useScaffold(node, name) {
687
+ const parts = this.parts(node)
688
+
689
+ if (node.type != "variable_declaration" || parts.length != 4 || parts[0].type != "identifier" || this.text(parts[0]) != "_" || parts[1].type != "=" || parts[3].type != ";") return undefined
690
+ if (parts[2].type == "identifier" && this.text(parts[2]) == name) return "use"
691
+ if (parts[2].type == "reference_expression") {
692
+ const reference = this.parts(parts[2])
693
+
694
+ if (reference.length == 2 && reference[0].type == "&" && reference[1].type == "identifier" && this.text(reference[1]) == name) return "address"
695
+ }
696
+ return undefined
697
+ }
698
+
699
+ /**
700
+ * Converts one canonical top-level semantic function.
701
+ * @param {CstNode} node - Function declaration node.
702
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
703
+ */
704
+ function(node) {
705
+ const name = this.field(node, "name")
706
+ const parameters = this.parts(node).find(child => child.type == "parameters")
707
+ const returnType = this.field(node, "type")
708
+ const body = this.field(node, "body")
709
+
710
+ if (!parameters) this.fail(node, "parameter list required")
711
+ this.shape(node, ["fn", name, parameters, returnType, body])
712
+ const parameterParts = this.parts(parameters)
713
+ const declarations = parameterParts.slice(1, -1).filter((_part, index) => index % 2 == 0)
714
+
715
+ this.shape(parameters, ["(", ...declarations.flatMap((parameter, index) => index ? [",", parameter] : [parameter]), ")"])
716
+ const converted = declarations.map(parameter => {
717
+ if (parameter.type != "parameter") this.fail(parameter, "required typed parameter")
718
+ const parameterName = this.field(parameter, "name")
719
+ const type = this.field(parameter, "type")
720
+
721
+ this.shape(parameter, [parameterName, ":", type])
722
+ return withParserRanges({kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(parameterName), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(type))}, {name: this.location(parameterName)})
723
+ })
724
+
725
+ return withParserRanges({kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
726
+ returnType: this.type(returnType, true), body: this.block(body, 0, converted)}, {name: this.location(name)})
727
+ }
728
+
729
+ /**
730
+ * Compares every node, token, and field against canonical generated support.
731
+ * @param {CstNode} actual - Source subtree.
732
+ * @param {CstNode} expected - Canonical subtree.
733
+ * @param {ZigReader} canonical - Reader owning the canonical source.
734
+ */
735
+ compareTree(actual, expected, canonical) {
736
+ if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra) this.fail(actual, "modified Zig support node")
737
+ const left = this.significant(actual)
738
+ const right = canonical.significant(expected)
739
+
740
+ if (left.length != right.length) this.fail(actual, "modified Zig support children")
741
+ if (!left.length) {
742
+ const actualText = actual.type == "comment" && /semantifold:/u.test(this.text(actual)) ? this.marker(actual) : this.text(actual)
743
+ const expectedText = expected.type == "comment" && /semantifold:/u.test(canonical.text(expected)) ? canonical.marker(expected) : canonical.text(expected)
744
+
745
+ if (actualText != expectedText) this.fail(actual, "modified Zig support token")
746
+ }
747
+ left.forEach((child, index) => {
748
+ const expectedChild = right[index]
749
+
750
+ if (!expectedChild || actual.children.find(edge => edge.node === child)?.field != expected.children.find(edge => edge.node === expectedChild)?.field) {
751
+ this.fail(child, "modified Zig support field")
752
+ }
753
+ this.compareTree(child, expectedChild, canonical)
754
+ })
755
+ }
756
+
757
+ /**
758
+ * Resolves a validated expression's scalar result.
759
+ * @param {Expression} expression - Semantic expression.
760
+ * @param {Map<string, Scalar>} bindings - Visible binding types.
761
+ * @returns {Scalar} Scalar result name.
762
+ */
763
+ expressionType(expression, bindings) {
764
+ if (expression.kind == "StringLiteral") return "string"
765
+ if (expression.kind == "IntegerLiteral") return "integer"
766
+ if (expression.kind == "BooleanLiteral") return "boolean"
767
+ if (expression.kind == "BinaryExpression" || expression.kind == "UnaryExpression") return expression.type
768
+ if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression") throw new Error("Validated Zig source exposed a collection expression.")
769
+ const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name)
770
+
771
+ if (!type) throw new Error("Validated Zig expression lost its scalar binding.")
772
+ return type
773
+ }
774
+
775
+ /**
776
+ * Requires each typed operation to retain the one exact Zig operator/helper spelling that implements it.
777
+ * @param {Expression} expression - Resolved scalar expression.
778
+ */
779
+ validateOperationExpression(expression) {
780
+ if (expression.kind == "CallExpression") {
781
+ expression.arguments.forEach(argument => this.validateOperationExpression(argument))
782
+ return
783
+ }
784
+ if (expression.kind == "UnaryExpression") {
785
+ const identity = this.operations.get(expression)
786
+ const expected = operationSpellings.get(expression.operation)
787
+
788
+ if (!identity) throw new Error("Resolved Zig unary operation lost its parser identity.")
789
+ if (identity.spelling != expected) this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`)
790
+ this.validateOperationExpression(expression.operand)
791
+ return
792
+ }
793
+ if (expression.kind == "BinaryExpression") {
794
+ const identity = this.operations.get(expression)
795
+ const expected = operationSpellings.get(expression.operation)
796
+
797
+ if (!identity) throw new Error("Resolved Zig binary operation lost its parser identity.")
798
+ if (identity.spelling != expected) this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`)
799
+ this.validateOperationExpression(expression.left)
800
+ this.validateOperationExpression(expression.right)
801
+ }
802
+ }
803
+
804
+ /**
805
+ * Validates operation identity throughout one lexical block.
806
+ * @param {import("../semantic/types.js").Block} block - Block whose expressions must retain exact Zig identity.
807
+ */
808
+ validateOperations(block) {
809
+ for (const statement of block.statements) {
810
+ if (statement.kind == "LocalDeclaration") this.validateOperationExpression(statement.initializer)
811
+ else if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
812
+ this.validateOperationExpression(statement.expression)
813
+ } else if (statement.kind == "ReturnStatement") {
814
+ if (statement.expression) this.validateOperationExpression(statement.expression)
815
+ } else if (statement.kind == "IfStatement") {
816
+ this.validateOperationExpression(statement.condition)
817
+ this.validateOperations(statement.consequent)
818
+ if (statement.alternate) this.validateOperations(statement.alternate)
819
+ }
820
+ }
821
+ }
822
+
823
+ /**
824
+ * Confirms each generated output helper matches its semantic operand.
825
+ * @param {import("../semantic/types.js").Block} block - Block to inspect.
826
+ * @param {Map<string, Scalar>} inherited - Visible binding types.
827
+ */
828
+ validatePrints(block, inherited) {
829
+ const bindings = new Map(inherited)
830
+
831
+ for (const statement of block.statements) {
832
+ if (statement.kind == "LocalDeclaration") {
833
+ bindings.set(statement.name, /** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name)
834
+ } else if (statement.kind == "PrintStatement") {
835
+ const print = this.prints.get(statement)
836
+
837
+ if (!print || this.expressionType(statement.expression, bindings) != print.type) this.fail(print?.node ?? /** @type {CstNode} */ ({}), "print helper scalar mismatch")
838
+ } else if (statement.kind == "IfStatement") {
839
+ this.validatePrints(statement.consequent, bindings)
840
+ if (statement.alternate) this.validatePrints(statement.alternate, bindings)
841
+ }
842
+ }
843
+ }
844
+
845
+ /**
846
+ * Confirms all and only compiler-required binding scaffolds are present.
847
+ * @param {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").EntryPoint} owner - Function or entry owner.
848
+ */
849
+ validateScaffolds(owner) {
850
+ const usage = collectZigBindingUsage(owner.body)
851
+ const parameters = owner.kind == "FunctionDeclaration" ? owner.parameters : []
852
+
853
+ for (const parameter of parameters) {
854
+ const expected = usage.reads.has(parameter.name) ? "none" : "use"
855
+
856
+ if (this.scaffolds.get(parameter) != expected) unsupportedSyntax("zig", `incorrect unused-parameter scaffold for '${parameter.name}'`, parameter.location)
857
+ }
858
+ /**
859
+ * Checks local scaffolds recursively.
860
+ * @param {import("../semantic/types.js").Block} block - Block to inspect.
861
+ */
862
+ const visit = (block) => {
863
+ for (const statement of block.statements) {
864
+ if (statement.kind == "LocalDeclaration") {
865
+ const expected = statement.mutable && !usage.writes.has(statement.name) ? "address" :
866
+ !statement.mutable && !usage.reads.has(statement.name) ? "use" : "none"
867
+
868
+ if (this.scaffolds.get(statement) != expected) unsupportedSyntax("zig", `incorrect local binding scaffold for '${statement.name}'`, statement.location)
869
+ } else if (statement.kind == "IfStatement") {
870
+ visit(statement.consequent)
871
+ if (statement.alternate) visit(statement.alternate)
872
+ }
873
+ }
874
+ }
875
+
876
+ visit(owner.body)
877
+ }
878
+
879
+ /**
880
+ * Converts a complete canonical Zig project entry.
881
+ * @param {CstNode} root - Source-file root.
882
+ * @returns {import("../semantic/types.js").SemanticModule} Validated semantic module.
883
+ */
884
+ module(root) {
885
+ this.validateTree(root)
886
+ if (root.type != "source_file") this.fail(root, "Zig source root required")
887
+ const canonical = new ZigReader(this.filename, zigRuntime)
888
+ const support = canonical.significant(parseZigCst(zigRuntime).root)
889
+ const nodes = this.significant(root)
890
+
891
+ if (nodes.length < support.length + 2) this.fail(root, "complete Zig runtime, ordered marker, and main shell required")
892
+ support.forEach((expected, index) => this.compareTree(nodes[index], expected, canonical))
893
+ const programMarker = nodes[support.length]
894
+
895
+ if (programMarker.type != "comment" || this.marker(programMarker) != "// semantifold:program:zig:v1") {
896
+ this.fail(programMarker, "exact generated Zig ordered-expression marker required")
897
+ }
898
+ this.generated = true
899
+ const definitions = nodes.slice(support.length + 1)
900
+ /** @type {CstNode | undefined} */
901
+ let main
902
+ /** @type {CstNode[]} */
903
+ const functions = []
904
+
905
+ for (const node of definitions) {
906
+ if (node.type != "function_declaration") this.fail(node, "top-level free functions only")
907
+ const name = this.text(this.field(node, "name"))
908
+
909
+ if (name == "main") {
910
+ if (main) this.fail(node, "duplicate main")
911
+ main = node
912
+ } else {
913
+ if (main) this.fail(node, "semantic function after main")
914
+ functions.push(node)
915
+ }
916
+ }
917
+ if (!main) this.fail(root, "canonical pub fn main() void required")
918
+ const mainParts = this.parts(main)
919
+ const mainName = this.field(main, "name")
920
+ const parameters = mainParts.find(child => child.type == "parameters")
921
+ const returnType = this.field(main, "type")
922
+ const body = this.field(main, "body")
923
+
924
+ if (!parameters) this.fail(main, "main parameters")
925
+ this.shape(main, ["pub", "fn", mainName, parameters, returnType, body])
926
+ if (this.text(mainName) != "main") this.fail(mainName, "main name")
927
+ this.shape(parameters, ["(", ")"])
928
+ this.type(returnType, true)
929
+ if (this.text(returnType) != "void") this.fail(returnType, "main return type")
930
+ const bodyParts = this.parts(body)
931
+ const deferNode = bodyParts[1]
932
+ const shellSource = "pub fn main() void {\n defer semantifold_arena.deinit();\n}\n"
933
+ const shellReader = new ZigReader(this.filename, shellSource)
934
+ const shellMain = shellReader.parts(parseZigCst(shellSource).root)[0]
935
+ const expectedDefer = shellReader.parts(shellReader.field(shellMain, "body"))[1]
936
+
937
+ if (!deferNode) this.fail(body, "arena lifetime defer required")
938
+ this.compareTree(deferNode, expectedDefer, shellReader)
939
+ const module = validateParsedModule({kind: "Module", location: this.location(root), functions: functions.map(node => this.function(node)),
940
+ entryPoint: {kind: "EntryPoint", location: this.location(main), body: this.block(body, 1)}}, "zig")
941
+
942
+ this.functions = new Map(module.functions.map(declaration => [declaration.name,
943
+ /** @type {import("../semantic/types.js").TypeReference} */ (declaration.returnType).name]))
944
+ for (const declaration of module.functions) this.validateOperations(declaration.body)
945
+ this.validateOperations(module.entryPoint.body)
946
+ for (const declaration of module.functions) this.validatePrints(declaration.body, new Map(declaration.parameters.map(parameter => [parameter.name,
947
+ /** @type {import("../semantic/types.js").TypeReference} */ (parameter.type).name])))
948
+ this.validatePrints(module.entryPoint.body, new Map())
949
+ for (const declaration of module.functions) this.validateScaffolds(declaration)
950
+ this.validateScaffolds(module.entryPoint)
951
+ const canonicalSource = generateZigProject({module}).artifacts[1]?.content
952
+
953
+ if (typeof canonicalSource != "string") throw new Error("Zig backend returned a nontext entry artifact.")
954
+ this.compareTree(root, parseZigCst(canonicalSource).root, new ZigReader(this.filename, canonicalSource))
955
+ return module
956
+ }
957
+ }
958
+
959
+ /**
960
+ * Parses only the qualified frozen Zig CST and rejects unsupported input before adaptation.
961
+ * @param {{filename: string, source: string}} input - Exact source request.
962
+ * @returns {import("../semantic/types.js").SemanticModule} Zig semantic module.
963
+ */
964
+ export function parseZig({filename, source}) {
965
+ const coordinates = createCoordinateIndex(source)
966
+ const location = {filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length)}
967
+
968
+ if (!hasOnlyUnicodeScalars(source)) {
969
+ const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u)
970
+
971
+ throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "zig", message: "Zig source contains a lone UTF-16 surrogate.",
972
+ location: {filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1)}})
973
+ }
974
+ if (source.length > maximumZigSourceLength) return unsupportedSyntax("zig", "source exceeds the 1000000 UTF-16 input limit", location)
975
+ let snapshot
976
+
977
+ try {
978
+ snapshot = parseZigCst(source)
979
+ } catch (error) {
980
+ throw new SemantifoldDiagnostic({code: "PARSE_ERROR", language: "zig", location,
981
+ cause: error instanceof Error ? error : undefined, message: "The qualified Zig parser could not produce a complete CST."})
982
+ }
983
+ const reader = new ZigReader(filename, source)
984
+
985
+ try {
986
+ return reader.module(snapshot.root)
987
+ } catch (error) {
988
+ if (reader.generated && error instanceof SemantifoldDiagnostic && error.language == "zig" &&
989
+ error.code != "PARSE_ERROR" && error.code != "UNSUPPORTED_SYNTAX") {
990
+ return unsupportedSyntax("zig", `invalid generated ordered scaffold: ${error.code}`, error.location ?? location)
991
+ }
992
+ throw error
993
+ }
994
+ }