redscript-mc 1.2.30 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (593) hide show
  1. package/.claudeignore +21 -0
  2. package/.github/workflows/ci.yml +1 -0
  3. package/README.md +12 -16
  4. package/README.zh.md +2 -2
  5. package/demo.gif +0 -0
  6. package/dist/cli.js +2 -554
  7. package/dist/compile.js +2 -266
  8. package/dist/index.js +2 -159
  9. package/dist/src/__tests__/budget.test.js +261 -0
  10. package/dist/src/__tests__/cli.test.js +104 -0
  11. package/dist/{__tests__ → src/__tests__}/dce.test.js +11 -47
  12. package/dist/{__tests__ → src/__tests__}/diagnostics.test.js +67 -40
  13. package/dist/src/__tests__/e2e/basic.test.d.ts +8 -0
  14. package/dist/src/__tests__/e2e/basic.test.js +140 -0
  15. package/dist/src/__tests__/e2e/coroutine.test.d.ts +7 -0
  16. package/dist/src/__tests__/e2e/coroutine.test.js +132 -0
  17. package/dist/src/__tests__/e2e/macros.test.d.ts +9 -0
  18. package/dist/src/__tests__/e2e/macros.test.js +182 -0
  19. package/dist/src/__tests__/e2e/migrate.test.d.ts +13 -0
  20. package/dist/src/__tests__/e2e/migrate.test.js +2739 -0
  21. package/dist/src/__tests__/e2e/stdlib-e2e.test.d.ts +10 -0
  22. package/dist/src/__tests__/e2e/stdlib-e2e.test.js +324 -0
  23. package/dist/src/__tests__/enum.test.d.ts +10 -0
  24. package/dist/src/__tests__/enum.test.js +389 -0
  25. package/dist/src/__tests__/generics.test.d.ts +14 -0
  26. package/dist/src/__tests__/generics.test.js +367 -0
  27. package/dist/src/__tests__/hir/desugar.test.js +234 -0
  28. package/dist/src/__tests__/incremental.test.d.ts +5 -0
  29. package/dist/src/__tests__/incremental.test.js +308 -0
  30. package/dist/src/__tests__/lir/lower.test.js +559 -0
  31. package/dist/src/__tests__/lir/types.test.js +185 -0
  32. package/dist/src/__tests__/lir/verify.test.js +221 -0
  33. package/dist/src/__tests__/lsp.test.d.ts +7 -0
  34. package/dist/src/__tests__/lsp.test.js +245 -0
  35. package/dist/{__tests__ → src/__tests__}/mc-integration.test.js +1 -3
  36. package/dist/src/__tests__/mc-version.test.d.ts +10 -0
  37. package/dist/src/__tests__/mc-version.test.js +154 -0
  38. package/dist/src/__tests__/mir/arithmetic.test.js +130 -0
  39. package/dist/src/__tests__/mir/control-flow.test.js +205 -0
  40. package/dist/src/__tests__/mir/verify.test.js +223 -0
  41. package/dist/src/__tests__/modules.test.d.ts +7 -0
  42. package/dist/src/__tests__/modules.test.js +333 -0
  43. package/dist/src/__tests__/optimizer/block_merge.test.js +78 -0
  44. package/dist/src/__tests__/optimizer/branch_simplify.test.js +58 -0
  45. package/dist/src/__tests__/optimizer/constant_fold.test.js +131 -0
  46. package/dist/src/__tests__/optimizer/copy_prop.test.js +91 -0
  47. package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
  48. package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
  49. package/dist/src/__tests__/optimizer/dce.test.d.ts +1 -0
  50. package/dist/src/__tests__/optimizer/dce.test.js +76 -0
  51. package/dist/src/__tests__/optimizer/interprocedural.test.d.ts +1 -0
  52. package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
  53. package/dist/src/__tests__/optimizer/lir/const_imm.test.d.ts +1 -0
  54. package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
  55. package/dist/src/__tests__/optimizer/lir/dead_slot.test.d.ts +1 -0
  56. package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
  57. package/dist/src/__tests__/optimizer/lir/peephole.test.d.ts +1 -0
  58. package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
  59. package/dist/src/__tests__/optimizer/lir/pipeline.test.d.ts +1 -0
  60. package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
  61. package/dist/src/__tests__/optimizer/nbt-batch.test.d.ts +1 -0
  62. package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
  63. package/dist/src/__tests__/optimizer/pipeline.test.d.ts +1 -0
  64. package/dist/src/__tests__/optimizer/pipeline.test.js +102 -0
  65. package/dist/src/__tests__/optimizer/selector-cache.test.d.ts +1 -0
  66. package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
  67. package/dist/src/__tests__/optimizer/unroll.test.d.ts +1 -0
  68. package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
  69. package/dist/src/__tests__/option.test.d.ts +14 -0
  70. package/dist/src/__tests__/option.test.js +275 -0
  71. package/dist/src/__tests__/parser.test.d.ts +1 -0
  72. package/dist/src/__tests__/repl.test.d.ts +1 -0
  73. package/dist/src/__tests__/schedule.test.d.ts +7 -0
  74. package/dist/src/__tests__/schedule.test.js +98 -0
  75. package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
  76. package/dist/src/__tests__/sourcemap.test.js +227 -0
  77. package/dist/src/__tests__/tuple.test.d.ts +11 -0
  78. package/dist/src/__tests__/tuple.test.js +202 -0
  79. package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
  80. package/dist/src/__tests__/typechecker-strict.test.js +197 -0
  81. package/dist/src/__tests__/typechecker.test.d.ts +1 -0
  82. package/dist/{ast → src/ast}/types.d.ts +58 -3
  83. package/dist/src/cache/deps.d.ts +41 -0
  84. package/dist/src/cache/deps.js +158 -0
  85. package/dist/src/cache/incremental.d.ts +35 -0
  86. package/dist/src/cache/incremental.js +165 -0
  87. package/dist/src/cache/index.d.ts +37 -0
  88. package/dist/src/cache/index.js +152 -0
  89. package/dist/{cli.d.ts → src/cli.d.ts} +1 -1
  90. package/dist/src/cli.js +474 -0
  91. package/dist/src/compile.d.ts +37 -0
  92. package/dist/src/compile.js +165 -0
  93. package/dist/{diagnostics → src/diagnostics}/index.d.ts +1 -1
  94. package/dist/{diagnostics → src/diagnostics}/index.js +8 -11
  95. package/dist/src/emit/compile.d.ts +29 -0
  96. package/dist/src/emit/compile.js +143 -0
  97. package/dist/src/emit/index.d.ts +26 -0
  98. package/dist/src/emit/index.js +223 -0
  99. package/dist/src/emit/modules.d.ts +29 -0
  100. package/dist/src/emit/modules.js +492 -0
  101. package/dist/src/emit/sourcemap.d.ts +53 -0
  102. package/dist/src/emit/sourcemap.js +73 -0
  103. package/dist/src/hir/lower.d.ts +15 -0
  104. package/dist/src/hir/lower.js +399 -0
  105. package/dist/src/hir/monomorphize.d.ts +22 -0
  106. package/dist/src/hir/monomorphize.js +379 -0
  107. package/dist/src/hir/types.d.ts +406 -0
  108. package/dist/src/hir/types.js +16 -0
  109. package/dist/src/index.d.ts +39 -0
  110. package/dist/src/index.js +67 -0
  111. package/dist/{lexer → src/lexer}/index.d.ts +1 -1
  112. package/dist/{lexer → src/lexer}/index.js +1 -0
  113. package/dist/src/lir/budget.d.ts +37 -0
  114. package/dist/src/lir/budget.js +280 -0
  115. package/dist/src/lir/lower.d.ts +15 -0
  116. package/dist/src/lir/lower.js +472 -0
  117. package/dist/src/lir/types.d.ts +139 -0
  118. package/dist/src/lir/types.js +11 -0
  119. package/dist/src/lir/verify.d.ts +14 -0
  120. package/dist/src/lir/verify.js +113 -0
  121. package/dist/src/lsp/main.d.ts +8 -0
  122. package/dist/src/lsp/main.js +11 -0
  123. package/dist/src/lsp/server.d.ts +11 -0
  124. package/dist/src/lsp/server.js +352 -0
  125. package/dist/{mc-test → src/mc-test}/runner.js +4 -3
  126. package/dist/src/mir/lower.d.ts +9 -0
  127. package/dist/src/mir/lower.js +1264 -0
  128. package/dist/src/mir/macro.d.ts +22 -0
  129. package/dist/src/mir/macro.js +168 -0
  130. package/dist/src/mir/types.d.ts +191 -0
  131. package/dist/src/mir/types.js +11 -0
  132. package/dist/src/mir/verify.d.ts +16 -0
  133. package/dist/src/mir/verify.js +216 -0
  134. package/dist/src/optimizer/block_merge.d.ts +12 -0
  135. package/dist/src/optimizer/block_merge.js +84 -0
  136. package/dist/src/optimizer/branch_simplify.d.ts +9 -0
  137. package/dist/src/optimizer/branch_simplify.js +28 -0
  138. package/dist/src/optimizer/constant_fold.d.ts +10 -0
  139. package/dist/src/optimizer/constant_fold.js +85 -0
  140. package/dist/src/optimizer/copy_prop.d.ts +9 -0
  141. package/dist/src/optimizer/copy_prop.js +113 -0
  142. package/dist/src/optimizer/coroutine.d.ts +34 -0
  143. package/dist/src/optimizer/coroutine.js +789 -0
  144. package/dist/src/optimizer/dce.d.ts +8 -0
  145. package/dist/src/optimizer/dce.js +156 -0
  146. package/dist/src/optimizer/interprocedural.d.ts +14 -0
  147. package/dist/src/optimizer/interprocedural.js +186 -0
  148. package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
  149. package/dist/src/optimizer/lir/const_imm.js +139 -0
  150. package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
  151. package/dist/src/optimizer/lir/dead_slot.js +130 -0
  152. package/dist/src/optimizer/lir/peephole.d.ts +21 -0
  153. package/dist/src/optimizer/lir/peephole.js +52 -0
  154. package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
  155. package/dist/src/optimizer/lir/pipeline.js +34 -0
  156. package/dist/src/optimizer/nbt-batch.d.ts +11 -0
  157. package/dist/src/optimizer/nbt-batch.js +51 -0
  158. package/dist/src/optimizer/pipeline.d.ts +14 -0
  159. package/dist/src/optimizer/pipeline.js +58 -0
  160. package/dist/src/optimizer/selector-cache.d.ts +22 -0
  161. package/dist/src/optimizer/selector-cache.js +100 -0
  162. package/dist/src/optimizer/unroll.d.ts +32 -0
  163. package/dist/src/optimizer/unroll.js +348 -0
  164. package/dist/{parser → src/parser}/index.d.ts +8 -0
  165. package/dist/{parser → src/parser}/index.js +204 -14
  166. package/dist/{repl.d.ts → src/repl.d.ts} +1 -1
  167. package/dist/{runtime → src/runtime}/index.js +1 -1
  168. package/dist/{typechecker → src/typechecker}/index.d.ts +4 -0
  169. package/dist/{typechecker → src/typechecker}/index.js +198 -13
  170. package/dist/src/types/mc-version.d.ts +24 -0
  171. package/dist/src/types/mc-version.js +49 -0
  172. package/docs/ROADMAP.md +395 -0
  173. package/docs/compiler-pipeline-redesign.md +2260 -0
  174. package/docs/optimization-ideas.md +1076 -0
  175. package/editors/vscode/out/extension.js +25176 -8000
  176. package/editors/vscode/package-lock.json +90 -6
  177. package/editors/vscode/package.json +3 -2
  178. package/editors/vscode/src/extension.ts +97 -67
  179. package/examples/showcase.mcrs +3 -3
  180. package/package.json +13 -6
  181. package/scripts/postbuild.js +15 -0
  182. package/src/__tests__/budget.test.ts +297 -0
  183. package/src/__tests__/cli.test.ts +8 -220
  184. package/src/__tests__/dce.test.ts +11 -56
  185. package/src/__tests__/diagnostics.test.ts +61 -41
  186. package/src/__tests__/e2e/basic.test.ts +154 -0
  187. package/src/__tests__/e2e/coroutine.test.ts +142 -0
  188. package/src/__tests__/e2e/macros.test.ts +199 -0
  189. package/src/__tests__/e2e/migrate.test.ts +3008 -0
  190. package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
  191. package/src/__tests__/enum.test.ts +425 -0
  192. package/src/__tests__/generics.test.ts +390 -0
  193. package/src/__tests__/hir/desugar.test.ts +263 -0
  194. package/src/__tests__/incremental.test.ts +337 -0
  195. package/src/__tests__/lir/lower.test.ts +619 -0
  196. package/src/__tests__/lir/types.test.ts +207 -0
  197. package/src/__tests__/lir/verify.test.ts +249 -0
  198. package/src/__tests__/lsp.test.ts +270 -0
  199. package/src/__tests__/mc-integration.test.ts +1 -2
  200. package/src/__tests__/mc-version.test.ts +178 -0
  201. package/src/__tests__/mir/arithmetic.test.ts +156 -0
  202. package/src/__tests__/mir/control-flow.test.ts +242 -0
  203. package/src/__tests__/mir/verify.test.ts +254 -0
  204. package/src/__tests__/modules.test.ts +365 -0
  205. package/src/__tests__/optimizer/block_merge.test.ts +84 -0
  206. package/src/__tests__/optimizer/branch_simplify.test.ts +64 -0
  207. package/src/__tests__/optimizer/constant_fold.test.ts +145 -0
  208. package/src/__tests__/optimizer/copy_prop.test.ts +99 -0
  209. package/src/__tests__/optimizer/coroutine.test.ts +312 -0
  210. package/src/__tests__/optimizer/dce.test.ts +83 -0
  211. package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
  212. package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
  213. package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
  214. package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
  215. package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
  216. package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
  217. package/src/__tests__/optimizer/pipeline.test.ts +116 -0
  218. package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
  219. package/src/__tests__/optimizer/unroll.test.ts +231 -0
  220. package/src/__tests__/option.test.ts +299 -0
  221. package/src/__tests__/schedule.test.ts +105 -0
  222. package/src/__tests__/sourcemap.test.ts +254 -0
  223. package/src/__tests__/tuple.test.ts +220 -0
  224. package/src/__tests__/typechecker-strict.test.ts +216 -0
  225. package/src/ast/types.ts +39 -3
  226. package/src/cache/deps.ts +132 -0
  227. package/src/cache/incremental.ts +173 -0
  228. package/src/cache/index.ts +135 -0
  229. package/src/cli.ts +111 -195
  230. package/src/compile.ts +6 -162
  231. package/src/diagnostics/index.ts +8 -11
  232. package/src/emit/compile.ts +177 -0
  233. package/src/emit/index.ts +286 -0
  234. package/src/emit/modules.ts +581 -0
  235. package/src/emit/sourcemap.ts +101 -0
  236. package/src/hir/lower.ts +455 -0
  237. package/src/hir/monomorphize.ts +416 -0
  238. package/src/hir/types.ts +228 -0
  239. package/src/index.ts +37 -182
  240. package/src/lexer/index.ts +2 -1
  241. package/src/lir/budget.ts +321 -0
  242. package/src/lir/lower.ts +587 -0
  243. package/src/lir/types.ts +113 -0
  244. package/src/lir/verify.ts +129 -0
  245. package/src/lsp/main.ts +9 -0
  246. package/src/lsp/server.ts +414 -0
  247. package/src/mc-test/runner.ts +4 -3
  248. package/src/mir/lower.ts +1403 -0
  249. package/src/mir/macro.ts +167 -0
  250. package/src/mir/types.ts +117 -0
  251. package/src/mir/verify.ts +218 -0
  252. package/src/optimizer/block_merge.ts +93 -0
  253. package/src/optimizer/branch_simplify.ts +27 -0
  254. package/src/optimizer/constant_fold.ts +88 -0
  255. package/src/optimizer/copy_prop.ts +106 -0
  256. package/src/optimizer/coroutine.ts +996 -0
  257. package/src/optimizer/dce.ts +108 -653
  258. package/src/optimizer/interprocedural.ts +177 -0
  259. package/src/optimizer/lir/const_imm.ts +143 -0
  260. package/src/optimizer/lir/dead_slot.ts +123 -0
  261. package/src/optimizer/lir/peephole.ts +57 -0
  262. package/src/optimizer/lir/pipeline.ts +37 -0
  263. package/src/optimizer/nbt-batch.ts +50 -0
  264. package/src/optimizer/pipeline.ts +59 -0
  265. package/src/optimizer/selector-cache.ts +103 -0
  266. package/src/optimizer/unroll.ts +386 -0
  267. package/src/parser/index.ts +213 -16
  268. package/src/repl.ts +1 -1
  269. package/src/runtime/index.ts +1 -1
  270. package/src/stdlib/math.mcrs +4 -4
  271. package/src/templates/quest.mcrs +4 -4
  272. package/src/typechecker/index.ts +215 -15
  273. package/src/types/mc-version.ts +46 -0
  274. package/tsconfig.json +1 -1
  275. package/dist/__tests__/cli.test.js +0 -278
  276. package/dist/__tests__/codegen.test.js +0 -152
  277. package/dist/__tests__/e2e.test.d.ts +0 -6
  278. package/dist/__tests__/e2e.test.js +0 -1847
  279. package/dist/__tests__/entity-types.test.js +0 -203
  280. package/dist/__tests__/lowering.test.js +0 -1015
  281. package/dist/__tests__/macro.test.d.ts +0 -8
  282. package/dist/__tests__/macro.test.js +0 -305
  283. package/dist/__tests__/nbt.test.js +0 -82
  284. package/dist/__tests__/optimizer-advanced.test.js +0 -124
  285. package/dist/__tests__/optimizer.test.js +0 -149
  286. package/dist/__tests__/runtime.test.js +0 -289
  287. package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
  288. package/dist/__tests__/stdlib-advanced.test.js +0 -378
  289. package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
  290. package/dist/__tests__/stdlib-bigint.test.js +0 -428
  291. package/dist/__tests__/stdlib-math.test.d.ts +0 -7
  292. package/dist/__tests__/stdlib-math.test.js +0 -352
  293. package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
  294. package/dist/__tests__/stdlib-vec.test.js +0 -264
  295. package/dist/__tests__/structure-optimizer.test.js +0 -33
  296. package/dist/__tests__/var-allocator.test.js +0 -69
  297. package/dist/codegen/cmdblock/index.d.ts +0 -26
  298. package/dist/codegen/cmdblock/index.js +0 -45
  299. package/dist/codegen/mcfunction/index.d.ts +0 -40
  300. package/dist/codegen/mcfunction/index.js +0 -606
  301. package/dist/codegen/structure/index.d.ts +0 -24
  302. package/dist/codegen/structure/index.js +0 -279
  303. package/dist/codegen/var-allocator.d.ts +0 -45
  304. package/dist/codegen/var-allocator.js +0 -104
  305. package/dist/compile.d.ts +0 -68
  306. package/dist/data/arena/function/__load.mcfunction +0 -6
  307. package/dist/data/arena/function/__tick.mcfunction +0 -2
  308. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
  309. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
  310. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
  311. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
  312. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
  313. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
  314. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
  315. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
  316. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
  317. package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
  318. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
  319. package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
  320. package/dist/data/arena/function/arena_tick.mcfunction +0 -11
  321. package/dist/data/counter/function/__load.mcfunction +0 -5
  322. package/dist/data/counter/function/__tick.mcfunction +0 -2
  323. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
  324. package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
  325. package/dist/data/counter/function/counter_tick.mcfunction +0 -11
  326. package/dist/data/gcd2/function/__load.mcfunction +0 -3
  327. package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
  328. package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
  329. package/dist/data/gcd2/function/abs.mcfunction +0 -7
  330. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
  331. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
  332. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
  333. package/dist/data/gcd2/function/gcd.mcfunction +0 -14
  334. package/dist/data/gcd3/function/__load.mcfunction +0 -3
  335. package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
  336. package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
  337. package/dist/data/gcd3/function/abs.mcfunction +0 -7
  338. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
  339. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
  340. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
  341. package/dist/data/gcd3/function/gcd.mcfunction +0 -14
  342. package/dist/data/gcd3/function/test.mcfunction +0 -7
  343. package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
  344. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
  345. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
  346. package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
  347. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
  348. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
  349. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
  350. package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
  351. package/dist/data/gcd3nm/function/test.mcfunction +0 -7
  352. package/dist/data/gcd_test/function/__load.mcfunction +0 -3
  353. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
  354. package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
  355. package/dist/data/gcd_test/function/abs.mcfunction +0 -7
  356. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
  357. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
  358. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
  359. package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
  360. package/dist/data/isqrttest/function/__load.mcfunction +0 -6
  361. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
  362. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
  363. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
  364. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
  365. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
  366. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
  367. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
  368. package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
  369. package/dist/data/isqrttest/function/test.mcfunction +0 -6
  370. package/dist/data/mathtest/function/__load.mcfunction +0 -3
  371. package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
  372. package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
  373. package/dist/data/mathtest/function/abs.mcfunction +0 -6
  374. package/dist/data/mathtest/function/test.mcfunction +0 -5
  375. package/dist/data/minecraft/tags/function/load.json +0 -5
  376. package/dist/data/minecraft/tags/function/tick.json +0 -5
  377. package/dist/data/mypack/function/__load.mcfunction +0 -13
  378. package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
  379. package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
  380. package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
  381. package/dist/data/mypack/function/abs.mcfunction +0 -6
  382. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
  383. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
  384. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
  385. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
  386. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
  387. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
  388. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
  389. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
  390. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
  391. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
  392. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
  393. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
  394. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
  395. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
  396. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
  397. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
  398. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
  399. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
  400. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
  401. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
  402. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
  403. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
  404. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
  405. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
  406. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
  407. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
  408. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
  409. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
  410. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
  411. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
  412. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
  413. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
  414. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
  415. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
  416. package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
  417. package/dist/data/mypack/function/my_game.mcfunction +0 -10
  418. package/dist/data/quiz/function/__load.mcfunction +0 -16
  419. package/dist/data/quiz/function/__tick.mcfunction +0 -6
  420. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
  421. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
  422. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
  423. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
  424. package/dist/data/quiz/function/answer_a.mcfunction +0 -4
  425. package/dist/data/quiz/function/answer_b.mcfunction +0 -4
  426. package/dist/data/quiz/function/answer_c.mcfunction +0 -4
  427. package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
  428. package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
  429. package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
  430. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
  431. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
  432. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
  433. package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
  434. package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
  435. package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
  436. package/dist/data/quiz/function/ask_question.mcfunction +0 -7
  437. package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
  438. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
  439. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
  440. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
  441. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
  442. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
  443. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
  444. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
  445. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
  446. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
  447. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
  448. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
  449. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
  450. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
  451. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
  452. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
  453. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
  454. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
  455. package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
  456. package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
  457. package/dist/data/reqtest/function/__load.mcfunction +0 -4
  458. package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
  459. package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
  460. package/dist/data/reqtest/function/use_table.mcfunction +0 -4
  461. package/dist/data/reqtest2/function/__load.mcfunction +0 -3
  462. package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
  463. package/dist/data/runtime/function/__load.mcfunction +0 -5
  464. package/dist/data/runtime/function/__tick.mcfunction +0 -2
  465. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
  466. package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
  467. package/dist/data/shop/function/__load.mcfunction +0 -7
  468. package/dist/data/shop/function/__tick.mcfunction +0 -3
  469. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
  470. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
  471. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
  472. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
  473. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
  474. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
  475. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
  476. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
  477. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
  478. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
  479. package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
  480. package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
  481. package/dist/data/swap_test/function/__load.mcfunction +0 -3
  482. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
  483. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
  484. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
  485. package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
  486. package/dist/data/turret/function/__load.mcfunction +0 -5
  487. package/dist/data/turret/function/__tick.mcfunction +0 -4
  488. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
  489. package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
  490. package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
  491. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
  492. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
  493. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
  494. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
  495. package/dist/data/turret/function/turret_tick.mcfunction +0 -5
  496. package/dist/gcd2.map.json +0 -15
  497. package/dist/gcd3.map.json +0 -17
  498. package/dist/gcd_test.map.json +0 -15
  499. package/dist/index.d.ts +0 -62
  500. package/dist/ir/builder.d.ts +0 -33
  501. package/dist/ir/builder.js +0 -99
  502. package/dist/ir/types.d.ts +0 -132
  503. package/dist/ir/types.js +0 -15
  504. package/dist/isqrttest.map.json +0 -15
  505. package/dist/lowering/index.d.ts +0 -188
  506. package/dist/lowering/index.js +0 -3403
  507. package/dist/mathtest.map.json +0 -6
  508. package/dist/mypack.map.json +0 -27
  509. package/dist/optimizer/commands.d.ts +0 -38
  510. package/dist/optimizer/commands.js +0 -451
  511. package/dist/optimizer/dce.d.ts +0 -34
  512. package/dist/optimizer/dce.js +0 -639
  513. package/dist/optimizer/passes.d.ts +0 -34
  514. package/dist/optimizer/passes.js +0 -243
  515. package/dist/optimizer/structure.d.ts +0 -9
  516. package/dist/optimizer/structure.js +0 -356
  517. package/dist/pack.mcmeta +0 -6
  518. package/dist/reqtest.map.json +0 -4
  519. package/dist/reqtest2.map.json +0 -4
  520. package/dist/runtime.map.json +0 -7
  521. package/dist/swap_test.map.json +0 -14
  522. package/src/__tests__/codegen.test.ts +0 -161
  523. package/src/__tests__/e2e.test.ts +0 -2039
  524. package/src/__tests__/entity-types.test.ts +0 -236
  525. package/src/__tests__/lowering.test.ts +0 -1185
  526. package/src/__tests__/macro.test.ts +0 -343
  527. package/src/__tests__/nbt.test.ts +0 -58
  528. package/src/__tests__/optimizer-advanced.test.ts +0 -144
  529. package/src/__tests__/optimizer.test.ts +0 -162
  530. package/src/__tests__/runtime.test.ts +0 -305
  531. package/src/__tests__/stdlib-advanced.test.ts +0 -379
  532. package/src/__tests__/stdlib-bigint.test.ts +0 -427
  533. package/src/__tests__/stdlib-math.test.ts +0 -374
  534. package/src/__tests__/stdlib-vec.test.ts +0 -259
  535. package/src/__tests__/structure-optimizer.test.ts +0 -38
  536. package/src/__tests__/var-allocator.test.ts +0 -75
  537. package/src/codegen/cmdblock/index.ts +0 -63
  538. package/src/codegen/mcfunction/index.ts +0 -662
  539. package/src/codegen/structure/index.ts +0 -346
  540. package/src/codegen/var-allocator.ts +0 -104
  541. package/src/ir/builder.ts +0 -116
  542. package/src/ir/types.ts +0 -134
  543. package/src/lowering/index.ts +0 -3876
  544. package/src/optimizer/commands.ts +0 -534
  545. package/src/optimizer/passes.ts +0 -250
  546. package/src/optimizer/structure.ts +0 -450
  547. /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
  548. /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/cli.test.d.ts} +0 -0
  549. /package/dist/{__tests__ → src/__tests__}/compile-all.test.d.ts +0 -0
  550. /package/dist/{__tests__ → src/__tests__}/compile-all.test.js +0 -0
  551. /package/dist/{__tests__ → src/__tests__}/dce.test.d.ts +0 -0
  552. /package/dist/{__tests__ → src/__tests__}/diagnostics.test.d.ts +0 -0
  553. /package/dist/{__tests__ → src/__tests__}/formatter.test.d.ts +0 -0
  554. /package/dist/{__tests__ → src/__tests__}/formatter.test.js +0 -0
  555. /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/hir/desugar.test.d.ts} +0 -0
  556. /package/dist/{__tests__ → src/__tests__}/lexer.test.d.ts +0 -0
  557. /package/dist/{__tests__ → src/__tests__}/lexer.test.js +0 -0
  558. /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/lir/lower.test.d.ts} +0 -0
  559. /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/lir/types.test.d.ts} +0 -0
  560. /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/lir/verify.test.d.ts} +0 -0
  561. /package/dist/{__tests__ → src/__tests__}/mc-integration.test.d.ts +0 -0
  562. /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/mc-syntax.test.d.ts} +0 -0
  563. /package/dist/{__tests__ → src/__tests__}/mc-syntax.test.js +0 -0
  564. /package/dist/{__tests__/optimizer.test.d.ts → src/__tests__/mir/arithmetic.test.d.ts} +0 -0
  565. /package/dist/{__tests__/parser.test.d.ts → src/__tests__/mir/control-flow.test.d.ts} +0 -0
  566. /package/dist/{__tests__/repl.test.d.ts → src/__tests__/mir/verify.test.d.ts} +0 -0
  567. /package/dist/{__tests__/runtime.test.d.ts → src/__tests__/optimizer/block_merge.test.d.ts} +0 -0
  568. /package/dist/{__tests__/structure-optimizer.test.d.ts → src/__tests__/optimizer/branch_simplify.test.d.ts} +0 -0
  569. /package/dist/{__tests__/typechecker.test.d.ts → src/__tests__/optimizer/constant_fold.test.d.ts} +0 -0
  570. /package/dist/{__tests__/var-allocator.test.d.ts → src/__tests__/optimizer/copy_prop.test.d.ts} +0 -0
  571. /package/dist/{__tests__ → src/__tests__}/parser.test.js +0 -0
  572. /package/dist/{__tests__ → src/__tests__}/repl.test.js +0 -0
  573. /package/dist/{__tests__ → src/__tests__}/typechecker.test.js +0 -0
  574. /package/dist/{ast → src/ast}/types.js +0 -0
  575. /package/dist/{builtins → src/builtins}/metadata.d.ts +0 -0
  576. /package/dist/{builtins → src/builtins}/metadata.js +0 -0
  577. /package/dist/{events → src/events}/types.d.ts +0 -0
  578. /package/dist/{events → src/events}/types.js +0 -0
  579. /package/dist/{formatter → src/formatter}/index.d.ts +0 -0
  580. /package/dist/{formatter → src/formatter}/index.js +0 -0
  581. /package/dist/{mc-test → src/mc-test}/client.d.ts +0 -0
  582. /package/dist/{mc-test → src/mc-test}/client.js +0 -0
  583. /package/dist/{mc-test → src/mc-test}/runner.d.ts +0 -0
  584. /package/dist/{mc-test → src/mc-test}/setup.d.ts +0 -0
  585. /package/dist/{mc-test → src/mc-test}/setup.js +0 -0
  586. /package/dist/{mc-validator → src/mc-validator}/index.d.ts +0 -0
  587. /package/dist/{mc-validator → src/mc-validator}/index.js +0 -0
  588. /package/dist/{nbt → src/nbt}/index.d.ts +0 -0
  589. /package/dist/{nbt → src/nbt}/index.js +0 -0
  590. /package/dist/{repl.js → src/repl.js} +0 -0
  591. /package/dist/{runtime → src/runtime}/index.d.ts +0 -0
  592. /package/dist/{types → src/types}/entity-hierarchy.d.ts +0 -0
  593. /package/dist/{types → src/types}/entity-hierarchy.js +0 -0
