redscript-mc 1.2.30 → 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 (593) hide show
  1. package/.claudeignore +21 -0
  2. package/.github/workflows/ci.yml +1 -0
  3. package/README.md +12 -16
  4. package/README.zh.md +2 -2
  5. package/demo.gif +0 -0
  6. package/dist/cli.js +2 -554
  7. package/dist/compile.js +2 -266
  8. package/dist/index.js +2 -159
  9. package/dist/src/__tests__/budget.test.js +261 -0
  10. package/dist/src/__tests__/cli.test.js +104 -0
  11. package/dist/{__tests__ → src/__tests__}/dce.test.js +11 -47
  12. package/dist/{__tests__ → src/__tests__}/diagnostics.test.js +67 -40
  13. package/dist/src/__tests__/e2e/basic.test.d.ts +8 -0
  14. package/dist/src/__tests__/e2e/basic.test.js +140 -0
  15. package/dist/src/__tests__/e2e/coroutine.test.d.ts +7 -0
  16. package/dist/src/__tests__/e2e/coroutine.test.js +132 -0
  17. package/dist/src/__tests__/e2e/macros.test.d.ts +9 -0
  18. package/dist/src/__tests__/e2e/macros.test.js +182 -0
  19. package/dist/src/__tests__/e2e/migrate.test.d.ts +13 -0
  20. package/dist/src/__tests__/e2e/migrate.test.js +2739 -0
  21. package/dist/src/__tests__/e2e/stdlib-e2e.test.d.ts +10 -0
  22. package/dist/src/__tests__/e2e/stdlib-e2e.test.js +324 -0
  23. package/dist/src/__tests__/enum.test.d.ts +10 -0
  24. package/dist/src/__tests__/enum.test.js +389 -0
  25. package/dist/src/__tests__/generics.test.d.ts +14 -0
  26. package/dist/src/__tests__/generics.test.js +367 -0
  27. package/dist/src/__tests__/hir/desugar.test.js +234 -0
  28. package/dist/src/__tests__/incremental.test.d.ts +5 -0
  29. package/dist/src/__tests__/incremental.test.js +308 -0
  30. package/dist/src/__tests__/lir/lower.test.js +559 -0
  31. package/dist/src/__tests__/lir/types.test.js +185 -0
  32. package/dist/src/__tests__/lir/verify.test.js +221 -0
  33. package/dist/src/__tests__/lsp.test.d.ts +7 -0
  34. package/dist/src/__tests__/lsp.test.js +245 -0
  35. package/dist/{__tests__ → src/__tests__}/mc-integration.test.js +1 -3
  36. package/dist/src/__tests__/mc-version.test.d.ts +10 -0
  37. package/dist/src/__tests__/mc-version.test.js +154 -0
  38. package/dist/src/__tests__/mir/arithmetic.test.js +130 -0
  39. package/dist/src/__tests__/mir/control-flow.test.js +205 -0
  40. package/dist/src/__tests__/mir/verify.test.js +223 -0
  41. package/dist/src/__tests__/modules.test.d.ts +7 -0
  42. package/dist/src/__tests__/modules.test.js +333 -0
  43. package/dist/src/__tests__/optimizer/block_merge.test.js +78 -0
  44. package/dist/src/__tests__/optimizer/branch_simplify.test.js +58 -0
  45. package/dist/src/__tests__/optimizer/constant_fold.test.js +131 -0
  46. package/dist/src/__tests__/optimizer/copy_prop.test.js +91 -0
  47. package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
  48. package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
  49. package/dist/src/__tests__/optimizer/dce.test.d.ts +1 -0
  50. package/dist/src/__tests__/optimizer/dce.test.js +76 -0
  51. package/dist/src/__tests__/optimizer/interprocedural.test.d.ts +1 -0
  52. package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
  53. package/dist/src/__tests__/optimizer/lir/const_imm.test.d.ts +1 -0
  54. package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
  55. package/dist/src/__tests__/optimizer/lir/dead_slot.test.d.ts +1 -0
  56. package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
  57. package/dist/src/__tests__/optimizer/lir/peephole.test.d.ts +1 -0
  58. package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
  59. package/dist/src/__tests__/optimizer/lir/pipeline.test.d.ts +1 -0
  60. package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
  61. package/dist/src/__tests__/optimizer/nbt-batch.test.d.ts +1 -0
  62. package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
  63. package/dist/src/__tests__/optimizer/pipeline.test.d.ts +1 -0
  64. package/dist/src/__tests__/optimizer/pipeline.test.js +102 -0
  65. package/dist/src/__tests__/optimizer/selector-cache.test.d.ts +1 -0
  66. package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
  67. package/dist/src/__tests__/optimizer/unroll.test.d.ts +1 -0
  68. package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
  69. package/dist/src/__tests__/option.test.d.ts +14 -0
  70. package/dist/src/__tests__/option.test.js +275 -0
  71. package/dist/src/__tests__/parser.test.d.ts +1 -0
  72. package/dist/src/__tests__/repl.test.d.ts +1 -0
  73. package/dist/src/__tests__/schedule.test.d.ts +7 -0
  74. package/dist/src/__tests__/schedule.test.js +98 -0
  75. package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
  76. package/dist/src/__tests__/sourcemap.test.js +227 -0
  77. package/dist/src/__tests__/tuple.test.d.ts +11 -0
  78. package/dist/src/__tests__/tuple.test.js +202 -0
  79. package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
  80. package/dist/src/__tests__/typechecker-strict.test.js +197 -0
  81. package/dist/src/__tests__/typechecker.test.d.ts +1 -0
  82. package/dist/{ast → src/ast}/types.d.ts +58 -3
  83. package/dist/src/cache/deps.d.ts +41 -0
  84. package/dist/src/cache/deps.js +158 -0
  85. package/dist/src/cache/incremental.d.ts +35 -0
  86. package/dist/src/cache/incremental.js +165 -0
  87. package/dist/src/cache/index.d.ts +37 -0
  88. package/dist/src/cache/index.js +152 -0
  89. package/dist/{cli.d.ts → src/cli.d.ts} +1 -1
  90. package/dist/src/cli.js +474 -0
  91. package/dist/src/compile.d.ts +37 -0
  92. package/dist/src/compile.js +165 -0
  93. package/dist/{diagnostics → src/diagnostics}/index.d.ts +1 -1
  94. package/dist/{diagnostics → src/diagnostics}/index.js +8 -11
  95. package/dist/src/emit/compile.d.ts +29 -0
  96. package/dist/src/emit/compile.js +143 -0
  97. package/dist/src/emit/index.d.ts +26 -0
  98. package/dist/src/emit/index.js +223 -0
  99. package/dist/src/emit/modules.d.ts +29 -0
  100. package/dist/src/emit/modules.js +492 -0
  101. package/dist/src/emit/sourcemap.d.ts +53 -0
  102. package/dist/src/emit/sourcemap.js +73 -0
  103. package/dist/src/hir/lower.d.ts +15 -0
  104. package/dist/src/hir/lower.js +399 -0
  105. package/dist/src/hir/monomorphize.d.ts +22 -0
  106. package/dist/src/hir/monomorphize.js +379 -0
  107. package/dist/src/hir/types.d.ts +406 -0
  108. package/dist/src/hir/types.js +16 -0
  109. package/dist/src/index.d.ts +39 -0
  110. package/dist/src/index.js +67 -0
  111. package/dist/{lexer → src/lexer}/index.d.ts +1 -1
  112. package/dist/{lexer → src/lexer}/index.js +1 -0
  113. package/dist/src/lir/budget.d.ts +37 -0
  114. package/dist/src/lir/budget.js +280 -0
  115. package/dist/src/lir/lower.d.ts +15 -0
  116. package/dist/src/lir/lower.js +472 -0
  117. package/dist/src/lir/types.d.ts +139 -0
  118. package/dist/src/lir/types.js +11 -0
  119. package/dist/src/lir/verify.d.ts +14 -0
  120. package/dist/src/lir/verify.js +113 -0
  121. package/dist/src/lsp/main.d.ts +8 -0
  122. package/dist/src/lsp/main.js +11 -0
  123. package/dist/src/lsp/server.d.ts +11 -0
  124. package/dist/src/lsp/server.js +352 -0
  125. package/dist/{mc-test → src/mc-test}/runner.js +4 -3
  126. package/dist/src/mir/lower.d.ts +9 -0
  127. package/dist/src/mir/lower.js +1264 -0
  128. package/dist/src/mir/macro.d.ts +22 -0
  129. package/dist/src/mir/macro.js +168 -0
  130. package/dist/src/mir/types.d.ts +191 -0
  131. package/dist/src/mir/types.js +11 -0
  132. package/dist/src/mir/verify.d.ts +16 -0
  133. package/dist/src/mir/verify.js +216 -0
  134. package/dist/src/optimizer/block_merge.d.ts +12 -0
  135. package/dist/src/optimizer/block_merge.js +84 -0
  136. package/dist/src/optimizer/branch_simplify.d.ts +9 -0
  137. package/dist/src/optimizer/branch_simplify.js +28 -0
  138. package/dist/src/optimizer/constant_fold.d.ts +10 -0
  139. package/dist/src/optimizer/constant_fold.js +85 -0
  140. package/dist/src/optimizer/copy_prop.d.ts +9 -0
  141. package/dist/src/optimizer/copy_prop.js +113 -0
  142. package/dist/src/optimizer/coroutine.d.ts +34 -0
  143. package/dist/src/optimizer/coroutine.js +789 -0
  144. package/dist/src/optimizer/dce.d.ts +8 -0
  145. package/dist/src/optimizer/dce.js +156 -0
  146. package/dist/src/optimizer/interprocedural.d.ts +14 -0
  147. package/dist/src/optimizer/interprocedural.js +186 -0
  148. package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
  149. package/dist/src/optimizer/lir/const_imm.js +139 -0
  150. package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
  151. package/dist/src/optimizer/lir/dead_slot.js +130 -0
  152. package/dist/src/optimizer/lir/peephole.d.ts +21 -0
  153. package/dist/src/optimizer/lir/peephole.js +52 -0
  154. package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
  155. package/dist/src/optimizer/lir/pipeline.js +34 -0
  156. package/dist/src/optimizer/nbt-batch.d.ts +11 -0
  157. package/dist/src/optimizer/nbt-batch.js +51 -0
  158. package/dist/src/optimizer/pipeline.d.ts +14 -0
  159. package/dist/src/optimizer/pipeline.js +58 -0
  160. package/dist/src/optimizer/selector-cache.d.ts +22 -0
  161. package/dist/src/optimizer/selector-cache.js +100 -0
  162. package/dist/src/optimizer/unroll.d.ts +32 -0
  163. package/dist/src/optimizer/unroll.js +348 -0
  164. package/dist/{parser → src/parser}/index.d.ts +8 -0
  165. package/dist/{parser → src/parser}/index.js +204 -14
  166. package/dist/{repl.d.ts → src/repl.d.ts} +1 -1
  167. package/dist/{runtime → src/runtime}/index.js +1 -1
  168. package/dist/{typechecker → src/typechecker}/index.d.ts +4 -0
  169. package/dist/{typechecker → src/typechecker}/index.js +198 -13
  170. package/dist/src/types/mc-version.d.ts +24 -0
  171. package/dist/src/types/mc-version.js +49 -0
  172. package/docs/ROADMAP.md +395 -0
  173. package/docs/compiler-pipeline-redesign.md +2260 -0
  174. package/docs/optimization-ideas.md +1076 -0
  175. package/editors/vscode/out/extension.js +25176 -8000
  176. package/editors/vscode/package-lock.json +90 -6
  177. package/editors/vscode/package.json +3 -2
  178. package/editors/vscode/src/extension.ts +97 -67
  179. package/examples/showcase.mcrs +3 -3
  180. package/package.json +13 -6
  181. package/scripts/postbuild.js +15 -0
  182. package/src/__tests__/budget.test.ts +297 -0
  183. package/src/__tests__/cli.test.ts +8 -220
  184. package/src/__tests__/dce.test.ts +11 -56
  185. package/src/__tests__/diagnostics.test.ts +61 -41
  186. package/src/__tests__/e2e/basic.test.ts +154 -0
  187. package/src/__tests__/e2e/coroutine.test.ts +142 -0
  188. package/src/__tests__/e2e/macros.test.ts +199 -0
  189. package/src/__tests__/e2e/migrate.test.ts +3008 -0
  190. package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
  191. package/src/__tests__/enum.test.ts +425 -0
  192. package/src/__tests__/generics.test.ts +390 -0
  193. package/src/__tests__/hir/desugar.test.ts +263 -0
  194. package/src/__tests__/incremental.test.ts +337 -0
  195. package/src/__tests__/lir/lower.test.ts +619 -0
  196. package/src/__tests__/lir/types.test.ts +207 -0
  197. package/src/__tests__/lir/verify.test.ts +249 -0
  198. package/src/__tests__/lsp.test.ts +270 -0
  199. package/src/__tests__/mc-integration.test.ts +1 -2
  200. package/src/__tests__/mc-version.test.ts +178 -0
  201. package/src/__tests__/mir/arithmetic.test.ts +156 -0
  202. package/src/__tests__/mir/control-flow.test.ts +242 -0
  203. package/src/__tests__/mir/verify.test.ts +254 -0
  204. package/src/__tests__/modules.test.ts +365 -0
  205. package/src/__tests__/optimizer/block_merge.test.ts +84 -0
  206. package/src/__tests__/optimizer/branch_simplify.test.ts +64 -0
  207. package/src/__tests__/optimizer/constant_fold.test.ts +145 -0
  208. package/src/__tests__/optimizer/copy_prop.test.ts +99 -0
  209. package/src/__tests__/optimizer/coroutine.test.ts +312 -0
  210. package/src/__tests__/optimizer/dce.test.ts +83 -0
  211. package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
  212. package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
  213. package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
  214. package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
  215. package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
  216. package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
  217. package/src/__tests__/optimizer/pipeline.test.ts +116 -0
  218. package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
  219. package/src/__tests__/optimizer/unroll.test.ts +231 -0
  220. package/src/__tests__/option.test.ts +299 -0
  221. package/src/__tests__/schedule.test.ts +105 -0
  222. package/src/__tests__/sourcemap.test.ts +254 -0
  223. package/src/__tests__/tuple.test.ts +220 -0
  224. package/src/__tests__/typechecker-strict.test.ts +216 -0
  225. package/src/ast/types.ts +39 -3
  226. package/src/cache/deps.ts +132 -0
  227. package/src/cache/incremental.ts +173 -0
  228. package/src/cache/index.ts +135 -0
  229. package/src/cli.ts +111 -195
  230. package/src/compile.ts +6 -162
  231. package/src/diagnostics/index.ts +8 -11
  232. package/src/emit/compile.ts +177 -0
  233. package/src/emit/index.ts +286 -0
  234. package/src/emit/modules.ts +581 -0
  235. package/src/emit/sourcemap.ts +101 -0
  236. package/src/hir/lower.ts +455 -0
  237. package/src/hir/monomorphize.ts +416 -0
  238. package/src/hir/types.ts +228 -0
  239. package/src/index.ts +37 -182
  240. package/src/lexer/index.ts +2 -1
  241. package/src/lir/budget.ts +321 -0
  242. package/src/lir/lower.ts +587 -0
  243. package/src/lir/types.ts +113 -0
  244. package/src/lir/verify.ts +129 -0
  245. package/src/lsp/main.ts +9 -0
  246. package/src/lsp/server.ts +414 -0
  247. package/src/mc-test/runner.ts +4 -3
  248. package/src/mir/lower.ts +1403 -0
  249. package/src/mir/macro.ts +167 -0
  250. package/src/mir/types.ts +117 -0
  251. package/src/mir/verify.ts +218 -0
  252. package/src/optimizer/block_merge.ts +93 -0
  253. package/src/optimizer/branch_simplify.ts +27 -0
  254. package/src/optimizer/constant_fold.ts +88 -0
  255. package/src/optimizer/copy_prop.ts +106 -0
  256. package/src/optimizer/coroutine.ts +996 -0
  257. package/src/optimizer/dce.ts +108 -653
  258. package/src/optimizer/interprocedural.ts +177 -0
  259. package/src/optimizer/lir/const_imm.ts +143 -0
  260. package/src/optimizer/lir/dead_slot.ts +123 -0
  261. package/src/optimizer/lir/peephole.ts +57 -0
  262. package/src/optimizer/lir/pipeline.ts +37 -0
  263. package/src/optimizer/nbt-batch.ts +50 -0
  264. package/src/optimizer/pipeline.ts +59 -0
  265. package/src/optimizer/selector-cache.ts +103 -0
  266. package/src/optimizer/unroll.ts +386 -0
  267. package/src/parser/index.ts +213 -16
  268. package/src/repl.ts +1 -1
  269. package/src/runtime/index.ts +1 -1
  270. package/src/stdlib/math.mcrs +4 -4
  271. package/src/templates/quest.mcrs +4 -4
  272. package/src/typechecker/index.ts +215 -15
  273. package/src/types/mc-version.ts +46 -0
  274. package/tsconfig.json +1 -1
  275. package/dist/__tests__/cli.test.js +0 -278
  276. package/dist/__tests__/codegen.test.js +0 -152
  277. package/dist/__tests__/e2e.test.d.ts +0 -6
  278. package/dist/__tests__/e2e.test.js +0 -1847
  279. package/dist/__tests__/entity-types.test.js +0 -203
  280. package/dist/__tests__/lowering.test.js +0 -1015
  281. package/dist/__tests__/macro.test.d.ts +0 -8
  282. package/dist/__tests__/macro.test.js +0 -305
  283. package/dist/__tests__/nbt.test.js +0 -82
  284. package/dist/__tests__/optimizer-advanced.test.js +0 -124
  285. package/dist/__tests__/optimizer.test.js +0 -149
  286. package/dist/__tests__/runtime.test.js +0 -289
  287. package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
  288. package/dist/__tests__/stdlib-advanced.test.js +0 -378
  289. package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
  290. package/dist/__tests__/stdlib-bigint.test.js +0 -428
  291. package/dist/__tests__/stdlib-math.test.d.ts +0 -7
  292. package/dist/__tests__/stdlib-math.test.js +0 -352
  293. package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
  294. package/dist/__tests__/stdlib-vec.test.js +0 -264
  295. package/dist/__tests__/structure-optimizer.test.js +0 -33
  296. package/dist/__tests__/var-allocator.test.js +0 -69
  297. package/dist/codegen/cmdblock/index.d.ts +0 -26
  298. package/dist/codegen/cmdblock/index.js +0 -45
  299. package/dist/codegen/mcfunction/index.d.ts +0 -40
  300. package/dist/codegen/mcfunction/index.js +0 -606
  301. package/dist/codegen/structure/index.d.ts +0 -24
  302. package/dist/codegen/structure/index.js +0 -279
  303. package/dist/codegen/var-allocator.d.ts +0 -45
  304. package/dist/codegen/var-allocator.js +0 -104
  305. package/dist/compile.d.ts +0 -68
  306. package/dist/data/arena/function/__load.mcfunction +0 -6
  307. package/dist/data/arena/function/__tick.mcfunction +0 -2
  308. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
  309. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
  310. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
  311. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
  312. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
  313. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
  314. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
  315. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
  316. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
  317. package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
  318. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
  319. package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
  320. package/dist/data/arena/function/arena_tick.mcfunction +0 -11
  321. package/dist/data/counter/function/__load.mcfunction +0 -5
  322. package/dist/data/counter/function/__tick.mcfunction +0 -2
  323. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
  324. package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
  325. package/dist/data/counter/function/counter_tick.mcfunction +0 -11
  326. package/dist/data/gcd2/function/__load.mcfunction +0 -3
  327. package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
  328. package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
  329. package/dist/data/gcd2/function/abs.mcfunction +0 -7
  330. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
  331. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
  332. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
  333. package/dist/data/gcd2/function/gcd.mcfunction +0 -14
  334. package/dist/data/gcd3/function/__load.mcfunction +0 -3
  335. package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
  336. package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
  337. package/dist/data/gcd3/function/abs.mcfunction +0 -7
  338. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
  339. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
  340. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
  341. package/dist/data/gcd3/function/gcd.mcfunction +0 -14
  342. package/dist/data/gcd3/function/test.mcfunction +0 -7
  343. package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
  344. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
  345. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
  346. package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
  347. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
  348. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
  349. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
  350. package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
  351. package/dist/data/gcd3nm/function/test.mcfunction +0 -7
  352. package/dist/data/gcd_test/function/__load.mcfunction +0 -3
  353. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
  354. package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
  355. package/dist/data/gcd_test/function/abs.mcfunction +0 -7
  356. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
  357. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
  358. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
  359. package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
  360. package/dist/data/isqrttest/function/__load.mcfunction +0 -6
  361. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
  362. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
  363. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
  364. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
  365. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
  366. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
  367. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
  368. package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
  369. package/dist/data/isqrttest/function/test.mcfunction +0 -6
  370. package/dist/data/mathtest/function/__load.mcfunction +0 -3
  371. package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
  372. package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
  373. package/dist/data/mathtest/function/abs.mcfunction +0 -6
  374. package/dist/data/mathtest/function/test.mcfunction +0 -5
  375. package/dist/data/minecraft/tags/function/load.json +0 -5
  376. package/dist/data/minecraft/tags/function/tick.json +0 -5
  377. package/dist/data/mypack/function/__load.mcfunction +0 -13
  378. package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
  379. package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
  380. package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
  381. package/dist/data/mypack/function/abs.mcfunction +0 -6
  382. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
  383. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
  384. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
  385. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
  386. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
  387. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
  388. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
  389. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
  390. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
  391. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
  392. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
  393. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
  394. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
  395. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
  396. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
  397. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
  398. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
  399. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
  400. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
  401. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
  402. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
  403. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
  404. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
  405. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
  406. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
  407. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
  408. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
  409. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
  410. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
  411. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
  412. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
  413. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
  414. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
  415. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
  416. package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
  417. package/dist/data/mypack/function/my_game.mcfunction +0 -10
  418. package/dist/data/quiz/function/__load.mcfunction +0 -16
  419. package/dist/data/quiz/function/__tick.mcfunction +0 -6
  420. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
  421. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
  422. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
  423. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
  424. package/dist/data/quiz/function/answer_a.mcfunction +0 -4
  425. package/dist/data/quiz/function/answer_b.mcfunction +0 -4
  426. package/dist/data/quiz/function/answer_c.mcfunction +0 -4
  427. package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
  428. package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
  429. package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
  430. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
  431. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
  432. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
  433. package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
  434. package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
  435. package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
  436. package/dist/data/quiz/function/ask_question.mcfunction +0 -7
  437. package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
  438. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
  439. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
  440. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
  441. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
  442. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
  443. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
  444. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
  445. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
  446. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
  447. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
  448. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
  449. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
  450. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
  451. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
  452. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
  453. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
  454. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
  455. package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
  456. package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
  457. package/dist/data/reqtest/function/__load.mcfunction +0 -4
  458. package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
  459. package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
  460. package/dist/data/reqtest/function/use_table.mcfunction +0 -4
  461. package/dist/data/reqtest2/function/__load.mcfunction +0 -3
  462. package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
  463. package/dist/data/runtime/function/__load.mcfunction +0 -5
  464. package/dist/data/runtime/function/__tick.mcfunction +0 -2
  465. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
  466. package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
  467. package/dist/data/shop/function/__load.mcfunction +0 -7
  468. package/dist/data/shop/function/__tick.mcfunction +0 -3
  469. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
  470. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
  471. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
  472. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
  473. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
  474. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
  475. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
  476. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
  477. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
  478. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
  479. package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
  480. package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
  481. package/dist/data/swap_test/function/__load.mcfunction +0 -3
  482. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
  483. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
  484. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
  485. package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
  486. package/dist/data/turret/function/__load.mcfunction +0 -5
  487. package/dist/data/turret/function/__tick.mcfunction +0 -4
  488. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
  489. package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
  490. package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
  491. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
  492. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
  493. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
  494. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
  495. package/dist/data/turret/function/turret_tick.mcfunction +0 -5
  496. package/dist/gcd2.map.json +0 -15
  497. package/dist/gcd3.map.json +0 -17
  498. package/dist/gcd_test.map.json +0 -15
  499. package/dist/index.d.ts +0 -62
  500. package/dist/ir/builder.d.ts +0 -33
  501. package/dist/ir/builder.js +0 -99
  502. package/dist/ir/types.d.ts +0 -132
  503. package/dist/ir/types.js +0 -15
  504. package/dist/isqrttest.map.json +0 -15
  505. package/dist/lowering/index.d.ts +0 -188
  506. package/dist/lowering/index.js +0 -3403
  507. package/dist/mathtest.map.json +0 -6
  508. package/dist/mypack.map.json +0 -27
  509. package/dist/optimizer/commands.d.ts +0 -38
  510. package/dist/optimizer/commands.js +0 -451
  511. package/dist/optimizer/dce.d.ts +0 -34
  512. package/dist/optimizer/dce.js +0 -639
  513. package/dist/optimizer/passes.d.ts +0 -34
  514. package/dist/optimizer/passes.js +0 -243
  515. package/dist/optimizer/structure.d.ts +0 -9
  516. package/dist/optimizer/structure.js +0 -356
  517. package/dist/pack.mcmeta +0 -6
  518. package/dist/reqtest.map.json +0 -4
  519. package/dist/reqtest2.map.json +0 -4
  520. package/dist/runtime.map.json +0 -7
  521. package/dist/swap_test.map.json +0 -14
  522. package/src/__tests__/codegen.test.ts +0 -161
  523. package/src/__tests__/e2e.test.ts +0 -2039
  524. package/src/__tests__/entity-types.test.ts +0 -236
  525. package/src/__tests__/lowering.test.ts +0 -1185
  526. package/src/__tests__/macro.test.ts +0 -343
  527. package/src/__tests__/nbt.test.ts +0 -58
  528. package/src/__tests__/optimizer-advanced.test.ts +0 -144
  529. package/src/__tests__/optimizer.test.ts +0 -162
  530. package/src/__tests__/runtime.test.ts +0 -305
  531. package/src/__tests__/stdlib-advanced.test.ts +0 -379
  532. package/src/__tests__/stdlib-bigint.test.ts +0 -427
  533. package/src/__tests__/stdlib-math.test.ts +0 -374
  534. package/src/__tests__/stdlib-vec.test.ts +0 -259
  535. package/src/__tests__/structure-optimizer.test.ts +0 -38
  536. package/src/__tests__/var-allocator.test.ts +0 -75
  537. package/src/codegen/cmdblock/index.ts +0 -63
  538. package/src/codegen/mcfunction/index.ts +0 -662
  539. package/src/codegen/structure/index.ts +0 -346
  540. package/src/codegen/var-allocator.ts +0 -104
  541. package/src/ir/builder.ts +0 -116
  542. package/src/ir/types.ts +0 -134
  543. package/src/lowering/index.ts +0 -3876
  544. package/src/optimizer/commands.ts +0 -534
  545. package/src/optimizer/passes.ts +0 -250
  546. package/src/optimizer/structure.ts +0 -450
  547. /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
  548. /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/cli.test.d.ts} +0 -0
  549. /package/dist/{__tests__ → src/__tests__}/compile-all.test.d.ts +0 -0
  550. /package/dist/{__tests__ → src/__tests__}/compile-all.test.js +0 -0
  551. /package/dist/{__tests__ → src/__tests__}/dce.test.d.ts +0 -0
  552. /package/dist/{__tests__ → src/__tests__}/diagnostics.test.d.ts +0 -0
  553. /package/dist/{__tests__ → src/__tests__}/formatter.test.d.ts +0 -0
  554. /package/dist/{__tests__ → src/__tests__}/formatter.test.js +0 -0
  555. /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/hir/desugar.test.d.ts} +0 -0
  556. /package/dist/{__tests__ → src/__tests__}/lexer.test.d.ts +0 -0
  557. /package/dist/{__tests__ → src/__tests__}/lexer.test.js +0 -0
  558. /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/lir/lower.test.d.ts} +0 -0
  559. /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/lir/types.test.d.ts} +0 -0
  560. /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/lir/verify.test.d.ts} +0 -0
  561. /package/dist/{__tests__ → src/__tests__}/mc-integration.test.d.ts +0 -0
  562. /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/mc-syntax.test.d.ts} +0 -0
  563. /package/dist/{__tests__ → src/__tests__}/mc-syntax.test.js +0 -0
  564. /package/dist/{__tests__/optimizer.test.d.ts → src/__tests__/mir/arithmetic.test.d.ts} +0 -0
  565. /package/dist/{__tests__/parser.test.d.ts → src/__tests__/mir/control-flow.test.d.ts} +0 -0
  566. /package/dist/{__tests__/repl.test.d.ts → src/__tests__/mir/verify.test.d.ts} +0 -0
  567. /package/dist/{__tests__/runtime.test.d.ts → src/__tests__/optimizer/block_merge.test.d.ts} +0 -0
  568. /package/dist/{__tests__/structure-optimizer.test.d.ts → src/__tests__/optimizer/branch_simplify.test.d.ts} +0 -0
  569. /package/dist/{__tests__/typechecker.test.d.ts → src/__tests__/optimizer/constant_fold.test.d.ts} +0 -0
  570. /package/dist/{__tests__/var-allocator.test.d.ts → src/__tests__/optimizer/copy_prop.test.d.ts} +0 -0
  571. /package/dist/{__tests__ → src/__tests__}/parser.test.js +0 -0
  572. /package/dist/{__tests__ → src/__tests__}/repl.test.js +0 -0
  573. /package/dist/{__tests__ → src/__tests__}/typechecker.test.js +0 -0
  574. /package/dist/{ast → src/ast}/types.js +0 -0
  575. /package/dist/{builtins → src/builtins}/metadata.d.ts +0 -0
  576. /package/dist/{builtins → src/builtins}/metadata.js +0 -0
  577. /package/dist/{events → src/events}/types.d.ts +0 -0
  578. /package/dist/{events → src/events}/types.js +0 -0
  579. /package/dist/{formatter → src/formatter}/index.d.ts +0 -0
  580. /package/dist/{formatter → src/formatter}/index.js +0 -0
  581. /package/dist/{mc-test → src/mc-test}/client.d.ts +0 -0
  582. /package/dist/{mc-test → src/mc-test}/client.js +0 -0
  583. /package/dist/{mc-test → src/mc-test}/runner.d.ts +0 -0
  584. /package/dist/{mc-test → src/mc-test}/setup.d.ts +0 -0
  585. /package/dist/{mc-test → src/mc-test}/setup.js +0 -0
  586. /package/dist/{mc-validator → src/mc-validator}/index.d.ts +0 -0
  587. /package/dist/{mc-validator → src/mc-validator}/index.js +0 -0
  588. /package/dist/{nbt → src/nbt}/index.d.ts +0 -0
  589. /package/dist/{nbt → src/nbt}/index.js +0 -0
  590. /package/dist/{repl.js → src/repl.js} +0 -0
  591. /package/dist/{runtime → src/runtime}/index.d.ts +0 -0
  592. /package/dist/{types → src/types}/entity-hierarchy.d.ts +0 -0
  593. /package/dist/{types → src/types}/entity-hierarchy.js +0 -0
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Macro function detection — pre-scans HIR to find parameters used in
3
+ * builtin call positions (coordinates, entity types, etc.)
4
+ *
5
+ * A function becomes a "macro function" when one of its params appears
6
+ * in a position that requires literal substitution in the MC command
7
+ * (e.g. summon coords, particle coords, setblock coords, local/relative
8
+ * coords like ^px or ~height).
9
+ */
10
+
11
+ import type { HIRModule, HIRExpr, HIRStmt, HIRBlock } from '../hir/types'
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Known builtins that emit MC commands with inline arguments
15
+ // ---------------------------------------------------------------------------
16
+
17
+ /** Builtins whose arguments appear literally in MC commands */
18
+ export const BUILTIN_SET = new Set([
19
+ 'say', 'tell', 'tellraw', 'title', 'actionbar', 'subtitle', 'title_times',
20
+ 'announce', 'give', 'kill', 'effect', 'effect_clear',
21
+ 'summon', 'particle', 'playsound', 'clear', 'weather',
22
+ 'time_set', 'time_add', 'gamerule', 'tag_add', 'tag_remove',
23
+ 'kick', 'setblock', 'fill', 'clone', 'difficulty', 'xp_add', 'xp_set',
24
+ ])
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Public API
28
+ // ---------------------------------------------------------------------------
29
+
30
+ export interface MacroFunctionInfo {
31
+ macroParams: Set<string>
32
+ /** param name → param type name (for NBT scale inference) */
33
+ paramTypes: Map<string, string>
34
+ }
35
+
36
+ /**
37
+ * Pre-scan HIR functions to detect which params need macro treatment.
38
+ * Returns a map: function name → MacroFunctionInfo.
39
+ */
40
+ export function detectMacroFunctions(hir: HIRModule): Map<string, MacroFunctionInfo> {
41
+ const result = new Map<string, MacroFunctionInfo>()
42
+
43
+ for (const fn of hir.functions) {
44
+ const paramNames = new Set(fn.params.map(p => p.name))
45
+ const macroParams = new Set<string>()
46
+ scanBlock(fn.body, paramNames, macroParams)
47
+ if (macroParams.size > 0) {
48
+ const paramTypes = new Map<string, string>()
49
+ for (const p of fn.params) {
50
+ const typeName = p.type?.kind === 'named' ? (p.type as any).name : 'int'
51
+ paramTypes.set(p.name, typeName)
52
+ }
53
+ result.set(fn.name, { macroParams, paramTypes })
54
+ }
55
+ }
56
+
57
+ for (const ib of hir.implBlocks) {
58
+ for (const m of ib.methods) {
59
+ const paramNames = new Set(m.params.map(p => p.name))
60
+ const macroParams = new Set<string>()
61
+ scanBlock(m.body, paramNames, macroParams)
62
+ if (macroParams.size > 0) {
63
+ const paramTypes = new Map<string, string>()
64
+ for (const p of m.params) {
65
+ const typeName = p.type?.kind === 'named' ? (p.type as any).name : 'int'
66
+ paramTypes.set(p.name, typeName)
67
+ }
68
+ result.set(`${ib.typeName}::${m.name}`, { macroParams, paramTypes })
69
+ }
70
+ }
71
+ }
72
+
73
+ return result
74
+ }
75
+
76
+ // ---------------------------------------------------------------------------
77
+ // HIR scanning
78
+ // ---------------------------------------------------------------------------
79
+
80
+ function scanBlock(stmts: HIRBlock, paramNames: Set<string>, macroParams: Set<string>): void {
81
+ for (const stmt of stmts) scanStmt(stmt, paramNames, macroParams)
82
+ }
83
+
84
+ function scanStmt(stmt: HIRStmt, paramNames: Set<string>, macroParams: Set<string>): void {
85
+ switch (stmt.kind) {
86
+ case 'expr': scanExpr(stmt.expr, paramNames, macroParams); break
87
+ case 'let': scanExpr(stmt.init, paramNames, macroParams); break
88
+ case 'return': if (stmt.value) scanExpr(stmt.value, paramNames, macroParams); break
89
+ case 'if':
90
+ scanExpr(stmt.cond, paramNames, macroParams)
91
+ scanBlock(stmt.then, paramNames, macroParams)
92
+ if (stmt.else_) scanBlock(stmt.else_, paramNames, macroParams)
93
+ break
94
+ case 'while':
95
+ scanExpr(stmt.cond, paramNames, macroParams)
96
+ scanBlock(stmt.body, paramNames, macroParams)
97
+ if (stmt.step) scanBlock(stmt.step, paramNames, macroParams)
98
+ break
99
+ case 'foreach': scanBlock(stmt.body, paramNames, macroParams); break
100
+ case 'match':
101
+ scanExpr(stmt.expr, paramNames, macroParams)
102
+ for (const arm of stmt.arms) scanBlock(arm.body, paramNames, macroParams)
103
+ break
104
+ case 'execute': scanBlock(stmt.body, paramNames, macroParams); break
105
+ case 'raw': break
106
+ }
107
+ }
108
+
109
+ function scanExpr(expr: HIRExpr, paramNames: Set<string>, macroParams: Set<string>): void {
110
+ if (expr.kind === 'call' && BUILTIN_SET.has(expr.fn)) {
111
+ // Check if any argument is a param identifier or a coord with a param variable
112
+ for (const arg of expr.args) {
113
+ checkMacroArg(arg, paramNames, macroParams)
114
+ }
115
+ // Recurse into args for nested expressions
116
+ for (const arg of expr.args) scanExpr(arg, paramNames, macroParams)
117
+ return
118
+ }
119
+
120
+ // Recurse into sub-expressions
121
+ switch (expr.kind) {
122
+ case 'call':
123
+ for (const arg of expr.args) scanExpr(arg, paramNames, macroParams)
124
+ break
125
+ case 'invoke':
126
+ scanExpr(expr.callee, paramNames, macroParams)
127
+ for (const arg of expr.args) scanExpr(arg, paramNames, macroParams)
128
+ break
129
+ case 'binary':
130
+ scanExpr(expr.left, paramNames, macroParams)
131
+ scanExpr(expr.right, paramNames, macroParams)
132
+ break
133
+ case 'unary':
134
+ scanExpr(expr.operand, paramNames, macroParams)
135
+ break
136
+ case 'assign':
137
+ scanExpr(expr.value, paramNames, macroParams)
138
+ break
139
+ case 'member_assign':
140
+ scanExpr(expr.obj, paramNames, macroParams)
141
+ scanExpr(expr.value, paramNames, macroParams)
142
+ break
143
+ case 'member':
144
+ scanExpr(expr.obj, paramNames, macroParams)
145
+ break
146
+ case 'index':
147
+ scanExpr(expr.obj, paramNames, macroParams)
148
+ scanExpr(expr.index, paramNames, macroParams)
149
+ break
150
+ case 'static_call':
151
+ for (const arg of expr.args) scanExpr(arg, paramNames, macroParams)
152
+ break
153
+ }
154
+ }
155
+
156
+ /** Check if a single argument expression references a function parameter in a macro position */
157
+ function checkMacroArg(expr: HIRExpr, paramNames: Set<string>, macroParams: Set<string>): void {
158
+ if (expr.kind === 'ident' && paramNames.has(expr.name)) {
159
+ macroParams.add(expr.name)
160
+ } else if (expr.kind === 'local_coord' || expr.kind === 'rel_coord') {
161
+ // ^varname or ~varname — extract the variable part
162
+ const rest = expr.value.slice(1)
163
+ if (rest && /^[a-zA-Z_]\w*$/.test(rest) && paramNames.has(rest)) {
164
+ macroParams.add(rest)
165
+ }
166
+ }
167
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * MIR (Mid-level IR) Types — Stage 3 of the RedScript compiler pipeline.
3
+ *
4
+ * MIR is a 3-address, explicit-CFG representation with versioned temporaries.
5
+ * Every instruction produces at most one result into a fresh temporary.
6
+ *
7
+ * Spec: docs/compiler-pipeline-redesign.md § "MIR Instruction Set"
8
+ */
9
+
10
+ // A temporary variable — unique within a function, named t0, t1, t2...
11
+ export type Temp = string
12
+
13
+ // Source location from the original .mcrs file
14
+ export interface SourceLoc {
15
+ file: string
16
+ line: number
17
+ col: number
18
+ }
19
+
20
+ // An operand: either a temp or an inline constant
21
+ export type Operand =
22
+ | { kind: 'temp'; name: Temp }
23
+ | { kind: 'const'; value: number }
24
+
25
+ // A basic block identifier
26
+ export type BlockId = string
27
+
28
+ // Comparison operators (for cmp instruction)
29
+ export type CmpOp = 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge'
30
+
31
+ // NBT value types (for nbt_write)
32
+ export type NBTType = 'int' | 'double' | 'float' | 'long' | 'short' | 'byte'
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Execute subcommands (used in call_context)
36
+ // ---------------------------------------------------------------------------
37
+
38
+ export type ExecuteSubcmd =
39
+ | { kind: 'as'; selector: string }
40
+ | { kind: 'at'; selector: string }
41
+ | { kind: 'at_self' }
42
+ | { kind: 'positioned'; x: string; y: string; z: string }
43
+ | { kind: 'rotated'; yaw: string; pitch: string }
44
+ | { kind: 'in'; dimension: string }
45
+ | { kind: 'anchored'; anchor: 'eyes' | 'feet' }
46
+ | { kind: 'if_score'; a: string; op: CmpOp; b: string }
47
+ | { kind: 'unless_score'; a: string; op: CmpOp; b: string }
48
+ | { kind: 'if_matches'; score: string; range: string }
49
+ | { kind: 'unless_matches'; score: string; range: string }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // MIR Instructions
53
+ // ---------------------------------------------------------------------------
54
+
55
+ // Base type for all MIR instructions — carries optional source location
56
+ export type MIRInstrBase = { sourceLoc?: SourceLoc }
57
+
58
+ export type MIRInstr = MIRInstrBase & (
59
+ // ── Constants & copies ──────────────────────────────────────────────────
60
+ | { kind: 'const'; dst: Temp; value: number }
61
+ | { kind: 'copy'; dst: Temp; src: Operand }
62
+
63
+ // ── Integer arithmetic ──────────────────────────────────────────────────
64
+ | { kind: 'add'; dst: Temp; a: Operand; b: Operand }
65
+ | { kind: 'sub'; dst: Temp; a: Operand; b: Operand }
66
+ | { kind: 'mul'; dst: Temp; a: Operand; b: Operand }
67
+ | { kind: 'div'; dst: Temp; a: Operand; b: Operand }
68
+ | { kind: 'mod'; dst: Temp; a: Operand; b: Operand }
69
+ | { kind: 'neg'; dst: Temp; src: Operand }
70
+
71
+ // ── Comparison (result is 0 or 1) ────────────────────────────────────────
72
+ | { kind: 'cmp'; dst: Temp; op: CmpOp; a: Operand; b: Operand }
73
+
74
+ // ── Boolean logic ────────────────────────────────────────────────────────
75
+ | { kind: 'and'; dst: Temp; a: Operand; b: Operand }
76
+ | { kind: 'or'; dst: Temp; a: Operand; b: Operand }
77
+ | { kind: 'not'; dst: Temp; src: Operand }
78
+
79
+ // ── NBT storage ──────────────────────────────────────────────────────────
80
+ | { kind: 'nbt_read'; dst: Temp; ns: string; path: string; scale: number }
81
+ | { kind: 'nbt_write'; ns: string; path: string; type: NBTType; scale: number; src: Operand }
82
+
83
+ // ── Function calls ────────────────────────────────────────────────────────
84
+ | { kind: 'call'; dst: Temp | null; fn: string; args: Operand[] }
85
+ | { kind: 'call_macro'; dst: Temp | null; fn: string; args: { name: string; value: Operand; type: NBTType; scale: number }[] }
86
+ | { kind: 'call_context'; fn: string; subcommands: ExecuteSubcmd[] }
87
+
88
+ // ── Terminators (exactly one per basic block, must be last) ──────────────
89
+ | { kind: 'jump'; target: BlockId }
90
+ | { kind: 'branch'; cond: Operand; then: BlockId; else: BlockId }
91
+ | { kind: 'return'; value: Operand | null }
92
+ )
93
+
94
+ // ---------------------------------------------------------------------------
95
+ // Basic block and function structure
96
+ // ---------------------------------------------------------------------------
97
+
98
+ export interface MIRBlock {
99
+ id: BlockId
100
+ instrs: MIRInstr[] // non-terminator instructions
101
+ term: MIRInstr // must be jump | branch | return
102
+ preds: BlockId[] // predecessor block ids (for dataflow)
103
+ }
104
+
105
+ export interface MIRFunction {
106
+ name: string
107
+ params: { name: Temp; isMacroParam: boolean }[]
108
+ blocks: MIRBlock[]
109
+ entry: BlockId // entry block id (always 'entry')
110
+ isMacro: boolean // true if any param is a macro param
111
+ }
112
+
113
+ export interface MIRModule {
114
+ functions: MIRFunction[]
115
+ namespace: string
116
+ objective: string // scoreboard objective (default: __<namespace>)
117
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * MIR Verifier — validates structural invariants of MIR modules.
3
+ *
4
+ * Checks:
5
+ * 1. Every block ends with exactly one terminator (jump | branch | return)
6
+ * 2. Every temp used is defined before use (in the block or as a param)
7
+ * 3. No unreachable blocks (all blocks reachable from entry)
8
+ * 4. Branch/jump targets must exist in the function
9
+ */
10
+
11
+ import type { MIRModule, MIRFunction, MIRBlock, MIRInstr, Operand, Temp } from './types'
12
+
13
+ export interface VerifyError {
14
+ fn: string
15
+ block?: string
16
+ message: string
17
+ }
18
+
19
+ export function verifyMIR(module: MIRModule): VerifyError[] {
20
+ const errors: VerifyError[] = []
21
+ for (const fn of module.functions) {
22
+ errors.push(...verifyFunction(fn))
23
+ }
24
+ return errors
25
+ }
26
+
27
+ function verifyFunction(fn: MIRFunction): VerifyError[] {
28
+ const errors: VerifyError[] = []
29
+
30
+ const blockIds = new Set(fn.blocks.map(b => b.id))
31
+
32
+ // 1. Check terminators
33
+ for (const block of fn.blocks) {
34
+ if (!isTerminator(block.term)) {
35
+ errors.push({
36
+ fn: fn.name,
37
+ block: block.id,
38
+ message: `block '${block.id}' does not end with a terminator (found '${block.term.kind}')`,
39
+ })
40
+ }
41
+
42
+ // Check that no non-terminator instruction is a terminator
43
+ for (const instr of block.instrs) {
44
+ if (isTerminator(instr)) {
45
+ errors.push({
46
+ fn: fn.name,
47
+ block: block.id,
48
+ message: `block '${block.id}' has terminator '${instr.kind}' in non-terminal position`,
49
+ })
50
+ }
51
+ }
52
+ }
53
+
54
+ // 2. Check that branch/jump targets exist
55
+ for (const block of fn.blocks) {
56
+ const targets = getTermTargets(block.term)
57
+ for (const target of targets) {
58
+ if (!blockIds.has(target)) {
59
+ errors.push({
60
+ fn: fn.name,
61
+ block: block.id,
62
+ message: `block '${block.id}' references non-existent target '${target}'`,
63
+ })
64
+ }
65
+ }
66
+ }
67
+
68
+ // 3. Check reachability from entry
69
+ const reachable = new Set<string>()
70
+ const entryBlock = fn.blocks.find(b => b.id === fn.entry)
71
+ if (!entryBlock) {
72
+ errors.push({
73
+ fn: fn.name,
74
+ message: `entry block '${fn.entry}' not found`,
75
+ })
76
+ } else {
77
+ // BFS from entry
78
+ const queue: string[] = [fn.entry]
79
+ while (queue.length > 0) {
80
+ const id = queue.shift()!
81
+ if (reachable.has(id)) continue
82
+ reachable.add(id)
83
+
84
+ const block = fn.blocks.find(b => b.id === id)
85
+ if (block) {
86
+ for (const target of getTermTargets(block.term)) {
87
+ if (!reachable.has(target)) {
88
+ queue.push(target)
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ for (const block of fn.blocks) {
95
+ if (!reachable.has(block.id)) {
96
+ errors.push({
97
+ fn: fn.name,
98
+ block: block.id,
99
+ message: `block '${block.id}' is unreachable from entry`,
100
+ })
101
+ }
102
+ }
103
+ }
104
+
105
+ // 4. Check use-before-def for temporaries
106
+ // Collect all defined temps: params + all dst fields in instructions
107
+ const allDefs = new Set<Temp>()
108
+ for (const p of fn.params) allDefs.add(p.name)
109
+ for (const block of fn.blocks) {
110
+ for (const instr of block.instrs) {
111
+ const dst = getDst(instr)
112
+ if (dst) allDefs.add(dst)
113
+ }
114
+ const termDst = getDst(block.term)
115
+ if (termDst) allDefs.add(termDst)
116
+ }
117
+
118
+ // Check that every temp used in an operand is in allDefs
119
+ for (const block of fn.blocks) {
120
+ for (const instr of block.instrs) {
121
+ for (const used of getUsedTemps(instr)) {
122
+ if (!allDefs.has(used)) {
123
+ errors.push({
124
+ fn: fn.name,
125
+ block: block.id,
126
+ message: `temp '${used}' used but never defined`,
127
+ })
128
+ }
129
+ }
130
+ }
131
+ for (const used of getUsedTemps(block.term)) {
132
+ if (!allDefs.has(used)) {
133
+ errors.push({
134
+ fn: fn.name,
135
+ block: block.id,
136
+ message: `temp '${used}' used in terminator but never defined`,
137
+ })
138
+ }
139
+ }
140
+ }
141
+
142
+ return errors
143
+ }
144
+
145
+ function isTerminator(instr: MIRInstr): boolean {
146
+ return instr.kind === 'jump' || instr.kind === 'branch' || instr.kind === 'return'
147
+ }
148
+
149
+ function getTermTargets(term: MIRInstr): string[] {
150
+ switch (term.kind) {
151
+ case 'jump': return [term.target]
152
+ case 'branch': return [term.then, term.else]
153
+ case 'return': return []
154
+ default: return []
155
+ }
156
+ }
157
+
158
+ function getDst(instr: MIRInstr): Temp | null {
159
+ switch (instr.kind) {
160
+ case 'const':
161
+ case 'copy':
162
+ case 'add': case 'sub': case 'mul': case 'div': case 'mod':
163
+ case 'neg':
164
+ case 'cmp':
165
+ case 'and': case 'or': case 'not':
166
+ case 'nbt_read':
167
+ return instr.dst
168
+ case 'call':
169
+ case 'call_macro':
170
+ return instr.dst
171
+ default:
172
+ return null
173
+ }
174
+ }
175
+
176
+ function getOperandTemps(op: Operand): Temp[] {
177
+ return op.kind === 'temp' ? [op.name] : []
178
+ }
179
+
180
+ function getUsedTemps(instr: MIRInstr): Temp[] {
181
+ const temps: Temp[] = []
182
+ switch (instr.kind) {
183
+ case 'const':
184
+ break
185
+ case 'copy':
186
+ case 'neg':
187
+ case 'not':
188
+ temps.push(...getOperandTemps(instr.src))
189
+ break
190
+ case 'add': case 'sub': case 'mul': case 'div': case 'mod':
191
+ case 'cmp':
192
+ case 'and': case 'or':
193
+ temps.push(...getOperandTemps(instr.a), ...getOperandTemps(instr.b))
194
+ break
195
+ case 'nbt_read':
196
+ break
197
+ case 'nbt_write':
198
+ temps.push(...getOperandTemps(instr.src))
199
+ break
200
+ case 'call':
201
+ for (const arg of instr.args) temps.push(...getOperandTemps(arg))
202
+ break
203
+ case 'call_macro':
204
+ for (const arg of instr.args) temps.push(...getOperandTemps(arg.value))
205
+ break
206
+ case 'call_context':
207
+ break
208
+ case 'jump':
209
+ break
210
+ case 'branch':
211
+ temps.push(...getOperandTemps(instr.cond))
212
+ break
213
+ case 'return':
214
+ if (instr.value) temps.push(...getOperandTemps(instr.value))
215
+ break
216
+ }
217
+ return temps
218
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Block Merging — MIR optimization pass.
3
+ *
4
+ * Merges a block B into its sole predecessor A when:
5
+ * - A ends with an unconditional jump to B
6
+ * - B has exactly one predecessor (A)
7
+ * - B is not the entry block
8
+ *
9
+ * The merged block keeps A's id and combines A's instrs + B's instrs + B's terminator.
10
+ */
11
+
12
+ import type { MIRFunction, MIRBlock, BlockId } from '../mir/types'
13
+
14
+ export function blockMerge(fn: MIRFunction): MIRFunction {
15
+ let blocks = fn.blocks
16
+
17
+ // Iterate until no more merges possible
18
+ let changed = true
19
+ while (changed) {
20
+ changed = false
21
+ const blockMap = new Map(blocks.map(b => [b.id, b]))
22
+ const predCounts = computePredCounts(blocks)
23
+
24
+ const newBlocks: MIRBlock[] = []
25
+ const removed = new Set<BlockId>()
26
+
27
+ for (const block of blocks) {
28
+ if (removed.has(block.id)) continue
29
+
30
+ // Check: does this block jump unconditionally to a single-pred successor?
31
+ if (block.term.kind === 'jump') {
32
+ const targetId = block.term.target
33
+ const target = blockMap.get(targetId)
34
+ if (target && targetId !== fn.entry && predCounts.get(targetId) === 1) {
35
+ // Merge target into this block
36
+ const merged: MIRBlock = {
37
+ id: block.id,
38
+ instrs: [...block.instrs, ...target.instrs],
39
+ term: target.term,
40
+ preds: block.preds,
41
+ }
42
+ newBlocks.push(merged)
43
+ removed.add(targetId)
44
+ changed = true
45
+ continue
46
+ }
47
+ }
48
+
49
+ newBlocks.push(block)
50
+ }
51
+
52
+ blocks = newBlocks
53
+ }
54
+
55
+ // Recompute preds after merging
56
+ blocks = recomputePreds(blocks)
57
+
58
+ return { ...fn, blocks }
59
+ }
60
+
61
+ function computePredCounts(blocks: MIRBlock[]): Map<BlockId, number> {
62
+ const counts = new Map<BlockId, number>()
63
+ for (const b of blocks) counts.set(b.id, 0)
64
+
65
+ for (const block of blocks) {
66
+ for (const target of getTermTargets(block.term)) {
67
+ counts.set(target, (counts.get(target) ?? 0) + 1)
68
+ }
69
+ }
70
+ return counts
71
+ }
72
+
73
+ function recomputePreds(blocks: MIRBlock[]): MIRBlock[] {
74
+ const predMap = new Map<BlockId, BlockId[]>()
75
+ for (const b of blocks) predMap.set(b.id, [])
76
+
77
+ for (const block of blocks) {
78
+ for (const target of getTermTargets(block.term)) {
79
+ const preds = predMap.get(target)
80
+ if (preds) preds.push(block.id)
81
+ }
82
+ }
83
+
84
+ return blocks.map(b => ({ ...b, preds: predMap.get(b.id) ?? [] }))
85
+ }
86
+
87
+ function getTermTargets(term: MIRBlock['term']): BlockId[] {
88
+ switch (term.kind) {
89
+ case 'jump': return [term.target]
90
+ case 'branch': return [term.then, term.else]
91
+ default: return []
92
+ }
93
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Branch Simplification — MIR optimization pass.
3
+ *
4
+ * Replaces `branch(const, then, else)` with an unconditional `jump`:
5
+ * - branch(nonzero, then, else) → jump(then)
6
+ * - branch(0, then, else) → jump(else)
7
+ */
8
+
9
+ import type { MIRFunction, MIRBlock } from '../mir/types'
10
+
11
+ export function branchSimplify(fn: MIRFunction): MIRFunction {
12
+ return {
13
+ ...fn,
14
+ blocks: fn.blocks.map(simplifyBlock),
15
+ }
16
+ }
17
+
18
+ function simplifyBlock(block: MIRBlock): MIRBlock {
19
+ if (block.term.kind !== 'branch') return block
20
+ if (block.term.cond.kind !== 'const') return block
21
+
22
+ const target = block.term.cond.value !== 0 ? block.term.then : block.term.else
23
+ return {
24
+ ...block,
25
+ term: { kind: 'jump', target },
26
+ }
27
+ }