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
package/src/cli.ts CHANGED
@@ -9,10 +9,14 @@
9
9
  * redscript version
10
10
  */
11
11
 
12
- import { compile, check } from './index'
12
+ import { compile, checkWithWarnings } from './index'
13
13
  import { formatError } from './diagnostics'
14
+ import { parseMcVersion, DEFAULT_MC_VERSION } from './types/mc-version'
14
15
  import { startRepl } from './repl'
15
16
  import { generateDts } from './builtins/metadata'
17
+ import { FileCache } from './cache/index'
18
+ import { DependencyGraph } from './cache/deps'
19
+ import { compileIncremental } from './cache/incremental'
16
20
  import * as fs from 'fs'
17
21
  import * as path from 'path'
18
22
  import * as https from 'https'
@@ -49,6 +53,10 @@ Options:
49
53
  --namespace <ns> Datapack namespace (default: derived from filename)
50
54
  --hot-reload <url> After each successful compile, POST to <url>/reload
51
55
  (use with redscript-testharness; e.g. http://localhost:25561)
56
+ --source-map Generate .sourcemap.json files alongside .mcfunction output
57
+ --mc-version <ver> Target Minecraft version (default: 1.21). Affects codegen features.
58
+ e.g. --mc-version 1.20.2, --mc-version 1.19
59
+ --lenient Treat type errors as warnings instead of blocking compilation
52
60
  -h, --help Show this help message
53
61
  `)
54
62
  }
@@ -150,6 +158,9 @@ function parseArgs(args: string[]): {
150
158
  namespace?: string
151
159
  help?: boolean
152
160
  hotReload?: string
161
+ sourceMap?: boolean
162
+ mcVersionStr?: string
163
+ lenient?: boolean
153
164
  } {
154
165
  const result: ReturnType<typeof parseArgs> = {}
155
166
  let i = 0
@@ -169,6 +180,15 @@ function parseArgs(args: string[]): {
169
180
  } else if (arg === '--hot-reload') {
170
181
  result.hotReload = args[++i]
171
182
  i++
183
+ } else if (arg === '--source-map') {
184
+ result.sourceMap = true
185
+ i++
186
+ } else if (arg === '--mc-version') {
187
+ result.mcVersionStr = args[++i]
188
+ i++
189
+ } else if (arg === '--lenient') {
190
+ result.lenient = true
191
+ i++
172
192
  } else if (!result.command) {
173
193
  result.command = arg
174
194
  i++
@@ -193,6 +213,9 @@ function compileCommand(
193
213
  file: string,
194
214
  output: string,
195
215
  namespace: string,
216
+ sourceMap = false,
217
+ mcVersionStr?: string,
218
+ lenient = false,
196
219
  ): void {
197
220
  // Read source file
198
221
  if (!fs.existsSync(file)) {
@@ -200,10 +223,20 @@ function compileCommand(
200
223
  process.exit(1)
201
224
  }
202
225
 
226
+ let mcVersion = DEFAULT_MC_VERSION
227
+ if (mcVersionStr) {
228
+ try {
229
+ mcVersion = parseMcVersion(mcVersionStr)
230
+ } catch (e) {
231
+ console.error(`Error: ${(e as Error).message}`)
232
+ process.exit(1)
233
+ }
234
+ }
235
+
203
236
  const source = fs.readFileSync(file, 'utf-8')
204
237
 
205
238
  try {
206
- const result = compile(source, { namespace, filePath: file })
239
+ const result = compile(source, { namespace, filePath: file, generateSourceMap: sourceMap, mcVersion, lenient })
207
240
 
208
241
  for (const w of result.warnings) {
209
242
  console.error(`Warning: ${w}`)
@@ -224,12 +257,12 @@ function compileCommand(
224
257
  console.log(` Namespace: ${namespace}`)
225
258
  console.log(` Files: ${result.files.length}`)
226
259
  } catch (err) {
227
- console.error(formatError(err as Error, source))
260
+ console.error(formatError(err as Error, source, file))
228
261
  process.exit(1)
229
262
  }
230
263
  }
231
264
 
232
- function checkCommand(file: string): void {
265
+ function checkCommand(file: string, namespace?: string): void {
233
266
  // Read source file
234
267
  if (!fs.existsSync(file)) {
235
268
  console.error(`Error: File not found: ${file}`)
@@ -238,13 +271,19 @@ function checkCommand(file: string): void {
238
271
 
239
272
  const source = fs.readFileSync(file, 'utf-8')
240
273
 
241
- const error = check(source, 'redscript', file)
242
- if (error) {
243
- console.error(formatError(error, source))
274
+ const ns = namespace ?? deriveNamespace(file)
275
+ const result = checkWithWarnings(source, ns, file)
276
+
277
+ for (const w of result.warnings) {
278
+ console.error(`Warning: ${w}`)
279
+ }
280
+
281
+ if (result.error) {
282
+ console.error(formatError(result.error, source, file))
244
283
  process.exit(1)
245
284
  }
246
285
 
247
- console.log(`✓ ${file} is valid`)
286
+ console.log(`✓ No errors found`)
248
287
  }
249
288
 
250
289
  async function hotReload(url: string): Promise<void> {
@@ -276,54 +315,55 @@ function watchCommand(dir: string, output: string, namespace?: string, hotReload
276
315
  console.log(`👁 Watching ${dir} for .mcrs file changes...`)
277
316
  console.log(` Output: ${output}`)
278
317
  if (hotReloadUrl) console.log(` Hot reload: ${hotReloadUrl}`)
318
+ console.log(` Incremental compilation enabled`)
279
319
  console.log(` Press Ctrl+C to stop\n`)
280
320
 
321
+ // Set up incremental compilation infrastructure
322
+ const cacheDir = path.join(dir, '.redscript-cache')
323
+ const cache = new FileCache(cacheDir)
324
+ cache.load()
325
+ const depGraph = new DependencyGraph()
326
+
281
327
  // Debounce timer
282
328
  let debounceTimer: NodeJS.Timeout | null = null
283
329
 
284
- // Compile all .mcrs files in directory
285
- async function compileAll(): Promise<void> {
330
+ // Compile all .mcrs files in directory (incrementally)
331
+ async function compileAllIncremental(): Promise<void> {
286
332
  const files = findRsFiles(dir)
287
333
  if (files.length === 0) {
288
334
  console.log(`⚠ No .mcrs files found in ${dir}`)
289
335
  return
290
336
  }
291
337
 
292
- let hasErrors = false
293
- for (const file of files) {
294
- let source = ''
295
- try {
296
- source = fs.readFileSync(file, 'utf-8')
297
- const ns = namespace ?? deriveNamespace(file)
298
- const result = compile(source, { namespace: ns, filePath: file })
299
- for (const w of result.warnings) {
300
- console.error(`Warning: ${w}`)
301
- }
302
-
303
- // Create output directory
304
- fs.mkdirSync(output, { recursive: true })
305
-
306
- // Write all files
307
- for (const dataFile of result.files) {
308
- const filePath = path.join(output, dataFile.path)
309
- const fileDir = path.dirname(filePath)
310
- fs.mkdirSync(fileDir, { recursive: true })
311
- fs.writeFileSync(filePath, dataFile.content)
312
- }
313
-
314
- const timestamp = new Date().toLocaleTimeString()
315
- console.log(`✓ [${timestamp}] Compiled ${file} (${result.files.length} files)`)
316
- } catch (err) {
317
- hasErrors = true
318
- const timestamp = new Date().toLocaleTimeString()
319
- console.error(`✗ [${timestamp}] ${formatError(err as Error, source)}`)
338
+ const incResult = compileIncremental(files, cache, depGraph, {
339
+ namespace,
340
+ output,
341
+ })
342
+
343
+ const timestamp = new Date().toLocaleTimeString()
344
+
345
+ // Print warnings from recompiled files
346
+ for (const [file, compileResult] of incResult.results) {
347
+ for (const w of compileResult.warnings) {
348
+ console.error(`Warning: ${w}`)
320
349
  }
350
+ console.log(`✓ [${timestamp}] Compiled ${path.relative(dir, file)} (${compileResult.files.length} files)`)
321
351
  }
322
352
 
323
- if (!hasErrors) {
324
- if (hotReloadUrl) await hotReload(hotReloadUrl)
325
- console.log('')
353
+ if (incResult.cached > 0) {
354
+ console.log(` [${timestamp}] ${incResult.cached} file(s) unchanged (cached)`)
326
355
  }
356
+
357
+ // Print errors
358
+ for (const [file, errMsg] of incResult.errors) {
359
+ console.error(`✗ [${timestamp}] ${path.relative(dir, file)}: ${errMsg}`)
360
+ }
361
+
362
+ // Persist cache
363
+ cache.save()
364
+
365
+ if (incResult.errors.size === 0 && hotReloadUrl) await hotReload(hotReloadUrl)
366
+ console.log('')
327
367
  }
328
368
 
329
369
  // Find all .mcrs files recursively
@@ -333,7 +373,7 @@ function watchCommand(dir: string, output: string, namespace?: string, hotReload
333
373
 
334
374
  for (const entry of entries) {
335
375
  const fullPath = path.join(directory, entry.name)
336
- if (entry.isDirectory()) {
376
+ if (entry.isDirectory() && entry.name !== '.redscript-cache') {
337
377
  results.push(...findRsFiles(fullPath))
338
378
  } else if (entry.isFile() && entry.name.endsWith('.mcrs')) {
339
379
  results.push(fullPath)
@@ -344,7 +384,7 @@ function watchCommand(dir: string, output: string, namespace?: string, hotReload
344
384
  }
345
385
 
346
386
  // Initial compile
347
- void compileAll()
387
+ void compileAllIncremental()
348
388
 
349
389
  // Watch for changes
350
390
  fs.watch(dir, { recursive: true }, (eventType, filename) => {
@@ -355,7 +395,7 @@ function watchCommand(dir: string, output: string, namespace?: string, hotReload
355
395
  }
356
396
  debounceTimer = setTimeout(() => {
357
397
  console.log(`📝 Change detected: ${filename}`)
358
- void compileAll()
398
+ void compileAllIncremental()
359
399
  }, 100)
360
400
  }
361
401
  })
@@ -392,6 +432,9 @@ async function main(): Promise<void> {
392
432
  parsed.file,
393
433
  output,
394
434
  namespace,
435
+ parsed.sourceMap,
436
+ parsed.mcVersionStr,
437
+ parsed.lenient,
395
438
  )
396
439
  }
397
440
  break
@@ -416,7 +459,7 @@ async function main(): Promise<void> {
416
459
  printUsage()
417
460
  process.exit(1)
418
461
  }
419
- checkCommand(parsed.file)
462
+ checkCommand(parsed.file, parsed.namespace)
420
463
  break
421
464
 
422
465
  case 'fmt':
package/src/compile.ts CHANGED
@@ -13,8 +13,8 @@ import { DiagnosticError } from './diagnostics'
13
13
  // Re-export v2 compile
14
14
  // ---------------------------------------------------------------------------
15
15
 
16
- export { compile, CompileOptions, CompileResult } from '../src2/emit/compile'
17
- export type { DatapackFile } from '../src2/emit/index'
16
+ export { compile, CompileOptions, CompileResult } from './emit/compile'
17
+ export type { DatapackFile } from './emit/index'
18
18
 
19
19
  // ---------------------------------------------------------------------------
20
20
  // Source Range / Preprocessing
@@ -161,26 +161,23 @@ export function parseErrorMessage(
161
161
  return new DiagnosticError(kind, rawMessage, { file: filePath, line: 1, col: 1 }, sourceLines)
162
162
  }
163
163
 
164
- export function formatError(error: Error | DiagnosticError, source?: string): string {
164
+ export function formatError(error: Error | DiagnosticError, source?: string, filePath?: string): string {
165
165
  if (error instanceof DiagnosticError) {
166
166
  const sourceLines = source?.split('\n') ?? error.sourceLines ?? []
167
167
  const { file, line, col } = error.location
168
- const locationPart = file
169
- ? ` in ${file} at line ${line}, col ${col}`
170
- : ` at line ${line}, col ${col}`
171
- const lines = [`Error${locationPart}:`]
168
+ const fileStr = file ?? filePath ?? '<input>'
169
+ const header = `${fileStr}:${line}:${col}: error: ${error.message}`
172
170
  const pointerLines = formatSourcePointer(sourceLines, line, col)
173
- if (pointerLines.length > 0) {
174
- lines.push(...pointerLines)
171
+ if (pointerLines.length === 0) {
172
+ return header
175
173
  }
176
- lines.push(error.message)
177
- return lines.join('\n')
174
+ return [header, ...pointerLines].join('\n')
178
175
  }
179
176
 
180
177
  if (!source) {
181
178
  return error.message
182
179
  }
183
180
 
184
- const parsed = parseErrorMessage('ParseError', error.message, source.split('\n'))
185
- return formatError(parsed, source)
181
+ const parsed = parseErrorMessage('ParseError', error.message, source.split('\n'), filePath)
182
+ return formatError(parsed, source, filePath)
186
183
  }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Top-level compile function for the v2 pipeline.
3
+ *
4
+ * Pipeline: source → Lexer → Parser → TypeCheck → HIR → MIR → optimize → LIR → emit
5
+ */
6
+
7
+ import { Lexer } from '../lexer'
8
+ import { Parser } from '../parser'
9
+ import { preprocessSourceWithMetadata } from '../compile'
10
+ import { DiagnosticError, parseErrorMessage } from '../diagnostics'
11
+ import { lowerToHIR } from '../hir/lower'
12
+ import { monomorphize } from '../hir/monomorphize'
13
+ import { lowerToMIR } from '../mir/lower'
14
+ import { optimizeModule } from '../optimizer/pipeline'
15
+ import { lowerToLIR } from '../lir/lower'
16
+ import { lirOptimizeModule } from '../optimizer/lir/pipeline'
17
+ import { emit, type DatapackFile } from './index'
18
+ import { coroutineTransform, type CoroutineInfo } from '../optimizer/coroutine'
19
+ import { analyzeBudget } from '../lir/budget'
20
+ import { McVersion, DEFAULT_MC_VERSION } from '../types/mc-version'
21
+ import { TypeChecker } from '../typechecker'
22
+
23
+ export interface CompileOptions {
24
+ namespace?: string
25
+ filePath?: string
26
+ /** v1 compat: inline library sources (treated as `module library;` imports) */
27
+ librarySources?: string[]
28
+ /** When true, generate .sourcemap.json files alongside .mcfunction output */
29
+ generateSourceMap?: boolean
30
+ /** Target Minecraft version (default: 1.21). Affects which MC features are used. */
31
+ mcVersion?: McVersion
32
+ /**
33
+ * When true, type errors are reported as warnings instead of blocking compilation.
34
+ * Use for gradual migration or testing with existing codebases that have type errors.
35
+ */
36
+ lenient?: boolean
37
+ }
38
+
39
+ export interface CompileResult {
40
+ files: DatapackFile[]
41
+ warnings: string[]
42
+ /** Always true — v1 compat shim (compile() throws on error) */
43
+ readonly success: true
44
+ }
45
+
46
+ export function compile(source: string, options: CompileOptions = {}): CompileResult {
47
+ const { namespace = 'redscript', filePath, generateSourceMap = false, mcVersion = DEFAULT_MC_VERSION, lenient = false } = options
48
+ const warnings: string[] = []
49
+
50
+ // Preprocess: resolve import directives, merge imported sources
51
+ const preprocessed = preprocessSourceWithMetadata(source, { filePath })
52
+ const processedSource = preprocessed.source
53
+
54
+ // Stage 1: Lex + Parse → AST
55
+ const lexer = new Lexer(processedSource)
56
+ const tokens = lexer.tokenize()
57
+ const parser = new Parser(tokens, processedSource, filePath)
58
+ const ast = parser.parse(namespace)
59
+
60
+ // Merge library imports (files with `module library;`) into AST
61
+ for (const li of preprocessed.libraryImports ?? []) {
62
+ const libPreprocessed = preprocessSourceWithMetadata(li.source, { filePath: li.filePath })
63
+ const libTokens = new Lexer(libPreprocessed.source, li.filePath).tokenize()
64
+ const libAst = new Parser(libTokens, libPreprocessed.source, li.filePath).parse(namespace)
65
+ for (const fn of libAst.declarations) fn.isLibraryFn = true
66
+ ast.declarations.push(...libAst.declarations)
67
+ ast.structs.push(...libAst.structs)
68
+ ast.implBlocks.push(...libAst.implBlocks)
69
+ ast.enums.push(...libAst.enums)
70
+ ast.consts.push(...libAst.consts)
71
+ ast.globals.push(...libAst.globals)
72
+ }
73
+
74
+ // Merge librarySources (v1 compat: inline library strings) before HIR
75
+ if (options.librarySources) {
76
+ for (const libSrc of options.librarySources) {
77
+ const libTokens = new Lexer(libSrc).tokenize()
78
+ const libAst = new Parser(libTokens, libSrc).parse(namespace)
79
+ for (const fn of libAst.declarations) fn.isLibraryFn = true
80
+ ast.declarations.push(...libAst.declarations)
81
+ ast.structs.push(...libAst.structs)
82
+ ast.implBlocks.push(...libAst.implBlocks)
83
+ ast.enums.push(...libAst.enums)
84
+ ast.consts.push(...libAst.consts)
85
+ ast.globals.push(...libAst.globals)
86
+ }
87
+ }
88
+
89
+ // Stage 1b: Type checking
90
+ // Run TypeChecker on the merged AST. In error-mode (default), throw on first type error.
91
+ // In lenient mode, demote type errors to warnings.
92
+ {
93
+ const checker = new TypeChecker(processedSource, filePath)
94
+ const typeErrors = checker.check(ast)
95
+ if (typeErrors.length > 0) {
96
+ if (lenient) {
97
+ for (const e of typeErrors) {
98
+ warnings.push(`[TypeError] line ${e.location.line}, col ${e.location.col}: ${e.message}`)
99
+ }
100
+ } else {
101
+ throw typeErrors[0]
102
+ }
103
+ }
104
+ }
105
+
106
+ // Stage 2–7: lower, optimize, emit
107
+ // Wrap non-DiagnosticError from later stages so CLI always gets structured errors.
108
+ try {
109
+ // Stage 2: AST → HIR
110
+ const hirRaw = lowerToHIR(ast)
111
+
112
+ // Stage 2b: Monomorphize generic functions
113
+ const hir = monomorphize(hirRaw)
114
+
115
+ // Extract @tick, @load, @coroutine, and @schedule functions from HIR (before decorator info is lost)
116
+ const tickFunctions: string[] = []
117
+ const loadFunctions: string[] = []
118
+ const coroutineInfos: CoroutineInfo[] = []
119
+ const scheduleFunctions: Array<{ name: string; ticks: number }> = []
120
+ for (const fn of hir.functions) {
121
+ for (const dec of fn.decorators) {
122
+ if (dec.name === 'tick') tickFunctions.push(fn.name)
123
+ if (dec.name === 'load') loadFunctions.push(fn.name)
124
+ if (dec.name === 'coroutine') {
125
+ coroutineInfos.push({
126
+ fnName: fn.name,
127
+ batch: dec.args?.batch ?? 10,
128
+ onDone: dec.args?.onDone,
129
+ })
130
+ }
131
+ if (dec.name === 'schedule') {
132
+ scheduleFunctions.push({ name: fn.name, ticks: dec.args?.ticks ?? 1 })
133
+ }
134
+ }
135
+ }
136
+
137
+ // Stage 3: HIR → MIR
138
+ const mir = lowerToMIR(hir, filePath)
139
+
140
+ // Stage 4: MIR optimization
141
+ const mirOpt = optimizeModule(mir)
142
+
143
+ // Stage 4b: Coroutine transform (opt-in, only for @coroutine functions)
144
+ const coroResult = coroutineTransform(mirOpt, coroutineInfos)
145
+ const mirFinal = coroResult.module
146
+ tickFunctions.push(...coroResult.generatedTickFunctions)
147
+
148
+ // Stage 5: MIR → LIR
149
+ const lir = lowerToLIR(mirFinal)
150
+
151
+ // Stage 6: LIR optimization
152
+ const lirOpt = lirOptimizeModule(lir)
153
+
154
+ // Static tick budget analysis
155
+ const coroutineNames = new Set(coroutineInfos.map(c => c.fnName))
156
+ const budgetDiags = analyzeBudget(lirOpt, coroutineNames)
157
+ for (const diag of budgetDiags) {
158
+ if (diag.level === 'error') {
159
+ throw new DiagnosticError(
160
+ 'LoweringError',
161
+ diag.message,
162
+ { line: 1, col: 1, file: filePath },
163
+ )
164
+ }
165
+ warnings.push(diag.message)
166
+ }
167
+
168
+ // Stage 7: LIR → .mcfunction
169
+ const files = emit(lirOpt, { namespace, tickFunctions, loadFunctions, scheduleFunctions, generateSourceMap, mcVersion })
170
+
171
+ return { files, warnings, success: true as const }
172
+ } catch (err) {
173
+ if (err instanceof DiagnosticError) throw err
174
+ const sourceLines = processedSource.split('\n')
175
+ throw parseErrorMessage('LoweringError', (err as Error).message, sourceLines, filePath)
176
+ }
177
+ }
@@ -6,6 +6,8 @@
6
6
  */
7
7
 
8
8
  import type { LIRModule, LIRFunction, LIRInstr, Slot, CmpOp, ExecuteSubcmd } from '../lir/types'
9
+ import { SourceMapBuilder, serializeSourceMap, sourceMapPath } from './sourcemap'
10
+ import { McVersion, DEFAULT_MC_VERSION } from '../types/mc-version'
9
11
 
10
12
  export interface DatapackFile {
11
13
  path: string
@@ -16,6 +18,11 @@ export interface EmitOptions {
16
18
  namespace: string
17
19
  tickFunctions?: string[]
18
20
  loadFunctions?: string[]
21
+ scheduleFunctions?: Array<{ name: string; ticks: number }>
22
+ /** When true, generate a .sourcemap.json sidecar file for each .mcfunction */
23
+ generateSourceMap?: boolean
24
+ /** Target Minecraft version; controls which MC features are used in codegen */
25
+ mcVersion?: McVersion
19
26
  }
20
27
 
21
28
  // ---------------------------------------------------------------------------
@@ -26,7 +33,10 @@ export function emit(module: LIRModule, options: EmitOptions): DatapackFile[] {
26
33
  const { namespace } = options
27
34
  const tickFns = options.tickFunctions ?? []
28
35
  const loadFns = options.loadFunctions ?? []
36
+ const scheduleFns = options.scheduleFunctions ?? []
29
37
  const objective = module.objective
38
+ const genSourceMap = options.generateSourceMap ?? false
39
+ const mcVersion = options.mcVersion ?? DEFAULT_MC_VERSION
30
40
  const files: DatapackFile[] = []
31
41
 
32
42
  // pack.mcmeta
@@ -46,9 +56,27 @@ export function emit(module: LIRModule, options: EmitOptions): DatapackFile[] {
46
56
 
47
57
  // Each LIR function → .mcfunction file
48
58
  for (const fn of module.functions) {
49
- const lines = emitFunction(fn, namespace, objective)
50
59
  const fnPath = fnNameToPath(fn.name, namespace)
51
- files.push({ path: fnPath, content: lines.join('\n') + '\n' })
60
+ if (genSourceMap) {
61
+ const builder = new SourceMapBuilder(fnPath)
62
+ const lines = emitFunctionWithSourceMap(fn, namespace, objective, builder, mcVersion)
63
+ files.push({ path: fnPath, content: lines.join('\n') + '\n' })
64
+ const map = builder.build()
65
+ if (map) {
66
+ files.push({ path: sourceMapPath(fnPath), content: serializeSourceMap(map) })
67
+ }
68
+ } else {
69
+ const lines = emitFunction(fn, namespace, objective, mcVersion)
70
+ files.push({ path: fnPath, content: lines.join('\n') + '\n' })
71
+ }
72
+ }
73
+
74
+ // @schedule wrapper functions: _schedule_xxx → schedule function ns:xxx Nt
75
+ for (const { name, ticks } of scheduleFns) {
76
+ files.push({
77
+ path: `data/${namespace}/function/_schedule_${name}.mcfunction`,
78
+ content: `schedule function ${namespace}:${name} ${ticks}t\n`,
79
+ })
52
80
  }
53
81
 
54
82
  // Tag files for tick/load
@@ -76,10 +104,25 @@ export function emit(module: LIRModule, options: EmitOptions): DatapackFile[] {
76
104
  // Function emission
77
105
  // ---------------------------------------------------------------------------
78
106
 
79
- function emitFunction(fn: LIRFunction, namespace: string, objective: string): string[] {
107
+ function emitFunction(fn: LIRFunction, namespace: string, objective: string, mcVersion: McVersion): string[] {
108
+ const lines: string[] = []
109
+ for (const instr of fn.instructions) {
110
+ lines.push(emitInstr(instr, namespace, objective, mcVersion))
111
+ }
112
+ return lines
113
+ }
114
+
115
+ function emitFunctionWithSourceMap(
116
+ fn: LIRFunction,
117
+ namespace: string,
118
+ objective: string,
119
+ builder: SourceMapBuilder,
120
+ mcVersion: McVersion,
121
+ ): string[] {
80
122
  const lines: string[] = []
81
123
  for (const instr of fn.instructions) {
82
- lines.push(emitInstr(instr, namespace, objective))
124
+ lines.push(emitInstr(instr, namespace, objective, mcVersion))
125
+ builder.addLine(instr.sourceLoc)
83
126
  }
84
127
  return lines
85
128
  }
@@ -94,7 +137,7 @@ function fnNameToPath(name: string, namespace: string): string {
94
137
  // Instruction emission
95
138
  // ---------------------------------------------------------------------------
96
139
 
97
- function emitInstr(instr: LIRInstr, ns: string, obj: string): string {
140
+ function emitInstr(instr: LIRInstr, ns: string, obj: string, mcVersion: McVersion): string {
98
141
  switch (instr.kind) {
99
142
  case 'score_set':
100
143
  return `scoreboard players set ${slot(instr.dst)} ${instr.value}`
@@ -127,7 +170,7 @@ function emitInstr(instr: LIRInstr, ns: string, obj: string): string {
127
170
  return `scoreboard players operation ${slot(instr.a)} >< ${slot(instr.b)}`
128
171
 
129
172
  case 'store_cmd_to_score':
130
- return `execute store result score ${slot(instr.dst)} run ${emitInstr(instr.cmd, ns, obj)}`
173
+ return `execute store result score ${slot(instr.dst)} run ${emitInstr(instr.cmd, ns, obj, mcVersion)}`
131
174
 
132
175
  case 'store_score_to_nbt':
133
176
  return `execute store result storage ${instr.ns} ${instr.path} ${instr.type} ${instr.scale} run scoreboard players get ${slot(instr.src)}`
@@ -145,7 +188,11 @@ function emitInstr(instr: LIRInstr, ns: string, obj: string): string {
145
188
  return `function ${instr.fn}`
146
189
 
147
190
  case 'call_macro':
148
- return `function ${instr.fn} with storage ${instr.storage}`
191
+ if (mcVersion >= McVersion.v1_20_2) {
192
+ return `function ${instr.fn} with storage ${instr.storage}`
193
+ }
194
+ // Pre-1.20.2: macros not supported; call function directly (args in storage are ignored)
195
+ return `function ${instr.fn}`
149
196
 
150
197
  case 'call_if_matches':
151
198
  return `execute if score ${slot(instr.slot)} matches ${instr.range} run function ${instr.fn}`
@@ -168,7 +215,13 @@ function emitInstr(instr: LIRInstr, ns: string, obj: string): string {
168
215
  return `scoreboard players operation $ret ${instr.slot.obj} = ${slot(instr.slot)}`
169
216
 
170
217
  case 'macro_line':
171
- return `$${instr.template}`
218
+ if (mcVersion >= McVersion.v1_20_2) {
219
+ return `$${instr.template}`
220
+ }
221
+ // Pre-1.20.2: function macros not available. Emit as a plain command with
222
+ // $(param) placeholders replaced by storage reads via data get (best-effort
223
+ // compat for string/id params; numeric coords will not be dynamic).
224
+ return macroLineCompat(instr.template)
172
225
 
173
226
  case 'raw':
174
227
  return instr.cmd
@@ -194,6 +247,17 @@ function cmpToMC(op: CmpOp): string {
194
247
  }
195
248
  }
196
249
 
250
+ /**
251
+ * Pre-1.20.2 compat: emit a macro template as a plain command.
252
+ * $(param) placeholders are replaced with `storage rs:macro_args <param>` data-get
253
+ * expressions for string/id values, or left as literal "0" for coordinates.
254
+ * This is best-effort — dynamic numeric positions cannot be truly emulated.
255
+ */
256
+ function macroLineCompat(template: string): string {
257
+ // Replace $(param) with data-get-style substitution marker
258
+ return template.replace(/\$\((\w+)\)/g, (_m, p) => `{storage:rs:macro_args,path:${p}}`)
259
+ }
260
+
197
261
  function emitSubcmd(sub: ExecuteSubcmd): string {
198
262
  switch (sub.kind) {
199
263
  case 'as':