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
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { DiagnosticError, DiagnosticCollector, formatError, parseErrorMessage } from '../diagnostics'
6
- import { compile, formatCompileError } from '../compile'
6
+ import { compile } from '../compile'
7
7
 
8
8
  describe('DiagnosticError', () => {
9
9
  describe('formatError', () => {
@@ -21,10 +21,9 @@ describe('DiagnosticError', () => {
21
21
  )
22
22
 
23
23
  expect(formatError(error, source)).toBe([
24
- 'Error at line 2, col 11:',
24
+ '<input>:2:11: error: Unknown function: foo',
25
25
  ' let x = foo(',
26
26
  ' ^',
27
- 'Unknown function: foo',
28
27
  ].join('\n'))
29
28
  })
30
29
 
@@ -37,7 +36,7 @@ describe('DiagnosticError', () => {
37
36
  source.split('\n')
38
37
  )
39
38
 
40
- expect(formatError(error, source)).toContain('Error in test.mcrs at line 1, col 9:')
39
+ expect(formatError(error, source)).toContain('test.mcrs:1:9: error: Unknown function: foo')
41
40
  })
42
41
  })
43
42
 
@@ -126,70 +125,91 @@ describe('parseErrorMessage', () => {
126
125
 
127
126
  describe('compile function', () => {
128
127
  it('returns success for valid code', () => {
129
- const result = compile('fn main() { let x = 1; }')
128
+ const result = compile('fn main() { let x = 1; }', { namespace: 'test' })
130
129
  expect(result.success).toBe(true)
131
130
  expect(result.files).toBeDefined()
132
131
  })
133
132
 
134
- it('returns DiagnosticError for lex errors', () => {
135
- const result = compile('fn main() { let x = $ }')
136
- expect(result.success).toBe(false)
137
- expect(result.error).toBeInstanceOf(DiagnosticError)
138
- expect(result.error?.kind).toBe('LexError')
133
+ it('throws DiagnosticError for lex errors', () => {
134
+ expect(() => compile('fn main() { let x = $ }', { namespace: 'test' }))
135
+ .toThrow()
136
+ try {
137
+ compile('fn main() { let x = $ }', { namespace: 'test' })
138
+ } catch (e) {
139
+ expect(e).toBeInstanceOf(DiagnosticError)
140
+ expect((e as DiagnosticError).kind).toBe('LexError')
141
+ }
139
142
  })
140
143
 
141
- it('returns DiagnosticError for parse errors', () => {
142
- const result = compile('fn main() { let x = }')
143
- expect(result.success).toBe(false)
144
- expect(result.error).toBeInstanceOf(DiagnosticError)
145
- expect(result.error?.kind).toBe('ParseError')
144
+ it('throws DiagnosticError for parse errors', () => {
145
+ expect(() => compile('fn main() { let x = }', { namespace: 'test' }))
146
+ .toThrow()
147
+ try {
148
+ compile('fn main() { let x = }', { namespace: 'test' })
149
+ } catch (e) {
150
+ expect(e).toBeInstanceOf(DiagnosticError)
151
+ expect((e as DiagnosticError).kind).toBe('ParseError')
152
+ }
146
153
  })
147
154
 
148
- it('returns DiagnosticError for missing semicolon', () => {
149
- const result = compile('fn main() { let x = 42 }')
150
- expect(result.success).toBe(false)
151
- expect(result.error?.kind).toBe('ParseError')
152
- expect(result.error?.message).toContain("Expected ';'")
155
+ it('throws DiagnosticError for missing semicolon', () => {
156
+ try {
157
+ compile('fn main() { let x = 42 }', { namespace: 'test' })
158
+ fail('Expected compile to throw')
159
+ } catch (e) {
160
+ expect((e as DiagnosticError).kind).toBe('ParseError')
161
+ expect((e as DiagnosticError).message).toContain("Expected ';'")
162
+ }
153
163
  })
154
164
 
155
165
  it('includes file path in error', () => {
156
- const result = compile('fn main() { }', { filePath: 'test.mcrs' })
157
- // This is valid, but test that filePath is passed through
166
+ const result = compile('fn main() { }', { filePath: 'test.mcrs', namespace: 'test' })
158
167
  expect(result.success).toBe(true)
159
168
  })
160
169
 
161
170
  it('formats error nicely', () => {
162
- const result = compile('fn main() {\n let x = 42\n}')
163
- expect(result.success).toBe(false)
164
- const formatted = formatCompileError(result)
165
- expect(formatted).toContain('Error at line')
166
- expect(formatted).toContain('^')
167
- // Error points to } on line 3, which is where semicolon was expected
168
- expect(formatted).toContain('}')
171
+ try {
172
+ compile('fn main() {\n let x = 42\n}', { namespace: 'test' })
173
+ fail('Expected compile to throw')
174
+ } catch (e) {
175
+ expect(e).toBeInstanceOf(DiagnosticError)
176
+ const formatted = (e as DiagnosticError).format()
177
+ expect(formatted).toContain('line')
178
+ expect(formatted).toContain('^')
179
+ }
169
180
  })
170
181
  })
171
182
 
172
183
  describe('Lexer DiagnosticError', () => {
173
184
  it('throws DiagnosticError for unexpected character', () => {
174
- const result = compile('fn main() { let x = $ }')
175
- expect(result.success).toBe(false)
176
- expect(result.error?.kind).toBe('LexError')
177
- expect(result.error?.message).toContain('Unexpected character')
185
+ try {
186
+ compile('fn main() { let x = $ }', { namespace: 'test' })
187
+ fail('Expected compile to throw')
188
+ } catch (e) {
189
+ expect((e as DiagnosticError).kind).toBe('LexError')
190
+ expect((e as DiagnosticError).message).toContain('Unexpected character')
191
+ }
178
192
  })
179
193
 
180
194
  it('throws DiagnosticError for unterminated string', () => {
181
- const result = compile('fn main() { let x = "hello }')
182
- expect(result.success).toBe(false)
183
- expect(result.error?.kind).toBe('LexError')
184
- expect(result.error?.message).toContain('Unterminated string')
195
+ try {
196
+ compile('fn main() { let x = "hello }', { namespace: 'test' })
197
+ fail('Expected compile to throw')
198
+ } catch (e) {
199
+ expect((e as DiagnosticError).kind).toBe('LexError')
200
+ expect((e as DiagnosticError).message).toContain('Unterminated string')
201
+ }
185
202
  })
186
203
  })
187
204
 
188
205
  describe('Parser DiagnosticError', () => {
189
206
  it('includes line and column info', () => {
190
- const result = compile('fn main() { return }')
191
- expect(result.success).toBe(false)
192
- expect(result.error?.location.line).toBeGreaterThan(0)
193
- expect(result.error?.location.col).toBeGreaterThan(0)
207
+ try {
208
+ compile('fn main() { return }', { namespace: 'test' })
209
+ fail('Expected compile to throw')
210
+ } catch (e) {
211
+ expect((e as DiagnosticError).location.line).toBeGreaterThan(0)
212
+ expect((e as DiagnosticError).location.col).toBeGreaterThan(0)
213
+ }
194
214
  })
195
215
  })
@@ -0,0 +1,154 @@
1
+ /**
2
+ * End-to-end tests for the v2 compiler pipeline.
3
+ *
4
+ * These tests compile RedScript source through the full pipeline
5
+ * (Lexer → Parser → HIR → MIR → optimize → LIR → emit) and verify
6
+ * the generated .mcfunction output contains expected MC commands.
7
+ */
8
+
9
+ import { compile } from '../../emit/compile'
10
+
11
+ function getFile(files: { path: string; content: string }[], pathSubstr: string): string | undefined {
12
+ const f = files.find(f => f.path.includes(pathSubstr))
13
+ return f?.content
14
+ }
15
+
16
+ describe('e2e: basic compilation', () => {
17
+ test('simple arithmetic function produces scoreboard commands', () => {
18
+ const source = `
19
+ fn add(a: int, b: int): int {
20
+ return a + b;
21
+ }
22
+ `
23
+ const result = compile(source, { namespace: 'test' })
24
+ expect(result.files.length).toBeGreaterThan(0)
25
+
26
+ const addFn = getFile(result.files, 'add.mcfunction')
27
+ expect(addFn).toBeDefined()
28
+ expect(addFn).toContain('scoreboard players operation')
29
+ expect(addFn).toContain('__test')
30
+ })
31
+
32
+ test('pack.mcmeta is generated with pack_format 26', () => {
33
+ const source = `fn noop(): void {}`
34
+ const result = compile(source, { namespace: 'demo' })
35
+ const meta = getFile(result.files, 'pack.mcmeta')
36
+ expect(meta).toBeDefined()
37
+ const parsed = JSON.parse(meta!)
38
+ expect(parsed.pack.pack_format).toBe(26)
39
+ })
40
+
41
+ test('load.mcfunction creates scoreboard objective', () => {
42
+ const source = `fn noop(): void {}`
43
+ const result = compile(source, { namespace: 'mypack' })
44
+ const load = getFile(result.files, 'load.mcfunction')
45
+ expect(load).toBeDefined()
46
+ expect(load).toContain('scoreboard objectives add __mypack dummy')
47
+ })
48
+
49
+ test('@tick function appears in tick.json', () => {
50
+ const source = `
51
+ @tick fn game_tick(): void {
52
+ let x: int = 1;
53
+ }
54
+ `
55
+ const result = compile(source, { namespace: 'ticktest' })
56
+ const tickJson = getFile(result.files, 'tick.json')
57
+ expect(tickJson).toBeDefined()
58
+ const parsed = JSON.parse(tickJson!)
59
+ expect(parsed.values).toContain('ticktest:game_tick')
60
+ })
61
+
62
+ test('@load function appears in load.json', () => {
63
+ const source = `
64
+ @load fn setup(): void {
65
+ let x: int = 42;
66
+ }
67
+ `
68
+ const result = compile(source, { namespace: 'loadtest' })
69
+ const loadJson = getFile(result.files, 'load.json')
70
+ expect(loadJson).toBeDefined()
71
+ const parsed = JSON.parse(loadJson!)
72
+ expect(parsed.values).toContain('loadtest:setup')
73
+ // load.json should also reference the objective-init load function
74
+ expect(parsed.values).toContain('loadtest:load')
75
+ })
76
+
77
+ test('if/else produces conditional call pattern', () => {
78
+ const source = `
79
+ fn check(x: int): int {
80
+ if (x > 0) {
81
+ return 1;
82
+ } else {
83
+ return 0;
84
+ }
85
+ }
86
+ `
87
+ const result = compile(source, { namespace: 'cond' })
88
+
89
+ // The main function should contain call_if_matches / call_unless_matches
90
+ const checkFn = getFile(result.files, 'check.mcfunction')
91
+ expect(checkFn).toBeDefined()
92
+ expect(checkFn).toContain('execute if score')
93
+ expect(checkFn).toContain('matches')
94
+ expect(checkFn).toContain('run function')
95
+ })
96
+
97
+ test('while loop produces loop structure with recursive call', () => {
98
+ const source = `
99
+ fn count(): void {
100
+ let i: int = 0;
101
+ while (i < 10) {
102
+ i = i + 1;
103
+ }
104
+ }
105
+ `
106
+ const result = compile(source, { namespace: 'loop' })
107
+
108
+ // There should be a loop body function that calls itself (or a header)
109
+ const fnFiles = result.files.filter(f => f.path.endsWith('.mcfunction'))
110
+ expect(fnFiles.length).toBeGreaterThan(1) // main + at least one extracted block
111
+
112
+ // At least one file should have a conditional call pattern for the loop
113
+ const allContent = fnFiles.map(f => f.content).join('\n')
114
+ expect(allContent).toContain('execute if score')
115
+ expect(allContent).toContain('run function')
116
+ })
117
+
118
+ test('function names are lowercased in output paths', () => {
119
+ const source = `fn MyFunc(): void {}`
120
+ const result = compile(source, { namespace: 'ns' })
121
+ const fn = result.files.find(f => f.path.includes('myfunc.mcfunction'))
122
+ expect(fn).toBeDefined()
123
+ })
124
+
125
+ test('constant assignment produces score_set', () => {
126
+ const source = `
127
+ fn init(): int {
128
+ let x: int = 42;
129
+ return x;
130
+ }
131
+ `
132
+ const result = compile(source, { namespace: 'cst' })
133
+ const fn = getFile(result.files, 'init.mcfunction')
134
+ expect(fn).toBeDefined()
135
+ expect(fn).toContain('scoreboard players set')
136
+ expect(fn).toContain('42')
137
+ })
138
+
139
+ test('load.json always includes namespace:load', () => {
140
+ const source = `fn noop(): void {}`
141
+ const result = compile(source, { namespace: 'abc' })
142
+ const loadJson = getFile(result.files, 'load.json')
143
+ expect(loadJson).toBeDefined()
144
+ const parsed = JSON.parse(loadJson!)
145
+ expect(parsed.values).toContain('abc:load')
146
+ })
147
+
148
+ test('no tick.json when no @tick functions', () => {
149
+ const source = `fn noop(): void {}`
150
+ const result = compile(source, { namespace: 'notick' })
151
+ const tickJson = getFile(result.files, 'tick.json')
152
+ expect(tickJson).toBeUndefined()
153
+ })
154
+ })
@@ -0,0 +1,142 @@
1
+ /**
2
+ * End-to-end tests for @coroutine decorator.
3
+ *
4
+ * Compiles RedScript with @coroutine through the full pipeline and
5
+ * verifies generated .mcfunction output and tick.json registration.
6
+ */
7
+
8
+ import { compile } from '../../emit/compile'
9
+
10
+ function getFile(files: { path: string; content: string }[], pathSubstr: string): string | undefined {
11
+ const f = files.find(f => f.path.includes(pathSubstr))
12
+ return f?.content
13
+ }
14
+
15
+ function getFileNames(files: { path: string; content: string }[]): string[] {
16
+ return files.map(f => f.path)
17
+ }
18
+
19
+ describe('e2e: @coroutine', () => {
20
+ test('@coroutine loop function generates dispatcher in tick.json', () => {
21
+ const source = `
22
+ @coroutine(batch=10)
23
+ fn process_all(): void {
24
+ let i: int = 0;
25
+ while (i < 100) {
26
+ let x: int = i * 2;
27
+ i = i + 1;
28
+ }
29
+ }
30
+ `
31
+ const result = compile(source, { namespace: 'corotest' })
32
+ const tickJson = getFile(result.files, 'tick.json')
33
+ expect(tickJson).toBeDefined()
34
+ const parsed = JSON.parse(tickJson!)
35
+ // The generated tick dispatcher should be registered
36
+ const hasCoroTick = parsed.values.some((v: string) => v.includes('_coro_'))
37
+ expect(hasCoroTick).toBe(true)
38
+ })
39
+
40
+ test('@coroutine generates continuation mcfunction files', () => {
41
+ const source = `
42
+ @coroutine(batch=5)
43
+ fn heavy_loop(): void {
44
+ let i: int = 0;
45
+ while (i < 1000) {
46
+ let x: int = i + 1;
47
+ i = i + 1;
48
+ }
49
+ }
50
+ `
51
+ const result = compile(source, { namespace: 'corotest' })
52
+ const paths = getFileNames(result.files)
53
+
54
+ // Should have at least one continuation function file
55
+ const contFiles = paths.filter(p => p.includes('_coro_') && p.includes('_cont_'))
56
+ expect(contFiles.length).toBeGreaterThanOrEqual(1)
57
+
58
+ // Should have a dispatcher tick function file (may include sub-function files)
59
+ const tickFiles = paths.filter(p => p.includes('_coro_') && p.includes('_tick'))
60
+ expect(tickFiles.length).toBeGreaterThanOrEqual(1)
61
+ })
62
+
63
+ test('@coroutine with onDone generates call to callback', () => {
64
+ const source = `
65
+ fn after_done(): void {
66
+ let x: int = 42;
67
+ }
68
+
69
+ @coroutine(batch=10, onDone=after_done)
70
+ fn process(): void {
71
+ let i: int = 0;
72
+ while (i < 100) {
73
+ let x: int = i;
74
+ i = i + 1;
75
+ }
76
+ }
77
+ `
78
+ const result = compile(source, { namespace: 'corotest' })
79
+
80
+ // The continuation files should reference after_done somewhere
81
+ const contFiles = result.files.filter(f => f.path.includes('_coro_') && f.path.includes('_cont_'))
82
+ const allContent = contFiles.map(f => f.content).join('\n')
83
+ expect(allContent).toContain('after_done')
84
+ })
85
+
86
+ test('@coroutine function without loops still compiles', () => {
87
+ const source = `
88
+ @coroutine(batch=10)
89
+ fn no_loop(): void {
90
+ let x: int = 1;
91
+ let y: int = x + 2;
92
+ }
93
+ `
94
+ const result = compile(source, { namespace: 'corotest' })
95
+ expect(result.files.length).toBeGreaterThan(0)
96
+
97
+ // Should still produce continuation + dispatcher
98
+ const paths = getFileNames(result.files)
99
+ const contFiles = paths.filter(p => p.includes('_coro_'))
100
+ expect(contFiles.length).toBeGreaterThanOrEqual(2) // at least cont + tick
101
+ })
102
+
103
+ test('@coroutine preserves non-coroutine functions', () => {
104
+ const source = `
105
+ fn helper(): int {
106
+ return 42;
107
+ }
108
+
109
+ @coroutine(batch=10)
110
+ fn process(): void {
111
+ let i: int = 0;
112
+ while (i < 100) {
113
+ let x: int = i;
114
+ i = i + 1;
115
+ }
116
+ }
117
+ `
118
+ const result = compile(source, { namespace: 'corotest' })
119
+ const helperFn = getFile(result.files, 'helper.mcfunction')
120
+ expect(helperFn).toBeDefined()
121
+ })
122
+
123
+ test('default batch value is 10 when not specified', () => {
124
+ // @coroutine without batch should default to batch=10
125
+ // We test by ensuring compilation succeeds
126
+ const source = `
127
+ @coroutine
128
+ fn process(): void {
129
+ let i: int = 0;
130
+ while (i < 100) {
131
+ let x: int = i;
132
+ i = i + 1;
133
+ }
134
+ }
135
+ `
136
+ const result = compile(source, { namespace: 'corotest' })
137
+ expect(result.files.length).toBeGreaterThan(0)
138
+ const paths = getFileNames(result.files)
139
+ const contFiles = paths.filter(p => p.includes('_coro_'))
140
+ expect(contFiles.length).toBeGreaterThanOrEqual(2)
141
+ })
142
+ })
@@ -0,0 +1,199 @@
1
+ /**
2
+ * End-to-end tests for MC 1.20.2+ macro function support in the v2 pipeline.
3
+ *
4
+ * When a function uses runtime parameters in positions that require literal
5
+ * values in MC commands (coordinates, entity types, etc.), the compiler should
6
+ * automatically compile it as a macro function using $-prefixed syntax and
7
+ * call it via `function ns:fn with storage rs:macro_args`.
8
+ */
9
+
10
+ import { compile } from '../../emit/compile'
11
+
12
+ function getFile(files: { path: string; content: string }[], pathSubstr: string): string | undefined {
13
+ const f = files.find(f => f.path.includes(pathSubstr))
14
+ return f?.content
15
+ }
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Macro function detection
19
+ // ---------------------------------------------------------------------------
20
+
21
+ describe('e2e: macro function detection', () => {
22
+ test('function with int params in summon coords emits $-prefixed command', () => {
23
+ const source = `
24
+ fn spawn_zombie(x: int, y: int, z: int) {
25
+ summon("minecraft:zombie", x, y, z);
26
+ }
27
+ `
28
+ const result = compile(source, { namespace: 'test' })
29
+ const fn = getFile(result.files, 'spawn_zombie.mcfunction')
30
+ expect(fn).toBeDefined()
31
+ // The function body should have a $summon macro line
32
+ expect(fn).toContain('$summon minecraft:zombie $(x) $(y) $(z)')
33
+ })
34
+
35
+ test('function with all constant args does NOT produce macro line', () => {
36
+ const source = `
37
+ fn spawn_fixed() {
38
+ summon("minecraft:zombie", 100, 64, 200);
39
+ }
40
+ `
41
+ const result = compile(source, { namespace: 'test' })
42
+ const fn = getFile(result.files, 'spawn_fixed.mcfunction')
43
+ expect(fn).toBeDefined()
44
+ expect(fn).toContain('summon minecraft:zombie 100 64 200')
45
+ // No $ prefix
46
+ expect(fn).not.toMatch(/^\$summon/m)
47
+ })
48
+
49
+ test('function with int params in particle coords emits $-prefixed command', () => {
50
+ const source = `
51
+ fn show_particle(x: int, y: int, z: int) {
52
+ particle("minecraft:flame", x, y, z);
53
+ }
54
+ `
55
+ const result = compile(source, { namespace: 'test' })
56
+ const fn = getFile(result.files, 'show_particle.mcfunction')
57
+ expect(fn).toBeDefined()
58
+ expect(fn).toContain('$particle minecraft:flame $(x) $(y) $(z)')
59
+ })
60
+
61
+ test('function with int params in setblock coords emits $-prefixed command', () => {
62
+ const source = `
63
+ fn place_block(x: int, y: int, z: int) {
64
+ setblock(x, y, z, "minecraft:stone");
65
+ }
66
+ `
67
+ const result = compile(source, { namespace: 'test' })
68
+ const fn = getFile(result.files, 'place_block.mcfunction')
69
+ expect(fn).toBeDefined()
70
+ expect(fn).toContain('$setblock $(x) $(y) $(z) minecraft:stone')
71
+ })
72
+
73
+ test('mixed literal and variable args: only variable args get $()', () => {
74
+ const source = `
75
+ fn teleport_y(y: int) {
76
+ summon("minecraft:zombie", 100, y, 200);
77
+ }
78
+ `
79
+ const result = compile(source, { namespace: 'test' })
80
+ const fn = getFile(result.files, 'teleport_y.mcfunction')
81
+ expect(fn).toBeDefined()
82
+ expect(fn).toContain('$summon minecraft:zombie 100 $(y) 200')
83
+ })
84
+ })
85
+
86
+ // ---------------------------------------------------------------------------
87
+ // Macro call site generation
88
+ // ---------------------------------------------------------------------------
89
+
90
+ describe('e2e: macro call site generation', () => {
91
+ test('call site emits store_score_to_nbt + function with storage', () => {
92
+ const source = `
93
+ fn spawn_zombie(x: int, y: int, z: int) {
94
+ summon("minecraft:zombie", x, y, z);
95
+ }
96
+
97
+ fn caller(px: int, pz: int) {
98
+ spawn_zombie(px, 64, pz);
99
+ }
100
+ `
101
+ const result = compile(source, { namespace: 'test' })
102
+ const callerFn = getFile(result.files, 'caller.mcfunction')
103
+ expect(callerFn).toBeDefined()
104
+
105
+ // Should have 'function test:spawn_zombie with storage rs:macro_args'
106
+ expect(callerFn).toContain('with storage rs:macro_args')
107
+ expect(callerFn).toContain('spawn_zombie')
108
+ })
109
+
110
+ test('call site stores args to rs:macro_args NBT', () => {
111
+ const source = `
112
+ fn spawn_zombie(x: int, y: int, z: int) {
113
+ summon("minecraft:zombie", x, y, z);
114
+ }
115
+
116
+ fn caller(my_x: int) {
117
+ spawn_zombie(my_x, 64, 0);
118
+ }
119
+ `
120
+ const result = compile(source, { namespace: 'test' })
121
+ const callerFn = getFile(result.files, 'caller.mcfunction')
122
+ expect(callerFn).toBeDefined()
123
+
124
+ // Should have NBT storage setup for macro args
125
+ expect(callerFn).toContain('rs:macro_args')
126
+ expect(callerFn).toContain('with storage')
127
+ })
128
+ })
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // Float macro params (local coords)
132
+ // ---------------------------------------------------------------------------
133
+
134
+ describe('e2e: float macro params with local coords', () => {
135
+ test('float params in ^coord positions produce macro function', () => {
136
+ const source = `
137
+ fn draw_pt(px: float, py: float) {
138
+ particle("minecraft:end_rod", ^px, ^py, ^5, 0.02, 0.02, 0.02, 0.0, 10);
139
+ }
140
+ `
141
+ const result = compile(source, { namespace: 'test' })
142
+ const fn = getFile(result.files, 'draw_pt.mcfunction')
143
+ expect(fn).toBeDefined()
144
+ // Should have $particle with ^$(px) and ^$(py)
145
+ expect(fn).toContain('$particle minecraft:end_rod ^$(px) ^$(py) ^5')
146
+ })
147
+
148
+ test('float macro call site uses double 0.01 scale for NBT storage', () => {
149
+ const source = `
150
+ fn draw_pt(px: float, py: float) {
151
+ particle("minecraft:end_rod", ^px, ^py, ^5, 0.02, 0.02, 0.02, 0.0, 10);
152
+ }
153
+
154
+ fn caller() {
155
+ draw_pt(100.0, 200.0);
156
+ }
157
+ `
158
+ const result = compile(source, { namespace: 'test' })
159
+ const callerFn = getFile(result.files, 'caller.mcfunction')
160
+ expect(callerFn).toBeDefined()
161
+
162
+ // Should store to NBT with double type and 0.01 scale
163
+ expect(callerFn).toContain('rs:macro_args')
164
+ expect(callerFn).toContain('double 0.01')
165
+ expect(callerFn).toContain('with storage rs:macro_args')
166
+ })
167
+ })
168
+
169
+ // ---------------------------------------------------------------------------
170
+ // Non-macro functions still work
171
+ // ---------------------------------------------------------------------------
172
+
173
+ describe('e2e: non-macro functions', () => {
174
+ test('say builtin emits normal (non-macro) command', () => {
175
+ const source = `
176
+ fn greet() {
177
+ say("hello world");
178
+ }
179
+ `
180
+ const result = compile(source, { namespace: 'test' })
181
+ const fn = getFile(result.files, 'greet.mcfunction')
182
+ expect(fn).toBeDefined()
183
+ expect(fn).toContain('say hello world')
184
+ // No $ prefix
185
+ expect(fn).not.toMatch(/^\$/m)
186
+ })
187
+
188
+ test('kill builtin emits normal command', () => {
189
+ const source = `
190
+ fn cleanup() {
191
+ kill(@e[tag=temp]);
192
+ }
193
+ `
194
+ const result = compile(source, { namespace: 'test' })
195
+ const fn = getFile(result.files, 'cleanup.mcfunction')
196
+ expect(fn).toBeDefined()
197
+ expect(fn).toContain('kill @e[tag=temp]')
198
+ })
199
+ })