semantifold 0.3.0 → 0.5.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 (303) hide show
  1. package/README.md +61 -15
  2. package/build/index.d.ts +52 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +60 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/android.d.ts +49 -0
  11. package/build/src/backends/android.d.ts.map +1 -0
  12. package/build/src/backends/android.js +1274 -0
  13. package/build/src/backends/c-validation.d.ts.map +1 -1
  14. package/build/src/backends/c-validation.js +7 -3
  15. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  16. package/build/src/backends/cpp-validation.js +7 -3
  17. package/build/src/backends/csharp.js +7 -1
  18. package/build/src/backends/dart-runtime.d.ts +2 -0
  19. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  20. package/build/src/backends/dart-runtime.js +41 -0
  21. package/build/src/backends/dart.d.ts +20 -0
  22. package/build/src/backends/dart.d.ts.map +1 -0
  23. package/build/src/backends/dart.js +321 -0
  24. package/build/src/backends/effects.d.ts +60 -0
  25. package/build/src/backends/effects.d.ts.map +1 -0
  26. package/build/src/backends/effects.js +746 -0
  27. package/build/src/backends/go.js +18 -4
  28. package/build/src/backends/identifiers.d.ts +36 -4
  29. package/build/src/backends/identifiers.d.ts.map +1 -1
  30. package/build/src/backends/identifiers.js +160 -10
  31. package/build/src/backends/index.d.ts.map +1 -1
  32. package/build/src/backends/index.js +27 -4
  33. package/build/src/backends/ios.d.ts +68 -0
  34. package/build/src/backends/ios.d.ts.map +1 -0
  35. package/build/src/backends/ios.js +1503 -0
  36. package/build/src/backends/java.d.ts.map +1 -1
  37. package/build/src/backends/java.js +429 -36
  38. package/build/src/backends/javascript.d.ts +6 -0
  39. package/build/src/backends/javascript.d.ts.map +1 -1
  40. package/build/src/backends/javascript.js +380 -24
  41. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  42. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  43. package/build/src/backends/kotlin-runtime.js +29 -0
  44. package/build/src/backends/kotlin.d.ts +33 -0
  45. package/build/src/backends/kotlin.d.ts.map +1 -0
  46. package/build/src/backends/kotlin.js +138 -0
  47. package/build/src/backends/native-validation.d.ts +2 -2
  48. package/build/src/backends/native-validation.d.ts.map +1 -1
  49. package/build/src/backends/native-validation.js +2 -2
  50. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  51. package/build/src/backends/ordered-expressions.js +39 -7
  52. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  53. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  54. package/build/src/backends/php-stdlib-support.js +227 -0
  55. package/build/src/backends/php.d.ts.map +1 -1
  56. package/build/src/backends/php.js +448 -33
  57. package/build/src/backends/program.d.ts +83 -0
  58. package/build/src/backends/program.d.ts.map +1 -0
  59. package/build/src/backends/program.js +1309 -0
  60. package/build/src/backends/python.js +7 -1
  61. package/build/src/backends/ruby.d.ts.map +1 -1
  62. package/build/src/backends/ruby.js +310 -24
  63. package/build/src/backends/rust-runtime.d.ts +7 -0
  64. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  65. package/build/src/backends/rust-runtime.js +32 -0
  66. package/build/src/backends/rust-validation.d.ts +9 -0
  67. package/build/src/backends/rust-validation.d.ts.map +1 -0
  68. package/build/src/backends/rust-validation.js +78 -0
  69. package/build/src/backends/rust.d.ts +24 -0
  70. package/build/src/backends/rust.d.ts.map +1 -0
  71. package/build/src/backends/rust.js +344 -0
  72. package/build/src/backends/scalars.d.ts +14 -6
  73. package/build/src/backends/scalars.d.ts.map +1 -1
  74. package/build/src/backends/scalars.js +167 -17
  75. package/build/src/backends/shared.d.ts +23 -4
  76. package/build/src/backends/shared.d.ts.map +1 -1
  77. package/build/src/backends/shared.js +2174 -62
  78. package/build/src/backends/stdlib-support.d.ts +14 -0
  79. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  80. package/build/src/backends/stdlib-support.js +237 -0
  81. package/build/src/backends/swift-runtime.d.ts +3 -0
  82. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  83. package/build/src/backends/swift-runtime.js +14 -0
  84. package/build/src/backends/swift.d.ts +8 -0
  85. package/build/src/backends/swift.d.ts.map +1 -0
  86. package/build/src/backends/swift.js +127 -0
  87. package/build/src/backends/typescript.d.ts.map +1 -1
  88. package/build/src/backends/typescript.js +344 -24
  89. package/build/src/backends/wasm.d.ts +43 -0
  90. package/build/src/backends/wasm.d.ts.map +1 -0
  91. package/build/src/backends/wasm.js +2164 -0
  92. package/build/src/backends/writer.d.ts +255 -4
  93. package/build/src/backends/writer.d.ts.map +1 -1
  94. package/build/src/backends/writer.js +491 -3
  95. package/build/src/diagnostic.d.ts +4 -3
  96. package/build/src/diagnostic.d.ts.map +1 -1
  97. package/build/src/diagnostic.js +5 -3
  98. package/build/src/frontends/c.d.ts.map +1 -1
  99. package/build/src/frontends/c.js +5 -3
  100. package/build/src/frontends/cpp.d.ts.map +1 -1
  101. package/build/src/frontends/cpp.js +5 -3
  102. package/build/src/frontends/csharp.d.ts.map +1 -1
  103. package/build/src/frontends/csharp.js +7 -3
  104. package/build/src/frontends/dart.d.ts +10 -0
  105. package/build/src/frontends/dart.d.ts.map +1 -0
  106. package/build/src/frontends/dart.js +913 -0
  107. package/build/src/frontends/index.d.ts +3 -1
  108. package/build/src/frontends/index.d.ts.map +1 -1
  109. package/build/src/frontends/index.js +15 -5
  110. package/build/src/frontends/java.d.ts +110 -1
  111. package/build/src/frontends/java.d.ts.map +1 -1
  112. package/build/src/frontends/java.js +1725 -70
  113. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  114. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  115. package/build/src/frontends/javascript-typescript.js +1825 -93
  116. package/build/src/frontends/kotlin.d.ts +10 -0
  117. package/build/src/frontends/kotlin.d.ts.map +1 -0
  118. package/build/src/frontends/kotlin.js +685 -0
  119. package/build/src/frontends/php.d.ts +118 -1
  120. package/build/src/frontends/php.d.ts.map +1 -1
  121. package/build/src/frontends/php.js +1583 -76
  122. package/build/src/frontends/program.d.ts +74 -0
  123. package/build/src/frontends/program.d.ts.map +1 -0
  124. package/build/src/frontends/program.js +989 -0
  125. package/build/src/frontends/ruby.d.ts +68 -1
  126. package/build/src/frontends/ruby.d.ts.map +1 -1
  127. package/build/src/frontends/ruby.js +1446 -101
  128. package/build/src/frontends/rust-parser.d.ts +11 -0
  129. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  130. package/build/src/frontends/rust-parser.js +15 -0
  131. package/build/src/frontends/rust.d.ts +14 -0
  132. package/build/src/frontends/rust.d.ts.map +1 -0
  133. package/build/src/frontends/rust.js +715 -0
  134. package/build/src/frontends/scalars.d.ts +10 -0
  135. package/build/src/frontends/scalars.d.ts.map +1 -1
  136. package/build/src/frontends/scalars.js +28 -2
  137. package/build/src/frontends/swift.d.ts +10 -0
  138. package/build/src/frontends/swift.d.ts.map +1 -0
  139. package/build/src/frontends/swift.js +860 -0
  140. package/build/src/frontends/types.d.ts +186 -0
  141. package/build/src/frontends/types.d.ts.map +1 -0
  142. package/build/src/frontends/types.js +634 -0
  143. package/build/src/language-registry.d.ts +46 -4
  144. package/build/src/language-registry.d.ts.map +1 -1
  145. package/build/src/language-registry.js +177 -13
  146. package/build/src/mapping.d.ts +2 -2
  147. package/build/src/mapping.d.ts.map +1 -1
  148. package/build/src/mapping.js +31 -10
  149. package/build/src/semantic/capabilities.d.ts +66 -0
  150. package/build/src/semantic/capabilities.d.ts.map +1 -0
  151. package/build/src/semantic/capabilities.js +649 -0
  152. package/build/src/semantic/effects.d.ts +26 -0
  153. package/build/src/semantic/effects.d.ts.map +1 -0
  154. package/build/src/semantic/effects.js +764 -0
  155. package/build/src/semantic/generics.d.ts +23 -0
  156. package/build/src/semantic/generics.d.ts.map +1 -0
  157. package/build/src/semantic/generics.js +61 -0
  158. package/build/src/semantic/lifetime.d.ts +37 -0
  159. package/build/src/semantic/lifetime.d.ts.map +1 -0
  160. package/build/src/semantic/lifetime.js +527 -0
  161. package/build/src/semantic/provenance.d.ts +9 -2
  162. package/build/src/semantic/provenance.d.ts.map +1 -1
  163. package/build/src/semantic/provenance.js +462 -20
  164. package/build/src/semantic/scalars.d.ts +11 -0
  165. package/build/src/semantic/scalars.d.ts.map +1 -1
  166. package/build/src/semantic/scalars.js +16 -1
  167. package/build/src/semantic/stdlib.d.ts +254 -0
  168. package/build/src/semantic/stdlib.d.ts.map +1 -0
  169. package/build/src/semantic/stdlib.js +880 -0
  170. package/build/src/semantic/types.d.ts +3108 -178
  171. package/build/src/semantic/types.d.ts.map +1 -1
  172. package/build/src/semantic/types.js +730 -15
  173. package/build/src/semantic/validate.d.ts +85 -5
  174. package/build/src/semantic/validate.d.ts.map +1 -1
  175. package/build/src/semantic/validate.js +2576 -98
  176. package/build/src/stdlib-facades.d.ts +304 -0
  177. package/build/src/stdlib-facades.d.ts.map +1 -0
  178. package/build/src/stdlib-facades.js +1167 -0
  179. package/build/src/stdlib-negotiation.d.ts +69 -0
  180. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  181. package/build/src/stdlib-negotiation.js +403 -0
  182. package/build/src/stdlib-providers.d.ts +72 -0
  183. package/build/src/stdlib-providers.d.ts.map +1 -0
  184. package/build/src/stdlib-providers.js +339 -0
  185. package/build/src/toolchains.d.ts +55 -1
  186. package/build/src/toolchains.d.ts.map +1 -1
  187. package/build/src/toolchains.js +15 -4
  188. package/docs/android.md +79 -0
  189. package/docs/architecture.md +47 -13
  190. package/docs/dart.md +60 -0
  191. package/docs/goals.md +3 -3
  192. package/docs/ios.md +121 -0
  193. package/docs/kotlin.md +42 -0
  194. package/docs/language-support.md +238 -26
  195. package/docs/multi-file-modules.md +52 -0
  196. package/docs/parser-qualification.md +121 -8
  197. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  198. package/docs/rust.md +88 -0
  199. package/docs/source-maps.md +17 -7
  200. package/docs/specification.md +5 -0
  201. package/docs/standard-library-portability.md +39 -8
  202. package/docs/swift.md +44 -0
  203. package/docs/testing.md +381 -4
  204. package/docs/webassembly.md +52 -0
  205. package/index.js +66 -8
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  231. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  232. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  233. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  234. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  235. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  236. package/package.json +5 -2
  237. package/src/artifact-path.js +47 -2
  238. package/src/artifacts.js +67 -0
  239. package/src/backends/android.js +1370 -0
  240. package/src/backends/c-validation.js +6 -1
  241. package/src/backends/cpp-validation.js +6 -1
  242. package/src/backends/csharp.js +3 -0
  243. package/src/backends/dart-runtime.js +41 -0
  244. package/src/backends/dart.js +326 -0
  245. package/src/backends/effects.js +705 -0
  246. package/src/backends/go.js +14 -2
  247. package/src/backends/identifiers.js +166 -9
  248. package/src/backends/index.js +27 -2
  249. package/src/backends/ios.js +1612 -0
  250. package/src/backends/java.js +454 -36
  251. package/src/backends/javascript.js +389 -23
  252. package/src/backends/kotlin-runtime.js +29 -0
  253. package/src/backends/kotlin.js +144 -0
  254. package/src/backends/native-validation.js +1 -1
  255. package/src/backends/ordered-expressions.js +40 -6
  256. package/src/backends/php-stdlib-support.js +239 -0
  257. package/src/backends/php.js +469 -32
  258. package/src/backends/program.js +1408 -0
  259. package/src/backends/python.js +3 -0
  260. package/src/backends/ruby.js +326 -23
  261. package/src/backends/rust-runtime.js +34 -0
  262. package/src/backends/rust-validation.js +75 -0
  263. package/src/backends/rust.js +335 -0
  264. package/src/backends/scalars.js +141 -16
  265. package/src/backends/shared.js +2314 -115
  266. package/src/backends/stdlib-support.js +234 -0
  267. package/src/backends/swift-runtime.js +14 -0
  268. package/src/backends/swift.js +132 -0
  269. package/src/backends/typescript.js +349 -23
  270. package/src/backends/wasm.js +2208 -0
  271. package/src/backends/writer.js +545 -2
  272. package/src/diagnostic.js +4 -2
  273. package/src/frontends/c.js +4 -2
  274. package/src/frontends/cpp.js +4 -2
  275. package/src/frontends/csharp.js +4 -2
  276. package/src/frontends/dart.js +963 -0
  277. package/src/frontends/index.js +14 -4
  278. package/src/frontends/java.js +1977 -69
  279. package/src/frontends/javascript-typescript.js +2046 -102
  280. package/src/frontends/kotlin.js +713 -0
  281. package/src/frontends/php.js +1725 -79
  282. package/src/frontends/program.js +1062 -0
  283. package/src/frontends/ruby.js +1624 -98
  284. package/src/frontends/rust-parser.js +18 -0
  285. package/src/frontends/rust.js +714 -0
  286. package/src/frontends/scalars.js +31 -1
  287. package/src/frontends/swift.js +893 -0
  288. package/src/frontends/types.js +750 -0
  289. package/src/language-registry.js +182 -12
  290. package/src/mapping.js +33 -9
  291. package/src/semantic/capabilities.js +671 -0
  292. package/src/semantic/effects.js +737 -0
  293. package/src/semantic/generics.js +58 -0
  294. package/src/semantic/lifetime.js +517 -0
  295. package/src/semantic/provenance.js +412 -19
  296. package/src/semantic/scalars.js +17 -0
  297. package/src/semantic/stdlib.js +921 -0
  298. package/src/semantic/types.js +810 -14
  299. package/src/semantic/validate.js +2934 -209
  300. package/src/stdlib-facades.js +1211 -0
  301. package/src/stdlib-negotiation.js +446 -0
  302. package/src/stdlib-providers.js +377 -0
  303. package/src/toolchains.js +16 -3
