redscript-mc 2.0.0 → 2.1.1

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 (643) hide show
  1. package/.claudeignore +21 -0
  2. package/README.md +48 -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 +321 -0
  22. package/dist/src/__tests__/mc-syntax.test.js +1 -6
  23. package/dist/src/__tests__/mc-version.test.d.ts +10 -0
  24. package/dist/src/__tests__/mc-version.test.js +154 -0
  25. package/dist/{src2 → src}/__tests__/mir/arithmetic.test.js +2 -2
  26. package/dist/{src2 → src}/__tests__/mir/control-flow.test.js +2 -2
  27. package/dist/src/__tests__/modules.test.d.ts +7 -0
  28. package/dist/src/__tests__/modules.test.js +333 -0
  29. package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
  30. package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
  31. package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
  32. package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
  33. package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
  34. package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
  35. package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
  36. package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
  37. package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
  38. package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
  39. package/dist/src/__tests__/option.test.d.ts +14 -0
  40. package/dist/src/__tests__/option.test.js +275 -0
  41. package/dist/src/__tests__/schedule.test.d.ts +7 -0
  42. package/dist/src/__tests__/schedule.test.js +98 -0
  43. package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
  44. package/dist/src/__tests__/sourcemap.test.js +227 -0
  45. package/dist/src/__tests__/stdlib-include.test.js +86 -0
  46. package/dist/src/__tests__/tuple.test.d.ts +11 -0
  47. package/dist/src/__tests__/tuple.test.js +202 -0
  48. package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
  49. package/dist/src/__tests__/typechecker-strict.test.js +197 -0
  50. package/dist/src/ast/types.d.ts +56 -2
  51. package/dist/src/cache/deps.d.ts +41 -0
  52. package/dist/src/cache/deps.js +158 -0
  53. package/dist/src/cache/incremental.d.ts +35 -0
  54. package/dist/src/cache/incremental.js +165 -0
  55. package/dist/src/cache/index.d.ts +37 -0
  56. package/dist/src/cache/index.js +152 -0
  57. package/dist/src/cli.js +83 -45
  58. package/dist/src/compile.d.ts +3 -2
  59. package/dist/src/compile.js +34 -11
  60. package/dist/src/diagnostics/index.d.ts +1 -1
  61. package/dist/src/diagnostics/index.js +8 -11
  62. package/dist/src/emit/compile.d.ts +31 -0
  63. package/dist/src/emit/compile.js +143 -0
  64. package/dist/{src2 → src}/emit/index.d.ts +9 -0
  65. package/dist/{src2 → src}/emit/index.js +59 -8
  66. package/dist/src/emit/modules.d.ts +29 -0
  67. package/dist/src/emit/modules.js +492 -0
  68. package/dist/src/emit/sourcemap.d.ts +53 -0
  69. package/dist/src/emit/sourcemap.js +73 -0
  70. package/dist/{src2 → src}/hir/lower.d.ts +1 -1
  71. package/dist/{src2 → src}/hir/lower.js +22 -1
  72. package/dist/src/hir/monomorphize.d.ts +22 -0
  73. package/dist/src/hir/monomorphize.js +379 -0
  74. package/dist/{src2 → src}/hir/types.d.ts +35 -2
  75. package/dist/src/index.d.ts +19 -2
  76. package/dist/src/index.js +36 -14
  77. package/dist/src/lexer/index.d.ts +1 -1
  78. package/dist/src/lexer/index.js +1 -0
  79. package/dist/src/lir/budget.d.ts +37 -0
  80. package/dist/src/lir/budget.js +280 -0
  81. package/dist/{src2 → src}/lir/lower.js +19 -0
  82. package/dist/{src2 → src}/lir/types.d.ts +7 -4
  83. package/dist/src/lsp/main.d.ts +8 -0
  84. package/dist/src/lsp/main.js +11 -0
  85. package/dist/src/lsp/server.d.ts +11 -0
  86. package/dist/src/lsp/server.js +403 -0
  87. package/dist/{src2 → src}/mir/lower.d.ts +1 -1
  88. package/dist/{src2 → src}/mir/lower.js +244 -10
  89. package/dist/{src2 → src}/mir/types.d.ts +10 -2
  90. package/dist/src/optimizer/coroutine.d.ts +34 -0
  91. package/dist/src/optimizer/coroutine.js +789 -0
  92. package/dist/src/optimizer/dce.d.ts +8 -34
  93. package/dist/src/optimizer/dce.js +146 -629
  94. package/dist/src/optimizer/interprocedural.d.ts +14 -0
  95. package/dist/src/optimizer/interprocedural.js +186 -0
  96. package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
  97. package/dist/src/optimizer/lir/const_imm.js +139 -0
  98. package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
  99. package/dist/src/optimizer/lir/dead_slot.js +130 -0
  100. package/dist/src/optimizer/lir/peephole.d.ts +21 -0
  101. package/dist/src/optimizer/lir/peephole.js +52 -0
  102. package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
  103. package/dist/src/optimizer/lir/pipeline.js +34 -0
  104. package/dist/src/optimizer/nbt-batch.d.ts +11 -0
  105. package/dist/src/optimizer/nbt-batch.js +51 -0
  106. package/dist/{src2 → src}/optimizer/pipeline.d.ts +4 -0
  107. package/dist/{src2 → src}/optimizer/pipeline.js +17 -1
  108. package/dist/src/optimizer/selector-cache.d.ts +22 -0
  109. package/dist/src/optimizer/selector-cache.js +100 -0
  110. package/dist/src/optimizer/unroll.d.ts +32 -0
  111. package/dist/src/optimizer/unroll.js +348 -0
  112. package/dist/src/parser/index.d.ts +8 -0
  113. package/dist/src/parser/index.js +204 -14
  114. package/dist/src/repl.d.ts +1 -1
  115. package/dist/src/typechecker/index.d.ts +4 -0
  116. package/dist/src/typechecker/index.js +198 -13
  117. package/dist/src/types/mc-version.d.ts +24 -0
  118. package/dist/src/types/mc-version.js +49 -0
  119. package/docs/ROADMAP.md +395 -0
  120. package/docs/compiler-pipeline-redesign.md +27 -10
  121. package/editors/vscode/out/extension.js +25176 -8000
  122. package/editors/vscode/package-lock.json +90 -6
  123. package/editors/vscode/package.json +3 -2
  124. package/editors/vscode/src/extension.ts +97 -67
  125. package/editors/vscode/syntaxes/redscript.tmLanguage.json +34 -0
  126. package/examples/coroutine-demo.mcrs +50 -0
  127. package/examples/enum-demo.mcrs +95 -0
  128. package/examples/scheduler-demo.mcrs +59 -0
  129. package/examples/showcase.mcrs +3 -3
  130. package/jest.config.js +1 -1
  131. package/package.json +9 -3
  132. package/src/__tests__/budget.test.ts +297 -0
  133. package/src/__tests__/diagnostics.test.ts +2 -3
  134. package/src/__tests__/e2e/coroutine.test.ts +142 -0
  135. package/{src2 → src}/__tests__/e2e/macros.test.ts +1 -1
  136. package/{src2 → src}/__tests__/e2e/migrate.test.ts +1 -1
  137. package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
  138. package/src/__tests__/enum.test.ts +425 -0
  139. package/src/__tests__/generics.test.ts +390 -0
  140. package/{src2 → src}/__tests__/hir/desugar.test.ts +2 -2
  141. package/src/__tests__/incremental.test.ts +337 -0
  142. package/src/__tests__/lsp.test.ts +359 -0
  143. package/src/__tests__/mc-syntax.test.ts +1 -7
  144. package/src/__tests__/mc-version.test.ts +178 -0
  145. package/{src2 → src}/__tests__/mir/arithmetic.test.ts +2 -2
  146. package/{src2 → src}/__tests__/mir/control-flow.test.ts +2 -2
  147. package/src/__tests__/modules.test.ts +365 -0
  148. package/src/__tests__/optimizer/coroutine.test.ts +312 -0
  149. package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
  150. package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
  151. package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
  152. package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
  153. package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
  154. package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
  155. package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
  156. package/src/__tests__/optimizer/unroll.test.ts +231 -0
  157. package/src/__tests__/option.test.ts +299 -0
  158. package/src/__tests__/schedule.test.ts +105 -0
  159. package/src/__tests__/sourcemap.test.ts +254 -0
  160. package/src/__tests__/stdlib-include.test.ts +61 -0
  161. package/src/__tests__/tuple.test.ts +220 -0
  162. package/src/__tests__/typechecker-strict.test.ts +216 -0
  163. package/src/ast/types.ts +33 -2
  164. package/src/cache/deps.ts +132 -0
  165. package/src/cache/incremental.ts +173 -0
  166. package/src/cache/index.ts +135 -0
  167. package/src/cli.ts +96 -45
  168. package/src/compile.ts +46 -17
  169. package/src/diagnostics/index.ts +8 -11
  170. package/src/emit/compile.ts +179 -0
  171. package/{src2 → src}/emit/index.ts +72 -8
  172. package/src/emit/modules.ts +581 -0
  173. package/src/emit/sourcemap.ts +101 -0
  174. package/{src2 → src}/hir/lower.ts +29 -2
  175. package/src/hir/monomorphize.ts +416 -0
  176. package/{src2 → src}/hir/types.ts +15 -3
  177. package/src/index.ts +29 -10
  178. package/src/lexer/index.ts +2 -1
  179. package/src/lir/budget.ts +321 -0
  180. package/{src2 → src}/lir/lower.ts +32 -1
  181. package/{src2 → src}/lir/types.ts +7 -3
  182. package/src/lsp/main.ts +9 -0
  183. package/src/lsp/server.ts +469 -0
  184. package/{src2 → src}/mir/lower.ts +251 -8
  185. package/{src2 → src}/mir/types.ts +12 -1
  186. package/src/optimizer/coroutine.ts +996 -0
  187. package/{src2 → src}/optimizer/dce.ts +2 -1
  188. package/src/optimizer/interprocedural.ts +177 -0
  189. package/src/optimizer/lir/const_imm.ts +143 -0
  190. package/src/optimizer/lir/dead_slot.ts +123 -0
  191. package/src/optimizer/lir/peephole.ts +57 -0
  192. package/src/optimizer/lir/pipeline.ts +37 -0
  193. package/src/optimizer/nbt-batch.ts +50 -0
  194. package/{src2 → src}/optimizer/pipeline.ts +16 -1
  195. package/src/optimizer/selector-cache.ts +103 -0
  196. package/src/optimizer/unroll.ts +386 -0
  197. package/src/parser/index.ts +212 -15
  198. package/src/repl.ts +1 -1
  199. package/src/stdlib/math.mcrs +4 -4
  200. package/src/templates/quest.mcrs +4 -4
  201. package/src/typechecker/index.ts +215 -15
  202. package/src/types/mc-version.ts +46 -0
  203. package/tsconfig.json +1 -1
  204. package/.claude/commands/build-test.md +0 -10
  205. package/.claude/commands/deploy-demo.md +0 -12
  206. package/.claude/commands/stage-status.md +0 -13
  207. package/.claude/settings.json +0 -12
  208. package/CLAUDE.md +0 -231
  209. package/dist/__tests__/cli.test.js +0 -278
  210. package/dist/__tests__/codegen.test.js +0 -152
  211. package/dist/__tests__/compile-all.test.d.ts +0 -10
  212. package/dist/__tests__/compile-all.test.js +0 -108
  213. package/dist/__tests__/dce.test.js +0 -138
  214. package/dist/__tests__/diagnostics.test.d.ts +0 -4
  215. package/dist/__tests__/diagnostics.test.js +0 -149
  216. package/dist/__tests__/e2e.test.d.ts +0 -6
  217. package/dist/__tests__/e2e.test.js +0 -1847
  218. package/dist/__tests__/entity-types.test.js +0 -203
  219. package/dist/__tests__/formatter.test.js +0 -40
  220. package/dist/__tests__/lexer.test.js +0 -343
  221. package/dist/__tests__/lowering.test.js +0 -1015
  222. package/dist/__tests__/macro.test.d.ts +0 -8
  223. package/dist/__tests__/macro.test.js +0 -305
  224. package/dist/__tests__/mc-integration.test.d.ts +0 -12
  225. package/dist/__tests__/mc-integration.test.js +0 -819
  226. package/dist/__tests__/mc-syntax.test.js +0 -124
  227. package/dist/__tests__/nbt.test.js +0 -82
  228. package/dist/__tests__/optimizer-advanced.test.js +0 -124
  229. package/dist/__tests__/optimizer.test.js +0 -149
  230. package/dist/__tests__/parser.test.d.ts +0 -1
  231. package/dist/__tests__/parser.test.js +0 -807
  232. package/dist/__tests__/repl.test.d.ts +0 -1
  233. package/dist/__tests__/repl.test.js +0 -27
  234. package/dist/__tests__/runtime.test.d.ts +0 -1
  235. package/dist/__tests__/runtime.test.js +0 -289
  236. package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
  237. package/dist/__tests__/stdlib-advanced.test.js +0 -378
  238. package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
  239. package/dist/__tests__/stdlib-bigint.test.js +0 -428
  240. package/dist/__tests__/stdlib-math.test.d.ts +0 -7
  241. package/dist/__tests__/stdlib-math.test.js +0 -352
  242. package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
  243. package/dist/__tests__/stdlib-vec.test.js +0 -264
  244. package/dist/__tests__/structure-optimizer.test.d.ts +0 -1
  245. package/dist/__tests__/structure-optimizer.test.js +0 -33
  246. package/dist/__tests__/typechecker.test.d.ts +0 -1
  247. package/dist/__tests__/typechecker.test.js +0 -552
  248. package/dist/__tests__/var-allocator.test.d.ts +0 -1
  249. package/dist/__tests__/var-allocator.test.js +0 -69
  250. package/dist/ast/types.d.ts +0 -514
  251. package/dist/ast/types.js +0 -9
  252. package/dist/builtins/metadata.d.ts +0 -36
  253. package/dist/builtins/metadata.js +0 -1014
  254. package/dist/cli.d.ts +0 -11
  255. package/dist/codegen/cmdblock/index.d.ts +0 -26
  256. package/dist/codegen/cmdblock/index.js +0 -45
  257. package/dist/codegen/mcfunction/index.d.ts +0 -40
  258. package/dist/codegen/mcfunction/index.js +0 -606
  259. package/dist/codegen/structure/index.d.ts +0 -24
  260. package/dist/codegen/structure/index.js +0 -279
  261. package/dist/codegen/var-allocator.d.ts +0 -45
  262. package/dist/codegen/var-allocator.js +0 -104
  263. package/dist/compile.d.ts +0 -68
  264. package/dist/data/arena/function/__load.mcfunction +0 -6
  265. package/dist/data/arena/function/__tick.mcfunction +0 -2
  266. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
  267. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
  268. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
  269. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
  270. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
  271. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
  272. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
  273. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
  274. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
  275. package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
  276. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
  277. package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
  278. package/dist/data/arena/function/arena_tick.mcfunction +0 -11
  279. package/dist/data/counter/function/__load.mcfunction +0 -5
  280. package/dist/data/counter/function/__tick.mcfunction +0 -2
  281. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
  282. package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
  283. package/dist/data/counter/function/counter_tick.mcfunction +0 -11
  284. package/dist/data/gcd2/function/__load.mcfunction +0 -3
  285. package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
  286. package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
  287. package/dist/data/gcd2/function/abs.mcfunction +0 -7
  288. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
  289. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
  290. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
  291. package/dist/data/gcd2/function/gcd.mcfunction +0 -14
  292. package/dist/data/gcd3/function/__load.mcfunction +0 -3
  293. package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
  294. package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
  295. package/dist/data/gcd3/function/abs.mcfunction +0 -7
  296. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
  297. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
  298. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
  299. package/dist/data/gcd3/function/gcd.mcfunction +0 -14
  300. package/dist/data/gcd3/function/test.mcfunction +0 -7
  301. package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
  302. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
  303. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
  304. package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
  305. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
  306. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
  307. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
  308. package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
  309. package/dist/data/gcd3nm/function/test.mcfunction +0 -7
  310. package/dist/data/gcd_test/function/__load.mcfunction +0 -3
  311. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
  312. package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
  313. package/dist/data/gcd_test/function/abs.mcfunction +0 -7
  314. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
  315. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
  316. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
  317. package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
  318. package/dist/data/isqrttest/function/__load.mcfunction +0 -6
  319. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
  320. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
  321. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
  322. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
  323. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
  324. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
  325. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
  326. package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
  327. package/dist/data/isqrttest/function/test.mcfunction +0 -6
  328. package/dist/data/mathtest/function/__load.mcfunction +0 -3
  329. package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
  330. package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
  331. package/dist/data/mathtest/function/abs.mcfunction +0 -6
  332. package/dist/data/mathtest/function/test.mcfunction +0 -5
  333. package/dist/data/minecraft/tags/function/load.json +0 -5
  334. package/dist/data/minecraft/tags/function/tick.json +0 -5
  335. package/dist/data/mypack/function/__load.mcfunction +0 -13
  336. package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
  337. package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
  338. package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
  339. package/dist/data/mypack/function/abs.mcfunction +0 -6
  340. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
  341. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
  342. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
  343. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
  344. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
  345. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
  346. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
  347. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
  348. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
  349. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
  350. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
  351. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
  352. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
  353. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
  354. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
  355. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
  356. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
  357. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
  358. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
  359. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
  360. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
  361. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
  362. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
  363. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
  364. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
  365. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
  366. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
  367. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
  368. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
  369. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
  370. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
  371. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
  372. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
  373. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
  374. package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
  375. package/dist/data/mypack/function/my_game.mcfunction +0 -10
  376. package/dist/data/quiz/function/__load.mcfunction +0 -16
  377. package/dist/data/quiz/function/__tick.mcfunction +0 -6
  378. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
  379. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
  380. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
  381. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
  382. package/dist/data/quiz/function/answer_a.mcfunction +0 -4
  383. package/dist/data/quiz/function/answer_b.mcfunction +0 -4
  384. package/dist/data/quiz/function/answer_c.mcfunction +0 -4
  385. package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
  386. package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
  387. package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
  388. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
  389. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
  390. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
  391. package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
  392. package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
  393. package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
  394. package/dist/data/quiz/function/ask_question.mcfunction +0 -7
  395. package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
  396. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
  397. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
  398. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
  399. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
  400. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
  401. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
  402. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
  403. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
  404. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
  405. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
  406. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
  407. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
  408. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
  409. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
  410. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
  411. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
  412. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
  413. package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
  414. package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
  415. package/dist/data/reqtest/function/__load.mcfunction +0 -4
  416. package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
  417. package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
  418. package/dist/data/reqtest/function/use_table.mcfunction +0 -4
  419. package/dist/data/reqtest2/function/__load.mcfunction +0 -3
  420. package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
  421. package/dist/data/runtime/function/__load.mcfunction +0 -5
  422. package/dist/data/runtime/function/__tick.mcfunction +0 -2
  423. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
  424. package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
  425. package/dist/data/shop/function/__load.mcfunction +0 -7
  426. package/dist/data/shop/function/__tick.mcfunction +0 -3
  427. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
  428. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
  429. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
  430. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
  431. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
  432. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
  433. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
  434. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
  435. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
  436. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
  437. package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
  438. package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
  439. package/dist/data/swap_test/function/__load.mcfunction +0 -3
  440. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
  441. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
  442. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
  443. package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
  444. package/dist/data/turret/function/__load.mcfunction +0 -5
  445. package/dist/data/turret/function/__tick.mcfunction +0 -4
  446. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
  447. package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
  448. package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
  449. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
  450. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
  451. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
  452. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
  453. package/dist/data/turret/function/turret_tick.mcfunction +0 -5
  454. package/dist/diagnostics/index.d.ts +0 -44
  455. package/dist/diagnostics/index.js +0 -140
  456. package/dist/events/types.d.ts +0 -35
  457. package/dist/events/types.js +0 -59
  458. package/dist/formatter/index.d.ts +0 -1
  459. package/dist/formatter/index.js +0 -26
  460. package/dist/gcd2.map.json +0 -15
  461. package/dist/gcd3.map.json +0 -17
  462. package/dist/gcd_test.map.json +0 -15
  463. package/dist/index.d.ts +0 -62
  464. package/dist/ir/builder.d.ts +0 -33
  465. package/dist/ir/builder.js +0 -99
  466. package/dist/ir/types.d.ts +0 -132
  467. package/dist/ir/types.js +0 -15
  468. package/dist/isqrttest.map.json +0 -15
  469. package/dist/lexer/index.d.ts +0 -37
  470. package/dist/lexer/index.js +0 -569
  471. package/dist/lowering/index.d.ts +0 -188
  472. package/dist/lowering/index.js +0 -3405
  473. package/dist/mathtest.map.json +0 -6
  474. package/dist/mc-test/client.d.ts +0 -128
  475. package/dist/mc-test/client.js +0 -174
  476. package/dist/mc-test/runner.d.ts +0 -28
  477. package/dist/mc-test/runner.js +0 -150
  478. package/dist/mc-test/setup.d.ts +0 -11
  479. package/dist/mc-test/setup.js +0 -98
  480. package/dist/mc-validator/index.d.ts +0 -17
  481. package/dist/mc-validator/index.js +0 -322
  482. package/dist/mypack.map.json +0 -27
  483. package/dist/nbt/index.d.ts +0 -86
  484. package/dist/nbt/index.js +0 -250
  485. package/dist/optimizer/commands.d.ts +0 -38
  486. package/dist/optimizer/commands.js +0 -451
  487. package/dist/optimizer/dce.d.ts +0 -34
  488. package/dist/optimizer/dce.js +0 -639
  489. package/dist/optimizer/passes.d.ts +0 -34
  490. package/dist/optimizer/passes.js +0 -243
  491. package/dist/optimizer/structure.d.ts +0 -9
  492. package/dist/optimizer/structure.js +0 -356
  493. package/dist/pack.mcmeta +0 -6
  494. package/dist/parser/index.d.ts +0 -93
  495. package/dist/parser/index.js +0 -1687
  496. package/dist/repl.d.ts +0 -16
  497. package/dist/repl.js +0 -165
  498. package/dist/reqtest.map.json +0 -4
  499. package/dist/reqtest2.map.json +0 -4
  500. package/dist/runtime/index.d.ts +0 -107
  501. package/dist/runtime/index.js +0 -1409
  502. package/dist/runtime.map.json +0 -7
  503. package/dist/src/__tests__/codegen.test.d.ts +0 -1
  504. package/dist/src/__tests__/codegen.test.js +0 -152
  505. package/dist/src/__tests__/e2e.test.d.ts +0 -6
  506. package/dist/src/__tests__/e2e.test.js +0 -1789
  507. package/dist/src/__tests__/entity-types.test.d.ts +0 -1
  508. package/dist/src/__tests__/entity-types.test.js +0 -203
  509. package/dist/src/__tests__/lowering.test.d.ts +0 -1
  510. package/dist/src/__tests__/lowering.test.js +0 -1015
  511. package/dist/src/__tests__/macro.test.d.ts +0 -8
  512. package/dist/src/__tests__/macro.test.js +0 -306
  513. package/dist/src/__tests__/nbt.test.d.ts +0 -1
  514. package/dist/src/__tests__/nbt.test.js +0 -82
  515. package/dist/src/__tests__/optimizer-advanced.test.d.ts +0 -1
  516. package/dist/src/__tests__/optimizer-advanced.test.js +0 -124
  517. package/dist/src/__tests__/optimizer.test.d.ts +0 -1
  518. package/dist/src/__tests__/optimizer.test.js +0 -149
  519. package/dist/src/__tests__/runtime.test.d.ts +0 -1
  520. package/dist/src/__tests__/runtime.test.js +0 -289
  521. package/dist/src/__tests__/stdlib-advanced.test.d.ts +0 -4
  522. package/dist/src/__tests__/stdlib-advanced.test.js +0 -374
  523. package/dist/src/__tests__/stdlib-bigint.test.d.ts +0 -7
  524. package/dist/src/__tests__/stdlib-bigint.test.js +0 -426
  525. package/dist/src/__tests__/stdlib-math.test.d.ts +0 -7
  526. package/dist/src/__tests__/stdlib-math.test.js +0 -351
  527. package/dist/src/__tests__/stdlib-vec.test.d.ts +0 -4
  528. package/dist/src/__tests__/stdlib-vec.test.js +0 -263
  529. package/dist/src/__tests__/structure-optimizer.test.d.ts +0 -1
  530. package/dist/src/__tests__/structure-optimizer.test.js +0 -33
  531. package/dist/src/__tests__/var-allocator.test.d.ts +0 -1
  532. package/dist/src/__tests__/var-allocator.test.js +0 -69
  533. package/dist/src/codegen/cmdblock/index.d.ts +0 -26
  534. package/dist/src/codegen/cmdblock/index.js +0 -45
  535. package/dist/src/codegen/mcfunction/index.d.ts +0 -40
  536. package/dist/src/codegen/mcfunction/index.js +0 -606
  537. package/dist/src/codegen/structure/index.d.ts +0 -24
  538. package/dist/src/codegen/structure/index.js +0 -279
  539. package/dist/src/codegen/var-allocator.d.ts +0 -45
  540. package/dist/src/codegen/var-allocator.js +0 -104
  541. package/dist/src/ir/builder.d.ts +0 -33
  542. package/dist/src/ir/builder.js +0 -99
  543. package/dist/src/ir/types.d.ts +0 -132
  544. package/dist/src/ir/types.js +0 -15
  545. package/dist/src/lowering/index.d.ts +0 -188
  546. package/dist/src/lowering/index.js +0 -3405
  547. package/dist/src/optimizer/commands.d.ts +0 -38
  548. package/dist/src/optimizer/commands.js +0 -451
  549. package/dist/src/optimizer/passes.d.ts +0 -34
  550. package/dist/src/optimizer/passes.js +0 -243
  551. package/dist/src/optimizer/structure.d.ts +0 -9
  552. package/dist/src/optimizer/structure.js +0 -356
  553. package/dist/src2/__tests__/optimizer/dce.test.d.ts +0 -1
  554. package/dist/src2/emit/compile.d.ts +0 -19
  555. package/dist/src2/emit/compile.js +0 -80
  556. package/dist/src2/optimizer/dce.d.ts +0 -8
  557. package/dist/src2/optimizer/dce.js +0 -155
  558. package/dist/swap_test.map.json +0 -14
  559. package/dist/tsconfig.tsbuildinfo +0 -1
  560. package/dist/typechecker/index.d.ts +0 -61
  561. package/dist/typechecker/index.js +0 -1034
  562. package/dist/types/entity-hierarchy.d.ts +0 -29
  563. package/dist/types/entity-hierarchy.js +0 -107
  564. package/examples/spiral.mcrs +0 -43
  565. package/src/examples/arena.mcrs +0 -44
  566. package/src/examples/counter.mcrs +0 -12
  567. package/src/examples/new_features_demo.mcrs +0 -193
  568. package/src/examples/rpg.mcrs +0 -13
  569. package/src/examples/stdlib_demo.mcrs +0 -181
  570. package/src2/emit/compile.ts +0 -99
  571. /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
  572. /package/dist/{src2 → src}/__tests__/e2e/basic.test.d.ts +0 -0
  573. /package/dist/{src2 → src}/__tests__/e2e/basic.test.js +0 -0
  574. /package/dist/{src2 → src}/__tests__/e2e/macros.test.d.ts +0 -0
  575. /package/dist/{src2 → src}/__tests__/e2e/migrate.test.d.ts +0 -0
  576. /package/dist/{src2 → src}/__tests__/hir/desugar.test.d.ts +0 -0
  577. /package/dist/{src2 → src}/__tests__/lir/lower.test.d.ts +0 -0
  578. /package/dist/{src2 → src}/__tests__/lir/lower.test.js +0 -0
  579. /package/dist/{src2 → src}/__tests__/lir/types.test.d.ts +0 -0
  580. /package/dist/{src2 → src}/__tests__/lir/types.test.js +0 -0
  581. /package/dist/{src2 → src}/__tests__/lir/verify.test.d.ts +0 -0
  582. /package/dist/{src2 → src}/__tests__/lir/verify.test.js +0 -0
  583. /package/dist/{src2 → src}/__tests__/mir/arithmetic.test.d.ts +0 -0
  584. /package/dist/{src2 → src}/__tests__/mir/control-flow.test.d.ts +0 -0
  585. /package/dist/{src2 → src}/__tests__/mir/verify.test.d.ts +0 -0
  586. /package/dist/{src2 → src}/__tests__/mir/verify.test.js +0 -0
  587. /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.d.ts +0 -0
  588. /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.js +0 -0
  589. /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.d.ts +0 -0
  590. /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.js +0 -0
  591. /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.d.ts +0 -0
  592. /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.js +0 -0
  593. /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.d.ts +0 -0
  594. /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.js +0 -0
  595. /package/dist/{__tests__ → src/__tests__/optimizer}/dce.test.d.ts +0 -0
  596. /package/dist/{src2 → src}/__tests__/optimizer/dce.test.js +0 -0
  597. /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/optimizer/interprocedural.test.d.ts} +0 -0
  598. /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/optimizer/lir/const_imm.test.d.ts} +0 -0
  599. /package/dist/{__tests__/formatter.test.d.ts → src/__tests__/optimizer/lir/dead_slot.test.d.ts} +0 -0
  600. /package/dist/{__tests__/lexer.test.d.ts → src/__tests__/optimizer/lir/peephole.test.d.ts} +0 -0
  601. /package/dist/{src2/__tests__/optimizer → src/__tests__/optimizer/lir}/pipeline.test.d.ts +0 -0
  602. /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/optimizer/nbt-batch.test.d.ts} +0 -0
  603. /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/optimizer/pipeline.test.d.ts} +0 -0
  604. /package/dist/{src2 → src}/__tests__/optimizer/pipeline.test.js +0 -0
  605. /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/optimizer/selector-cache.test.d.ts} +0 -0
  606. /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/optimizer/unroll.test.d.ts} +0 -0
  607. /package/dist/{__tests__/optimizer.test.d.ts → src/__tests__/stdlib-include.test.d.ts} +0 -0
  608. /package/dist/{src2 → src}/hir/types.js +0 -0
  609. /package/dist/{src2 → src}/lir/lower.d.ts +0 -0
  610. /package/dist/{src2 → src}/lir/types.js +0 -0
  611. /package/dist/{src2 → src}/lir/verify.d.ts +0 -0
  612. /package/dist/{src2 → src}/lir/verify.js +0 -0
  613. /package/dist/{src2 → src}/mir/macro.d.ts +0 -0
  614. /package/dist/{src2 → src}/mir/macro.js +0 -0
  615. /package/dist/{src2 → src}/mir/types.js +0 -0
  616. /package/dist/{src2 → src}/mir/verify.d.ts +0 -0
  617. /package/dist/{src2 → src}/mir/verify.js +0 -0
  618. /package/dist/{src2 → src}/optimizer/block_merge.d.ts +0 -0
  619. /package/dist/{src2 → src}/optimizer/block_merge.js +0 -0
  620. /package/dist/{src2 → src}/optimizer/branch_simplify.d.ts +0 -0
  621. /package/dist/{src2 → src}/optimizer/branch_simplify.js +0 -0
  622. /package/dist/{src2 → src}/optimizer/constant_fold.d.ts +0 -0
  623. /package/dist/{src2 → src}/optimizer/constant_fold.js +0 -0
  624. /package/dist/{src2 → src}/optimizer/copy_prop.d.ts +0 -0
  625. /package/dist/{src2 → src}/optimizer/copy_prop.js +0 -0
  626. /package/{src2 → src}/__tests__/e2e/basic.test.ts +0 -0
  627. /package/{src2 → src}/__tests__/lir/lower.test.ts +0 -0
  628. /package/{src2 → src}/__tests__/lir/types.test.ts +0 -0
  629. /package/{src2 → src}/__tests__/lir/verify.test.ts +0 -0
  630. /package/{src2 → src}/__tests__/mir/verify.test.ts +0 -0
  631. /package/{src2 → src}/__tests__/optimizer/block_merge.test.ts +0 -0
  632. /package/{src2 → src}/__tests__/optimizer/branch_simplify.test.ts +0 -0
  633. /package/{src2 → src}/__tests__/optimizer/constant_fold.test.ts +0 -0
  634. /package/{src2 → src}/__tests__/optimizer/copy_prop.test.ts +0 -0
  635. /package/{src2 → src}/__tests__/optimizer/dce.test.ts +0 -0
  636. /package/{src2 → src}/__tests__/optimizer/pipeline.test.ts +0 -0
  637. /package/{src2 → src}/lir/verify.ts +0 -0
  638. /package/{src2 → src}/mir/macro.ts +0 -0
  639. /package/{src2 → src}/mir/verify.ts +0 -0
  640. /package/{src2 → src}/optimizer/block_merge.ts +0 -0
  641. /package/{src2 → src}/optimizer/branch_simplify.ts +0 -0
  642. /package/{src2 → src}/optimizer/constant_fold.ts +0 -0
  643. /package/{src2 → src}/optimizer/copy_prop.ts +0 -0
