redscript-mc 1.2.30 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (593) hide show
  1. package/.claudeignore +21 -0
  2. package/.github/workflows/ci.yml +1 -0
  3. package/README.md +12 -16
  4. package/README.zh.md +2 -2
  5. package/demo.gif +0 -0
  6. package/dist/cli.js +2 -554
  7. package/dist/compile.js +2 -266
  8. package/dist/index.js +2 -159
  9. package/dist/src/__tests__/budget.test.js +261 -0
  10. package/dist/src/__tests__/cli.test.js +104 -0
  11. package/dist/{__tests__ → src/__tests__}/dce.test.js +11 -47
  12. package/dist/{__tests__ → src/__tests__}/diagnostics.test.js +67 -40
  13. package/dist/src/__tests__/e2e/basic.test.d.ts +8 -0
  14. package/dist/src/__tests__/e2e/basic.test.js +140 -0
  15. package/dist/src/__tests__/e2e/coroutine.test.d.ts +7 -0
  16. package/dist/src/__tests__/e2e/coroutine.test.js +132 -0
  17. package/dist/src/__tests__/e2e/macros.test.d.ts +9 -0
  18. package/dist/src/__tests__/e2e/macros.test.js +182 -0
  19. package/dist/src/__tests__/e2e/migrate.test.d.ts +13 -0
  20. package/dist/src/__tests__/e2e/migrate.test.js +2739 -0
  21. package/dist/src/__tests__/e2e/stdlib-e2e.test.d.ts +10 -0
  22. package/dist/src/__tests__/e2e/stdlib-e2e.test.js +324 -0
  23. package/dist/src/__tests__/enum.test.d.ts +10 -0
  24. package/dist/src/__tests__/enum.test.js +389 -0
  25. package/dist/src/__tests__/generics.test.d.ts +14 -0
  26. package/dist/src/__tests__/generics.test.js +367 -0
  27. package/dist/src/__tests__/hir/desugar.test.js +234 -0
  28. package/dist/src/__tests__/incremental.test.d.ts +5 -0
  29. package/dist/src/__tests__/incremental.test.js +308 -0
  30. package/dist/src/__tests__/lir/lower.test.js +559 -0
  31. package/dist/src/__tests__/lir/types.test.js +185 -0
  32. package/dist/src/__tests__/lir/verify.test.js +221 -0
  33. package/dist/src/__tests__/lsp.test.d.ts +7 -0
  34. package/dist/src/__tests__/lsp.test.js +245 -0
  35. package/dist/{__tests__ → src/__tests__}/mc-integration.test.js +1 -3
  36. package/dist/src/__tests__/mc-version.test.d.ts +10 -0
  37. package/dist/src/__tests__/mc-version.test.js +154 -0
  38. package/dist/src/__tests__/mir/arithmetic.test.js +130 -0
  39. package/dist/src/__tests__/mir/control-flow.test.js +205 -0
  40. package/dist/src/__tests__/mir/verify.test.js +223 -0
  41. package/dist/src/__tests__/modules.test.d.ts +7 -0
  42. package/dist/src/__tests__/modules.test.js +333 -0
  43. package/dist/src/__tests__/optimizer/block_merge.test.js +78 -0
  44. package/dist/src/__tests__/optimizer/branch_simplify.test.js +58 -0
  45. package/dist/src/__tests__/optimizer/constant_fold.test.js +131 -0
  46. package/dist/src/__tests__/optimizer/copy_prop.test.js +91 -0
  47. package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
  48. package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
  49. package/dist/src/__tests__/optimizer/dce.test.d.ts +1 -0
  50. package/dist/src/__tests__/optimizer/dce.test.js +76 -0
  51. package/dist/src/__tests__/optimizer/interprocedural.test.d.ts +1 -0
  52. package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
  53. package/dist/src/__tests__/optimizer/lir/const_imm.test.d.ts +1 -0
  54. package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
  55. package/dist/src/__tests__/optimizer/lir/dead_slot.test.d.ts +1 -0
  56. package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
  57. package/dist/src/__tests__/optimizer/lir/peephole.test.d.ts +1 -0
  58. package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
  59. package/dist/src/__tests__/optimizer/lir/pipeline.test.d.ts +1 -0
  60. package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
  61. package/dist/src/__tests__/optimizer/nbt-batch.test.d.ts +1 -0
  62. package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
  63. package/dist/src/__tests__/optimizer/pipeline.test.d.ts +1 -0
  64. package/dist/src/__tests__/optimizer/pipeline.test.js +102 -0
  65. package/dist/src/__tests__/optimizer/selector-cache.test.d.ts +1 -0
  66. package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
  67. package/dist/src/__tests__/optimizer/unroll.test.d.ts +1 -0
  68. package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
  69. package/dist/src/__tests__/option.test.d.ts +14 -0
  70. package/dist/src/__tests__/option.test.js +275 -0
  71. package/dist/src/__tests__/parser.test.d.ts +1 -0
  72. package/dist/src/__tests__/repl.test.d.ts +1 -0
  73. package/dist/src/__tests__/schedule.test.d.ts +7 -0
  74. package/dist/src/__tests__/schedule.test.js +98 -0
  75. package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
  76. package/dist/src/__tests__/sourcemap.test.js +227 -0
  77. package/dist/src/__tests__/tuple.test.d.ts +11 -0
  78. package/dist/src/__tests__/tuple.test.js +202 -0
  79. package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
  80. package/dist/src/__tests__/typechecker-strict.test.js +197 -0
  81. package/dist/src/__tests__/typechecker.test.d.ts +1 -0
  82. package/dist/{ast → src/ast}/types.d.ts +58 -3
  83. package/dist/src/cache/deps.d.ts +41 -0
  84. package/dist/src/cache/deps.js +158 -0
  85. package/dist/src/cache/incremental.d.ts +35 -0
  86. package/dist/src/cache/incremental.js +165 -0
  87. package/dist/src/cache/index.d.ts +37 -0
  88. package/dist/src/cache/index.js +152 -0
  89. package/dist/{cli.d.ts → src/cli.d.ts} +1 -1
  90. package/dist/src/cli.js +474 -0
  91. package/dist/src/compile.d.ts +37 -0
  92. package/dist/src/compile.js +165 -0
  93. package/dist/{diagnostics → src/diagnostics}/index.d.ts +1 -1
  94. package/dist/{diagnostics → src/diagnostics}/index.js +8 -11
  95. package/dist/src/emit/compile.d.ts +29 -0
  96. package/dist/src/emit/compile.js +143 -0
  97. package/dist/src/emit/index.d.ts +26 -0
  98. package/dist/src/emit/index.js +223 -0
  99. package/dist/src/emit/modules.d.ts +29 -0
  100. package/dist/src/emit/modules.js +492 -0
  101. package/dist/src/emit/sourcemap.d.ts +53 -0
  102. package/dist/src/emit/sourcemap.js +73 -0
  103. package/dist/src/hir/lower.d.ts +15 -0
  104. package/dist/src/hir/lower.js +399 -0
  105. package/dist/src/hir/monomorphize.d.ts +22 -0
  106. package/dist/src/hir/monomorphize.js +379 -0
  107. package/dist/src/hir/types.d.ts +406 -0
  108. package/dist/src/hir/types.js +16 -0
  109. package/dist/src/index.d.ts +39 -0
  110. package/dist/src/index.js +67 -0
  111. package/dist/{lexer → src/lexer}/index.d.ts +1 -1
  112. package/dist/{lexer → src/lexer}/index.js +1 -0
  113. package/dist/src/lir/budget.d.ts +37 -0
  114. package/dist/src/lir/budget.js +280 -0
  115. package/dist/src/lir/lower.d.ts +15 -0
  116. package/dist/src/lir/lower.js +472 -0
  117. package/dist/src/lir/types.d.ts +139 -0
  118. package/dist/src/lir/types.js +11 -0
  119. package/dist/src/lir/verify.d.ts +14 -0
  120. package/dist/src/lir/verify.js +113 -0
  121. package/dist/src/lsp/main.d.ts +8 -0
  122. package/dist/src/lsp/main.js +11 -0
  123. package/dist/src/lsp/server.d.ts +11 -0
  124. package/dist/src/lsp/server.js +352 -0
  125. package/dist/{mc-test → src/mc-test}/runner.js +4 -3
  126. package/dist/src/mir/lower.d.ts +9 -0
  127. package/dist/src/mir/lower.js +1264 -0
  128. package/dist/src/mir/macro.d.ts +22 -0
  129. package/dist/src/mir/macro.js +168 -0
  130. package/dist/src/mir/types.d.ts +191 -0
  131. package/dist/src/mir/types.js +11 -0
  132. package/dist/src/mir/verify.d.ts +16 -0
  133. package/dist/src/mir/verify.js +216 -0
  134. package/dist/src/optimizer/block_merge.d.ts +12 -0
  135. package/dist/src/optimizer/block_merge.js +84 -0
  136. package/dist/src/optimizer/branch_simplify.d.ts +9 -0
  137. package/dist/src/optimizer/branch_simplify.js +28 -0
  138. package/dist/src/optimizer/constant_fold.d.ts +10 -0
  139. package/dist/src/optimizer/constant_fold.js +85 -0
  140. package/dist/src/optimizer/copy_prop.d.ts +9 -0
  141. package/dist/src/optimizer/copy_prop.js +113 -0
  142. package/dist/src/optimizer/coroutine.d.ts +34 -0
  143. package/dist/src/optimizer/coroutine.js +789 -0
  144. package/dist/src/optimizer/dce.d.ts +8 -0
  145. package/dist/src/optimizer/dce.js +156 -0
  146. package/dist/src/optimizer/interprocedural.d.ts +14 -0
  147. package/dist/src/optimizer/interprocedural.js +186 -0
  148. package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
  149. package/dist/src/optimizer/lir/const_imm.js +139 -0
  150. package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
  151. package/dist/src/optimizer/lir/dead_slot.js +130 -0
  152. package/dist/src/optimizer/lir/peephole.d.ts +21 -0
  153. package/dist/src/optimizer/lir/peephole.js +52 -0
  154. package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
  155. package/dist/src/optimizer/lir/pipeline.js +34 -0
  156. package/dist/src/optimizer/nbt-batch.d.ts +11 -0
  157. package/dist/src/optimizer/nbt-batch.js +51 -0
  158. package/dist/src/optimizer/pipeline.d.ts +14 -0
  159. package/dist/src/optimizer/pipeline.js +58 -0
  160. package/dist/src/optimizer/selector-cache.d.ts +22 -0
  161. package/dist/src/optimizer/selector-cache.js +100 -0
  162. package/dist/src/optimizer/unroll.d.ts +32 -0
  163. package/dist/src/optimizer/unroll.js +348 -0
  164. package/dist/{parser → src/parser}/index.d.ts +8 -0
  165. package/dist/{parser → src/parser}/index.js +204 -14
  166. package/dist/{repl.d.ts → src/repl.d.ts} +1 -1
  167. package/dist/{runtime → src/runtime}/index.js +1 -1
  168. package/dist/{typechecker → src/typechecker}/index.d.ts +4 -0
  169. package/dist/{typechecker → src/typechecker}/index.js +198 -13
  170. package/dist/src/types/mc-version.d.ts +24 -0
  171. package/dist/src/types/mc-version.js +49 -0
  172. package/docs/ROADMAP.md +395 -0
  173. package/docs/compiler-pipeline-redesign.md +2260 -0
  174. package/docs/optimization-ideas.md +1076 -0
  175. package/editors/vscode/out/extension.js +25176 -8000
  176. package/editors/vscode/package-lock.json +90 -6
  177. package/editors/vscode/package.json +3 -2
  178. package/editors/vscode/src/extension.ts +97 -67
  179. package/examples/showcase.mcrs +3 -3
  180. package/package.json +13 -6
  181. package/scripts/postbuild.js +15 -0
  182. package/src/__tests__/budget.test.ts +297 -0
  183. package/src/__tests__/cli.test.ts +8 -220
  184. package/src/__tests__/dce.test.ts +11 -56
  185. package/src/__tests__/diagnostics.test.ts +61 -41
  186. package/src/__tests__/e2e/basic.test.ts +154 -0
  187. package/src/__tests__/e2e/coroutine.test.ts +142 -0
  188. package/src/__tests__/e2e/macros.test.ts +199 -0
  189. package/src/__tests__/e2e/migrate.test.ts +3008 -0
  190. package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
  191. package/src/__tests__/enum.test.ts +425 -0
  192. package/src/__tests__/generics.test.ts +390 -0
  193. package/src/__tests__/hir/desugar.test.ts +263 -0
  194. package/src/__tests__/incremental.test.ts +337 -0
  195. package/src/__tests__/lir/lower.test.ts +619 -0
  196. package/src/__tests__/lir/types.test.ts +207 -0
  197. package/src/__tests__/lir/verify.test.ts +249 -0
  198. package/src/__tests__/lsp.test.ts +270 -0
  199. package/src/__tests__/mc-integration.test.ts +1 -2
  200. package/src/__tests__/mc-version.test.ts +178 -0
  201. package/src/__tests__/mir/arithmetic.test.ts +156 -0
  202. package/src/__tests__/mir/control-flow.test.ts +242 -0
  203. package/src/__tests__/mir/verify.test.ts +254 -0
  204. package/src/__tests__/modules.test.ts +365 -0
  205. package/src/__tests__/optimizer/block_merge.test.ts +84 -0
  206. package/src/__tests__/optimizer/branch_simplify.test.ts +64 -0
  207. package/src/__tests__/optimizer/constant_fold.test.ts +145 -0
  208. package/src/__tests__/optimizer/copy_prop.test.ts +99 -0
  209. package/src/__tests__/optimizer/coroutine.test.ts +312 -0
  210. package/src/__tests__/optimizer/dce.test.ts +83 -0
  211. package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
  212. package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
  213. package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
  214. package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
  215. package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
  216. package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
  217. package/src/__tests__/optimizer/pipeline.test.ts +116 -0
  218. package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
  219. package/src/__tests__/optimizer/unroll.test.ts +231 -0
  220. package/src/__tests__/option.test.ts +299 -0
  221. package/src/__tests__/schedule.test.ts +105 -0
  222. package/src/__tests__/sourcemap.test.ts +254 -0
  223. package/src/__tests__/tuple.test.ts +220 -0
  224. package/src/__tests__/typechecker-strict.test.ts +216 -0
  225. package/src/ast/types.ts +39 -3
  226. package/src/cache/deps.ts +132 -0
  227. package/src/cache/incremental.ts +173 -0
  228. package/src/cache/index.ts +135 -0
  229. package/src/cli.ts +111 -195
  230. package/src/compile.ts +6 -162
  231. package/src/diagnostics/index.ts +8 -11
  232. package/src/emit/compile.ts +177 -0
  233. package/src/emit/index.ts +286 -0
  234. package/src/emit/modules.ts +581 -0
  235. package/src/emit/sourcemap.ts +101 -0
  236. package/src/hir/lower.ts +455 -0
  237. package/src/hir/monomorphize.ts +416 -0
  238. package/src/hir/types.ts +228 -0
  239. package/src/index.ts +37 -182
  240. package/src/lexer/index.ts +2 -1
  241. package/src/lir/budget.ts +321 -0
  242. package/src/lir/lower.ts +587 -0
  243. package/src/lir/types.ts +113 -0
  244. package/src/lir/verify.ts +129 -0
  245. package/src/lsp/main.ts +9 -0
  246. package/src/lsp/server.ts +414 -0
  247. package/src/mc-test/runner.ts +4 -3
  248. package/src/mir/lower.ts +1403 -0
  249. package/src/mir/macro.ts +167 -0
  250. package/src/mir/types.ts +117 -0
  251. package/src/mir/verify.ts +218 -0
  252. package/src/optimizer/block_merge.ts +93 -0
  253. package/src/optimizer/branch_simplify.ts +27 -0
  254. package/src/optimizer/constant_fold.ts +88 -0
  255. package/src/optimizer/copy_prop.ts +106 -0
  256. package/src/optimizer/coroutine.ts +996 -0
  257. package/src/optimizer/dce.ts +108 -653
  258. package/src/optimizer/interprocedural.ts +177 -0
  259. package/src/optimizer/lir/const_imm.ts +143 -0
  260. package/src/optimizer/lir/dead_slot.ts +123 -0
  261. package/src/optimizer/lir/peephole.ts +57 -0
  262. package/src/optimizer/lir/pipeline.ts +37 -0
  263. package/src/optimizer/nbt-batch.ts +50 -0
  264. package/src/optimizer/pipeline.ts +59 -0
  265. package/src/optimizer/selector-cache.ts +103 -0
  266. package/src/optimizer/unroll.ts +386 -0
  267. package/src/parser/index.ts +213 -16
  268. package/src/repl.ts +1 -1
  269. package/src/runtime/index.ts +1 -1
  270. package/src/stdlib/math.mcrs +4 -4
  271. package/src/templates/quest.mcrs +4 -4
  272. package/src/typechecker/index.ts +215 -15
  273. package/src/types/mc-version.ts +46 -0
  274. package/tsconfig.json +1 -1
  275. package/dist/__tests__/cli.test.js +0 -278
  276. package/dist/__tests__/codegen.test.js +0 -152
  277. package/dist/__tests__/e2e.test.d.ts +0 -6
  278. package/dist/__tests__/e2e.test.js +0 -1847
  279. package/dist/__tests__/entity-types.test.js +0 -203
  280. package/dist/__tests__/lowering.test.js +0 -1015
  281. package/dist/__tests__/macro.test.d.ts +0 -8
  282. package/dist/__tests__/macro.test.js +0 -305
  283. package/dist/__tests__/nbt.test.js +0 -82
  284. package/dist/__tests__/optimizer-advanced.test.js +0 -124
  285. package/dist/__tests__/optimizer.test.js +0 -149
  286. package/dist/__tests__/runtime.test.js +0 -289
  287. package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
  288. package/dist/__tests__/stdlib-advanced.test.js +0 -378
  289. package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
  290. package/dist/__tests__/stdlib-bigint.test.js +0 -428
  291. package/dist/__tests__/stdlib-math.test.d.ts +0 -7
  292. package/dist/__tests__/stdlib-math.test.js +0 -352
  293. package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
  294. package/dist/__tests__/stdlib-vec.test.js +0 -264
  295. package/dist/__tests__/structure-optimizer.test.js +0 -33
  296. package/dist/__tests__/var-allocator.test.js +0 -69
  297. package/dist/codegen/cmdblock/index.d.ts +0 -26
  298. package/dist/codegen/cmdblock/index.js +0 -45
  299. package/dist/codegen/mcfunction/index.d.ts +0 -40
  300. package/dist/codegen/mcfunction/index.js +0 -606
  301. package/dist/codegen/structure/index.d.ts +0 -24
  302. package/dist/codegen/structure/index.js +0 -279
  303. package/dist/codegen/var-allocator.d.ts +0 -45
  304. package/dist/codegen/var-allocator.js +0 -104
  305. package/dist/compile.d.ts +0 -68
  306. package/dist/data/arena/function/__load.mcfunction +0 -6
  307. package/dist/data/arena/function/__tick.mcfunction +0 -2
  308. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
  309. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
  310. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
  311. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
  312. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
  313. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
  314. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
  315. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
  316. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
  317. package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
  318. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
  319. package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
  320. package/dist/data/arena/function/arena_tick.mcfunction +0 -11
  321. package/dist/data/counter/function/__load.mcfunction +0 -5
  322. package/dist/data/counter/function/__tick.mcfunction +0 -2
  323. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
  324. package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
  325. package/dist/data/counter/function/counter_tick.mcfunction +0 -11
  326. package/dist/data/gcd2/function/__load.mcfunction +0 -3
  327. package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
  328. package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
  329. package/dist/data/gcd2/function/abs.mcfunction +0 -7
  330. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
  331. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
  332. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
  333. package/dist/data/gcd2/function/gcd.mcfunction +0 -14
  334. package/dist/data/gcd3/function/__load.mcfunction +0 -3
  335. package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
  336. package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
  337. package/dist/data/gcd3/function/abs.mcfunction +0 -7
  338. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
  339. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
  340. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
  341. package/dist/data/gcd3/function/gcd.mcfunction +0 -14
  342. package/dist/data/gcd3/function/test.mcfunction +0 -7
  343. package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
  344. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
  345. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
  346. package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
  347. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
  348. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
  349. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
  350. package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
  351. package/dist/data/gcd3nm/function/test.mcfunction +0 -7
  352. package/dist/data/gcd_test/function/__load.mcfunction +0 -3
  353. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
  354. package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
  355. package/dist/data/gcd_test/function/abs.mcfunction +0 -7
  356. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
  357. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
  358. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
  359. package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
  360. package/dist/data/isqrttest/function/__load.mcfunction +0 -6
  361. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
  362. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
  363. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
  364. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
  365. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
  366. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
  367. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
  368. package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
  369. package/dist/data/isqrttest/function/test.mcfunction +0 -6
  370. package/dist/data/mathtest/function/__load.mcfunction +0 -3
  371. package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
  372. package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
  373. package/dist/data/mathtest/function/abs.mcfunction +0 -6
  374. package/dist/data/mathtest/function/test.mcfunction +0 -5
  375. package/dist/data/minecraft/tags/function/load.json +0 -5
  376. package/dist/data/minecraft/tags/function/tick.json +0 -5
  377. package/dist/data/mypack/function/__load.mcfunction +0 -13
  378. package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
  379. package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
  380. package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
  381. package/dist/data/mypack/function/abs.mcfunction +0 -6
  382. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
  383. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
  384. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
  385. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
  386. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
  387. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
  388. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
  389. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
  390. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
  391. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
  392. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
  393. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
  394. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
  395. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
  396. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
  397. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
  398. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
  399. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
  400. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
  401. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
  402. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
  403. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
  404. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
  405. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
  406. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
  407. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
  408. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
  409. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
  410. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
  411. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
  412. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
  413. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
  414. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
  415. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
  416. package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
  417. package/dist/data/mypack/function/my_game.mcfunction +0 -10
  418. package/dist/data/quiz/function/__load.mcfunction +0 -16
  419. package/dist/data/quiz/function/__tick.mcfunction +0 -6
  420. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
  421. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
  422. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
  423. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
  424. package/dist/data/quiz/function/answer_a.mcfunction +0 -4
  425. package/dist/data/quiz/function/answer_b.mcfunction +0 -4
  426. package/dist/data/quiz/function/answer_c.mcfunction +0 -4
  427. package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
  428. package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
  429. package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
  430. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
  431. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
  432. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
  433. package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
  434. package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
  435. package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
  436. package/dist/data/quiz/function/ask_question.mcfunction +0 -7
  437. package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
  438. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
  439. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
  440. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
  441. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
  442. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
  443. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
  444. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
  445. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
  446. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
  447. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
  448. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
  449. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
  450. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
  451. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
  452. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
  453. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
  454. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
  455. package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
  456. package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
  457. package/dist/data/reqtest/function/__load.mcfunction +0 -4
  458. package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
  459. package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
  460. package/dist/data/reqtest/function/use_table.mcfunction +0 -4
  461. package/dist/data/reqtest2/function/__load.mcfunction +0 -3
  462. package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
  463. package/dist/data/runtime/function/__load.mcfunction +0 -5
  464. package/dist/data/runtime/function/__tick.mcfunction +0 -2
  465. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
  466. package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
  467. package/dist/data/shop/function/__load.mcfunction +0 -7
  468. package/dist/data/shop/function/__tick.mcfunction +0 -3
  469. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
  470. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
  471. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
  472. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
  473. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
  474. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
  475. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
  476. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
  477. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
  478. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
  479. package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
  480. package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
  481. package/dist/data/swap_test/function/__load.mcfunction +0 -3
  482. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
  483. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
  484. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
  485. package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
  486. package/dist/data/turret/function/__load.mcfunction +0 -5
  487. package/dist/data/turret/function/__tick.mcfunction +0 -4
  488. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
  489. package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
  490. package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
  491. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
  492. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
  493. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
  494. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
  495. package/dist/data/turret/function/turret_tick.mcfunction +0 -5
  496. package/dist/gcd2.map.json +0 -15
  497. package/dist/gcd3.map.json +0 -17
  498. package/dist/gcd_test.map.json +0 -15
  499. package/dist/index.d.ts +0 -62
  500. package/dist/ir/builder.d.ts +0 -33
  501. package/dist/ir/builder.js +0 -99
  502. package/dist/ir/types.d.ts +0 -132
  503. package/dist/ir/types.js +0 -15
  504. package/dist/isqrttest.map.json +0 -15
  505. package/dist/lowering/index.d.ts +0 -188
  506. package/dist/lowering/index.js +0 -3403
  507. package/dist/mathtest.map.json +0 -6
  508. package/dist/mypack.map.json +0 -27
  509. package/dist/optimizer/commands.d.ts +0 -38
  510. package/dist/optimizer/commands.js +0 -451
  511. package/dist/optimizer/dce.d.ts +0 -34
  512. package/dist/optimizer/dce.js +0 -639
  513. package/dist/optimizer/passes.d.ts +0 -34
  514. package/dist/optimizer/passes.js +0 -243
  515. package/dist/optimizer/structure.d.ts +0 -9
  516. package/dist/optimizer/structure.js +0 -356
  517. package/dist/pack.mcmeta +0 -6
  518. package/dist/reqtest.map.json +0 -4
  519. package/dist/reqtest2.map.json +0 -4
  520. package/dist/runtime.map.json +0 -7
  521. package/dist/swap_test.map.json +0 -14
  522. package/src/__tests__/codegen.test.ts +0 -161
  523. package/src/__tests__/e2e.test.ts +0 -2039
  524. package/src/__tests__/entity-types.test.ts +0 -236
  525. package/src/__tests__/lowering.test.ts +0 -1185
  526. package/src/__tests__/macro.test.ts +0 -343
  527. package/src/__tests__/nbt.test.ts +0 -58
  528. package/src/__tests__/optimizer-advanced.test.ts +0 -144
  529. package/src/__tests__/optimizer.test.ts +0 -162
  530. package/src/__tests__/runtime.test.ts +0 -305
  531. package/src/__tests__/stdlib-advanced.test.ts +0 -379
  532. package/src/__tests__/stdlib-bigint.test.ts +0 -427
  533. package/src/__tests__/stdlib-math.test.ts +0 -374
  534. package/src/__tests__/stdlib-vec.test.ts +0 -259
  535. package/src/__tests__/structure-optimizer.test.ts +0 -38
  536. package/src/__tests__/var-allocator.test.ts +0 -75
  537. package/src/codegen/cmdblock/index.ts +0 -63
  538. package/src/codegen/mcfunction/index.ts +0 -662
  539. package/src/codegen/structure/index.ts +0 -346
  540. package/src/codegen/var-allocator.ts +0 -104
  541. package/src/ir/builder.ts +0 -116
  542. package/src/ir/types.ts +0 -134
  543. package/src/lowering/index.ts +0 -3876
  544. package/src/optimizer/commands.ts +0 -534
  545. package/src/optimizer/passes.ts +0 -250
  546. package/src/optimizer/structure.ts +0 -450
  547. /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
  548. /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/cli.test.d.ts} +0 -0
  549. /package/dist/{__tests__ → src/__tests__}/compile-all.test.d.ts +0 -0
  550. /package/dist/{__tests__ → src/__tests__}/compile-all.test.js +0 -0
  551. /package/dist/{__tests__ → src/__tests__}/dce.test.d.ts +0 -0
  552. /package/dist/{__tests__ → src/__tests__}/diagnostics.test.d.ts +0 -0
  553. /package/dist/{__tests__ → src/__tests__}/formatter.test.d.ts +0 -0
  554. /package/dist/{__tests__ → src/__tests__}/formatter.test.js +0 -0
  555. /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/hir/desugar.test.d.ts} +0 -0
  556. /package/dist/{__tests__ → src/__tests__}/lexer.test.d.ts +0 -0
  557. /package/dist/{__tests__ → src/__tests__}/lexer.test.js +0 -0
  558. /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/lir/lower.test.d.ts} +0 -0
  559. /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/lir/types.test.d.ts} +0 -0
  560. /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/lir/verify.test.d.ts} +0 -0
  561. /package/dist/{__tests__ → src/__tests__}/mc-integration.test.d.ts +0 -0
  562. /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/mc-syntax.test.d.ts} +0 -0
  563. /package/dist/{__tests__ → src/__tests__}/mc-syntax.test.js +0 -0
  564. /package/dist/{__tests__/optimizer.test.d.ts → src/__tests__/mir/arithmetic.test.d.ts} +0 -0
  565. /package/dist/{__tests__/parser.test.d.ts → src/__tests__/mir/control-flow.test.d.ts} +0 -0
  566. /package/dist/{__tests__/repl.test.d.ts → src/__tests__/mir/verify.test.d.ts} +0 -0
  567. /package/dist/{__tests__/runtime.test.d.ts → src/__tests__/optimizer/block_merge.test.d.ts} +0 -0
  568. /package/dist/{__tests__/structure-optimizer.test.d.ts → src/__tests__/optimizer/branch_simplify.test.d.ts} +0 -0
  569. /package/dist/{__tests__/typechecker.test.d.ts → src/__tests__/optimizer/constant_fold.test.d.ts} +0 -0
  570. /package/dist/{__tests__/var-allocator.test.d.ts → src/__tests__/optimizer/copy_prop.test.d.ts} +0 -0
  571. /package/dist/{__tests__ → src/__tests__}/parser.test.js +0 -0
  572. /package/dist/{__tests__ → src/__tests__}/repl.test.js +0 -0
  573. /package/dist/{__tests__ → src/__tests__}/typechecker.test.js +0 -0
  574. /package/dist/{ast → src/ast}/types.js +0 -0
  575. /package/dist/{builtins → src/builtins}/metadata.d.ts +0 -0
  576. /package/dist/{builtins → src/builtins}/metadata.js +0 -0
  577. /package/dist/{events → src/events}/types.d.ts +0 -0
  578. /package/dist/{events → src/events}/types.js +0 -0
  579. /package/dist/{formatter → src/formatter}/index.d.ts +0 -0
  580. /package/dist/{formatter → src/formatter}/index.js +0 -0
  581. /package/dist/{mc-test → src/mc-test}/client.d.ts +0 -0
  582. /package/dist/{mc-test → src/mc-test}/client.js +0 -0
  583. /package/dist/{mc-test → src/mc-test}/runner.d.ts +0 -0
  584. /package/dist/{mc-test → src/mc-test}/setup.d.ts +0 -0
  585. /package/dist/{mc-test → src/mc-test}/setup.js +0 -0
  586. /package/dist/{mc-validator → src/mc-validator}/index.d.ts +0 -0
  587. /package/dist/{mc-validator → src/mc-validator}/index.js +0 -0
  588. /package/dist/{nbt → src/nbt}/index.d.ts +0 -0
  589. /package/dist/{nbt → src/nbt}/index.js +0 -0
  590. /package/dist/{repl.js → src/repl.js} +0 -0
  591. /package/dist/{runtime → src/runtime}/index.d.ts +0 -0
  592. /package/dist/{types → src/types}/entity-hierarchy.d.ts +0 -0
  593. /package/dist/{types → src/types}/entity-hierarchy.js +0 -0
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const budget_1 = require("../lir/budget");
4
+ const compile_1 = require("../emit/compile");
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+ const NS = 'test';
9
+ const OBJ = '__test';
10
+ function slot(name) {
11
+ return { player: name, obj: OBJ };
12
+ }
13
+ function mkFn(name, instructions) {
14
+ return { name, instructions, isMacro: false, macroParams: [] };
15
+ }
16
+ function mkModule(functions) {
17
+ return { functions, namespace: NS, objective: OBJ };
18
+ }
19
+ // ---------------------------------------------------------------------------
20
+ // Unit tests: estimateCommandCount
21
+ // ---------------------------------------------------------------------------
22
+ describe('estimateCommandCount', () => {
23
+ test('flat function — counts each instruction as 1', () => {
24
+ const fn = mkFn('simple', [
25
+ { kind: 'score_set', dst: slot('$x'), value: 0 },
26
+ { kind: 'score_set', dst: slot('$y'), value: 1 },
27
+ { kind: 'score_add', dst: slot('$x'), src: slot('$y') },
28
+ ]);
29
+ const mod = mkModule([fn]);
30
+ expect((0, budget_1.estimateCommandCount)('simple', mod)).toBe(3);
31
+ });
32
+ test('function calling another — sums callee cost', () => {
33
+ const callee = mkFn('helper', [
34
+ { kind: 'score_set', dst: slot('$a'), value: 42 },
35
+ { kind: 'score_set', dst: slot('$b'), value: 43 },
36
+ ]);
37
+ const caller = mkFn('main', [
38
+ { kind: 'score_set', dst: slot('$x'), value: 0 },
39
+ { kind: 'call', fn: `${NS}:helper` },
40
+ ]);
41
+ const mod = mkModule([caller, callee]);
42
+ // caller: 2 instrs + callee: 2 instrs = 4
43
+ expect((0, budget_1.estimateCommandCount)('main', mod)).toBe(4);
44
+ });
45
+ test('self-recursive function (loop) — multiplies by estimated iterations', () => {
46
+ // Simulate a loop: header checks condition, calls body, body calls header
47
+ const header = mkFn('loop__header', [
48
+ { kind: 'call_if_matches', fn: `${NS}:loop__body`, slot: slot('$i'), range: '..99' },
49
+ ]);
50
+ const body = mkFn('loop__body', [
51
+ { kind: 'score_add', dst: slot('$i'), src: slot('$one') },
52
+ { kind: 'score_set', dst: slot('$tmp'), value: 1 },
53
+ { kind: 'call', fn: `${NS}:loop__header` },
54
+ ]);
55
+ const mod = mkModule([header, body]);
56
+ // Cycle: header(1) + body(3) = 4 cmds/iteration
57
+ // Range ..99 → 100 iterations
58
+ // Total: 4 × 100 = 400
59
+ expect((0, budget_1.estimateCommandCount)('loop__header', mod)).toBe(400);
60
+ });
61
+ test('unknown loop bound defaults to 100 iterations', () => {
62
+ const header = mkFn('loop__header', [
63
+ { kind: 'call_if_score', fn: `${NS}:loop__body`, a: slot('$i'), op: 'lt', b: slot('$limit') },
64
+ ]);
65
+ const body = mkFn('loop__body', [
66
+ { kind: 'score_add', dst: slot('$i'), src: slot('$one') },
67
+ { kind: 'call', fn: `${NS}:loop__header` },
68
+ ]);
69
+ const mod = mkModule([header, body]);
70
+ // Cycle: 1 + 2 = 3 cmds/iteration, 100 default iterations = 300
71
+ expect((0, budget_1.estimateCommandCount)('loop__header', mod)).toBe(300);
72
+ });
73
+ test('nested loops — outer × inner', () => {
74
+ // Inner loop: inner_header ↔ inner_body (5 cmds/iter, 10 iters)
75
+ const innerHeader = mkFn('inner__header', [
76
+ { kind: 'call_if_matches', fn: `${NS}:inner__body`, slot: slot('$j'), range: '..9' },
77
+ ]);
78
+ const innerBody = mkFn('inner__body', [
79
+ { kind: 'score_set', dst: slot('$a'), value: 1 },
80
+ { kind: 'score_set', dst: slot('$b'), value: 2 },
81
+ { kind: 'score_add', dst: slot('$j'), src: slot('$one') },
82
+ { kind: 'call', fn: `${NS}:inner__header` },
83
+ ]);
84
+ // Outer loop: outer_header ↔ outer_body (calls inner loop + own work)
85
+ const outerHeader = mkFn('outer__header', [
86
+ { kind: 'call_if_matches', fn: `${NS}:outer__body`, slot: slot('$i'), range: '..19' },
87
+ ]);
88
+ const outerBody = mkFn('outer__body', [
89
+ { kind: 'score_set', dst: slot('$j'), value: 0 },
90
+ { kind: 'call', fn: `${NS}:inner__header` },
91
+ { kind: 'score_add', dst: slot('$i'), src: slot('$one') },
92
+ { kind: 'call', fn: `${NS}:outer__header` },
93
+ ]);
94
+ const mod = mkModule([innerHeader, innerBody, outerHeader, outerBody]);
95
+ // Inner cycle: header(1) + body(4) = 5 cmds × 10 iters = 50
96
+ // Outer cycle local: header(1) + body(4) = 5 cmds
97
+ // Outer cycle external callee: inner = 50
98
+ // Outer total: (5 + 50) × 20 = 1100
99
+ expect((0, budget_1.estimateCommandCount)('outer__header', mod)).toBe(1100);
100
+ });
101
+ test('external call (not in module) contributes 0', () => {
102
+ const fn = mkFn('main', [
103
+ { kind: 'score_set', dst: slot('$x'), value: 0 },
104
+ { kind: 'call', fn: 'other_ns:external_fn' },
105
+ ]);
106
+ const mod = mkModule([fn]);
107
+ expect((0, budget_1.estimateCommandCount)('main', mod)).toBe(2);
108
+ });
109
+ });
110
+ // ---------------------------------------------------------------------------
111
+ // Unit tests: analyzeBudget
112
+ // ---------------------------------------------------------------------------
113
+ describe('analyzeBudget', () => {
114
+ test('small loop (100 iters × 5 cmds = 500) → no diagnostic', () => {
115
+ const header = mkFn('process', [
116
+ { kind: 'call_if_matches', fn: `${NS}:process__body`, slot: slot('$i'), range: '..99' },
117
+ ]);
118
+ const body = mkFn('process__body', [
119
+ { kind: 'score_set', dst: slot('$a'), value: 1 },
120
+ { kind: 'score_set', dst: slot('$b'), value: 2 },
121
+ { kind: 'score_add', dst: slot('$c'), src: slot('$a') },
122
+ { kind: 'call', fn: `${NS}:process` },
123
+ ]);
124
+ const mod = mkModule([header, body]);
125
+ const diags = (0, budget_1.analyzeBudget)(mod);
126
+ expect(diags).toEqual([]);
127
+ });
128
+ test('medium loop (1000 iters × 50 cmds = 50000) → warning', () => {
129
+ // Build a body with 48 instructions + 1 call back + header 1 = 50 per iter
130
+ const bodyInstrs = [];
131
+ for (let i = 0; i < 48; i++) {
132
+ bodyInstrs.push({ kind: 'score_set', dst: slot(`$v${i}`), value: i });
133
+ }
134
+ bodyInstrs.push({ kind: 'call', fn: `${NS}:bigloop` });
135
+ const header = mkFn('bigloop', [
136
+ { kind: 'call_if_matches', fn: `${NS}:bigloop__body`, slot: slot('$i'), range: '..999' },
137
+ ]);
138
+ const body = mkFn('bigloop__body', bodyInstrs);
139
+ const mod = mkModule([header, body]);
140
+ const diags = (0, budget_1.analyzeBudget)(mod);
141
+ expect(diags).toHaveLength(1);
142
+ expect(diags[0].level).toBe('warning');
143
+ expect(diags[0].fnName).toBe('bigloop');
144
+ expect(diags[0].estimatedCommands).toBe(50000);
145
+ expect(diags[0].message).toContain('consider @coroutine');
146
+ });
147
+ test('large loop (1000 iters × 100 cmds = 100000) → error', () => {
148
+ const bodyInstrs = [];
149
+ for (let i = 0; i < 98; i++) {
150
+ bodyInstrs.push({ kind: 'score_set', dst: slot(`$v${i}`), value: i });
151
+ }
152
+ bodyInstrs.push({ kind: 'call', fn: `${NS}:hugeloop` });
153
+ const header = mkFn('hugeloop', [
154
+ { kind: 'call_if_matches', fn: `${NS}:hugeloop__body`, slot: slot('$i'), range: '..999' },
155
+ ]);
156
+ const body = mkFn('hugeloop__body', bodyInstrs);
157
+ const mod = mkModule([header, body]);
158
+ const diags = (0, budget_1.analyzeBudget)(mod);
159
+ expect(diags).toHaveLength(1);
160
+ expect(diags[0].level).toBe('error');
161
+ expect(diags[0].fnName).toBe('hugeloop');
162
+ expect(diags[0].estimatedCommands).toBe(100000);
163
+ });
164
+ test('@coroutine function is skipped', () => {
165
+ const bodyInstrs = [];
166
+ for (let i = 0; i < 98; i++) {
167
+ bodyInstrs.push({ kind: 'score_set', dst: slot(`$v${i}`), value: i });
168
+ }
169
+ bodyInstrs.push({ kind: 'call', fn: `${NS}:bigfn` });
170
+ const header = mkFn('bigfn', [
171
+ { kind: 'call_if_matches', fn: `${NS}:bigfn__body`, slot: slot('$i'), range: '..999' },
172
+ ]);
173
+ const body = mkFn('bigfn__body', bodyInstrs);
174
+ const mod = mkModule([header, body]);
175
+ const diags = (0, budget_1.analyzeBudget)(mod, new Set(['bigfn']));
176
+ expect(diags).toEqual([]);
177
+ });
178
+ test('compiler-generated __helper functions are skipped', () => {
179
+ // Only top-level user functions are analyzed; __body etc are internal
180
+ const bodyInstrs = [];
181
+ for (let i = 0; i < 98; i++) {
182
+ bodyInstrs.push({ kind: 'score_set', dst: slot(`$v${i}`), value: i });
183
+ }
184
+ bodyInstrs.push({ kind: 'call', fn: `${NS}:fn__header` });
185
+ // Only fn__header and fn__body exist — both have __ so both skipped
186
+ const header = mkFn('fn__header', [
187
+ { kind: 'call_if_matches', fn: `${NS}:fn__body`, slot: slot('$i'), range: '..999' },
188
+ ]);
189
+ const body = mkFn('fn__body', bodyInstrs);
190
+ const mod = mkModule([header, body]);
191
+ const diags = (0, budget_1.analyzeBudget)(mod);
192
+ expect(diags).toEqual([]);
193
+ });
194
+ test('nested loop estimation is correct', () => {
195
+ // Inner: 5 cmds × 10 iters = 50
196
+ const innerHeader = mkFn('run__inner_header', [
197
+ { kind: 'call_if_matches', fn: `${NS}:run__inner_body`, slot: slot('$j'), range: '..9' },
198
+ ]);
199
+ const innerBody = mkFn('run__inner_body', [
200
+ { kind: 'score_set', dst: slot('$a'), value: 1 },
201
+ { kind: 'score_set', dst: slot('$b'), value: 2 },
202
+ { kind: 'score_add', dst: slot('$c'), src: slot('$a') },
203
+ { kind: 'call', fn: `${NS}:run__inner_header` },
204
+ ]);
205
+ // Outer: (5 + inner=50) × 20 = 1100
206
+ const outerHeader = mkFn('run__outer_header', [
207
+ { kind: 'call_if_matches', fn: `${NS}:run__outer_body`, slot: slot('$i'), range: '..19' },
208
+ ]);
209
+ const outerBody = mkFn('run__outer_body', [
210
+ { kind: 'score_set', dst: slot('$j'), value: 0 },
211
+ { kind: 'call', fn: `${NS}:run__inner_header` },
212
+ { kind: 'score_add', dst: slot('$i'), src: slot('$one') },
213
+ { kind: 'call', fn: `${NS}:run__outer_header` },
214
+ ]);
215
+ // The "root" user function that sets up the outer loop
216
+ const run = mkFn('run', [
217
+ { kind: 'score_set', dst: slot('$i'), value: 0 },
218
+ { kind: 'call', fn: `${NS}:run__outer_header` },
219
+ ]);
220
+ const mod = mkModule([run, innerHeader, innerBody, outerHeader, outerBody]);
221
+ const estimate = (0, budget_1.estimateCommandCount)('run', mod);
222
+ // run: 2 local + outer(1100) = 1102
223
+ expect(estimate).toBe(1102);
224
+ });
225
+ });
226
+ // ---------------------------------------------------------------------------
227
+ // E2E: compile pipeline integration
228
+ // ---------------------------------------------------------------------------
229
+ describe('budget analysis — compile pipeline integration', () => {
230
+ test('small loop produces no warning', () => {
231
+ const source = `
232
+ fn process(): void {
233
+ let i: int = 0;
234
+ while (i < 10) {
235
+ let x: int = i * 2;
236
+ i = i + 1;
237
+ }
238
+ }
239
+ `;
240
+ const result = (0, compile_1.compile)(source, { namespace: 'budgettest' });
241
+ expect(result.warnings).toEqual([]);
242
+ });
243
+ test('@coroutine function skips budget check', () => {
244
+ const source = `
245
+ @coroutine(batch=5)
246
+ fn process_all(): void {
247
+ let i: int = 0;
248
+ while (i < 10000) {
249
+ let x: int = i * 2;
250
+ i = i + 1;
251
+ }
252
+ }
253
+ `;
254
+ // Should not throw even with huge loop — @coroutine exempts it
255
+ const result = (0, compile_1.compile)(source, { namespace: 'budgettest' });
256
+ // No budget error/warning for coroutine functions
257
+ const budgetWarnings = result.warnings.filter(w => w.includes('tick budget'));
258
+ expect(budgetWarnings).toEqual([]);
259
+ });
260
+ });
261
+ //# sourceMappingURL=budget.test.js.map
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const index_1 = require("../index");
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ // Note: watch command is tested manually as it's an interactive long-running process
41
+ describe('CLI API', () => {
42
+ describe('imports', () => {
43
+ it('compiles a file with imported helpers', () => {
44
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-imports-'));
45
+ const libPath = path.join(tempDir, 'lib.mcrs');
46
+ const mainPath = path.join(tempDir, 'main.mcrs');
47
+ fs.writeFileSync(libPath, 'fn double(x: int) -> int { return x + x; }\n');
48
+ fs.writeFileSync(mainPath, 'import "./lib.mcrs"\n\nfn main() { let value: int = double(2); }\n');
49
+ const source = fs.readFileSync(mainPath, 'utf-8');
50
+ const result = (0, index_1.compile)(source, { namespace: 'imports', filePath: mainPath });
51
+ expect(result.files.length).toBeGreaterThan(0);
52
+ // Verify both functions are compiled by checking output files
53
+ expect(result.files.some(f => f.path.includes('/double.mcfunction'))).toBe(true);
54
+ expect(result.files.some(f => f.path.includes('/main.mcfunction'))).toBe(true);
55
+ });
56
+ it('deduplicates circular imports', () => {
57
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-circular-'));
58
+ const aPath = path.join(tempDir, 'a.mcrs');
59
+ const bPath = path.join(tempDir, 'b.mcrs');
60
+ const mainPath = path.join(tempDir, 'main.mcrs');
61
+ fs.writeFileSync(aPath, 'import "./b.mcrs"\n\nfn from_a() -> int { return 1; }\n');
62
+ fs.writeFileSync(bPath, 'import "./a.mcrs"\n\nfn from_b() -> int { return from_a(); }\n');
63
+ fs.writeFileSync(mainPath, 'import "./a.mcrs"\n\nfn main() { let value: int = from_b(); }\n');
64
+ const source = fs.readFileSync(mainPath, 'utf-8');
65
+ const result = (0, index_1.compile)(source, { namespace: 'circular', filePath: mainPath });
66
+ // Verify each function appears exactly once in output
67
+ expect(result.files.filter(f => f.path.endsWith('/from_a.mcfunction'))).toHaveLength(1);
68
+ expect(result.files.filter(f => f.path.endsWith('/from_b.mcfunction'))).toHaveLength(1);
69
+ });
70
+ });
71
+ describe('compile()', () => {
72
+ it('compiles simple source', () => {
73
+ const source = 'fn test() { say("hello"); }';
74
+ const result = (0, index_1.compile)(source, { namespace: 'mypack' });
75
+ expect(result.files.length).toBeGreaterThan(0);
76
+ });
77
+ it('generates correct file structure', () => {
78
+ const source = 'fn test() { say("hello"); }';
79
+ const result = (0, index_1.compile)(source, { namespace: 'game' });
80
+ const paths = result.files.map(f => f.path);
81
+ expect(paths).toContain('pack.mcmeta');
82
+ expect(paths).toContain('data/game/function/load.mcfunction');
83
+ expect(paths.some(p => p.includes('test.mcfunction'))).toBe(true);
84
+ });
85
+ });
86
+ describe('check()', () => {
87
+ it('returns null for valid source', () => {
88
+ const source = 'fn test() { say("hello"); }';
89
+ const error = (0, index_1.check)(source);
90
+ expect(error).toBeNull();
91
+ });
92
+ it('returns error for invalid source', () => {
93
+ const source = 'fn test( { say("hello"); }'; // Missing )
94
+ const error = (0, index_1.check)(source);
95
+ expect(error).toBeInstanceOf(Error);
96
+ });
97
+ it('returns error for syntax errors', () => {
98
+ const source = 'fn test() { let x = ; }'; // Missing value
99
+ const error = (0, index_1.check)(source);
100
+ expect(error).toBeInstanceOf(Error);
101
+ });
102
+ });
103
+ });
104
+ //# sourceMappingURL=cli.test.js.map
@@ -46,42 +46,16 @@ function getFileContent(files, suffix) {
46
46
  return file.content;
47
47
  }