@@ -81,15 +81,18 @@ function emitStatement(writer, statement, indent, path) {
81
81
  emitIf(writer, statement, indent, path, "if")
82
82
  return
83
83
  }
84
+ if (statement.kind == "ExpressionStatement") throw new TypeError("Python Task 005 expression statement reached emission.")
84
85
 
85
86
  writer.synthetic(indent, "indentation", [statement], [path])
86
87
  if (statement.kind == "ReturnStatement") {
88
+ if (!statement.expression) throw new TypeError("Python bare return reached emission.")
87
89
  writer.mapped("return", {mappingKind: "anchor", node: statement, path})
88
90
  writer.synthetic(" ", "return spacing", [statement], [path])
89
91
  emitExpression(writer, statement.expression, `${path}/expression`, "python", identity)
90
92
  writer.synthetic("\n", "line break", [statement], [path])
91
93
  return
92
94
  }
95
+ if (statement.kind != "PrintStatement") throw new TypeError("Unsupported Python statement reached emission.")
93
96
 
94
97
  writer.mapped("print", {mappingKind: "anchor", node: statement, path})
95
98
  writer.mapped("(", {mappingKind: "anchor", node: statement, path})
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
- import {emitExpression} from "./shared.js"
4
- import {emitScalarType} from "./scalars.js"
3
+ import {emitExpression, emitType} from "./shared.js"
4
+ import {emitEffectPrefixes, emitEffectSupport} from "./effects.js"
5
5
 