package/src/index.ts CHANGED
@@ -1,205 +1,60 @@
1
1
  /**
2
2
  * RedScript Compiler
3
- *
3
+ *
4
4
  * Main entry point for programmatic usage.
5
5
  */
6
6
 
7
- // eslint-disable-next-line @typescript-eslint/no-var-requires
8
- export const version = '1.2.11'
7
+ export const version = '2.0.0'
9
8
 
10
- import { Lexer } from './lexer'
11
- import { Parser } from './parser'
12
- import { TypeChecker } from './typechecker'
13
- import { Lowering, setScoreboardObjective } from './lowering'
14
- import type { Warning } from './lowering'
15
- import {
16
- constantFoldingWithStats,
17
- copyPropagation,
18
- deadCodeEliminationWithStats,
19
- } from './optimizer/passes'
20
- import { eliminateDeadCode } from './optimizer/dce'
21
- import {
22
- countMcfunctionCommands,
23
- generateDatapackWithStats,
24
- DatapackFile,
25
- } from './codegen/mcfunction'
26
- import { preprocessSource, preprocessSourceWithMetadata } from './compile'
27
- import type { IRModule } from './ir/types'
28
- import type { Program } from './ast/types'
29
- import type { DiagnosticError } from './diagnostics'
30
- import { createEmptyOptimizationStats, type OptimizationStats } from './optimizer/commands'
9
+ import { compile } from './emit/compile'
31
10
 