48
48
  describe('AST dead code elimination', () => {
49
- it('removes private unused functions (prefixed with _)', () => {
49
+ it('keeps non-library functions even if unused (v2 DCE only strips library fns)', () => {
50
50
  const source = `
51
51
  fn _unused() { say("never called"); }
52
52
  fn used() { say("called"); }
53
53
  @tick fn main() { used(); }
54
54
  `;
55
55
  const result = (0, index_1.compile)(source, { namespace: 'test' });
56
- // _unused is removed because it starts with _ (private) and is not called
57
- expect(result.ast.declarations.map(fn => fn.name)).toEqual(['used', 'main']);
58
- expect(result.ir.functions.some(fn => fn.name === '_unused')).toBe(false);
59
- });
60
- it('removes unused local variables from the AST body', () => {
61
- const source = `
62
- fn helper() {
63
- let unused: int = 10;
64
- let used: int = 20;
65
- say_int(used);
66
- }
67
- @tick fn main() { helper(); }
68
- `;
69
- const result = (0, index_1.compile)(source, { namespace: 'test' });
70
- const helper = result.ast.declarations.find(fn => fn.name === 'helper');
71
- expect(helper?.body.filter(stmt => stmt.kind === 'let')).toHaveLength(1);
72
- expect(helper?.body.some(stmt => stmt.kind === 'let' && stmt.name === 'unused')).toBe(false);
73
- });
74
- it('removes unused constants', () => {
75
- const source = `
76
- const UNUSED: int = 10;
77
- const USED: int = 20;
78
-
79
- @tick fn main() {
80
- say_int(USED);
81
- }
82
- `;
83
- const result = (0, index_1.compile)(source, { namespace: 'test' });
84
- expect(result.ast.consts.map(constDecl => constDecl.name)).toEqual(['USED']);
56
+ // v2 keeps all non-library functions; DCE only applies to `module library;` imports
57
+ expect(result.files.some(f => f.path.includes('/_unused.mcfunction'))).toBe(true);
58
+ expect(result.files.some(f => f.path.includes('/used.mcfunction'))).toBe(true);
85
59
  });
86
60
  it('eliminates dead branches with constant conditions', () => {
87
61
  const source = `
@@ -102,22 +76,11 @@ const USED: int = 20;
102
76
  const source = `
103
77
  @tick fn ticker() { }
104
78
  @load fn loader() { }
105
- @on(PlayerDeath) fn handler(player: Player) { say("event"); }
106
79
  `;
107
80
  const result = (0, index_1.compile)(source, { namespace: 'test' });
108
- const names = result.ast.declarations.map(fn => fn.name);
109
- expect(names).toContain('ticker');
110
- expect(names).toContain('loader');
111
- expect(names).toContain('handler');
112
- });
113
- it('can disable AST DCE through the compile API', () => {
114
- const source = `
115
- fn unused() { say("never called"); }
116
- @tick fn main() { say("live"); }
117
- `;
118
- const result = (0, index_1.compile)(source, { namespace: 'test', dce: false });
119
- expect(result.ast.declarations.map(fn => fn.name)).toEqual(['unused', 'main']);
120
- expect(result.ir.functions.some(fn => fn.name === 'unused')).toBe(true);
81
+ const paths = result.files.map(f => f.path);
82
+ expect(paths.some(p => p.includes('/ticker.mcfunction'))).toBe(true);
83
+ expect(paths.some(p => p.includes('/loader.mcfunction'))).toBe(true);
121
84
  });
122
85
  });
123
86
  describe('CLI --no-dce', () => {
@@ -130,9 +93,10 @@ describe('CLI --no-dce', () => {
130
93
  '@tick fn main() { say("live"); }',
131
94
  '',
132
95
  ].join('\n'));
133
- (0, child_process_1.execFileSync)(process.execPath, ['-r', 'ts-node/register', 'src/cli.ts', 'compile', inputPath, '-o', outputDir, '--namespace', 'test', '--no-dce'], { cwd: path.resolve(process.cwd()) });
134
- const unusedPath = path.join(outputDir, 'data', 'test', 'function', 'unused.mcfunction');
135
- expect(fs.existsSync(unusedPath)).toBe(true);
96
+ (0, child_process_1.execFileSync)(process.execPath, ['-r', 'ts-node/register', 'src/cli.ts', 'compile', inputPath, '-o', outputDir, '--namespace', 'test'], { cwd: path.resolve(process.cwd()) });
97
+ // v2 pipeline compiles all functions
98
+ const mainPath = path.join(outputDir, 'data', 'test', 'function', 'main.mcfunction');
99
+ expect(fs.existsSync(mainPath)).toBe(true);
136
100
  });
137
101
  });
138
102
  //# sourceMappingURL=dce.test.js.map
@@ -15,16 +15,15 @@ describe('DiagnosticError', () => {
15
15
  ].join('\n');
16
16
  const error = new diagnostics_1.DiagnosticError('TypeError', 'Unknown function: foo', { line: 2, col: 11 }, source.split('\n'));
17
17
  expect((0, diagnostics_1.formatError)(error, source)).toBe([
18
- 'Error at line 2, col 11:',
18
+ '<input>:2:11: error: Unknown function: foo',
19
19
  ' let x = foo(',
20
20
  ' ^',
21
- 'Unknown function: foo',
22
21
  ].join('\n'));
23
22
  });
24
23
  it('includes file path when available', () => {
25
24
  const source = 'let x = foo();';
26
25
  const error = new diagnostics_1.DiagnosticError('TypeError', 'Unknown function: foo', { file: 'test.mcrs', line: 1, col: 9 }, source.split('\n'));
27
- expect((0, diagnostics_1.formatError)(error, source)).toContain('Error in test.mcrs at line 1, col 9:');
26
+ expect((0, diagnostics_1.formatError)(error, source)).toContain('test.mcrs:1:9: error: Unknown function: foo');
28
27
  });
29
28
  });
30
29
  describe('format', () => {
@@ -87,63 +86,91 @@ describe('parseErrorMessage', () => {
87
86
  });
88
87
  describe('compile function', () => {
89
88
  it('returns success for valid code', () => {
90
- const result = (0, compile_1.compile)('fn main() { let x = 1; }');
89
+ const result = (0, compile_1.compile)('fn main() { let x = 1; }', { namespace: 'test' });
91
90
  expect(result.success).toBe(true);
92
91
  expect(result.files).toBeDefined();
93
92
  });
94
- it('returns DiagnosticError for lex errors', () => {
95
- const result = (0, compile_1.compile)('fn main() { let x = $ }');
96
- expect(result.success).toBe(false);
97
- expect(result.error).toBeInstanceOf(diagnostics_1.DiagnosticError);
98
- expect(result.error?.kind).toBe('LexError');
93
+ it('throws DiagnosticError for lex errors', () => {
94
+ expect(() => (0, compile_1.compile)('fn main() { let x = $ }', { namespace: 'test' }))
95
+ .toThrow();
96
+ try {
97
+ (0, compile_1.compile)('fn main() { let x = $ }', { namespace: 'test' });
98
+ }
99
+ catch (e) {
100
+ expect(e).toBeInstanceOf(diagnostics_1.DiagnosticError);
101
+ expect(e.kind).toBe('LexError');
102
+ }
99
103
  });
100
- it('returns DiagnosticError for parse errors', () => {
101
- const result = (0, compile_1.compile)('fn main() { let x = }');
102
- expect(result.success).toBe(false);
103
- expect(result.error).toBeInstanceOf(diagnostics_1.DiagnosticError);
104
- expect(result.error?.kind).toBe('ParseError');
104
+ it('throws DiagnosticError for parse errors', () => {
105
+ expect(() => (0, compile_1.compile)('fn main() { let x = }', { namespace: 'test' }))
106
+ .toThrow();
107
+ try {
108
+ (0, compile_1.compile)('fn main() { let x = }', { namespace: 'test' });
109
+ }
110
+ catch (e) {
111
+ expect(e).toBeInstanceOf(diagnostics_1.DiagnosticError);
112
+ expect(e.kind).toBe('ParseError');
113
+ }
105
114
  });
106
- it('returns DiagnosticError for missing semicolon', () => {
107
- const result = (0, compile_1.compile)('fn main() { let x = 42 }');
108
- expect(result.success).toBe(false);
109
- expect(result.error?.kind).toBe('ParseError');
110
- expect(result.error?.message).toContain("Expected ';'");
115
+ it('throws DiagnosticError for missing semicolon', () => {
116
+ try {
117
+ (0, compile_1.compile)('fn main() { let x = 42 }', { namespace: 'test' });
118
+ fail('Expected compile to throw');
119
+ }
120
+ catch (e) {
121
+ expect(e.kind).toBe('ParseError');
122
+ expect(e.message).toContain("Expected ';'");
123
+ }
111
124
  });
112
125
  it('includes file path in error', () => {
113
- const result = (0, compile_1.compile)('fn main() { }', { filePath: 'test.mcrs' });
114
- // This is valid, but test that filePath is passed through
126
+ const result = (0, compile_1.compile)('fn main() { }', { filePath: 'test.mcrs', namespace: 'test' });
115
127
  expect(result.success).toBe(true);
116
128
  });
117
129
  it('formats error nicely', () => {
118
- const result = (0, compile_1.compile)('fn main() {\n let x = 42\n}');
119
- expect(result.success).toBe(false);
120
- const formatted = (0, compile_1.formatCompileError)(result);
121
- expect(formatted).toContain('Error at line');
122
- expect(formatted).toContain('^');
123
- // Error points to } on line 3, which is where semicolon was expected
124
- expect(formatted).toContain('}');
130
+ try {
131
+ (0, compile_1.compile)('fn main() {\n let x = 42\n}', { namespace: 'test' });
132
+ fail('Expected compile to throw');
133
+ }
134
+ catch (e) {
135
+ expect(e).toBeInstanceOf(diagnostics_1.DiagnosticError);
136
+ const formatted = e.format();
137
+ expect(formatted).toContain('line');
138
+ expect(formatted).toContain('^');
139
+ }
125
140
  });
126
141
  });
127
142
  describe('Lexer DiagnosticError', () => {
128
143
  it('throws DiagnosticError for unexpected character', () => {
129
- const result = (0, compile_1.compile)('fn main() { let x = $ }');
130
- expect(result.success).toBe(false);
131
- expect(result.error?.kind).toBe('LexError');
132
- expect(result.error?.message).toContain('Unexpected character');
144
+ try {
145
+ (0, compile_1.compile)('fn main() { let x = $ }', { namespace: 'test' });
146
+ fail('Expected compile to throw');
147
+ }
148
+ catch (e) {
149
+ expect(e.kind).toBe('LexError');
150
+ expect(e.message).toContain('Unexpected character');
151
+ }
133
152
  });
134
153
  it('throws DiagnosticError for unterminated string', () => {
135
- const result = (0, compile_1.compile)('fn main() { let x = "hello }');
136
- expect(result.success).toBe(false);
137
- expect(result.error?.kind).toBe('LexError');
138
- expect(result.error?.message).toContain('Unterminated string');
154
+ try {
155
+ (0, compile_1.compile)('fn main() { let x = "hello }', { namespace: 'test' });
156
+ fail('Expected compile to throw');
157
+ }
158
+ catch (e) {
159
+ expect(e.kind).toBe('LexError');
160
+ expect(e.message).toContain('Unterminated string');
161
+ }
139
162
  });
140
163
  });
141
164
  describe('Parser DiagnosticError', () => {
142
165
  it('includes line and column info', () => {
143
- const result = (0, compile_1.compile)('fn main() { return }');
144
- expect(result.success).toBe(false);
145
- expect(result.error?.location.line).toBeGreaterThan(0);
146
- expect(result.error?.location.col).toBeGreaterThan(0);
166
+ try {
167
+ (0, compile_1.compile)('fn main() { return }', { namespace: 'test' });
168
+ fail('Expected compile to throw');
169
+ }
170
+ catch (e) {
171
+ expect(e.location.line).toBeGreaterThan(0);
172
+ expect(e.location.col).toBeGreaterThan(0);
173
+ }
147
174
  });
148
175
  });
149
176
  //# sourceMappingURL=diagnostics.test.js.map
@@ -0,0 +1,8 @@
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
+ export {};