6
6
  /**
7
7
  * Emits an independently executable Ruby program through the source-aware writer.
@@ -10,30 +10,116 @@ import {emitScalarType} from "./scalars.js"
10
10
  * @returns {void}
11
11
  */
12
12
  export function generateRuby(module, writer) {
13
+ const records = module.records ?? []
14
+ const classes = module.classes ?? []
15
+ const errors = module.errors ?? []
16
+
17
+ if (writer.program) {
18
+ const programModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (/** @type {unknown} */ (module))
19
+
20
+ for (const moduleId of [...new Set(programModule.imports.map((item) => item.moduleId))]) {
21
+ const relative = writer.relativeModuleSpecifier(moduleId).replace(/\.rb$/u, "").replace(/^\.\//u, "")
22
+ const imported = /** @type {import("../semantic/types.js").SemanticImport} */ (
23
+ programModule.imports.find((item) => item.moduleId == moduleId))
24
+ const importPath = `/imports/${programModule.imports.indexOf(imported)}`
25
+
26
+ writer.synthetic("require_relative ", "Ruby require-relative edge", [imported], [importPath])
27
+ writer.mapped(JSON.stringify(relative), {mappingKind: "anchor", node: imported, path: importPath, role: "path"})
28
+ writer.synthetic("\n", "Ruby require-relative terminator", [imported], [importPath])
29
+ }
30
+ if (programModule.imports.length > 0) writer.synthetic("\n", "Ruby require/module separator", [module])
31
+ if (writer.stdlibProviderEntries) {
32
+ const relative = writer.stdlibProviderSpecifier().replace(/\.rb$/u, "").replace(/^\.\//u, "")
33
+
34
+ writer.synthetic("require_relative ", "Ruby stdlib provider require-relative edge", [module])
35
+ writer.synthetic(JSON.stringify(relative), "Ruby stdlib provider require-relative path", [module])
36
+ writer.synthetic("\n", "Ruby stdlib provider require-relative terminator", [module])
37
+ writer.synthetic("\n", "Ruby stdlib provider require separator", [module])
38
+ }
39
+ writer.synthetic(`module ${writer.programModuleName(programModule.id)}\n`, "Ruby semantic module wrapper", [module])
40
+ if (module.functions.length > 0) writer.synthetic("module_function\n\n", "Ruby module-function profile", [module])
41
+ }
42
+
43
+ emitEffectSupport(writer, module, "ruby")
44
+ errors.forEach((error, index) => {
45
+ const path = `/errors/${index}`
46
+
47
+ if (index > 0) writer.synthetic("\n\n", "error declaration separator", [error], [path])
48
+ writer.mapped("class", {mappingKind: "anchor", node: error, path})
49
+ writer.synthetic(" ", "error declaration spacing", [error], [path])
50
+ writer.mapped(error.name, {mappingKind: "exact", node: error, path, role: "name"})
51
+ writer.synthetic(" < StandardError\nend", "Ruby unchecked error scaffolding", [error], [path])
52
+ })
53
+ if (errors.length > 0) writer.synthetic("\n\n", "error/declaration separator", [module])
54
+
55
+ records.forEach((record, recordIndex) => {
56
+ const recordPath = `/records/${recordIndex}`
57
+
58
+ if (recordIndex > 0) writer.synthetic("\n\n", "record declaration separator", [record], [recordPath])
59
+ emitTemplateComments(writer, record.typeParameters ?? [], `${recordPath}/typeParameters`)
60
+ writer.mapped("class", {mappingKind: "anchor", node: record, path: recordPath})
61
+ writer.synthetic(" ", "record declaration spacing", [record], [recordPath])
62
+ writer.mapped(record.name, {mappingKind: "exact", node: record, path: recordPath, role: "name"})
63
+ writer.synthetic("\n", "line break", [record], [recordPath])
64
+ record.fields.forEach((field, fieldIndex) => {
65
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
66
+
67
+ writer.synthetic(" # @type [", "Ruby record field type scaffolding", [field], [fieldPath])
68
+ emitType(writer, field.type, `${fieldPath}/type`, "ruby")
69
+ writer.synthetic("]\n attr_reader :", "Ruby record reader scaffolding", [field], [fieldPath])
70
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
71
+ writer.synthetic("\n", "line break", [field], [fieldPath])
72
+ })
73
+ writer.synthetic("\n", "record constructor separator", [record], [recordPath])
74
+ record.fields.forEach((field, fieldIndex) => {
75
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
76
+
77
+ writer.synthetic(" # @param ", "Ruby record constructor type scaffolding", [field], [fieldPath])
78
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
79
+ writer.synthetic(" [", "Ruby record constructor type scaffolding", [field], [fieldPath])
80
+ emitType(writer, field.type, `${fieldPath}/type`, "ruby")
81
+ writer.synthetic("]\n", "Ruby record constructor type scaffolding", [field], [fieldPath])
82
+ })
83
+ writer.synthetic(" def initialize(", "Ruby record constructor scaffolding", [record], [recordPath])
84
+ record.fields.forEach((field, fieldIndex) => {
85
+ if (fieldIndex) writer.synthetic(", ", "record field separator", [record], [recordPath])
86
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: `${recordPath}/fields/${fieldIndex}`, role: "name"})
87
+ })
88
+ writer.synthetic(")\n", "Ruby record constructor scaffolding", [record], [recordPath])
89
+ record.fields.forEach((field, fieldIndex) => {
90
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
91
+
92
+ writer.synthetic(" @", "Ruby record storage scaffolding", [field], [fieldPath])
93
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
94
+ writer.synthetic(" = ", "Ruby record storage scaffolding", [field], [fieldPath])
95
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
96
+ writer.synthetic("\n", "line break", [field], [fieldPath])
97
+ })
98
+ writer.synthetic(" ::Kernel.instance_method(:freeze).bind_call(self)\n end\nend", "Ruby record immutability scaffolding", [record], [recordPath])
99
+ })
100
+ if (records.length > 0) writer.synthetic("\n\n", "record/function separator", [module])
101
+
102
+ classes.forEach((declaration, classIndex) => {
103
+ if (classIndex > 0) writer.synthetic("\n\n", "reference class separator", [declaration], [`/classes/${classIndex}`])
104
+ emitReferenceClass(writer, declaration, classIndex)
105
+ })
106
+ if (classes.length > 0) writer.synthetic("\n\n", "reference class/function separator", [module])
107
+
13
108
  module.functions.forEach((declaration, functionIndex) => {
14
109
  if (functionIndex > 0) writer.synthetic("\n\n", "declaration separator", [declaration])
15
110
 
111
+ emitTemplateComments(writer, declaration.typeParameters ?? [], `/functions/${functionIndex}/typeParameters`)
16
112
  for (const [parameterIndex, parameter] of declaration.parameters.entries()) {
17
113
  const parameterPath = `/functions/${functionIndex}/parameters/${parameterIndex}`
18
114
 
19
115
  writer.synthetic("# @param ", "Ruby type scaffolding", [parameter], [parameterPath])
20
116
  writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
21
117
  writer.synthetic(" [", "Ruby type scaffolding", [parameter], [parameterPath])
22
- writer.mapped(emitScalarType("ruby", parameter.type), {
23
- mappingKind: "exact",
24
- node: parameter.type,
25
- path: `${parameterPath}/type`,
26
- role: "type"
27
- })
118
+ emitType(writer, parameter.type, `${parameterPath}/type`, "ruby")
28
119
  writer.synthetic("]\n", "Ruby type scaffolding", [parameter], [parameterPath])
29
120
  }
30
121
  writer.synthetic("# @return [", "Ruby type scaffolding", [declaration])
31
- writer.mapped(emitScalarType("ruby", declaration.returnType), {
32
- mappingKind: "exact",
33
- node: declaration.returnType,
34
- path: `/functions/${functionIndex}/returnType`,
35
- role: "type"
36
- })
122
+ emitType(writer, declaration.returnType, `/functions/${functionIndex}/returnType`, "ruby")
37
123
  writer.synthetic("]\n", "Ruby type scaffolding", [declaration])
38
124
  writer.mapped("def", {mappingKind: "anchor", node: declaration})
39
125
  writer.synthetic(" ", "function spacing", [declaration])
@@ -55,8 +141,129 @@ export function generateRuby(module, writer) {
55
141
  writer.mapped("end", {mappingKind: "anchor", node: declaration})
56
142
  })
57
143
 
58
- writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
59
- emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body")
144
+ if (writer.program) {
145
+ const privateNominals = [...errors, ...records].filter((declaration) => !writer.isExported(declaration.id))
146
+ const privateFunctions = module.functions.filter((declaration) => !writer.isExported(declaration.id))
147
+
148
+ for (const declaration of privateNominals) {
149
+ writer.synthetic("\nprivate_constant :", "Ruby private semantic nominal declaration", [declaration])
150
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, role: "name"})
151
+ }
152
+ for (const declaration of privateFunctions) {
153
+ writer.synthetic("\nprivate_class_method :", "Ruby private semantic function", [declaration])
154
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, role: "name"})
155
+ }
156
+ }
157
+
158
+ if (!writer.program || writer.isProgramEntry()) {
159
+ writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
160
+ emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body")
161
+ }
162
+ if (writer.program) writer.synthetic("\nend\n", "Ruby semantic module close", [module])
163
+ }
164
+
165
+ /**
166
+ * Emits one native Ruby reference class.
167
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
168
+ * @param {import("../semantic/types.js").ClassDeclaration} declaration - Reference class.
169
+ * @param {number} classIndex - Module class index.
170
+ * @returns {void}
171
+ */
172
+ function emitReferenceClass(writer, declaration, classIndex) {
173
+ const path = `/classes/${classIndex}`
174
+
175
+ writer.mapped("class", {mappingKind: "anchor", node: declaration, path})
176
+ writer.synthetic(" ", "reference class spacing", [declaration], [path])
177
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, path, role: "name"})
178
+ writer.synthetic("\n", "line break", [declaration], [path])
179
+ declaration.fields.forEach((field, index) => {
180
+ const fieldPath = `${path}/fields/${index}`
181
+
182
+ writer.synthetic(" # @semantifold-private ", "private field metadata", [field], [fieldPath])
183
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
184
+ writer.synthetic(" [", "private field type metadata", [field], [fieldPath])
185
+ emitType(writer, field.type, `${fieldPath}/type`, "ruby")
186
+ writer.synthetic("]\n", "line break", [field], [fieldPath])
187
+ })
188
+ const constructor = declaration.constructor
189
+ const constructorPath = `${path}/constructor`
190
+
191
+ writer.synthetic("\n", "constructor spacing", [constructor], [constructorPath])
192
+ emitRubyCallableComments(writer, constructor.parameters, undefined, `${constructorPath}/parameters`, undefined)
193
+ writer.synthetic(" ", "constructor indentation", [constructor], [constructorPath])
194
+ writer.mapped("def initialize", {mappingKind: "exact", node: constructor, path: constructorPath, role: "constructor"})
195
+ emitRubyParameters(writer, constructor.parameters, `${constructorPath}/parameters`)
196
+ writer.synthetic("\n", "line break", [constructor], [constructorPath])
197
+ emitBlock(writer, constructor.body, " ", `${constructorPath}/body`)
198
+ writer.synthetic(" end", "constructor close", [constructor], [constructorPath])
199
+ declaration.methods.forEach((method, index) => {
200
+ const methodPath = `${path}/methods/${index}`
201
+
202
+ writer.synthetic("\n\n", "method spacing", [method], [methodPath])
203
+ emitRubyCallableComments(writer, method.parameters, method.returnType, `${methodPath}/parameters`, `${methodPath}/returnType`)
204
+ writer.synthetic(" def ", "method indentation", [method], [methodPath])
205
+ writer.mapped(method.name, {mappingKind: "exact", node: method, path: methodPath, role: "name"})
206
+ emitRubyParameters(writer, method.parameters, `${methodPath}/parameters`)
207
+ writer.synthetic("\n", "line break", [method], [methodPath])
208
+ emitBlock(writer, method.body, " ", `${methodPath}/body`)
209
+ writer.synthetic(" end", "method close", [method], [methodPath])
210
+ })
211
+ writer.synthetic("\n", "line break", [declaration], [path])
212
+ writer.mapped("end", {mappingKind: "anchor", node: declaration, path})
213
+ }
214
+
215
+ /**
216
+ * Emits exact Ruby callable type comments.
217
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
218
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Ordered parameters.
219
+ * @param {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Optional return type.
220
+ * @param {string} parameterPath - Parameter collection path.
221
+ * @param {string | undefined} returnPath - Return type path.
222
+ * @returns {void}
223
+ */
224
+ function emitRubyCallableComments(writer, parameters, returnType, parameterPath, returnPath) {
225
+ for (const [index, parameter] of parameters.entries()) {
226
+ writer.synthetic(" # @param ", "parameter type metadata", [parameter], [`${parameterPath}/${index}`])
227
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${parameterPath}/${index}`, role: "name"})
228
+ writer.synthetic(" [", "parameter type metadata", [parameter], [`${parameterPath}/${index}`])
229
+ emitType(writer, parameter.type, `${parameterPath}/${index}/type`, "ruby")
230
+ writer.synthetic("]\n", "line break", [parameter])
231
+ }
232
+ if (returnType && returnPath) {
233
+ writer.synthetic(" # @return [", "return type metadata", [])
234
+ emitType(writer, returnType, returnPath, "ruby")
235
+ writer.synthetic("]\n", "line break", [])
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Emits one Ruby parameter list.
241
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
242
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Ordered parameters.
243
+ * @param {string} path - Parameter collection path.
244
+ * @returns {void}
245
+ */
246
+ function emitRubyParameters(writer, parameters, path) {
247
+ writer.synthetic("(", "parameter list open", parameters)
248
+ parameters.forEach((parameter, index) => {
249
+ if (index) writer.synthetic(", ", "parameter separator", parameters)
250
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${path}/${index}`, role: "name"})
251
+ })
252
+ writer.synthetic(")", "parameter list close", parameters)
253
+ }
254
+
255
+ /**
256
+ * Emits exact RDoc declaration parameters.
257
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
258
+ * @param {import("../semantic/types.js").TypeParameter[]} parameters - Ordered type parameters.
259
+ * @param {string} path - Type-parameter collection path.
260
+ */
261
+ function emitTemplateComments(writer, parameters, path) {
262
+ parameters.forEach((parameter, index) => {
263
+ writer.synthetic("# @template ", "Ruby type parameter scaffolding", [parameter], [`${path}/${index}`])
264
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${path}/${index}`, role: "name"})
265
+ writer.synthetic("\n", "line break", [parameter])
266
+ })
60
267
  }
61
268
 
62
269
  /**
@@ -80,11 +287,112 @@ function emitBlock(writer, block, indent, path) {
80
287
  * @returns {void}
81
288
  */
82
289
  function emitStatement(writer, statement, indent, path) {
290
+ emitEffectPrefixes(writer, statement, indent, path, "ruby",
291
+ (expression, expressionPath) => emitExpression(writer, expression, expressionPath, "ruby", identity))
83
292
  if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement") return emitLocal(writer, statement, indent, path)
84
293
  writer.synthetic(indent, "indentation", [statement], [path])
294
+ if (statement.kind == "PrivateFieldWriteStatement") {
295
+ const field = writer.privateFieldForId(statement.field)
296
+
297
+ writer.mapped(`@${field.name}`, {mappingKind: "exact", name: field.name, node: statement, path, role: "member"})
298
+ writer.synthetic(" = ", "private field assignment", [statement], [path])
299
+ emitExpression(writer, statement.expression, `${path}/expression`, "ruby", identity)
300
+ writer.synthetic("\n", "line break", [statement], [path])
301
+ return
302
+ }
303
+ if (statement.kind == "BreakStatement" || statement.kind == "ContinueStatement") {
304
+ writer.mapped(statement.kind == "BreakStatement" ? "break" : "next", {mappingKind: "exact", node: statement, path})
305
+ writer.synthetic("\n", "line break", [statement], [path])
306
+ return
307
+ }
308
+ if (statement.kind == "WhileStatement") {
309
+ writer.mapped("while", {mappingKind: "exact", node: statement, path})
310
+ writer.synthetic(" ", "condition-controlled loop spacing", [statement], [path])
311
+ emitExpression(writer, statement.condition, `${path}/condition`, "ruby", identity)
312
+ writer.synthetic("\n", "line break", [statement], [path])
313
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`)
314
+ writer.synthetic(indent, "indentation", [statement], [path])
315
+ writer.mapped("end", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
316
+ writer.synthetic("\n", "line break", [statement], [path])
317
+ return
318
+ }
319
+ if (statement.kind == "ForEachStatement") {
320
+ emitExpression(writer, statement.list, `${path}/list`, "ruby", identity)
321
+ writer.mapped(".each", {mappingKind: "anchor", node: statement, path})
322
+ writer.synthetic(" ", "loop spacing", [statement], [path])
323
+ writer.mapped("do", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
324
+ writer.synthetic(" |", "iteration binding delimiter", [statement.valueBinding], [`${path}/valueBinding`])
325
+ writer.mapped(statement.valueBinding.name, {
326
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
327
+ })
328
+ writer.synthetic("|\n", "iteration binding delimiter", [statement.valueBinding], [`${path}/valueBinding`])
329
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`)
330
+ writer.synthetic(indent, "indentation", [statement], [path])
331
+ writer.mapped("end", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
332
+ writer.synthetic("\n", "line break", [statement], [path])
333
+ return
334
+ }
335
+ if (statement.kind == "ForEachMapStatement") {
336
+ emitExpression(writer, statement.map, `${path}/map`, "ruby", identity)
337
+ writer.mapped(".each", {mappingKind: "anchor", node: statement, path})
338
+ writer.synthetic(" ", "map loop spacing", [statement], [path])
339
+ writer.mapped("do", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
340
+ writer.synthetic(" |", "map iteration binding delimiter", [statement], [path])
341
+ writer.mapped(statement.keyBinding.name, {
342
+ mappingKind: "exact", node: statement.keyBinding, path: `${path}/keyBinding`, role: "name"
343
+ })
344
+ writer.synthetic(", ", "map iteration binding separator", [statement], [path])
345
+ writer.mapped(statement.valueBinding.name, {
346
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
347
+ })
348
+ writer.synthetic("|\n", "map iteration binding delimiter", [statement], [path])
349
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`)
350
+ writer.synthetic(indent, "indentation", [statement], [path])
351
+ writer.mapped("end", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
352
+ writer.synthetic("\n", "line break", [statement], [path])
353
+ return
354
+ }
355
+ if (statement.kind == "RaiseStatement") {
356
+ const type = statement.error.error
357
+ const error = writer.errorForId(type.declarationId)
358
+
359
+ writer.mapped("raise", {mappingKind: "anchor", node: statement, path})
360
+ writer.synthetic(" ", "raise spacing", [statement], [path])
361
+ writer.mapped(writer.errorNameForId(type.declarationId), {mappingKind: "exact", name: error.name, node: statement.error, path: `${path}/error`, role: "type"})
362
+ writer.synthetic(", ", "error message separator", [statement.error], [`${path}/error`])
363
+ emitExpression(writer, statement.error.message, `${path}/error/message`, "ruby", identity)
364
+ writer.synthetic("\n", "line break", [statement], [path])
365
+ return
366
+ }
367
+ if (statement.kind == "TryStatement") {
368
+ const caught = writer.errorForId(statement.catchType.declarationId)
369
+
370
+ writer.mapped("begin", {mappingKind: "anchor", node: statement, path})
371
+ writer.synthetic("\n", "line break", [statement], [path])
372
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`)
373
+ writer.synthetic(indent, "indentation", [statement], [path])
374
+ writer.mapped("rescue", {mappingKind: "anchor", node: statement, path, role: "catch"})
375
+ writer.synthetic(" ", "rescue spacing", [statement], [path])
376
+ writer.mapped(writer.errorNameForId(statement.catchType.declarationId), {mappingKind: "exact", name: caught.name, node: statement.catchType, path: `${path}/catchType`, role: "type"})
377
+ writer.synthetic(" => ", "catch binding separator", [statement.catchBinding], [`${path}/catchBinding`])
378
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
379
+ writer.synthetic("\n", "line break", [statement], [path])
380
+ emitBlock(writer, statement.catchBody, `${indent} `, `${path}/catchBody`)
381
+ writer.synthetic(indent, "indentation", [statement], [path])
382
+ writer.mapped("end", {mappingKind: "anchor", node: statement.catchBody, path: `${path}/catchBody`})
383
+ writer.synthetic("\n", "line break", [statement], [path])
384
+ return
385
+ }
85
386
  if (statement.kind == "ReturnStatement") {
86
387
  writer.mapped("return", {mappingKind: "anchor", node: statement, path})
87
- writer.synthetic(" ", "return spacing", [statement], [path])
388
+ if (statement.expression) {
389
+ writer.synthetic(" ", "return spacing", [statement], [path])
390
+ emitExpression(writer, statement.expression, `${path}/expression`, "ruby", identity)
391
+ }
392
+ writer.synthetic("\n", "line break", [statement], [path])
393
+ return
394
+ }
395
+ if (statement.kind == "ExpressionStatement") {
88
396
  emitExpression(writer, statement.expression, `${path}/expression`, "ruby", identity)
89
397
  writer.synthetic("\n", "line break", [statement], [path])
90
398
  return
@@ -134,12 +442,7 @@ function emitLocal(writer, statement, indent, statementPath) {
134
442
  }
135
443
 
136
444
  writer.synthetic("# @type [", "Ruby local type scaffolding", [statement], [statementPath])
137
- writer.mapped(emitScalarType("ruby", statement.type), {
138
- mappingKind: "exact",
139
- node: statement.type,
140
- path: `${statementPath}/type`,
141
- role: "type"
142
- })
445
+ emitType(writer, statement.type, `${statementPath}/type`, "ruby")
143
446
  writer.synthetic("]\n", "Ruby local type scaffolding", [statement], [statementPath])
144
447
  if (!statement.mutable) {
145
448
  writer.synthetic(`${indent}# @semantifold-immutable\n`, "Ruby immutability scaffolding", [statement], [statementPath])
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+
3
+ /** Qualified edition-2021 support. Every token is checked by the Rust frontend before collapse. */
4
+ export const rustRuntime = `#![allow(dead_code, unused_variables, unused_mut, unused_assignments, unused_parens, unconditional_recursion, non_snake_case)]
5
+ fn semantifold_print_integer(value: i64) { println!("{}", value); }
6
+ fn semantifold_print_boolean(value: bool) { println!("{}", value); }
7
+ fn semantifold_print_string(value: String) { println!("{}", value); }
8
+ fn semantifold_integer_add(left: i64, right: i64) -> i64 {
9
+ let (result, overflow): (i64, bool) = left.overflowing_add(right);
10
+ if overflow { eprintln!("semantifold: integer overflow"); std::process::exit(70); }
11
+ return result;
12
+ }
13
+ fn semantifold_integer_subtract(left: i64, right: i64) -> i64 {
14
+ let (result, overflow): (i64, bool) = left.overflowing_sub(right);
15
+ if overflow { eprintln!("semantifold: integer overflow"); std::process::exit(70); }
16
+ return result;
17
+ }
18
+ fn semantifold_integer_multiply(left: i64, right: i64) -> i64 {
19
+ let (result, overflow): (i64, bool) = left.overflowing_mul(right);
20
+ if overflow { eprintln!("semantifold: integer overflow"); std::process::exit(70); }
21
+ return result;
22
+ }
23
+ fn semantifold_integer_negate(value: i64) -> i64 {
24
+ let (result, overflow): (i64, bool) = value.overflowing_neg();
25
+ if overflow { eprintln!("semantifold: integer overflow"); std::process::exit(70); }
26
+ return result;
27
+ }
28
+ `
29
+
30
+ /** Actual manifest qualified with Cargo 1.98.1 on Ubuntu 24.04 and 26.04. */
31
+ export const rustManifest = '[package]\nname = "semantifold-generated"\nversion = "0.0.0"\nedition = "2021"\nrust-version = "1.98.1"\npublish = false\nbuild = false\n\n[profile.dev]\noverflow-checks = true\npanic = "abort"\n\n[profile.release]\noverflow-checks = true\npanic = "abort"\n'
32
+
33
+ /** Cargo-generated bytes, SHA-256 185a41f6648ef49c8e7721f3321604abf05fae11c7007f823121c17fe48eec64. */
34
+ export const rustLockfile = '# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = "semantifold-generated"\nversion = "0.0.0"\n'
@@ -0,0 +1,75 @@
1
+ // @ts-check
2
+
3
+ import {unsupportedCapability} from "../diagnostic.js"
4
+
5
+ /** Qualified legacy Rust grammar input limit, including support source. */
6
+ export const maximumRustSourceLength = 32767
7
+
8
+ /** Propagates known owned UTF-8 lengths to reject impossible native allocations before emission. */
9
+ class RustValueValidator {
10
+ /**
11
+ * Validates each expression without folding or changing the semantic graph.
12
+ * @param {import("../semantic/types.js").Expression} expression - Validated expression.
13
+ * @param {Map<string, bigint | undefined>} sizes - Known lexical string byte sizes.
14
+ * @returns {bigint | undefined} Proven result size when known.
15
+ */
16
+ size(expression, sizes) {
17
+ if (expression.kind == "StringLiteral") return BigInt(Buffer.byteLength(expression.value, "utf8"))
18
+ if (expression.kind == "IdentifierExpression") return sizes.get(expression.name)
19
+ if (expression.kind == "CallExpression") {
20
+ for (const argument of expression.arguments) this.size(argument, sizes)
21
+ } else if (expression.kind == "UnaryExpression") this.size(expression.operand, sizes)
22
+ else if (expression.kind == "BinaryExpression") {
23
+ const left = this.size(expression.left, sizes)
24
+ const right = this.size(expression.right, sizes)
25
+
26
+ if (expression.operation == "StringConcat") {
27
+ if ((left ?? 0n) + (right ?? 0n) > 9223372036854775807n) {
28
+ unsupportedCapability("rust", "known owned string size exceeds the qualified signed-64-bit allocation limit", expression.location)
29
+ }
30
+ if (left !== undefined && right !== undefined) return left + right
31
+ }
32
+ }
33
+ return undefined
34
+ }
35
+
36
+ /**
37
+ * Follows value copies and independent branches, retaining only equal outgoing size proofs.
38
+ * @param {import("../semantic/types.js").Block} block - Lexical block.
39
+ * @param {Map<string, bigint | undefined>} inherited - Visible sizes.
40
+ * @returns {Map<string, bigint | undefined>} Outgoing size proofs.
41
+ */
42
+ block(block, inherited) {
43
+ const sizes = new Map(inherited)
44
+
45
+ for (const statement of block.statements) {
46
+ if (statement.kind == "LocalDeclaration") sizes.set(statement.name, this.size(statement.initializer, sizes))
47
+ else if (statement.kind == "AssignmentStatement") sizes.set(statement.target.name, this.size(statement.expression, sizes))
48
+ else if (statement.kind == "IfStatement") {
49
+ this.size(statement.condition, sizes)
50
+ const left = this.block(statement.consequent, sizes)
51
+ const right = statement.alternate ? this.block(statement.alternate, sizes) : sizes
52
+
53
+ for (const name of sizes.keys()) sizes.set(name, left.get(name) === right.get(name) ? left.get(name) : undefined)
54
+ } else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ||
55
+ statement.kind == "ReturnStatement") {
56
+ const expression = statement.expression
57
+
58
+ if (expression) this.size(expression, sizes)
59
+ }
60
+ }
61
+ return sizes
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Rejects statically unrepresentable owned values before constructing any artifacts.
67
+ * @param {import("../semantic/types.js").SemanticModule} module - Fully validated semantics.
68
+ * @returns {void}
69
+ */
70
+ export function validateRustValues(module) {
71
+ const validator = new RustValueValidator()
72
+
73
+ for (const declaration of module.functions) validator.block(declaration.body, new Map())
74
+ validator.block(module.entryPoint.body, new Map())
75
+ }