32
- export interface CompileOptions {
33
- namespace?: string
34
- optimize?: boolean
35
- typeCheck?: boolean
36
- filePath?: string
37
- dce?: boolean
38
- mangle?: boolean
39
- /** Scoreboard objective used for all variable slots.
40
- * Defaults to '__<namespace>' (e.g. '__mathshow') to avoid collisions when
41
- * multiple RedScript datapacks are loaded simultaneously, without occupying
42
- * the user's own namespace. Override only if you need a specific name. */
43
- scoreboardObjective?: string
44
- }
45
-
46
- export interface CompileResult {
47
- files: DatapackFile[]
48
- advancements: DatapackFile[]
49
- ast: Program
50
- ir: IRModule
51
- typeErrors?: DiagnosticError[]
52
- warnings?: Warning[]
53
- stats?: OptimizationStats
54
- sourceMap?: Record<string, string>
55
- }
56
-
57
- /**
58
- * Compile RedScript source code to a Minecraft datapack.
59
- *
60
- * @param source - The RedScript source code
61
- * @param options - Compilation options
62
- * @returns Compiled datapack files
63
- */
64
- export function compile(source: string, options: CompileOptions = {}): CompileResult {
65
- const namespace = options.namespace ?? 'redscript'
66
- const shouldOptimize = options.optimize ?? true
67
- const shouldTypeCheck = options.typeCheck ?? true
68
- const shouldRunDce = options.dce ?? shouldOptimize
69
- const mangle = options.mangle ?? false
70
- const filePath = options.filePath
71
- const preprocessed = preprocessSourceWithMetadata(source, { filePath })
72
- const preprocessedSource = preprocessed.source
73
-
74
- // Lexing
75
- const tokens = new Lexer(preprocessedSource, filePath).tokenize()
76
-
77
- // Parsing — user source
78
- const parsedAst = new Parser(tokens, preprocessedSource, filePath).parse(namespace)
79
-
80
- // Library imports: files that declared `module library;` are parsed independently
81
- // (fresh Parser per file) so their functions are DCE-eligible but never bleed into user code.
82
- const allLibrarySources: Array<{ src: string; fp?: string }> = []
83
- for (const li of preprocessed.libraryImports ?? []) {
84
- allLibrarySources.push({ src: li.source, fp: li.filePath })
85
- }
86
- for (const { src, fp } of allLibrarySources) {
87
- const libPreprocessed = preprocessSourceWithMetadata(src, fp ? { filePath: fp } : {})
88
- const libTokens = new Lexer(libPreprocessed.source, fp).tokenize()
89
- const libAst = new Parser(libTokens, libPreprocessed.source, fp).parse(namespace)
90
- for (const fn of libAst.declarations) fn.isLibraryFn = true
91
- parsedAst.declarations.push(...libAst.declarations)
92
- parsedAst.structs.push(...libAst.structs)
93
- parsedAst.implBlocks.push(...libAst.implBlocks)
94
- parsedAst.enums.push(...libAst.enums)
95
- parsedAst.consts.push(...libAst.consts)
96
- parsedAst.globals.push(...libAst.globals)
97
- }
98
-
99
- const dceResult = shouldRunDce ? eliminateDeadCode(parsedAst, preprocessed.ranges) : { program: parsedAst, warnings: [] }
100
- const ast = dceResult.program
101
-
102
- // Type checking (warn mode - collect errors but don't block)
103
- let typeErrors: DiagnosticError[] | undefined
104
- if (shouldTypeCheck) {
105
- const checker = new TypeChecker(preprocessedSource, filePath)
106
- typeErrors = checker.check(ast)
107
- }
108
-
109
- // Configure scoreboard objective for this compilation.
110
- // Default: use the datapack namespace so each datapack gets its own objective
111
- // automatically, preventing variable collisions when multiple datapacks coexist.
112
- const scoreboardObj = options.scoreboardObjective ?? `__${namespace}`
113
- setScoreboardObjective(scoreboardObj)
114
-
115
- // Lowering to IR
116
- const lowering = new Lowering(namespace, preprocessed.ranges)
117
- const ir = lowering.lower(ast)
118
-
119
- let optimizedIR: IRModule = ir
120
- let generated = generateDatapackWithStats(ir, { optimizeCommands: shouldOptimize, mangle, scoreboardObjective: scoreboardObj })
121
- let optimizationStats: OptimizationStats | undefined
122
-
123
- if (shouldOptimize) {
124
- const stats = createEmptyOptimizationStats()
125
- const copyPropagatedFunctions = []
126
- const deadCodeEliminatedFunctions = []
127
-
128
- for (const fn of ir.functions) {
129
- const folded = constantFoldingWithStats(fn)
130
- stats.constantFolds += folded.stats.constantFolds ?? 0
11
+ // Re-export v2 compile API
12
+ export { compile, CompileOptions, CompileResult } from './emit/compile'
13
+ export { compileModules } from './emit/modules'
14
+ export type { ModuleInput, CompileModulesOptions, CompileModulesResult } from './emit/modules'
15
+ export { McVersion, parseMcVersion, compareMcVersion, DEFAULT_MC_VERSION } from './types/mc-version'
16
+ export type { DatapackFile } from './emit/index'
131
17
 
132
- const propagated = copyPropagation(folded.fn)
133
- copyPropagatedFunctions.push(propagated)
134
-
135
- const dce = deadCodeEliminationWithStats(propagated)
136
- deadCodeEliminatedFunctions.push(dce.fn)
137
- }
138
-
139
- const copyPropagatedIR: IRModule = { ...ir, functions: copyPropagatedFunctions }
140
- optimizedIR = { ...ir, functions: deadCodeEliminatedFunctions }
141
-
142
- const baselineGenerated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
143
- const beforeDceGenerated = generateDatapackWithStats(copyPropagatedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
144
- const afterDceGenerated = generateDatapackWithStats(optimizedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
145
- generated = generateDatapackWithStats(optimizedIR, { optimizeCommands: true, mangle, scoreboardObjective: scoreboardObj })
18
+ // Re-export utilities
19
+ export { Lexer } from './lexer'
20
+ export { Parser } from './parser'
21
+ export { preprocessSource, preprocessSourceWithMetadata } from './compile'
22
+ export { MCCommandValidator } from './mc-validator'
23
+ export type { Program, FnDecl, Expr, Stmt, Span } from './ast/types'
24
+ export type { DiagnosticError } from './diagnostics'
146
25
 
147
- stats.deadCodeRemoved =
148
- countMcfunctionCommands(beforeDceGenerated.files) - countMcfunctionCommands(afterDceGenerated.files)
149
- stats.licmHoists = generated.stats.licmHoists
150
- stats.licmLoopBodies = generated.stats.licmLoopBodies
151
- stats.cseRedundantReads = generated.stats.cseRedundantReads
152
- stats.cseArithmetic = generated.stats.cseArithmetic
153
- stats.setblockMergedCommands = generated.stats.setblockMergedCommands
154
- stats.setblockFillCommands = generated.stats.setblockFillCommands
155
- stats.setblockSavedCommands = generated.stats.setblockSavedCommands
156
- stats.totalCommandsBefore = countMcfunctionCommands(baselineGenerated.files)
157
- stats.totalCommandsAfter = countMcfunctionCommands(generated.files)
158
- optimizationStats = stats
159
- } else {
160
- optimizedIR = ir
161
- generated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
162
- }
26
+ // Incremental compilation
27
+ export { FileCache, hashFile } from './cache/index'
28
+ export { DependencyGraph, parseImports } from './cache/deps'
29
+ export { compileIncremental, resetCompileCache } from './cache/incremental'
30
+ export type { IncrementalOptions, IncrementalResult } from './cache/incremental'
163
31
 
164
- return {
165
- files: [...generated.files, ...generated.advancements],
166
- advancements: generated.advancements,
167
- ast,
168
- ir: optimizedIR,
169
- typeErrors,
170
- warnings: [...dceResult.warnings, ...lowering.warnings],
171
- stats: optimizationStats,
172
- sourceMap: generated.sourceMap,
173
- }
32
+ export interface CheckResult {
33
+ error: Error | null
34
+ warnings: string[]
174
35
  }
175
36
 
176
37
  /**
177
38
  * Check RedScript source code for errors without generating output.
178
- *
39
+ * Runs the full compile pipeline (lex → parse → HIR → MIR → LIR → emit)
40
+ * to catch type-level and lowering errors, not just parse errors.
41
+ *
179
42
  * @param source - The RedScript source code
180
43
  * @param namespace - Optional namespace
181
44
  * @returns null if no errors, or an error object
182
45
  */
183
46
  export function check(source: string, namespace = 'redscript', filePath?: string): Error | null {
47
+ return checkWithWarnings(source, namespace, filePath).error
48
+ }
49
+
50
+ /**
51
+ * Like check(), but also returns warnings (e.g., tick budget analysis).
52
+ */
53
+ export function checkWithWarnings(source: string, namespace = 'redscript', filePath?: string): CheckResult {
184
54
  try {
185
- const preprocessedSource = preprocessSource(source, { filePath })
186
- const tokens = new Lexer(preprocessedSource, filePath).tokenize()
187
- new Parser(tokens, preprocessedSource, filePath).parse(namespace)
188
- return null
55
+ const result = compile(source, { namespace, filePath })
56
+ return { error: null, warnings: result.warnings }
189
57
  } catch (err) {
190
- return err as Error
58
+ return { error: err as Error, warnings: [] }
191
59
  }
192
60
  }
193
-
194
- // Re-export types and classes for advanced usage
195
- export { Lexer } from './lexer'
196
- export { Parser } from './parser'
197
- export { TypeChecker } from './typechecker'
198
- export { Lowering } from './lowering'
199
- export { optimize } from './optimizer/passes'
200
- export { generateDatapack } from './codegen/mcfunction'
201
- export { MCCommandValidator } from './mc-validator'
202
- export type { DatapackFile } from './codegen/mcfunction'
203
- export type { IRModule, IRFunction } from './ir/types'
204
- export type { Program, FnDecl, Expr, Stmt, Span } from './ast/types'
205
- export type { DiagnosticError } from './diagnostics'
@@ -16,7 +16,7 @@ export type TokenKind =
16
16
  // Keywords
17
17
  | 'fn' | 'let' | 'const' | 'if' | 'else' | 'while' | 'for' | 'foreach' | 'match'
18
18
  | 'return' | 'break' | 'continue' | 'as' | 'at' | 'in' | 'is' | 'struct' | 'impl' | 'enum' | 'trigger' | 'namespace' | 'module'
19
- | 'execute' | 'run' | 'unless' | 'declare'
19
+ | 'execute' | 'run' | 'unless' | 'declare' | 'export'
20
20
  // Types
21
21
  | 'int' | 'bool' | 'float' | 'string' | 'void'
22
22
  | 'BlockPos'
@@ -91,6 +91,7 @@ const KEYWORDS: Record<string, TokenKind> = {
91
91
  run: 'run',
92
92
  unless: 'unless',
93
93
  declare: 'declare',
94
+ export: 'export',
94
95
  int: 'int',
95
96
  bool: 'bool',
96
97
  float: 'float',
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Static Tick Budget Analysis — Phase 1a
3
+ *
4
+ * Estimates the number of MC commands a function will execute at runtime.
5
+ * Used to warn when loops may exceed Minecraft's maxCommandChainLength (65536).
6
+ *
7
+ * In LIR, loops are represented as mutually-recursive function calls
8
+ * (e.g., fn__header ↔ fn__body). This module detects call-graph cycles
9
+ * and multiplies the loop body cost by an estimated iteration count.
10
+ */
11
+
12
+ import type { LIRModule, LIRFunction, LIRInstr } from './types'
13
+
14
+ /** Default estimated iteration count when the upper bound is unknown */
15
+ const DEFAULT_LOOP_ITERATIONS = 100
16
+
17
+ /** Warning threshold: suggest @coroutine */
18
+ export const BUDGET_WARN_THRESHOLD = 32768
19
+
20
+ /** Error threshold: likely exceeds maxCommandChainLength */
21
+ export const BUDGET_ERROR_THRESHOLD = 65536
22
+
23
+ export interface BudgetDiagnostic {
24
+ level: 'warning' | 'error'
25
+ fnName: string
26
+ estimatedCommands: number
27
+ message: string
28
+ }
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Call graph utilities
32
+ // ---------------------------------------------------------------------------
33
+
34
+ /** Extract all function names called by an instruction */
35
+ function getCalledFunctions(instr: LIRInstr): string[] {
36
+ switch (instr.kind) {
37
+ case 'call':
38
+ case 'call_macro':
39
+ return [instr.fn]
40
+ case 'call_if_matches':
41
+ case 'call_unless_matches':
42
+ case 'call_if_score':
43
+ case 'call_unless_score':
44
+ case 'call_context':
45
+ return [instr.fn]
46
+ case 'store_cmd_to_score':
47
+ // The nested cmd may also be a call
48
+ return getCalledFunctions(instr.cmd)
49
+ default:
50
+ return []
51
+ }
52
+ }
53
+
54
+ /** Build adjacency list: fnName → set of called function names (module-local only) */
55
+ function buildCallGraph(mod: LIRModule): Map<string, Set<string>> {
56
+ const fnNames = new Set(mod.functions.map(f => f.name))
57
+ const graph = new Map<string, Set<string>>()
58
+
59
+ for (const fn of mod.functions) {
60
+ const callees = new Set<string>()
61
+ for (const instr of fn.instructions) {
62
+ for (const callee of getCalledFunctions(instr)) {
63
+ // Strip namespace prefix to match local function names
64
+ const local = stripNamespace(callee, mod.namespace)
65
+ if (fnNames.has(local)) {
66
+ callees.add(local)
67
+ }
68
+ }
69
+ }
70
+ graph.set(fn.name, callees)
71
+ }
72
+
73
+ return graph
74
+ }
75
+
76
+ /** Strip "namespace:" prefix from a qualified function name */
77
+ function stripNamespace(qualifiedName: string, namespace: string): string {
78
+ const prefix = `${namespace}:`
79
+ if (qualifiedName.startsWith(prefix)) {
80
+ return qualifiedName.slice(prefix.length)
81
+ }
82
+ return qualifiedName
83
+ }
84
+
85
+ /** Find all strongly connected components (Tarjan's algorithm) */
86
+ function findSCCs(graph: Map<string, Set<string>>): string[][] {
87
+ let index = 0
88
+ const stack: string[] = []
89
+ const onStack = new Set<string>()
90
+ const indices = new Map<string, number>()
91
+ const lowlinks = new Map<string, number>()
92
+ const sccs: string[][] = []
93
+
94
+ function strongconnect(v: string): void {
95
+ indices.set(v, index)
96
+ lowlinks.set(v, index)
97
+ index++
98
+ stack.push(v)
99
+ onStack.add(v)
100
+
101
+ for (const w of graph.get(v) ?? []) {
102
+ if (!indices.has(w)) {
103
+ strongconnect(w)
104
+ lowlinks.set(v, Math.min(lowlinks.get(v)!, lowlinks.get(w)!))
105
+ } else if (onStack.has(w)) {
106
+ lowlinks.set(v, Math.min(lowlinks.get(v)!, indices.get(w)!))
107
+ }
108
+ }
109
+
110
+ if (lowlinks.get(v) === indices.get(v)) {
111
+ const scc: string[] = []
112
+ let w: string
113
+ do {
114
+ w = stack.pop()!
115
+ onStack.delete(w)
116
+ scc.push(w)
117
+ } while (w !== v)
118
+ sccs.push(scc)
119
+ }
120
+ }
121
+
122
+ for (const v of graph.keys()) {
123
+ if (!indices.has(v)) {
124
+ strongconnect(v)
125
+ }
126
+ }
127
+
128
+ return sccs
129
+ }
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // Command count estimation
133
+ // ---------------------------------------------------------------------------
134
+
135
+ /** Count the number of MC commands an instruction generates (non-recursive) */
136
+ function instrCommandCount(instr: LIRInstr): number {
137
+ switch (instr.kind) {
138
+ case 'store_cmd_to_score':
139
+ // The execute store wrapper + the inner command
140
+ return 1
141
+ default:
142
+ // Each LIR instruction maps to ~1 MC command
143
+ return 1
144
+ }
145
+ }
146
+
147
+ /** Count raw (non-call) commands in a function */
148
+ function localCommandCount(fn: LIRFunction): number {
149
+ let count = 0
150
+ for (const instr of fn.instructions) {
151
+ count += instrCommandCount(instr)
152
+ }
153
+ return count
154
+ }
155
+
156
+ /**
157
+ * Try to extract a constant loop bound from a loop's LIR functions.
158
+ *
159
+ * Looks for patterns like:
160
+ * score_set <limit_slot> <N>
161
+ * in the cycle's functions, where N is used as a comparison bound.
162
+ *
163
+ * Returns the bound if found, otherwise DEFAULT_LOOP_ITERATIONS.
164
+ */
165
+ function estimateLoopIterations(cycleFns: LIRFunction[]): number {
166
+ // Look for score_set instructions that might be loop bounds
167
+ // Heuristic: find the largest constant set in the cycle's callers
168
+ // that looks like a loop limit (typically set before the loop)
169
+ for (const fn of cycleFns) {
170
+ for (const instr of fn.instructions) {
171
+ if (instr.kind === 'call_if_matches' || instr.kind === 'call_unless_matches') {
172
+ // Parse range like "..999" or "0..999" to extract upper bound
173
+ const range = instr.range
174
+ const match = range.match(/\.\.(\d+)/)
175
+ if (match) {
176
+ return parseInt(match[1], 10) + 1
177
+ }
178
+ }
179
+ }
180
+ }
181
+
182
+ return DEFAULT_LOOP_ITERATIONS
183
+ }
184
+
185
+ /**
186
+ * Estimate the total command count for a function, including callees.
187
+ *
188
+ * @param fnName - Name of the function to estimate
189
+ * @param mod - The LIR module
190
+ * @returns Estimated number of MC commands
191
+ */
192
+ export function estimateCommandCount(fnName: string, mod: LIRModule): number {
193
+ const fnMap = new Map<string, LIRFunction>()
194
+ for (const fn of mod.functions) {
195
+ fnMap.set(fn.name, fn)
196
+ }
197
+
198
+ const callGraph = buildCallGraph(mod)
199
+ const sccs = findSCCs(callGraph)
200
+
201
+ // Map each function to its SCC
202
+ const fnToSCC = new Map<string, string[]>()
203
+ for (const scc of sccs) {
204
+ for (const name of scc) {
205
+ fnToSCC.set(name, scc)
206
+ }
207
+ }
208
+
209
+ // Memoize estimated counts
210
+ const memo = new Map<string, number>()
211
+
212
+ function estimate(name: string, visiting: Set<string>): number {
213
+ if (memo.has(name)) return memo.get(name)!
214
+
215
+ const fn = fnMap.get(name)
216
+ if (!fn) return 0
217
+
218
+ // Detect cycle: if we're already visiting this function, return 0
219
+ // (cycle cost is handled at the SCC level)
220
+ if (visiting.has(name)) return 0
221
+
222
+ visiting.add(name)
223
+
224
+ const scc = fnToSCC.get(name)!
225
+ const isCyclic = scc.length > 1 || (scc.length === 1 && callGraph.get(name)?.has(name))
226
+
227
+ if (isCyclic) {
228
+ // Sum local commands across all functions in the cycle
229
+ let cycleLocalCost = 0
230
+ for (const member of scc) {
231
+ const memberFn = fnMap.get(member)
232
+ if (memberFn) cycleLocalCost += localCommandCount(memberFn)
233
+ }
234
+
235
+ // Estimate iterations
236
+ const cycleFns = scc.map(n => fnMap.get(n)!).filter(Boolean)
237
+ const iterations = estimateLoopIterations(cycleFns)
238
+
239
+ // Also add cost of non-cycle callees
240
+ let externalCalleeCost = 0
241
+ for (const member of scc) {
242
+ for (const callee of callGraph.get(member) ?? []) {
243
+ if (!scc.includes(callee)) {
244
+ externalCalleeCost += estimate(callee, new Set(visiting))
245
+ }
246
+ }
247
+ }
248
+
249
+ const total = (cycleLocalCost + externalCalleeCost) * iterations
250
+ // Memoize for all members of this SCC
251
+ for (const member of scc) {
252
+ memo.set(member, total)
253
+ }
254
+ visiting.delete(name)
255
+ return total
256
+ }
257
+
258
+ // Non-cyclic: local cost + callee costs
259
+ let total = localCommandCount(fn)
260
+ for (const callee of callGraph.get(name) ?? []) {
261
+ total += estimate(callee, visiting)
262
+ }
263
+
264
+ memo.set(name, total)
265
+ visiting.delete(name)
266
+ return total
267
+ }
268
+
269
+ return estimate(fnName, new Set())
270
+ }
271
+
272
+ // ---------------------------------------------------------------------------
273
+ // Budget analysis for a full module
274
+ // ---------------------------------------------------------------------------
275
+
276
+ /**
277
+ * Analyze all "top-level" functions in the module for tick budget violations.
278
+ *
279
+ * @param mod - The LIR module to analyze
280
+ * @param coroutineFunctions - Set of function names marked @coroutine (skip these)
281
+ * @returns Array of budget diagnostics (warnings and errors)
282
+ */
283
+ export function analyzeBudget(
284
+ mod: LIRModule,
285
+ coroutineFunctions: Set<string> = new Set(),
286
+ ): BudgetDiagnostic[] {
287
+ const diagnostics: BudgetDiagnostic[] = []
288
+
289
+ // Only analyze user-defined "root" functions, not compiler-generated helper blocks
290
+ // Helper blocks have names like "fnname__blockid"
291
+ for (const fn of mod.functions) {
292
+ // Skip coroutine-annotated functions
293
+ if (coroutineFunctions.has(fn.name)) continue
294
+
295
+ // Skip compiler-generated helper functions (contain __)
296
+ if (fn.name.includes('__')) continue
297
+
298
+ // Skip coroutine-generated functions
299
+ if (fn.name.startsWith('_coro_')) continue
300
+
301
+ const estimated = estimateCommandCount(fn.name, mod)
302
+
303
+ if (estimated > BUDGET_ERROR_THRESHOLD) {
304
+ diagnostics.push({
305
+ level: 'error',
306
+ fnName: fn.name,
307
+ estimatedCommands: estimated,
308
+ message: `function '${fn.name}' may exceed tick budget (~${estimated} commands), this will likely crash. Consider @coroutine or reducing loop iterations`,
309
+ })
310
+ } else if (estimated > BUDGET_WARN_THRESHOLD) {
311
+ diagnostics.push({
312
+ level: 'warning',
313
+ fnName: fn.name,
314
+ estimatedCommands: estimated,
315
+ message: `loop may exceed tick budget (~${estimated} commands), consider @coroutine`,
316
+ })
317
+ }
318
+ }
319
+
320
+ return diagnostics
321
+ }