@@ -0,0 +1,581 @@
1
+ /**
2
+ * Phase 5b — Multi-Module Compilation
3
+ *
4
+ * Compiles multiple .mcrs files that use `module <name>;` / `import <mod>::<sym>;`
5
+ * into a single datapack with namespace-isolated scoreboards and correct cross-module
6
+ * function paths.
7
+ *
8
+ * Design:
9
+ * - Each module gets its own scoreboard objective: `__${namespace}_${moduleName}`
10
+ * - Cross-module function calls are emitted as `${namespace}:${moduleName}/${fnName}`
11
+ * - DCE: exported-but-never-imported functions are stripped from the output
12
+ * - Circular imports are detected and rejected
13
+ */
14
+
15
+ import { Lexer } from '../lexer'
16
+ import { Parser } from '../parser'
17
+ import { DiagnosticError } from '../diagnostics'
18
+ import { lowerToHIR } from '../hir/lower'
19
+ import { monomorphize } from '../hir/monomorphize'
20
+ import { lowerToMIR } from '../mir/lower'
21
+ import { optimizeModule } from '../optimizer/pipeline'
22
+ import { lowerToLIR } from '../lir/lower'
23
+ import { lirOptimizeModule } from '../optimizer/lir/pipeline'
24
+ import { emit, type DatapackFile } from './index'
25
+ import { coroutineTransform, type CoroutineInfo } from '../optimizer/coroutine'
26
+ import type { HIRModule, HIRFunction, HIRExpr, HIRStmt, HIRBlock } from '../hir/types'
27
+ import type { Program, FnDecl, Expr, Stmt, Block } from '../ast/types'
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Public API
31
+ // ---------------------------------------------------------------------------
32
+
33
+ export interface ModuleInput {
34
+ /** Module name (must match the `module <name>;` declaration in source, or be inferred) */
35
+ name: string
36
+ source: string
37
+ filePath?: string
38
+ }
39
+
40
+ export interface CompileModulesOptions {
41
+ /** Datapack namespace (e.g. "mypack") */
42
+ namespace?: string
43
+ }
44
+
45
+ export interface CompileModulesResult {
46
+ files: DatapackFile[]
47
+ warnings: string[]
48
+ }
49
+
50
+ export function compileModules(
51
+ modules: ModuleInput[],
52
+ options: CompileModulesOptions = {},
53
+ ): CompileModulesResult {
54
+ const namespace = options.namespace ?? 'redscript'
55
+ const warnings: string[] = []
56
+
57
+ if (modules.length === 0) {
58
+ throw new DiagnosticError('LoweringError', 'No modules provided', { line: 1, col: 1 })
59
+ }
60
+
61
+ // -------------------------------------------------------------------------
62
+ // Step 1: Parse all modules
63
+ // -------------------------------------------------------------------------
64
+
65
+ const parsedModules = new Map<string, Program>() // moduleName → AST
66
+
67
+ for (const mod of modules) {
68
+ const lexer = new Lexer(mod.source, mod.filePath)
69
+ const tokens = lexer.tokenize()
70
+ const parser = new Parser(tokens, mod.source, mod.filePath)
71
+ const ast = parser.parse(namespace)
72
+
73
+ // Verify declared module name matches provided name
74
+ const declaredName = ast.moduleName
75
+ if (declaredName && declaredName !== mod.name) {
76
+ throw new DiagnosticError(
77
+ 'LoweringError',
78
+ `Module declares name '${declaredName}' but was registered as '${mod.name}'`,
79
+ { file: mod.filePath, line: 1, col: 1 },
80
+ )
81
+ }
82
+
83
+ parsedModules.set(mod.name, ast)
84
+ }
85
+
86
+ // -------------------------------------------------------------------------
87
+ // Step 2: Build export tables and validate imports
88
+ // -------------------------------------------------------------------------
89
+
90
+ // moduleName → set of exported function names
91
+ const exportTable = new Map<string, Set<string>>()
92
+ for (const [modName, ast] of parsedModules) {
93
+ const exports = new Set<string>()
94
+ for (const fn of ast.declarations) {
95
+ if (fn.isExported) exports.add(fn.name)
96
+ }
97
+ exportTable.set(modName, exports)
98
+ }
99
+
100
+ // -------------------------------------------------------------------------
101
+ // Step 3: Circular import detection
102
+ // -------------------------------------------------------------------------
103
+
104
+ detectCircularImports(parsedModules)
105
+
106
+ // -------------------------------------------------------------------------
107
+ // Step 4: Build import resolution table per module
108
+ // importMap: moduleName → { symbolName → qualifiedName (e.g. "math/sin") }
109
+ // -------------------------------------------------------------------------
110
+
111
+ const importMap = new Map<string, Map<string, string>>()
112
+
113
+ for (const [modName, ast] of parsedModules) {
114
+ const resolved = new Map<string, string>()
115
+ for (const imp of ast.imports) {
116
+ const sourceExports = exportTable.get(imp.moduleName)
117
+ if (!sourceExports) {
118
+ throw new DiagnosticError(
119
+ 'LoweringError',
120
+ `Module '${imp.moduleName}' not found (imported in '${modName}')`,
121
+ { file: ast.namespace, line: 1, col: 1 },
122
+ )
123
+ }
124
+
125
+ if (imp.symbol === '*') {
126
+ // Wildcard: import all exports
127
+ for (const sym of sourceExports) {
128
+ resolved.set(sym, `${imp.moduleName}/${sym}`)
129
+ }
130
+ } else {
131
+ if (!sourceExports.has(imp.symbol)) {
132
+ throw new DiagnosticError(
133
+ 'LoweringError',
134
+ `Module '${imp.moduleName}' does not export '${imp.symbol}'`,
135
+ { line: 1, col: 1 },
136
+ )
137
+ }
138
+ resolved.set(imp.symbol, `${imp.moduleName}/${imp.symbol}`)
139
+ }
140
+ }
141
+ importMap.set(modName, resolved)
142
+ }
143
+
144
+ // -------------------------------------------------------------------------
145
+ // Step 5: Compute which exported symbols are actually used (for cross-module DCE)
146
+ // usedExports: moduleName → set of exported fn names that are imported somewhere
147
+ // -------------------------------------------------------------------------
148
+
149
+ const usedExports = new Map<string, Set<string>>()
150
+ for (const modName of parsedModules.keys()) {
151
+ usedExports.set(modName, new Set())
152
+ }
153
+
154
+ for (const ast of parsedModules.values()) {
155
+ for (const imp of ast.imports) {
156
+ const used = usedExports.get(imp.moduleName)
157
+ if (!used) continue
158
+ if (imp.symbol === '*') {
159
+ const exports = exportTable.get(imp.moduleName)
160
+ if (exports) for (const s of exports) used.add(s)
161
+ } else {
162
+ used.add(imp.symbol)
163
+ }
164
+ }
165
+ }
166
+
167
+ // -------------------------------------------------------------------------
168
+ // Step 6: Compile each module
169
+ // -------------------------------------------------------------------------
170
+
171
+ const allFiles: DatapackFile[] = []
172
+ // Track library-eligible file paths for cross-module DCE
173
+ const libraryFilePaths = new Set<string>()
174
+ let packMetaEmitted = false
175
+
176
+ for (const mod of modules) {
177
+ const ast = parsedModules.get(mod.name)!
178
+ const symbolMap = importMap.get(mod.name) ?? new Map()
179
+ const isNamed = !!ast.moduleName
180
+
181
+ // Rewrite call sites in AST: imported symbol names → qualified names
182
+ if (symbolMap.size > 0) {
183
+ rewriteCallsInProgram(ast, symbolMap)
184
+ }
185
+
186
+ // For named modules: prefix all function definitions with `${moduleName}/`
187
+ // so they emit to `${namespace}:${moduleName}/${fnName}.mcfunction`
188
+ // Track which exported functions are not imported anywhere (for cross-module DCE)
189
+ const unusedExportedFns = new Set<string>()
190
+ if (isNamed) {
191
+ const used = usedExports.get(mod.name) ?? new Set()
192
+ for (const fn of ast.declarations) {
193
+ // Prefix function name
194
+ fn.name = `${mod.name}/${fn.name}`
195
+
196
+ // Functions not imported by anyone are library-eligible (DCE)
197
+ const baseName = fn.name.split('/').pop()!
198
+ if (fn.isExported && !used.has(baseName)) {
199
+ unusedExportedFns.add(fn.name)
200
+ }
201
+ }
202
+ }
203
+
204
+ // Determine scoreboard objective
205
+ // Named module: `__${namespace}_${moduleName}`, anonymous: `__${namespace}`
206
+ const objective = isNamed ? `__${namespace}_${mod.name}` : `__${namespace}`
207
+
208
+ // Run the pipeline
209
+ const modFiles = compileSingleModule(ast, namespace, objective, isNamed ? mod.name : undefined, mod.filePath)
210
+ warnings.push(...modFiles.warnings)
211
+
212
+ // Record library-eligible file paths (only if there are multiple modules — single module = library author)
213
+ if (modules.length > 1) {
214
+ for (const fnName of unusedExportedFns) {
215
+ // fnName is like "math/unused" → file path "data/<ns>/function/math/unused.mcfunction"
216
+ libraryFilePaths.add(`data/${namespace}/function/${fnName}.mcfunction`)
217
+ }
218
+ }
219
+
220
+ // Merge files, emitting pack.mcmeta only once
221
+ for (const file of modFiles.files) {
222
+ if (file.path === 'pack.mcmeta') {
223
+ if (!packMetaEmitted) {
224
+ allFiles.push(file)
225
+ packMetaEmitted = true
226
+ }
227
+ continue
228
+ }
229
+ // Merge load.json tag values
230
+ if (file.path === 'data/minecraft/tags/function/load.json') {
231
+ mergeTagFile(allFiles, file)
232
+ continue
233
+ }
234
+ // Merge tick.json tag values
235
+ if (file.path === 'data/minecraft/tags/function/tick.json') {
236
+ mergeTagFile(allFiles, file)
237
+ continue
238
+ }
239
+ allFiles.push(file)
240
+ }
241
+ }
242
+
243
+ // -------------------------------------------------------------------------
244
+ // Step 7: Cross-module DCE — remove unreachable library-eligible functions
245
+ // -------------------------------------------------------------------------
246
+ const finalFiles = crossModuleDCE(allFiles, libraryFilePaths, namespace)
247
+
248
+ return { files: finalFiles, warnings }
249
+ }
250
+
251
+ // ---------------------------------------------------------------------------
252
+ // Helpers
253
+ // ---------------------------------------------------------------------------
254
+
255
+ interface SingleModuleResult {
256
+ files: DatapackFile[]
257
+ warnings: string[]
258
+ }
259
+
260
+ /**
261
+ * File-level cross-module DCE.
262
+ *
263
+ * After all module files are emitted, prune .mcfunction files that:
264
+ * 1. Correspond to exported-but-unimported functions (tracked in `libraryPaths`)
265
+ * 2. Are not reachable (directly or transitively) from any non-library entry file
266
+ *
267
+ * The reachability is computed by scanning `function <ns>:<path>` calls in
268
+ * every .mcfunction file.
269
+ */
270
+ function crossModuleDCE(
271
+ files: DatapackFile[],
272
+ libraryPaths: Set<string>, // file paths (e.g. "data/ns/function/math/unused.mcfunction")
273
+ namespace: string,
274
+ ): DatapackFile[] {
275
+ if (libraryPaths.size === 0) return files
276
+
277
+ // Build a map: fnPath (e.g. "ns:math/add") → file path
278
+ const fnPathToFilePath = new Map<string, string>()
279
+ for (const file of files) {
280
+ const m = file.path.match(/^data\/([^/]+)\/function\/(.+)\.mcfunction$/)
281
+ if (m) {
282
+ fnPathToFilePath.set(`${m[1]}:${m[2]}`, file.path)
283
+ }
284
+ }
285
+
286
+ // Build call graph: filePath → set of called fnPaths (namespace:path)
287
+ const callGraph = new Map<string, Set<string>>()
288
+ const callPattern = /\bfunction\s+([\w\-]+:[\w\-./]+)/g
289
+ for (const file of files) {
290
+ if (!file.path.endsWith('.mcfunction')) continue
291
+ const called = new Set<string>()
292
+ let match: RegExpExecArray | null
293
+ callPattern.lastIndex = 0
294
+ while ((match = callPattern.exec(file.content)) !== null) {
295
+ called.add(match[1])
296
+ }
297
+ callGraph.set(file.path, called)
298
+ }
299
+
300
+ // BFS from non-library entry files
301
+ const reachableFiles = new Set<string>()
302
+ const queue: string[] = []
303
+ for (const file of files) {
304
+ if (!file.path.endsWith('.mcfunction')) continue
305
+ if (!libraryPaths.has(file.path)) {
306
+ // Non-library file: it's an entry point
307
+ queue.push(file.path)
308
+ reachableFiles.add(file.path)
309
+ }
310
+ }
311
+
312
+ while (queue.length > 0) {
313
+ const current = queue.shift()!
314
+ const called = callGraph.get(current) ?? new Set()
315
+ for (const fnPath of called) {
316
+ const filePath = fnPathToFilePath.get(fnPath)
317
+ if (filePath && !reachableFiles.has(filePath)) {
318
+ reachableFiles.add(filePath)
319
+ queue.push(filePath)
320
+ }
321
+ }
322
+ }
323
+
324
+ // Filter out unreachable library files
325
+ return files.filter(file => {
326
+ if (!libraryPaths.has(file.path)) return true // non-library: always keep
327
+ return reachableFiles.has(file.path) // library: keep only if reachable
328
+ })
329
+ }
330
+
331
+ function compileSingleModule(
332
+ ast: Program,
333
+ namespace: string,
334
+ objective: string,
335
+ moduleName: string | undefined,
336
+ filePath?: string,
337
+ ): SingleModuleResult {
338
+ const warnings: string[] = []
339
+
340
+ try {
341
+ const hirRaw = lowerToHIR(ast)
342
+ const hir = monomorphize(hirRaw)
343
+
344
+
345
+
346
+ // Extract decorator metadata
347
+ const tickFunctions: string[] = []
348
+ const loadFunctions: string[] = []
349
+ const coroutineInfos: CoroutineInfo[] = []
350
+ const scheduleFunctions: Array<{ name: string; ticks: number }> = []
351
+ for (const fn of hir.functions) {
352
+ for (const dec of fn.decorators) {
353
+ if (dec.name === 'tick') tickFunctions.push(fn.name)
354
+ if (dec.name === 'load') loadFunctions.push(fn.name)
355
+ if (dec.name === 'coroutine') {
356
+ coroutineInfos.push({ fnName: fn.name, batch: dec.args?.batch ?? 10, onDone: dec.args?.onDone })
357
+ }
358
+ if (dec.name === 'schedule') {
359
+ scheduleFunctions.push({ name: fn.name, ticks: dec.args?.ticks ?? 1 })
360
+ }
361
+ }
362
+ }
363
+
364
+ // Patch the MIR module objective (lowerToMIR computes `__${namespace}` by default)
365
+ const mir = lowerToMIR(hir, filePath)
366
+ mir.objective = objective
367
+
368
+ const mirOpt = optimizeModule(mir)
369
+ const coroResult = coroutineTransform(mirOpt, coroutineInfos)
370
+ const mirFinal = coroResult.module
371
+ tickFunctions.push(...coroResult.generatedTickFunctions)
372
+
373
+ const lir = lowerToLIR(mirFinal)
374
+ lir.objective = objective
375
+ const lirOpt = lirOptimizeModule(lir)
376
+
377
+ const files = emit(lirOpt, { namespace, tickFunctions, loadFunctions, scheduleFunctions })
378
+
379
+ // For named modules: rename the load.mcfunction to avoid path collision.
380
+ // Rename `data/${ns}/function/load.mcfunction` → `data/${ns}/function/${modName}/_load.mcfunction`
381
+ // and update the load tag reference accordingly.
382
+ if (moduleName) {
383
+ const loadPath = `data/${namespace}/function/load.mcfunction`
384
+ const newLoadPath = `data/${namespace}/function/${moduleName}/_load.mcfunction`
385
+ const loadTagPath = 'data/minecraft/tags/function/load.json'
386
+
387
+ for (const file of files) {
388
+ if (file.path === loadPath) {
389
+ file.path = newLoadPath
390
+ } else if (file.path === loadTagPath) {
391
+ const tag = JSON.parse(file.content) as { values: string[] }
392
+ tag.values = tag.values.map(v =>
393
+ v === `${namespace}:load` ? `${namespace}:${moduleName}/_load` : v
394
+ )
395
+ file.content = JSON.stringify(tag, null, 2) + '\n'
396
+ }
397
+ }
398
+ }
399
+
400
+ return { files, warnings }
401
+ } catch (err) {
402
+ if (err instanceof DiagnosticError) throw err
403
+ throw err
404
+ }
405
+ }
406
+
407
+ /** Merge a tag file (load.json / tick.json) values into existing files array. */
408
+ function mergeTagFile(files: DatapackFile[], newFile: DatapackFile): void {
409
+ const existing = files.find(f => f.path === newFile.path)
410
+ if (!existing) {
411
+ files.push(newFile)
412
+ return
413
+ }
414
+ const existingJson = JSON.parse(existing.content) as { values: string[] }
415
+ const newJson = JSON.parse(newFile.content) as { values: string[] }
416
+ existingJson.values.push(...newJson.values)
417
+ existing.content = JSON.stringify(existingJson, null, 2) + '\n'
418
+ }
419
+
420
+ /** Detect circular imports using DFS. Throws if a cycle is found. */
421
+ function detectCircularImports(parsedModules: Map<string, Program>): void {
422
+ const visited = new Set<string>()
423
+ const inStack = new Set<string>()
424
+
425
+ function dfs(modName: string, stack: string[]): void {
426
+ if (inStack.has(modName)) {
427
+ const cycle = [...stack.slice(stack.indexOf(modName)), modName]
428
+ throw new DiagnosticError(
429
+ 'LoweringError',
430
+ `Circular import detected: ${cycle.join(' → ')}`,
431
+ { line: 1, col: 1 },
432
+ )
433
+ }
434
+ if (visited.has(modName)) return
435
+ visited.add(modName)
436
+ inStack.add(modName)
437
+ const ast = parsedModules.get(modName)
438
+ if (ast) {
439
+ for (const imp of ast.imports) {
440
+ dfs(imp.moduleName, [...stack, modName])
441
+ }
442
+ }
443
+ inStack.delete(modName)
444
+ }
445
+
446
+ for (const modName of parsedModules.keys()) {
447
+ dfs(modName, [])
448
+ }
449
+ }
450
+
451
+ // ---------------------------------------------------------------------------
452
+ // AST rewriting: remap imported symbol calls to qualified names
453
+ // ---------------------------------------------------------------------------
454
+
455
+ /** Rewrite call expressions in the program AST.
456
+ * symbolMap: localName → qualifiedName (e.g. "sin" → "math/sin") */
457
+ function rewriteCallsInProgram(program: Program, symbolMap: Map<string, string>): void {
458
+ for (const fn of program.declarations) {
459
+ rewriteBlock(fn.body, symbolMap)
460
+ }
461
+ for (const ib of program.implBlocks) {
462
+ for (const m of ib.methods) {
463
+ rewriteBlock(m.body, symbolMap)
464
+ }
465
+ }
466
+ }
467
+
468
+ function rewriteBlock(block: Block, symbolMap: Map<string, string>): void {
469
+ for (const stmt of block) {
470
+ rewriteStmt(stmt, symbolMap)
471
+ }
472
+ }
473
+
474
+ function rewriteStmt(stmt: Stmt, symbolMap: Map<string, string>): void {
475
+ switch (stmt.kind) {
476
+ case 'let':
477
+ case 'expr':
478
+ rewriteExpr(stmt.kind === 'let' ? stmt.init : stmt.expr, symbolMap)
479
+ break
480
+ case 'return':
481
+ if (stmt.value) rewriteExpr(stmt.value, symbolMap)
482
+ break
483
+ case 'if':
484
+ rewriteExpr(stmt.cond, symbolMap)
485
+ rewriteBlock(stmt.then, symbolMap)
486
+ if (stmt.else_) rewriteBlock(stmt.else_, symbolMap)
487
+ break
488
+ case 'while':
489
+ rewriteExpr(stmt.cond, symbolMap)
490
+ rewriteBlock(stmt.body, symbolMap)
491
+ break
492
+ case 'for':
493
+ if (stmt.init) rewriteStmt(stmt.init, symbolMap)
494
+ rewriteExpr(stmt.cond, symbolMap)
495
+ rewriteExpr(stmt.step, symbolMap)
496
+ rewriteBlock(stmt.body, symbolMap)
497
+ break
498
+ case 'for_range':
499
+ rewriteExpr(stmt.start, symbolMap)
500
+ rewriteExpr(stmt.end, symbolMap)
501
+ rewriteBlock(stmt.body, symbolMap)
502
+ break
503
+ case 'foreach':
504
+ rewriteExpr(stmt.iterable, symbolMap)
505
+ rewriteBlock(stmt.body, symbolMap)
506
+ break
507
+ case 'match':
508
+ rewriteExpr(stmt.expr, symbolMap)
509
+ for (const arm of stmt.arms) {
510
+ if (arm.pattern) rewriteExpr(arm.pattern, symbolMap)
511
+ rewriteBlock(arm.body, symbolMap)
512
+ }
513
+ break
514
+ case 'as_block':
515
+ case 'at_block':
516
+ rewriteBlock(stmt.body, symbolMap)
517
+ break
518
+ case 'as_at':
519
+ rewriteBlock(stmt.body, symbolMap)
520
+ break
521
+ case 'execute':
522
+ rewriteBlock(stmt.body, symbolMap)
523
+ break
524
+ case 'let_destruct':
525
+ rewriteExpr(stmt.init, symbolMap)
526
+ break
527
+ // break, continue, raw: nothing to rewrite
528
+ }
529
+ }
530
+
531
+ function rewriteExpr(expr: Expr, symbolMap: Map<string, string>): void {
532
+ switch (expr.kind) {
533
+ case 'call': {
534
+ // Remap the function name if it's an imported symbol
535
+ const remapped = symbolMap.get(expr.fn)
536
+ if (remapped) {
537
+ ; (expr as { fn: string }).fn = remapped
538
+ }
539
+ for (const arg of expr.args) rewriteExpr(arg, symbolMap)
540
+ break
541
+ }
542
+ case 'assign':
543
+ rewriteExpr(expr.value, symbolMap)
544
+ break
545
+ case 'binary':
546
+ rewriteExpr(expr.left, symbolMap)
547
+ rewriteExpr(expr.right, symbolMap)
548
+ break
549
+ case 'unary':
550
+ rewriteExpr(expr.operand, symbolMap)
551
+ break
552
+ case 'member':
553
+ rewriteExpr(expr.obj, symbolMap)
554
+ break
555
+ case 'member_assign':
556
+ rewriteExpr(expr.obj, symbolMap)
557
+ rewriteExpr(expr.value, symbolMap)
558
+ break
559
+ case 'index':
560
+ rewriteExpr(expr.obj, symbolMap)
561
+ rewriteExpr(expr.index, symbolMap)
562
+ break
563
+ case 'array_lit':
564
+ for (const el of expr.elements) rewriteExpr(el, symbolMap)
565
+ break
566
+ case 'struct_lit':
567
+ for (const f of expr.fields) rewriteExpr(f.value, symbolMap)
568
+ break
569
+ case 'invoke':
570
+ rewriteExpr(expr.callee, symbolMap)
571
+ for (const arg of expr.args) rewriteExpr(arg, symbolMap)
572
+ break
573
+ case 'tuple_lit':
574
+ for (const el of expr.elements) rewriteExpr(el, symbolMap)
575
+ break
576
+ case 'static_call':
577
+ for (const arg of expr.args) rewriteExpr(arg, symbolMap)
578
+ break
579
+ // Literals, ident, selector, path_expr, f_string, etc: nothing to rewrite
580
+ }
581
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Source Map Generation — Stage 7 auxiliary output.
3
+ *
4
+ * For each generated .mcfunction file, produces a parallel sourcemap.json
5
+ * that maps output line numbers back to .mcrs source locations.
6
+ *
7
+ * Format:
8
+ * {
9
+ * "version": 1,
10
+ * "generatedFile": "data/ns/function/main.mcfunction",
11
+ * "sources": ["src/main.mcrs"],
12
+ * "mappings": [
13
+ * { "line": 1, "source": 0, "sourceLine": 5, "sourceCol": 2 },
14
+ * ...
15
+ * ]
16
+ * }
17
+ */
18
+
19
+ import type { SourceLoc } from '../lir/types'
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Public types
23
+ // ---------------------------------------------------------------------------
24
+
25
+ export interface SourceMapEntry {
26
+ /** 1-based output line number in the .mcfunction file */
27
+ line: number
28
+ /** Index into the `sources` array */
29
+ source: number
30
+ /** 1-based line in the source .mcrs file */
31
+ sourceLine: number
32
+ /** 1-based column in the source .mcrs file */
33
+ sourceCol: number
34
+ }
35
+
36
+ export interface SourceMap {
37
+ version: 1
38
+ /** Relative path to the generated .mcfunction file */
39
+ generatedFile: string
40
+ /** List of source file paths referenced by mappings */
41
+ sources: string[]
42
+ /** One entry per mapped output line */
43
+ mappings: SourceMapEntry[]
44
+ }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Builder — accumulates mappings as lines are emitted
48
+ // ---------------------------------------------------------------------------
49
+
50
+ export class SourceMapBuilder {
51
+ private readonly generatedFile: string
52
+ private readonly sourceIndex = new Map<string, number>()
53
+ private readonly sources: string[] = []
54
+ private readonly mappings: SourceMapEntry[] = []
55
+ private lineNumber = 0
56
+
57
+ constructor(generatedFile: string) {
58
+ this.generatedFile = generatedFile
59
+ }
60
+
61
+ /** Record the source location for the next output line. */
62
+ addLine(sourceLoc: SourceLoc | undefined): void {
63
+ this.lineNumber++
64
+ if (!sourceLoc) return
65
+
66
+ let idx = this.sourceIndex.get(sourceLoc.file)
67
+ if (idx === undefined) {
68
+ idx = this.sources.length
69
+ this.sources.push(sourceLoc.file)
70
+ this.sourceIndex.set(sourceLoc.file, idx)
71
+ }
72
+
73
+ this.mappings.push({
74
+ line: this.lineNumber,
75
+ source: idx,
76
+ sourceLine: sourceLoc.line,
77
+ sourceCol: sourceLoc.col,
78
+ })
79
+ }
80
+
81
+ /** Return the completed SourceMap, or null if there are no mappings. */
82
+ build(): SourceMap | null {
83
+ if (this.mappings.length === 0) return null
84
+ return {
85
+ version: 1,
86
+ generatedFile: this.generatedFile,
87
+ sources: [...this.sources],
88
+ mappings: [...this.mappings],
89
+ }
90
+ }
91
+ }
92
+
93
+ /** Serialize a SourceMap to JSON string (pretty-printed). */
94
+ export function serializeSourceMap(map: SourceMap): string {
95
+ return JSON.stringify(map, null, 2) + '\n'
96
+ }
97
+
98
+ /** Given a .mcfunction path, return the path for the sidecar sourcemap.json. */
99
+ export function sourceMapPath(mcfunctionPath: string): string {
100
+ return mcfunctionPath.replace(/\.mcfunction$/, '.sourcemap.json')
101
+ }