redscript-mc 2.0.0 → 2.1.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 (629) hide show
  1. package/.claudeignore +21 -0
  2. package/README.md +12 -16
  3. package/README.zh.md +2 -2
  4. package/dist/cli.js +0 -0
  5. package/dist/src/__tests__/budget.test.js +261 -0
  6. package/dist/src/__tests__/diagnostics.test.js +2 -3
  7. package/dist/src/__tests__/e2e/coroutine.test.d.ts +7 -0
  8. package/dist/src/__tests__/e2e/coroutine.test.js +132 -0
  9. package/dist/{src2 → src}/__tests__/e2e/macros.test.js +1 -1
  10. package/dist/{src2 → src}/__tests__/e2e/migrate.test.js +1 -1
  11. package/dist/src/__tests__/e2e/stdlib-e2e.test.d.ts +10 -0
  12. package/dist/src/__tests__/e2e/stdlib-e2e.test.js +324 -0
  13. package/dist/src/__tests__/enum.test.d.ts +10 -0
  14. package/dist/src/__tests__/enum.test.js +389 -0
  15. package/dist/src/__tests__/generics.test.d.ts +14 -0
  16. package/dist/src/__tests__/generics.test.js +367 -0
  17. package/dist/{src2 → src}/__tests__/hir/desugar.test.js +2 -2
  18. package/dist/src/__tests__/incremental.test.d.ts +5 -0
  19. package/dist/src/__tests__/incremental.test.js +308 -0
  20. package/dist/src/__tests__/lsp.test.d.ts +7 -0
  21. package/dist/src/__tests__/lsp.test.js +245 -0
  22. package/dist/src/__tests__/mc-version.test.d.ts +10 -0
  23. package/dist/src/__tests__/mc-version.test.js +154 -0
  24. package/dist/{src2 → src}/__tests__/mir/arithmetic.test.js +2 -2
  25. package/dist/{src2 → src}/__tests__/mir/control-flow.test.js +2 -2
  26. package/dist/src/__tests__/modules.test.d.ts +7 -0
  27. package/dist/src/__tests__/modules.test.js +333 -0
  28. package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
  29. package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
  30. package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
  31. package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
  32. package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
  33. package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
  34. package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
  35. package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
  36. package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
  37. package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
  38. package/dist/src/__tests__/option.test.d.ts +14 -0
  39. package/dist/src/__tests__/option.test.js +275 -0
  40. package/dist/src/__tests__/schedule.test.d.ts +7 -0
  41. package/dist/src/__tests__/schedule.test.js +98 -0
  42. package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
  43. package/dist/src/__tests__/sourcemap.test.js +227 -0
  44. package/dist/src/__tests__/tuple.test.d.ts +11 -0
  45. package/dist/src/__tests__/tuple.test.js +202 -0
  46. package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
  47. package/dist/src/__tests__/typechecker-strict.test.js +197 -0
  48. package/dist/src/ast/types.d.ts +56 -2
  49. package/dist/src/cache/deps.d.ts +41 -0
  50. package/dist/src/cache/deps.js +158 -0
  51. package/dist/src/cache/incremental.d.ts +35 -0
  52. package/dist/src/cache/incremental.js +165 -0
  53. package/dist/src/cache/index.d.ts +37 -0
  54. package/dist/src/cache/index.js +152 -0
  55. package/dist/src/cli.js +76 -45
  56. package/dist/src/compile.d.ts +2 -2
  57. package/dist/src/compile.js +1 -1
  58. package/dist/src/diagnostics/index.d.ts +1 -1
  59. package/dist/src/diagnostics/index.js +8 -11
  60. package/dist/src/emit/compile.d.ts +29 -0
  61. package/dist/src/emit/compile.js +143 -0
  62. package/dist/{src2 → src}/emit/index.d.ts +9 -0
  63. package/dist/{src2 → src}/emit/index.js +59 -8
  64. package/dist/src/emit/modules.d.ts +29 -0
  65. package/dist/src/emit/modules.js +492 -0
  66. package/dist/src/emit/sourcemap.d.ts +53 -0
  67. package/dist/src/emit/sourcemap.js +73 -0
  68. package/dist/{src2 → src}/hir/lower.d.ts +1 -1
  69. package/dist/{src2 → src}/hir/lower.js +22 -1
  70. package/dist/src/hir/monomorphize.d.ts +22 -0
  71. package/dist/src/hir/monomorphize.js +379 -0
  72. package/dist/{src2 → src}/hir/types.d.ts +35 -2
  73. package/dist/src/index.d.ts +19 -2
  74. package/dist/src/index.js +36 -14
  75. package/dist/src/lexer/index.d.ts +1 -1
  76. package/dist/src/lexer/index.js +1 -0
  77. package/dist/src/lir/budget.d.ts +37 -0
  78. package/dist/src/lir/budget.js +280 -0
  79. package/dist/{src2 → src}/lir/lower.js +19 -0
  80. package/dist/{src2 → src}/lir/types.d.ts +7 -4
  81. package/dist/src/lsp/main.d.ts +8 -0
  82. package/dist/src/lsp/main.js +11 -0
  83. package/dist/src/lsp/server.d.ts +11 -0
  84. package/dist/src/lsp/server.js +352 -0
  85. package/dist/{src2 → src}/mir/lower.d.ts +1 -1
  86. package/dist/{src2 → src}/mir/lower.js +244 -10
  87. package/dist/{src2 → src}/mir/types.d.ts +10 -2
  88. package/dist/src/optimizer/coroutine.d.ts +34 -0
  89. package/dist/src/optimizer/coroutine.js +789 -0
  90. package/dist/src/optimizer/dce.d.ts +8 -34
  91. package/dist/src/optimizer/dce.js +146 -629
  92. package/dist/src/optimizer/interprocedural.d.ts +14 -0
  93. package/dist/src/optimizer/interprocedural.js +186 -0
  94. package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
  95. package/dist/src/optimizer/lir/const_imm.js +139 -0
  96. package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
  97. package/dist/src/optimizer/lir/dead_slot.js +130 -0
  98. package/dist/src/optimizer/lir/peephole.d.ts +21 -0
  99. package/dist/src/optimizer/lir/peephole.js +52 -0
  100. package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
  101. package/dist/src/optimizer/lir/pipeline.js +34 -0
  102. package/dist/src/optimizer/nbt-batch.d.ts +11 -0
  103. package/dist/src/optimizer/nbt-batch.js +51 -0
  104. package/dist/{src2 → src}/optimizer/pipeline.d.ts +4 -0
  105. package/dist/{src2 → src}/optimizer/pipeline.js +17 -1
  106. package/dist/src/optimizer/selector-cache.d.ts +22 -0
  107. package/dist/src/optimizer/selector-cache.js +100 -0
  108. package/dist/src/optimizer/unroll.d.ts +32 -0
  109. package/dist/src/optimizer/unroll.js +348 -0
  110. package/dist/src/parser/index.d.ts +8 -0
  111. package/dist/src/parser/index.js +204 -14
  112. package/dist/src/repl.d.ts +1 -1
  113. package/dist/src/typechecker/index.d.ts +4 -0
  114. package/dist/src/typechecker/index.js +198 -13
  115. package/dist/src/types/mc-version.d.ts +24 -0
  116. package/dist/src/types/mc-version.js +49 -0
  117. package/docs/ROADMAP.md +395 -0
  118. package/docs/compiler-pipeline-redesign.md +27 -10
  119. package/editors/vscode/out/extension.js +25176 -8000
  120. package/editors/vscode/package-lock.json +90 -6
  121. package/editors/vscode/package.json +3 -2
  122. package/editors/vscode/src/extension.ts +97 -67
  123. package/examples/showcase.mcrs +3 -3
  124. package/jest.config.js +1 -1
  125. package/package.json +9 -3
  126. package/src/__tests__/budget.test.ts +297 -0
  127. package/src/__tests__/diagnostics.test.ts +2 -3
  128. package/src/__tests__/e2e/coroutine.test.ts +142 -0
  129. package/{src2 → src}/__tests__/e2e/macros.test.ts +1 -1
  130. package/{src2 → src}/__tests__/e2e/migrate.test.ts +1 -1
  131. package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
  132. package/src/__tests__/enum.test.ts +425 -0
  133. package/src/__tests__/generics.test.ts +390 -0
  134. package/{src2 → src}/__tests__/hir/desugar.test.ts +2 -2
  135. package/src/__tests__/incremental.test.ts +337 -0
  136. package/src/__tests__/lsp.test.ts +270 -0
  137. package/src/__tests__/mc-version.test.ts +178 -0
  138. package/{src2 → src}/__tests__/mir/arithmetic.test.ts +2 -2
  139. package/{src2 → src}/__tests__/mir/control-flow.test.ts +2 -2
  140. package/src/__tests__/modules.test.ts +365 -0
  141. package/src/__tests__/optimizer/coroutine.test.ts +312 -0
  142. package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
  143. package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
  144. package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
  145. package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
  146. package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
  147. package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
  148. package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
  149. package/src/__tests__/optimizer/unroll.test.ts +231 -0
  150. package/src/__tests__/option.test.ts +299 -0
  151. package/src/__tests__/schedule.test.ts +105 -0
  152. package/src/__tests__/sourcemap.test.ts +254 -0
  153. package/src/__tests__/tuple.test.ts +220 -0
  154. package/src/__tests__/typechecker-strict.test.ts +216 -0
  155. package/src/ast/types.ts +33 -2
  156. package/src/cache/deps.ts +132 -0
  157. package/src/cache/incremental.ts +173 -0
  158. package/src/cache/index.ts +135 -0
  159. package/src/cli.ts +88 -45
  160. package/src/compile.ts +2 -2
  161. package/src/diagnostics/index.ts +8 -11
  162. package/src/emit/compile.ts +177 -0
  163. package/{src2 → src}/emit/index.ts +72 -8
  164. package/src/emit/modules.ts +581 -0
  165. package/src/emit/sourcemap.ts +101 -0
  166. package/{src2 → src}/hir/lower.ts +29 -2
  167. package/src/hir/monomorphize.ts +416 -0
  168. package/{src2 → src}/hir/types.ts +15 -3
  169. package/src/index.ts +29 -10
  170. package/src/lexer/index.ts +2 -1
  171. package/src/lir/budget.ts +321 -0
  172. package/{src2 → src}/lir/lower.ts +32 -1
  173. package/{src2 → src}/lir/types.ts +7 -3
  174. package/src/lsp/main.ts +9 -0
  175. package/src/lsp/server.ts +414 -0
  176. package/{src2 → src}/mir/lower.ts +251 -8
  177. package/{src2 → src}/mir/types.ts +12 -1
  178. package/src/optimizer/coroutine.ts +996 -0
  179. package/{src2 → src}/optimizer/dce.ts +2 -1
  180. package/src/optimizer/interprocedural.ts +177 -0
  181. package/src/optimizer/lir/const_imm.ts +143 -0
  182. package/src/optimizer/lir/dead_slot.ts +123 -0
  183. package/src/optimizer/lir/peephole.ts +57 -0
  184. package/src/optimizer/lir/pipeline.ts +37 -0
  185. package/src/optimizer/nbt-batch.ts +50 -0
  186. package/{src2 → src}/optimizer/pipeline.ts +16 -1
  187. package/src/optimizer/selector-cache.ts +103 -0
  188. package/src/optimizer/unroll.ts +386 -0
  189. package/src/parser/index.ts +212 -15
  190. package/src/repl.ts +1 -1
  191. package/src/stdlib/math.mcrs +4 -4
  192. package/src/templates/quest.mcrs +4 -4
  193. package/src/typechecker/index.ts +215 -15
  194. package/src/types/mc-version.ts +46 -0
  195. package/tsconfig.json +1 -1
  196. package/.claude/commands/build-test.md +0 -10
  197. package/.claude/commands/deploy-demo.md +0 -12
  198. package/.claude/commands/stage-status.md +0 -13
  199. package/.claude/settings.json +0 -12
  200. package/CLAUDE.md +0 -231
  201. package/dist/__tests__/cli.test.js +0 -278
  202. package/dist/__tests__/codegen.test.js +0 -152
  203. package/dist/__tests__/compile-all.test.d.ts +0 -10
  204. package/dist/__tests__/compile-all.test.js +0 -108
  205. package/dist/__tests__/dce.test.js +0 -138
  206. package/dist/__tests__/diagnostics.test.d.ts +0 -4
  207. package/dist/__tests__/diagnostics.test.js +0 -149
  208. package/dist/__tests__/e2e.test.d.ts +0 -6
  209. package/dist/__tests__/e2e.test.js +0 -1847
  210. package/dist/__tests__/entity-types.test.js +0 -203
  211. package/dist/__tests__/formatter.test.js +0 -40
  212. package/dist/__tests__/lexer.test.js +0 -343
  213. package/dist/__tests__/lowering.test.js +0 -1015
  214. package/dist/__tests__/macro.test.d.ts +0 -8
  215. package/dist/__tests__/macro.test.js +0 -305
  216. package/dist/__tests__/mc-integration.test.d.ts +0 -12
  217. package/dist/__tests__/mc-integration.test.js +0 -819
  218. package/dist/__tests__/mc-syntax.test.js +0 -124
  219. package/dist/__tests__/nbt.test.js +0 -82
  220. package/dist/__tests__/optimizer-advanced.test.js +0 -124
  221. package/dist/__tests__/optimizer.test.d.ts +0 -1
  222. package/dist/__tests__/optimizer.test.js +0 -149
  223. package/dist/__tests__/parser.test.d.ts +0 -1
  224. package/dist/__tests__/parser.test.js +0 -807
  225. package/dist/__tests__/repl.test.d.ts +0 -1
  226. package/dist/__tests__/repl.test.js +0 -27
  227. package/dist/__tests__/runtime.test.d.ts +0 -1
  228. package/dist/__tests__/runtime.test.js +0 -289
  229. package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
  230. package/dist/__tests__/stdlib-advanced.test.js +0 -378
  231. package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
  232. package/dist/__tests__/stdlib-bigint.test.js +0 -428
  233. package/dist/__tests__/stdlib-math.test.d.ts +0 -7
  234. package/dist/__tests__/stdlib-math.test.js +0 -352
  235. package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
  236. package/dist/__tests__/stdlib-vec.test.js +0 -264
  237. package/dist/__tests__/structure-optimizer.test.d.ts +0 -1
  238. package/dist/__tests__/structure-optimizer.test.js +0 -33
  239. package/dist/__tests__/typechecker.test.d.ts +0 -1
  240. package/dist/__tests__/typechecker.test.js +0 -552
  241. package/dist/__tests__/var-allocator.test.d.ts +0 -1
  242. package/dist/__tests__/var-allocator.test.js +0 -69
  243. package/dist/ast/types.d.ts +0 -514
  244. package/dist/ast/types.js +0 -9
  245. package/dist/builtins/metadata.d.ts +0 -36
  246. package/dist/builtins/metadata.js +0 -1014
  247. package/dist/cli.d.ts +0 -11
  248. package/dist/codegen/cmdblock/index.d.ts +0 -26
  249. package/dist/codegen/cmdblock/index.js +0 -45
  250. package/dist/codegen/mcfunction/index.d.ts +0 -40
  251. package/dist/codegen/mcfunction/index.js +0 -606
  252. package/dist/codegen/structure/index.d.ts +0 -24
  253. package/dist/codegen/structure/index.js +0 -279
  254. package/dist/codegen/var-allocator.d.ts +0 -45
  255. package/dist/codegen/var-allocator.js +0 -104
  256. package/dist/compile.d.ts +0 -68
  257. package/dist/data/arena/function/__load.mcfunction +0 -6
  258. package/dist/data/arena/function/__tick.mcfunction +0 -2
  259. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
  260. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
  261. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
  262. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
  263. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
  264. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
  265. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
  266. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
  267. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
  268. package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
  269. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
  270. package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
  271. package/dist/data/arena/function/arena_tick.mcfunction +0 -11
  272. package/dist/data/counter/function/__load.mcfunction +0 -5
  273. package/dist/data/counter/function/__tick.mcfunction +0 -2
  274. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
  275. package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
  276. package/dist/data/counter/function/counter_tick.mcfunction +0 -11
  277. package/dist/data/gcd2/function/__load.mcfunction +0 -3
  278. package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
  279. package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
  280. package/dist/data/gcd2/function/abs.mcfunction +0 -7
  281. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
  282. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
  283. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
  284. package/dist/data/gcd2/function/gcd.mcfunction +0 -14
  285. package/dist/data/gcd3/function/__load.mcfunction +0 -3
  286. package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
  287. package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
  288. package/dist/data/gcd3/function/abs.mcfunction +0 -7
  289. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
  290. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
  291. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
  292. package/dist/data/gcd3/function/gcd.mcfunction +0 -14
  293. package/dist/data/gcd3/function/test.mcfunction +0 -7
  294. package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
  295. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
  296. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
  297. package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
  298. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
  299. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
  300. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
  301. package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
  302. package/dist/data/gcd3nm/function/test.mcfunction +0 -7
  303. package/dist/data/gcd_test/function/__load.mcfunction +0 -3
  304. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
  305. package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
  306. package/dist/data/gcd_test/function/abs.mcfunction +0 -7
  307. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
  308. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
  309. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
  310. package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
  311. package/dist/data/isqrttest/function/__load.mcfunction +0 -6
  312. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
  313. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
  314. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
  315. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
  316. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
  317. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
  318. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
  319. package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
  320. package/dist/data/isqrttest/function/test.mcfunction +0 -6
  321. package/dist/data/mathtest/function/__load.mcfunction +0 -3
  322. package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
  323. package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
  324. package/dist/data/mathtest/function/abs.mcfunction +0 -6
  325. package/dist/data/mathtest/function/test.mcfunction +0 -5
  326. package/dist/data/minecraft/tags/function/load.json +0 -5
  327. package/dist/data/minecraft/tags/function/tick.json +0 -5
  328. package/dist/data/mypack/function/__load.mcfunction +0 -13
  329. package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
  330. package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
  331. package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
  332. package/dist/data/mypack/function/abs.mcfunction +0 -6
  333. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
  334. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
  335. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
  336. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
  337. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
  338. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
  339. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
  340. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
  341. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
  342. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
  343. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
  344. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
  345. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
  346. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
  347. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
  348. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
  349. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
  350. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
  351. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
  352. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
  353. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
  354. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
  355. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
  356. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
  357. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
  358. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
  359. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
  360. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
  361. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
  362. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
  363. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
  364. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
  365. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
  366. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
  367. package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
  368. package/dist/data/mypack/function/my_game.mcfunction +0 -10
  369. package/dist/data/quiz/function/__load.mcfunction +0 -16
  370. package/dist/data/quiz/function/__tick.mcfunction +0 -6
  371. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
  372. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
  373. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
  374. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
  375. package/dist/data/quiz/function/answer_a.mcfunction +0 -4
  376. package/dist/data/quiz/function/answer_b.mcfunction +0 -4
  377. package/dist/data/quiz/function/answer_c.mcfunction +0 -4
  378. package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
  379. package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
  380. package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
  381. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
  382. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
  383. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
  384. package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
  385. package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
  386. package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
  387. package/dist/data/quiz/function/ask_question.mcfunction +0 -7
  388. package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
  389. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
  390. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
  391. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
  392. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
  393. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
  394. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
  395. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
  396. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
  397. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
  398. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
  399. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
  400. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
  401. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
  402. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
  403. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
  404. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
  405. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
  406. package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
  407. package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
  408. package/dist/data/reqtest/function/__load.mcfunction +0 -4
  409. package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
  410. package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
  411. package/dist/data/reqtest/function/use_table.mcfunction +0 -4
  412. package/dist/data/reqtest2/function/__load.mcfunction +0 -3
  413. package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
  414. package/dist/data/runtime/function/__load.mcfunction +0 -5
  415. package/dist/data/runtime/function/__tick.mcfunction +0 -2
  416. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
  417. package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
  418. package/dist/data/shop/function/__load.mcfunction +0 -7
  419. package/dist/data/shop/function/__tick.mcfunction +0 -3
  420. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
  421. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
  422. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
  423. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
  424. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
  425. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
  426. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
  427. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
  428. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
  429. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
  430. package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
  431. package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
  432. package/dist/data/swap_test/function/__load.mcfunction +0 -3
  433. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
  434. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
  435. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
  436. package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
  437. package/dist/data/turret/function/__load.mcfunction +0 -5
  438. package/dist/data/turret/function/__tick.mcfunction +0 -4
  439. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
  440. package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
  441. package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
  442. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
  443. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
  444. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
  445. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
  446. package/dist/data/turret/function/turret_tick.mcfunction +0 -5
  447. package/dist/diagnostics/index.d.ts +0 -44
  448. package/dist/diagnostics/index.js +0 -140
  449. package/dist/events/types.d.ts +0 -35
  450. package/dist/events/types.js +0 -59
  451. package/dist/formatter/index.d.ts +0 -1
  452. package/dist/formatter/index.js +0 -26
  453. package/dist/gcd2.map.json +0 -15
  454. package/dist/gcd3.map.json +0 -17
  455. package/dist/gcd_test.map.json +0 -15
  456. package/dist/index.d.ts +0 -62
  457. package/dist/ir/builder.d.ts +0 -33
  458. package/dist/ir/builder.js +0 -99
  459. package/dist/ir/types.d.ts +0 -132
  460. package/dist/ir/types.js +0 -15
  461. package/dist/isqrttest.map.json +0 -15
  462. package/dist/lexer/index.d.ts +0 -37
  463. package/dist/lexer/index.js +0 -569
  464. package/dist/lowering/index.d.ts +0 -188
  465. package/dist/lowering/index.js +0 -3405
  466. package/dist/mathtest.map.json +0 -6
  467. package/dist/mc-test/client.d.ts +0 -128
  468. package/dist/mc-test/client.js +0 -174
  469. package/dist/mc-test/runner.d.ts +0 -28
  470. package/dist/mc-test/runner.js +0 -150
  471. package/dist/mc-test/setup.d.ts +0 -11
  472. package/dist/mc-test/setup.js +0 -98
  473. package/dist/mc-validator/index.d.ts +0 -17
  474. package/dist/mc-validator/index.js +0 -322
  475. package/dist/mypack.map.json +0 -27
  476. package/dist/nbt/index.d.ts +0 -86
  477. package/dist/nbt/index.js +0 -250
  478. package/dist/optimizer/commands.d.ts +0 -38
  479. package/dist/optimizer/commands.js +0 -451
  480. package/dist/optimizer/dce.d.ts +0 -34
  481. package/dist/optimizer/dce.js +0 -639
  482. package/dist/optimizer/passes.d.ts +0 -34
  483. package/dist/optimizer/passes.js +0 -243
  484. package/dist/optimizer/structure.d.ts +0 -9
  485. package/dist/optimizer/structure.js +0 -356
  486. package/dist/pack.mcmeta +0 -6
  487. package/dist/parser/index.d.ts +0 -93
  488. package/dist/parser/index.js +0 -1687
  489. package/dist/repl.d.ts +0 -16
  490. package/dist/repl.js +0 -165
  491. package/dist/reqtest.map.json +0 -4
  492. package/dist/reqtest2.map.json +0 -4
  493. package/dist/runtime/index.d.ts +0 -107
  494. package/dist/runtime/index.js +0 -1409
  495. package/dist/runtime.map.json +0 -7
  496. package/dist/src/__tests__/codegen.test.d.ts +0 -1
  497. package/dist/src/__tests__/codegen.test.js +0 -152
  498. package/dist/src/__tests__/e2e.test.d.ts +0 -6
  499. package/dist/src/__tests__/e2e.test.js +0 -1789
  500. package/dist/src/__tests__/entity-types.test.d.ts +0 -1
  501. package/dist/src/__tests__/entity-types.test.js +0 -203
  502. package/dist/src/__tests__/lowering.test.d.ts +0 -1
  503. package/dist/src/__tests__/lowering.test.js +0 -1015
  504. package/dist/src/__tests__/macro.test.d.ts +0 -8
  505. package/dist/src/__tests__/macro.test.js +0 -306
  506. package/dist/src/__tests__/nbt.test.d.ts +0 -1
  507. package/dist/src/__tests__/nbt.test.js +0 -82
  508. package/dist/src/__tests__/optimizer-advanced.test.d.ts +0 -1
  509. package/dist/src/__tests__/optimizer-advanced.test.js +0 -124
  510. package/dist/src/__tests__/optimizer.test.d.ts +0 -1
  511. package/dist/src/__tests__/optimizer.test.js +0 -149
  512. package/dist/src/__tests__/runtime.test.d.ts +0 -1
  513. package/dist/src/__tests__/runtime.test.js +0 -289
  514. package/dist/src/__tests__/stdlib-advanced.test.d.ts +0 -4
  515. package/dist/src/__tests__/stdlib-advanced.test.js +0 -374
  516. package/dist/src/__tests__/stdlib-bigint.test.d.ts +0 -7
  517. package/dist/src/__tests__/stdlib-bigint.test.js +0 -426
  518. package/dist/src/__tests__/stdlib-math.test.d.ts +0 -7
  519. package/dist/src/__tests__/stdlib-math.test.js +0 -351
  520. package/dist/src/__tests__/stdlib-vec.test.d.ts +0 -4
  521. package/dist/src/__tests__/stdlib-vec.test.js +0 -263
  522. package/dist/src/__tests__/structure-optimizer.test.d.ts +0 -1
  523. package/dist/src/__tests__/structure-optimizer.test.js +0 -33
  524. package/dist/src/__tests__/var-allocator.test.d.ts +0 -1
  525. package/dist/src/__tests__/var-allocator.test.js +0 -69
  526. package/dist/src/codegen/cmdblock/index.d.ts +0 -26
  527. package/dist/src/codegen/cmdblock/index.js +0 -45
  528. package/dist/src/codegen/mcfunction/index.d.ts +0 -40
  529. package/dist/src/codegen/mcfunction/index.js +0 -606
  530. package/dist/src/codegen/structure/index.d.ts +0 -24
  531. package/dist/src/codegen/structure/index.js +0 -279
  532. package/dist/src/codegen/var-allocator.d.ts +0 -45
  533. package/dist/src/codegen/var-allocator.js +0 -104
  534. package/dist/src/ir/builder.d.ts +0 -33
  535. package/dist/src/ir/builder.js +0 -99
  536. package/dist/src/ir/types.d.ts +0 -132
  537. package/dist/src/ir/types.js +0 -15
  538. package/dist/src/lowering/index.d.ts +0 -188
  539. package/dist/src/lowering/index.js +0 -3405
  540. package/dist/src/optimizer/commands.d.ts +0 -38
  541. package/dist/src/optimizer/commands.js +0 -451
  542. package/dist/src/optimizer/passes.d.ts +0 -34
  543. package/dist/src/optimizer/passes.js +0 -243
  544. package/dist/src/optimizer/structure.d.ts +0 -9
  545. package/dist/src/optimizer/structure.js +0 -356
  546. package/dist/src2/__tests__/optimizer/dce.test.d.ts +0 -1
  547. package/dist/src2/emit/compile.d.ts +0 -19
  548. package/dist/src2/emit/compile.js +0 -80
  549. package/dist/src2/optimizer/dce.d.ts +0 -8
  550. package/dist/src2/optimizer/dce.js +0 -155
  551. package/dist/swap_test.map.json +0 -14
  552. package/dist/tsconfig.tsbuildinfo +0 -1
  553. package/dist/typechecker/index.d.ts +0 -61
  554. package/dist/typechecker/index.js +0 -1034
  555. package/dist/types/entity-hierarchy.d.ts +0 -29
  556. package/dist/types/entity-hierarchy.js +0 -107
  557. package/src2/emit/compile.ts +0 -99
  558. /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
  559. /package/dist/{src2 → src}/__tests__/e2e/basic.test.d.ts +0 -0
  560. /package/dist/{src2 → src}/__tests__/e2e/basic.test.js +0 -0
  561. /package/dist/{src2 → src}/__tests__/e2e/macros.test.d.ts +0 -0
  562. /package/dist/{src2 → src}/__tests__/e2e/migrate.test.d.ts +0 -0
  563. /package/dist/{src2 → src}/__tests__/hir/desugar.test.d.ts +0 -0
  564. /package/dist/{src2 → src}/__tests__/lir/lower.test.d.ts +0 -0
  565. /package/dist/{src2 → src}/__tests__/lir/lower.test.js +0 -0
  566. /package/dist/{src2 → src}/__tests__/lir/types.test.d.ts +0 -0
  567. /package/dist/{src2 → src}/__tests__/lir/types.test.js +0 -0
  568. /package/dist/{src2 → src}/__tests__/lir/verify.test.d.ts +0 -0
  569. /package/dist/{src2 → src}/__tests__/lir/verify.test.js +0 -0
  570. /package/dist/{src2 → src}/__tests__/mir/arithmetic.test.d.ts +0 -0
  571. /package/dist/{src2 → src}/__tests__/mir/control-flow.test.d.ts +0 -0
  572. /package/dist/{src2 → src}/__tests__/mir/verify.test.d.ts +0 -0
  573. /package/dist/{src2 → src}/__tests__/mir/verify.test.js +0 -0
  574. /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.d.ts +0 -0
  575. /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.js +0 -0
  576. /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.d.ts +0 -0
  577. /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.js +0 -0
  578. /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.d.ts +0 -0
  579. /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.js +0 -0
  580. /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.d.ts +0 -0
  581. /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.js +0 -0
  582. /package/dist/{__tests__ → src/__tests__/optimizer}/dce.test.d.ts +0 -0
  583. /package/dist/{src2 → src}/__tests__/optimizer/dce.test.js +0 -0
  584. /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/optimizer/interprocedural.test.d.ts} +0 -0
  585. /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/optimizer/lir/const_imm.test.d.ts} +0 -0
  586. /package/dist/{__tests__/formatter.test.d.ts → src/__tests__/optimizer/lir/dead_slot.test.d.ts} +0 -0
  587. /package/dist/{__tests__/lexer.test.d.ts → src/__tests__/optimizer/lir/peephole.test.d.ts} +0 -0
  588. /package/dist/{src2/__tests__/optimizer → src/__tests__/optimizer/lir}/pipeline.test.d.ts +0 -0
  589. /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/optimizer/nbt-batch.test.d.ts} +0 -0
  590. /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/optimizer/pipeline.test.d.ts} +0 -0
  591. /package/dist/{src2 → src}/__tests__/optimizer/pipeline.test.js +0 -0
  592. /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/optimizer/selector-cache.test.d.ts} +0 -0
  593. /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/optimizer/unroll.test.d.ts} +0 -0
  594. /package/dist/{src2 → src}/hir/types.js +0 -0
  595. /package/dist/{src2 → src}/lir/lower.d.ts +0 -0
  596. /package/dist/{src2 → src}/lir/types.js +0 -0
  597. /package/dist/{src2 → src}/lir/verify.d.ts +0 -0
  598. /package/dist/{src2 → src}/lir/verify.js +0 -0
  599. /package/dist/{src2 → src}/mir/macro.d.ts +0 -0
  600. /package/dist/{src2 → src}/mir/macro.js +0 -0
  601. /package/dist/{src2 → src}/mir/types.js +0 -0
  602. /package/dist/{src2 → src}/mir/verify.d.ts +0 -0
  603. /package/dist/{src2 → src}/mir/verify.js +0 -0
  604. /package/dist/{src2 → src}/optimizer/block_merge.d.ts +0 -0
  605. /package/dist/{src2 → src}/optimizer/block_merge.js +0 -0
  606. /package/dist/{src2 → src}/optimizer/branch_simplify.d.ts +0 -0
  607. /package/dist/{src2 → src}/optimizer/branch_simplify.js +0 -0
  608. /package/dist/{src2 → src}/optimizer/constant_fold.d.ts +0 -0
  609. /package/dist/{src2 → src}/optimizer/constant_fold.js +0 -0
  610. /package/dist/{src2 → src}/optimizer/copy_prop.d.ts +0 -0
  611. /package/dist/{src2 → src}/optimizer/copy_prop.js +0 -0
  612. /package/{src2 → src}/__tests__/e2e/basic.test.ts +0 -0
  613. /package/{src2 → src}/__tests__/lir/lower.test.ts +0 -0
  614. /package/{src2 → src}/__tests__/lir/types.test.ts +0 -0
  615. /package/{src2 → src}/__tests__/lir/verify.test.ts +0 -0
  616. /package/{src2 → src}/__tests__/mir/verify.test.ts +0 -0
  617. /package/{src2 → src}/__tests__/optimizer/block_merge.test.ts +0 -0
  618. /package/{src2 → src}/__tests__/optimizer/branch_simplify.test.ts +0 -0
  619. /package/{src2 → src}/__tests__/optimizer/constant_fold.test.ts +0 -0
  620. /package/{src2 → src}/__tests__/optimizer/copy_prop.test.ts +0 -0
  621. /package/{src2 → src}/__tests__/optimizer/dce.test.ts +0 -0
  622. /package/{src2 → src}/__tests__/optimizer/pipeline.test.ts +0 -0
  623. /package/{src2 → src}/lir/verify.ts +0 -0
  624. /package/{src2 → src}/mir/macro.ts +0 -0
  625. /package/{src2 → src}/mir/verify.ts +0 -0
  626. /package/{src2 → src}/optimizer/block_merge.ts +0 -0
  627. /package/{src2 → src}/optimizer/branch_simplify.ts +0 -0
  628. /package/{src2 → src}/optimizer/constant_fold.ts +0 -0
  629. /package/{src2 → src}/optimizer/copy_prop.ts +0 -0
@@ -0,0 +1,789 @@
1
+ "use strict";
2
+ /**
3
+ * Coroutine Transform — MIR module-level pass.
4
+ *
5
+ * Transforms functions annotated with @coroutine(batch=N, onDone=fn) into
6
+ * tick-spread state machines. Each loop back-edge becomes a yield point,
7
+ * and the function is split into continuation functions dispatched by a
8
+ * @tick function via a pc (program counter) scoreboard slot.
9
+ *
10
+ * Algorithm:
11
+ * 1. Compute dominator tree → find back edges (yield points)
12
+ * 2. Backward liveness analysis at yield points
13
+ * 3. Split CFG into continuations at yield points
14
+ * 4. Promote live variables to persistent scoreboard slots
15
+ * 5. Generate @tick dispatcher function
16
+ *
17
+ * Spec: docs/compiler-pipeline-redesign.md § "Coroutine Transform"
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.coroutineTransform = coroutineTransform;
21
+ /**
22
+ * Apply the coroutine transform to all functions in `infos`.
23
+ * Returns a new module with continuations + dispatchers injected,
24
+ * and the original function replaced with initialization code.
25
+ */
26
+ function coroutineTransform(mod, infos) {
27
+ if (infos.length === 0)
28
+ return { module: mod, generatedTickFunctions: [] };
29
+ const infoMap = new Map(infos.map(i => [i.fnName, i]));
30
+ const newFunctions = [];
31
+ const tickFns = [];
32
+ for (const fn of mod.functions) {
33
+ const info = infoMap.get(fn.name);
34
+ if (!info) {
35
+ newFunctions.push(fn);
36
+ continue;
37
+ }
38
+ const transformed = transformCoroutine(fn, info, mod.objective);
39
+ newFunctions.push(transformed.initFn);
40
+ newFunctions.push(...transformed.continuations);
41
+ newFunctions.push(transformed.dispatcher);
42
+ tickFns.push(transformed.dispatcher.name);
43
+ }
44
+ return {
45
+ module: { ...mod, functions: newFunctions },
46
+ generatedTickFunctions: tickFns,
47
+ };
48
+ }
49
+ function transformCoroutine(fn, info, objective) {
50
+ const prefix = `_coro_${fn.name}`;
51
+ const pcTemp = `${prefix}_pc`;
52
+ const batchCountTemp = `${prefix}_batch_count`;
53
+ // Step 1: Build dominator tree and find back edges
54
+ const blockMap = new Map(fn.blocks.map(b => [b.id, b]));
55
+ const doms = computeDominators(fn.blocks, fn.entry);
56
+ const backEdges = findBackEdges(fn.blocks, doms);
57
+ // If no back edges (no loops), the function doesn't need coroutine splitting.
58
+ // Just wrap it as a single continuation.
59
+ if (backEdges.length === 0) {
60
+ return buildSingleContinuation(fn, info, prefix, pcTemp, objective);
61
+ }
62
+ // Step 2: Liveness analysis — find live variables at each yield point
63
+ const liveAtYield = computeLivenessAtYieldPoints(fn.blocks, backEdges, fn.params);
64
+ // Collect all live variables across all yield points (these need promotion)
65
+ const allLiveVars = new Set();
66
+ for (const liveSet of liveAtYield.values()) {
67
+ for (const v of liveSet)
68
+ allLiveVars.add(v);
69
+ }
70
+ // Build promoted variable names: original temp → persistent slot name
71
+ const promoted = new Map();
72
+ for (const v of allLiveVars) {
73
+ promoted.set(v, `${prefix}_${v}`);
74
+ }
75
+ // Step 3: Split CFG into continuations
76
+ // Each continuation runs from a loop header to the next yield point.
77
+ // For simplicity, we split at loop headers (targets of back edges).
78
+ const loopHeaders = new Set(backEdges.map(e => e.target));
79
+ // Partition blocks into continuation groups.
80
+ // Continuation 1: entry block → until first yield
81
+ // Continuation N: from loop header → until next yield or exit
82
+ const continuations = partitionIntoContinuations(fn, loopHeaders, backEdges);
83
+ // Step 4: Build continuation functions with batch counting and variable promotion
84
+ const contFunctions = [];
85
+ for (let i = 0; i < continuations.length; i++) {
86
+ const contId = i + 1;
87
+ const cont = continuations[i];
88
+ const contFn = buildContinuationFunction(`${prefix}_cont_${contId}`, cont, info.batch, contId, continuations.length, promoted, pcTemp, batchCountTemp, objective, info.onDone, fn.name);
89
+ contFunctions.push(contFn);
90
+ }
91
+ // Step 5: Build the init function (replaces original)
92
+ const initFn = buildInitFunction(fn, promoted, pcTemp, prefix, objective);
93
+ // Step 6: Build the @tick dispatcher
94
+ const dispatcher = buildDispatcher(`${prefix}_tick`, contFunctions, pcTemp, objective, fn.name);
95
+ return { initFn, continuations: contFunctions, dispatcher };
96
+ }
97
+ // ---------------------------------------------------------------------------
98
+ // Step 1: Dominator tree & back-edge detection
99
+ // ---------------------------------------------------------------------------
100
+ function computeDominators(blocks, entry) {
101
+ // Simple iterative dominator algorithm (Cooper, Harvey, Kennedy)
102
+ const blockIds = blocks.map(b => b.id);
103
+ const idom = new Map();
104
+ // RPO ordering
105
+ const rpo = reversePostorder(blocks, entry);
106
+ const rpoIndex = new Map(rpo.map((id, i) => [id, i]));
107
+ // Initialize: entry dominates itself
108
+ idom.set(entry, entry);
109
+ let changed = true;
110
+ while (changed) {
111
+ changed = false;
112
+ for (const bId of rpo) {
113
+ if (bId === entry)
114
+ continue;
115
+ const block = blocks.find(b => b.id === bId);
116
+ if (!block)
117
+ continue;
118
+ // Find first processed predecessor
119
+ const processedPreds = block.preds.filter(p => idom.has(p));
120
+ if (processedPreds.length === 0)
121
+ continue;
122
+ let newIdom = processedPreds[0];
123
+ for (let i = 1; i < processedPreds.length; i++) {
124
+ newIdom = intersect(newIdom, processedPreds[i], idom, rpoIndex);
125
+ }
126
+ if (idom.get(bId) !== newIdom) {
127
+ idom.set(bId, newIdom);
128
+ changed = true;
129
+ }
130
+ }
131
+ }
132
+ return idom;
133
+ }
134
+ function intersect(a, b, idom, rpoIndex) {
135
+ let f1 = a;
136
+ let f2 = b;
137
+ while (f1 !== f2) {
138
+ while ((rpoIndex.get(f1) ?? 0) > (rpoIndex.get(f2) ?? 0)) {
139
+ f1 = idom.get(f1) ?? f1;
140
+ }
141
+ while ((rpoIndex.get(f2) ?? 0) > (rpoIndex.get(f1) ?? 0)) {
142
+ f2 = idom.get(f2) ?? f2;
143
+ }
144
+ }
145
+ return f1;
146
+ }
147
+ function reversePostorder(blocks, entry) {
148
+ const visited = new Set();
149
+ const order = [];
150
+ const blockMap = new Map(blocks.map(b => [b.id, b]));
151
+ function dfs(id) {
152
+ if (visited.has(id))
153
+ return;
154
+ visited.add(id);
155
+ const block = blockMap.get(id);
156
+ if (!block)
157
+ return;
158
+ for (const succ of getSuccessors(block.term)) {
159
+ dfs(succ);
160
+ }
161
+ order.push(id);
162
+ }
163
+ dfs(entry);
164
+ return order.reverse();
165
+ }
166
+ function findBackEdges(blocks, doms) {
167
+ const edges = [];
168
+ for (const block of blocks) {
169
+ for (const succ of getSuccessors(block.term)) {
170
+ if (dominates(succ, block.id, doms)) {
171
+ edges.push({ source: block.id, target: succ });
172
+ }
173
+ }
174
+ }
175
+ return edges;
176
+ }
177
+ function dominates(a, b, doms) {
178
+ let cur = b;
179
+ while (cur !== a) {
180
+ const idom = doms.get(cur);
181
+ if (!idom || idom === cur)
182
+ return false;
183
+ cur = idom;
184
+ }
185
+ return true;
186
+ }
187
+ // ---------------------------------------------------------------------------
188
+ // Step 2: Liveness analysis
189
+ // ---------------------------------------------------------------------------
190
+ function computeLivenessAtYieldPoints(blocks, backEdges, params) {
191
+ // Standard backward liveness: live_in[B] = use[B] ∪ (live_out[B] \ def[B])
192
+ const blockMap = new Map(blocks.map(b => [b.id, b]));
193
+ // Compute use/def for each block
194
+ const useSets = new Map();
195
+ const defSets = new Map();
196
+ for (const block of blocks) {
197
+ const use = new Set();
198
+ const def = new Set();
199
+ for (const instr of [...block.instrs, block.term]) {
200
+ // Uses before defs
201
+ for (const t of getUsedTemps(instr)) {
202
+ if (!def.has(t))
203
+ use.add(t);
204
+ }
205
+ const dst = getDst(instr);
206
+ if (dst)
207
+ def.add(dst);
208
+ }
209
+ useSets.set(block.id, use);
210
+ defSets.set(block.id, def);
211
+ }
212
+ // Iterative liveness
213
+ const liveIn = new Map();
214
+ const liveOut = new Map();
215
+ for (const block of blocks) {
216
+ liveIn.set(block.id, new Set());
217
+ liveOut.set(block.id, new Set());
218
+ }
219
+ let changed = true;
220
+ while (changed) {
221
+ changed = false;
222
+ for (const block of [...blocks].reverse()) {
223
+ // live_out = ∪ live_in[succ]
224
+ const newOut = new Set();
225
+ for (const succ of getSuccessors(block.term)) {
226
+ const succIn = liveIn.get(succ);
227
+ if (succIn)
228
+ for (const t of succIn)
229
+ newOut.add(t);
230
+ }
231
+ // live_in = use ∪ (live_out \ def)
232
+ const newIn = new Set(useSets.get(block.id) ?? []);
233
+ const def = defSets.get(block.id) ?? new Set();
234
+ for (const t of newOut) {
235
+ if (!def.has(t))
236
+ newIn.add(t);
237
+ }
238
+ const prevIn = liveIn.get(block.id);
239
+ const prevOut = liveOut.get(block.id);
240
+ if (!setsEqual(newIn, prevIn) || !setsEqual(newOut, prevOut)) {
241
+ liveIn.set(block.id, newIn);
242
+ liveOut.set(block.id, newOut);
243
+ changed = true;
244
+ }
245
+ }
246
+ }
247
+ // At each yield point (back edge source → target), the live vars
248
+ // are the live-out of the source block
249
+ const result = new Map();
250
+ for (const edge of backEdges) {
251
+ const lo = liveOut.get(edge.source) ?? new Set();
252
+ result.set(edge.source, lo);
253
+ }
254
+ return result;
255
+ }
256
+ function setsEqual(a, b) {
257
+ if (a.size !== b.size)
258
+ return false;
259
+ for (const v of a)
260
+ if (!b.has(v))
261
+ return false;
262
+ return true;
263
+ }
264
+ function partitionIntoContinuations(fn, loopHeaders, backEdges) {
265
+ const blockMap = new Map(fn.blocks.map(b => [b.id, b]));
266
+ const backEdgeTargets = new Set(backEdges.map(e => e.target));
267
+ const backEdgeSources = new Set(backEdges.map(e => e.source));
268
+ // Find which blocks belong to which loop (blocks between header and back edge)
269
+ // We use a simple approach: BFS from entry, split at loop headers
270
+ const loopBlocks = new Map(); // header → blocks in loop
271
+ for (const header of loopHeaders) {
272
+ const inLoop = new Set();
273
+ // Find all blocks that can reach the back edge source without leaving the loop
274
+ // i.e., blocks dominated by the header that can reach a back edge source
275
+ const sources = backEdges.filter(e => e.target === header).map(e => e.source);
276
+ // Backward BFS from back-edge sources to header
277
+ const queue = [...sources];
278
+ for (const s of sources)
279
+ inLoop.add(s);
280
+ inLoop.add(header);
281
+ while (queue.length > 0) {
282
+ const bid = queue.shift();
283
+ const block = blockMap.get(bid);
284
+ if (!block)
285
+ continue;
286
+ for (const pred of block.preds) {
287
+ if (!inLoop.has(pred) && pred !== header) {
288
+ inLoop.add(pred);
289
+ queue.push(pred);
290
+ }
291
+ }
292
+ }
293
+ inLoop.add(header);
294
+ loopBlocks.set(header, inLoop);
295
+ }
296
+ // Build continuations:
297
+ // Continuation 1 = loop body (the main one — header + loop blocks)
298
+ // Continuation 2 = post-loop (blocks after loop exit)
299
+ const conts = [];
300
+ // For each loop, create a loop-body continuation
301
+ for (const header of loopHeaders) {
302
+ const lb = loopBlocks.get(header);
303
+ const loopBlocksList = fn.blocks.filter(b => lb.has(b.id));
304
+ const exitBlocks = new Set();
305
+ // Find exit blocks: blocks in the loop that branch to blocks outside the loop
306
+ for (const block of loopBlocksList) {
307
+ for (const succ of getSuccessors(block.term)) {
308
+ if (!lb.has(succ))
309
+ exitBlocks.add(block.id);
310
+ }
311
+ }
312
+ conts.push({
313
+ blocks: loopBlocksList,
314
+ isLoopBody: true,
315
+ loopHeaderId: header,
316
+ exitBlocks,
317
+ });
318
+ }
319
+ // Post-loop continuation: all blocks not in any loop
320
+ const allLoopBlockIds = new Set();
321
+ for (const lb of loopBlocks.values()) {
322
+ for (const id of lb)
323
+ allLoopBlockIds.add(id);
324
+ }
325
+ // Also exclude the entry block if it's not in a loop (it becomes the init fn)
326
+ const postLoopBlocks = fn.blocks.filter(b => !allLoopBlockIds.has(b.id) && b.id !== fn.entry);
327
+ if (postLoopBlocks.length > 0) {
328
+ conts.push({
329
+ blocks: postLoopBlocks,
330
+ isLoopBody: false,
331
+ exitBlocks: new Set(),
332
+ });
333
+ }
334
+ return conts;
335
+ }
336
+ // ---------------------------------------------------------------------------
337
+ // Step 4: Build continuation functions
338
+ // ---------------------------------------------------------------------------
339
+ function buildContinuationFunction(name, cont, batch, contId, totalConts, promoted, pcTemp, batchCountTemp, objective, onDone, originalFnName) {
340
+ if (cont.isLoopBody) {
341
+ return buildLoopContinuation(name, cont, batch, contId, totalConts, promoted, pcTemp, batchCountTemp, objective, onDone);
342
+ }
343
+ else {
344
+ return buildPostLoopContinuation(name, cont, contId, promoted, pcTemp, objective, onDone);
345
+ }
346
+ }
347
+ function buildLoopContinuation(name, cont, batch, contId, totalConts, promoted, pcTemp, batchCountTemp, objective, onDone) {
348
+ // Build a new function that:
349
+ // 1. Initializes batch_count = 0
350
+ // 2. Runs the loop body up to `batch` iterations
351
+ // 3. At back edge: if batch_count >= batch, yield (return)
352
+ // 4. On loop exit: return (dispatcher handles next continuation via pc)
353
+ //
354
+ // IMPORTANT: The LIR lowerer handles multi-pred blocks via `jump` terminators
355
+ // correctly (emits a function call) but `branch → multi-pred` can cause infinite
356
+ // recursion. So we ensure back edges use `jump` via a trampoline block, and
357
+ // batch-done checks use `branch → yield_block | continue_block` where both
358
+ // targets have single predecessors.
359
+ const blocks = [];
360
+ const batchCmpTemp = `${batchCountTemp}_cmp`;
361
+ // Entry: set batch_count = 0, then jump to loop header
362
+ const entryBlock = {
363
+ id: 'entry',
364
+ instrs: [
365
+ { kind: 'const', dst: batchCountTemp, value: 0 },
366
+ ],
367
+ term: { kind: 'jump', target: cont.loopHeaderId ?? cont.blocks[0].id },
368
+ preds: [],
369
+ };
370
+ blocks.push(entryBlock);
371
+ // Clone and rewrite the loop blocks with promoted variable names
372
+ for (const block of cont.blocks) {
373
+ const rewritten = rewriteBlock(block, promoted);
374
+ const succs = getSuccessors(rewritten.term);
375
+ const isBackEdgeBlock = cont.loopHeaderId && succs.includes(cont.loopHeaderId);
376
+ if (isBackEdgeBlock) {
377
+ // This block has a back edge to the loop header.
378
+ // Append batch counting to the body, then branch:
379
+ // batch_done → yield (return), !batch_done → continue (jump → header)
380
+ //
381
+ // body_block → branch(batch_done) → yield_block | continue_block
382
+ // continue_block → jump → loop_header (uses 'jump', safe for multi-pred)
383
+ // yield_block → return
384
+ const continueBlockId = `${block.id}_continue`;
385
+ const yieldBlockId = `${block.id}_yield`;
386
+ // Append batch check instructions to the body block
387
+ const bodyInstrs = [
388
+ ...rewritten.instrs,
389
+ { kind: 'add', dst: batchCountTemp, a: { kind: 'temp', name: batchCountTemp }, b: { kind: 'const', value: 1 } },
390
+ { kind: 'cmp', dst: batchCmpTemp, op: 'ge', a: { kind: 'temp', name: batchCountTemp }, b: { kind: 'const', value: batch } },
391
+ ];
392
+ blocks.push({
393
+ ...rewritten,
394
+ instrs: bodyInstrs,
395
+ // Rewrite terminator: instead of jumping to header, branch on batch check
396
+ term: {
397
+ kind: 'branch',
398
+ cond: { kind: 'temp', name: batchCmpTemp },
399
+ then: yieldBlockId,
400
+ else: continueBlockId,
401
+ },
402
+ });
403
+ // Continue block: jump back to loop header (uses jump → multi-pred = call)
404
+ blocks.push({
405
+ id: continueBlockId,
406
+ instrs: [],
407
+ term: { kind: 'jump', target: cont.loopHeaderId },
408
+ preds: [block.id],
409
+ });
410
+ // Yield block: return (resume next tick)
411
+ blocks.push({
412
+ id: yieldBlockId,
413
+ instrs: [],
414
+ term: { kind: 'return', value: null },
415
+ preds: [block.id],
416
+ });
417
+ }
418
+ else {
419
+ // Check if this block exits the loop
420
+ const exitSuccs = succs.filter(s => !cont.blocks.some(b => b.id === s));
421
+ if (exitSuccs.length > 0) {
422
+ // Redirect exit branch to an exit block that returns
423
+ const exitBlockId = `${block.id}_exit`;
424
+ const exitBlock = {
425
+ id: exitBlockId,
426
+ instrs: [],
427
+ term: { kind: 'return', value: null },
428
+ preds: [block.id],
429
+ };
430
+ if (rewritten.term.kind === 'branch') {
431
+ const branchTerm = rewritten.term;
432
+ const thenInLoop = cont.blocks.some(b => b.id === branchTerm.then);
433
+ const elseInLoop = cont.blocks.some(b => b.id === branchTerm.else);
434
+ if (!thenInLoop && elseInLoop) {
435
+ blocks.push({
436
+ ...rewritten,
437
+ term: { ...branchTerm, then: exitBlockId },
438
+ });
439
+ }
440
+ else if (thenInLoop && !elseInLoop) {
441
+ blocks.push({
442
+ ...rewritten,
443
+ term: { ...branchTerm, else: exitBlockId },
444
+ });
445
+ }
446
+ else {
447
+ blocks.push(rewritten);
448
+ }
449
+ }
450
+ else {
451
+ blocks.push(rewritten);
452
+ }
453
+ blocks.push(exitBlock);
454
+ }
455
+ else {
456
+ blocks.push(rewritten);
457
+ }
458
+ }
459
+ }
460
+ // Deduplicate blocks by ID
461
+ const seenIds = new Set();
462
+ const dedupBlocks = [];
463
+ for (const b of blocks) {
464
+ if (!seenIds.has(b.id)) {
465
+ seenIds.add(b.id);
466
+ dedupBlocks.push(b);
467
+ }
468
+ }
469
+ return {
470
+ name,
471
+ params: [],
472
+ blocks: dedupBlocks,
473
+ entry: 'entry',
474
+ isMacro: false,
475
+ };
476
+ }
477
+ function buildPostLoopContinuation(name, cont, contId, promoted, pcTemp, objective, onDone) {
478
+ const blocks = [];
479
+ // Rewrite blocks with promoted variables
480
+ for (const block of cont.blocks) {
481
+ blocks.push(rewriteBlock(block, promoted));
482
+ }
483
+ // The entry is the first block in the continuation
484
+ const entry = cont.blocks[0]?.id ?? 'entry';
485
+ // Add onDone call if this is the last continuation
486
+ if (onDone) {
487
+ // Find blocks with return terminators and add onDone call before them
488
+ for (let i = 0; i < blocks.length; i++) {
489
+ if (blocks[i].term.kind === 'return') {
490
+ blocks[i] = {
491
+ ...blocks[i],
492
+ instrs: [
493
+ ...blocks[i].instrs,
494
+ { kind: 'call', dst: null, fn: onDone, args: [] },
495
+ ],
496
+ };
497
+ }
498
+ }
499
+ }
500
+ return {
501
+ name,
502
+ params: [],
503
+ blocks,
504
+ entry,
505
+ isMacro: false,
506
+ };
507
+ }
508
+ // ---------------------------------------------------------------------------
509
+ // Step 5: Build init function (replaces original)
510
+ // ---------------------------------------------------------------------------
511
+ function buildInitFunction(originalFn, promoted, pcTemp, prefix, objective) {
512
+ // The init function:
513
+ // 1. Sets pc = 1 (start from continuation 1)
514
+ // 2. Initializes promoted variables from the entry block's pre-loop code
515
+ const instrs = [];
516
+ // Set pc = 1
517
+ instrs.push({ kind: 'const', dst: pcTemp, value: 1 });
518
+ // Initialize promoted variables from entry block instructions
519
+ // Walk the entry block and copy any const/copy instructions for promoted vars
520
+ const entryBlock = originalFn.blocks.find(b => b.id === originalFn.entry);
521
+ if (entryBlock) {
522
+ for (const instr of entryBlock.instrs) {
523
+ const dst = getDst(instr);
524
+ if (dst && promoted.has(dst)) {
525
+ // Rewrite to use promoted name
526
+ instrs.push(rewriteInstr(instr, promoted));
527
+ }
528
+ }
529
+ }
530
+ const block = {
531
+ id: 'entry',
532
+ instrs,
533
+ term: { kind: 'return', value: null },
534
+ preds: [],
535
+ };
536
+ return {
537
+ name: originalFn.name,
538
+ params: originalFn.params,
539
+ blocks: [block],
540
+ entry: 'entry',
541
+ isMacro: originalFn.isMacro,
542
+ };
543
+ }
544
+ // ---------------------------------------------------------------------------
545
+ // Step 6: Build dispatcher
546
+ // ---------------------------------------------------------------------------
547
+ function buildDispatcher(name, continuations, pcTemp, objective, originalFnName) {
548
+ // Generates a dispatcher function that checks pc and calls the right continuation.
549
+ // For each continuation i (1-indexed):
550
+ // execute if score $coro_pc __ns matches i run function ns:_coro_cont_i
551
+ //
552
+ // We model this as a chain of branches in MIR.
553
+ const blocks = [];
554
+ if (continuations.length === 0) {
555
+ // No continuations — just return
556
+ blocks.push({
557
+ id: 'entry',
558
+ instrs: [],
559
+ term: { kind: 'return', value: null },
560
+ preds: [],
561
+ });
562
+ }
563
+ else {
564
+ // Build a chain: check pc==1 → call cont_1, else check pc==2 → call cont_2, ...
565
+ for (let i = 0; i < continuations.length; i++) {
566
+ const contFn = continuations[i];
567
+ const blockId = i === 0 ? 'entry' : `check_${i + 1}`;
568
+ const cmpTemp = `${name}_cmp_${i + 1}`;
569
+ const nextBlock = i < continuations.length - 1 ? `check_${i + 2}` : 'done';
570
+ const callBlock = `call_${i + 1}`;
571
+ blocks.push({
572
+ id: blockId,
573
+ instrs: [
574
+ { kind: 'cmp', dst: cmpTemp, op: 'eq', a: { kind: 'temp', name: pcTemp }, b: { kind: 'const', value: i + 1 } },
575
+ ],
576
+ term: { kind: 'branch', cond: { kind: 'temp', name: cmpTemp }, then: callBlock, else: nextBlock },
577
+ preds: i === 0 ? [] : [`check_${i}`],
578
+ });
579
+ blocks.push({
580
+ id: callBlock,
581
+ instrs: [
582
+ { kind: 'call', dst: null, fn: contFn.name, args: [] },
583
+ ],
584
+ term: { kind: 'return', value: null },
585
+ preds: [blockId],
586
+ });
587
+ }
588
+ // Done block (pc doesn't match any continuation — coroutine finished)
589
+ blocks.push({
590
+ id: 'done',
591
+ instrs: [],
592
+ term: { kind: 'return', value: null },
593
+ preds: [continuations.length === 1 ? 'entry' : `check_${continuations.length}`],
594
+ });
595
+ }
596
+ return {
597
+ name,
598
+ params: [],
599
+ blocks,
600
+ entry: 'entry',
601
+ isMacro: false,
602
+ };
603
+ }
604
+ // ---------------------------------------------------------------------------
605
+ // Single-continuation fallback (no loops)
606
+ // ---------------------------------------------------------------------------
607
+ function buildSingleContinuation(fn, info, prefix, pcTemp, objective) {
608
+ // If there are no loops, the entire function body runs in one tick.
609
+ // We still wrap it in the coroutine pattern for consistency (init → cont_1 → done).
610
+ const contName = `${prefix}_cont_1`;
611
+ // Continuation = entire original function body, plus set pc=-1 at the end
612
+ const contBlocks = fn.blocks.map(block => {
613
+ if (block.term.kind === 'return') {
614
+ const instrs = [...block.instrs];
615
+ if (info.onDone) {
616
+ instrs.push({ kind: 'call', dst: null, fn: info.onDone, args: [] });
617
+ }
618
+ return { ...block, instrs };
619
+ }
620
+ return block;
621
+ });
622
+ const contFn = {
623
+ name: contName,
624
+ params: [],
625
+ blocks: contBlocks,
626
+ entry: fn.entry,
627
+ isMacro: false,
628
+ };
629
+ // Init: set pc = 1
630
+ const initBlock = {
631
+ id: 'entry',
632
+ instrs: [
633
+ { kind: 'const', dst: pcTemp, value: 1 },
634
+ ],
635
+ term: { kind: 'return', value: null },
636
+ preds: [],
637
+ };
638
+ const initFn = {
639
+ name: fn.name,
640
+ params: fn.params,
641
+ blocks: [initBlock],
642
+ entry: 'entry',
643
+ isMacro: fn.isMacro,
644
+ };
645
+ const dispatcher = buildDispatcher(`${prefix}_tick`, [contFn], pcTemp, objective, fn.name);
646
+ return { initFn, continuations: [contFn], dispatcher };
647
+ }
648
+ // ---------------------------------------------------------------------------
649
+ // Helpers: instruction rewriting
650
+ // ---------------------------------------------------------------------------
651
+ function rewriteBlock(block, promoted) {
652
+ return {
653
+ ...block,
654
+ instrs: block.instrs.map(i => rewriteInstr(i, promoted)),
655
+ term: rewriteInstr(block.term, promoted),
656
+ };
657
+ }
658
+ function rewriteInstr(instr, promoted) {
659
+ // Deep-rewrite all temp references through the promoted map
660
+ const rTemp = (t) => promoted.get(t) ?? t;
661
+ const rOp = (op) => op.kind === 'temp' ? { kind: 'temp', name: rTemp(op.name) } : op;
662
+ switch (instr.kind) {
663
+ case 'const':
664
+ return { ...instr, dst: rTemp(instr.dst) };
665
+ case 'copy':
666
+ return { ...instr, dst: rTemp(instr.dst), src: rOp(instr.src) };
667
+ case 'add':
668
+ case 'sub':
669
+ case 'mul':
670
+ case 'div':
671
+ case 'mod':
672
+ return { ...instr, dst: rTemp(instr.dst), a: rOp(instr.a), b: rOp(instr.b) };
673
+ case 'neg':
674
+ return { ...instr, dst: rTemp(instr.dst), src: rOp(instr.src) };
675
+ case 'cmp':
676
+ return { ...instr, dst: rTemp(instr.dst), a: rOp(instr.a), b: rOp(instr.b) };
677
+ case 'and':
678
+ case 'or':
679
+ return { ...instr, dst: rTemp(instr.dst), a: rOp(instr.a), b: rOp(instr.b) };
680
+ case 'not':
681
+ return { ...instr, dst: rTemp(instr.dst), src: rOp(instr.src) };
682
+ case 'nbt_read':
683
+ return { ...instr, dst: rTemp(instr.dst) };
684
+ case 'nbt_write':
685
+ return { ...instr, src: rOp(instr.src) };
686
+ case 'call':
687
+ return { ...instr, dst: instr.dst ? rTemp(instr.dst) : null, args: instr.args.map(rOp) };
688
+ case 'call_macro':
689
+ return { ...instr, dst: instr.dst ? rTemp(instr.dst) : null, args: instr.args.map(a => ({ ...a, value: rOp(a.value) })) };
690
+ case 'call_context':
691
+ return instr;
692
+ case 'branch':
693
+ return { ...instr, cond: rOp(instr.cond) };
694
+ case 'return':
695
+ return { ...instr, value: instr.value ? rOp(instr.value) : null };
696
+ case 'jump':
697
+ return instr;
698
+ default:
699
+ return instr;
700
+ }
701
+ }
702
+ function rewriteTerminator(term, from, to) {
703
+ switch (term.kind) {
704
+ case 'jump':
705
+ return term.target === from ? { ...term, target: to } : term;
706
+ case 'branch':
707
+ return {
708
+ ...term,
709
+ then: term.then === from ? to : term.then,
710
+ else: term.else === from ? to : term.else,
711
+ };
712
+ default:
713
+ return term;
714
+ }
715
+ }
716
+ // ---------------------------------------------------------------------------
717
+ // Helpers: MIR instruction queries
718
+ // ---------------------------------------------------------------------------
719
+ function getSuccessors(term) {
720
+ switch (term.kind) {
721
+ case 'jump': return [term.target];
722
+ case 'branch': return [term.then, term.else];
723
+ default: return [];
724
+ }
725
+ }
726
+ function getDst(instr) {
727
+ switch (instr.kind) {
728
+ case 'const':
729
+ case 'copy':
730
+ case 'add':
731
+ case 'sub':
732
+ case 'mul':
733
+ case 'div':
734
+ case 'mod':
735
+ case 'neg':
736
+ case 'cmp':
737
+ case 'and':
738
+ case 'or':
739
+ case 'not':
740
+ case 'nbt_read':
741
+ return instr.dst;
742
+ case 'call':
743
+ case 'call_macro':
744
+ return instr.dst;
745
+ default:
746
+ return null;
747
+ }
748
+ }
749
+ function getUsedTemps(instr) {
750
+ const temps = [];
751
+ const addOp = (op) => { if (op.kind === 'temp')
752
+ temps.push(op.name); };
753
+ switch (instr.kind) {
754
+ case 'copy':
755
+ case 'neg':
756
+ case 'not':
757
+ addOp(instr.src);
758
+ break;
759
+ case 'add':
760
+ case 'sub':
761
+ case 'mul':
762
+ case 'div':
763
+ case 'mod':
764
+ case 'cmp':
765
+ case 'and':
766
+ case 'or':
767
+ addOp(instr.a);
768
+ addOp(instr.b);
769
+ break;
770
+ case 'nbt_write':
771
+ addOp(instr.src);
772
+ break;
773
+ case 'call':
774
+ instr.args.forEach(addOp);
775
+ break;
776
+ case 'call_macro':
777
+ instr.args.forEach(a => addOp(a.value));
778
+ break;
779
+ case 'branch':
780
+ addOp(instr.cond);
781
+ break;
782
+ case 'return':
783
+ if (instr.value)
784
+ addOp(instr.value);
785
+ break;
786
+ }
787
+ return temps;
788
+ }
789
+ //# sourceMappingURL=coroutine.js.map