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
@@ -117,6 +117,7 @@ class TypeChecker {
117
117
  this.structs = new Map();
118
118
  this.enums = new Map();
119
119
  this.consts = new Map();
120
+ this.globals = new Map();
120
121
  this.currentFn = null;
121
122
  this.currentReturnType = null;
122
123
  this.scope = new Map();
@@ -152,6 +153,10 @@ class TypeChecker {
152
153
  for (const fn of program.declarations) {
153
154
  this.functions.set(fn.name, fn);
154
155
  }
156
+ // Register global variables (mutable) so functions can reference and assign them
157
+ for (const global of program.globals ?? []) {
158
+ this.globals.set(global.name, this.normalizeType(global.type));
159
+ }
155
160
  for (const implBlock of program.implBlocks ?? []) {
156
161
  let methods = this.implMethods.get(implBlock.typeName);
157
162
  if (!methods) {
@@ -206,6 +211,10 @@ class TypeChecker {
206
211
  return this.collector.getErrors();
207
212
  }
208
213
  checkFunction(fn) {
214
+ // Generic functions (with type params like <T>) are checked after monomorphization.
215
+ // Skip body checking here to avoid false errors for unresolved type params.
216
+ if (fn.typeParams && fn.typeParams.length > 0)
217
+ return;
209
218
  this.currentFn = fn;
210
219
  this.currentReturnType = this.normalizeType(fn.returnType);
211
220
  this.scope = new Map();
@@ -214,6 +223,9 @@ class TypeChecker {
214
223
  for (const [name, type] of this.consts.entries()) {
215
224
  this.scope.set(name, { type, mutable: false });
216
225
  }
226
+ for (const [name, type] of this.globals.entries()) {
227
+ this.scope.set(name, { type, mutable: true });
228
+ }
217
229
  // Add parameters to scope
218
230
  for (const param of fn.params) {
219
231
  this.scope.set(param.name, { type: this.normalizeType(param.type), mutable: true });
@@ -276,6 +288,9 @@ class TypeChecker {
276
288
  case 'let':
277
289
  this.checkLetStmt(stmt);
278
290
  break;
291
+ case 'let_destruct':
292
+ this.checkLetDestructStmt(stmt);
293
+ break;
279
294
  case 'return':
280
295
  this.checkReturnStmt(stmt);
281
296
  break;
@@ -324,7 +339,12 @@ class TypeChecker {
324
339
  for (const arm of stmt.arms) {
325
340
  if (arm.pattern) {
326
341
  this.checkExpr(arm.pattern);
327
- if (!this.typesMatch(this.inferType(stmt.expr), this.inferType(arm.pattern))) {
342
+ const subjectType = this.inferType(stmt.expr);
343
+ const patternType = this.inferType(arm.pattern);
344
+ // Skip check if either type is unknown (void) — struct field access not yet inferred
345
+ const isUnknown = (t) => t.kind === 'named' && t.name === 'void';
346
+ if (!isUnknown(subjectType) && !isUnknown(patternType) &&
347
+ !this.typesMatch(subjectType, patternType)) {
328
348
  this.report('Match arm pattern type must match subject type', arm.pattern);
329
349
  }
330
350
  }
@@ -375,6 +395,41 @@ class TypeChecker {
375
395
  break;
376
396
  }
377
397
  }
398
+ checkLetDestructStmt(stmt) {
399
+ this.checkExpr(stmt.init);
400
+ const initType = this.inferType(stmt.init);
401
+ if (stmt.type) {
402
+ // Type annotation must be a tuple
403
+ const normalized = this.normalizeType(stmt.type);
404
+ if (normalized.kind !== 'tuple') {
405
+ this.report(`Destructuring type annotation must be a tuple type`, stmt);
406
+ return;
407
+ }
408
+ if (normalized.elements.length !== stmt.names.length) {
409
+ this.report(`Destructuring pattern has ${stmt.names.length} bindings but type has ${normalized.elements.length} elements`, stmt);
410
+ }
411
+ for (let i = 0; i < stmt.names.length; i++) {
412
+ const elemType = normalized.elements[i] ?? { kind: 'named', name: 'int' };
413
+ this.scope.set(stmt.names[i], { type: elemType, mutable: true });
414
+ }
415
+ }
416
+ else if (initType.kind === 'tuple') {
417
+ // Infer element types from tuple literal type
418
+ if (initType.elements.length !== stmt.names.length) {
419
+ this.report(`Destructuring pattern has ${stmt.names.length} bindings but tuple has ${initType.elements.length} elements`, stmt);
420
+ }
421
+ for (let i = 0; i < stmt.names.length; i++) {
422
+ const elemType = initType.elements[i] ?? { kind: 'named', name: 'int' };
423
+ this.scope.set(stmt.names[i], { type: elemType, mutable: true });
424
+ }
425
+ }
426
+ else {
427
+ // Can't infer element types — use int as fallback (tuple returns inferred as int from scoreboard)
428
+ for (const name of stmt.names) {
429
+ this.scope.set(name, { type: INT_TYPE, mutable: true });
430
+ }
431
+ }
432
+ }
378
433
  checkLetStmt(stmt) {
379
434
  // Check initializer
380
435
  const expectedType = stmt.type ? this.normalizeType(stmt.type) : undefined;
@@ -386,9 +441,15 @@ class TypeChecker {
386
441
  if (expectedType &&
387
442
  stmt.init.kind !== 'struct_lit' &&
388
443
  stmt.init.kind !== 'array_lit' &&
389
- !(actualType.kind === 'named' && actualType.name === 'void') &&
390
- !this.typesMatch(expectedType, actualType)) {
391
- this.report(`Type mismatch: expected ${this.typeToString(expectedType)}, got ${this.typeToString(actualType)}`, stmt);
444
+ !(actualType.kind === 'named' && actualType.name === 'void')) {
445
+ if (this.isNumericMismatch(expectedType, actualType)) {
446
+ // Explicit numeric conversion required for let assignments
447
+ this.report(`Type mismatch: cannot implicitly convert ${this.typeToString(actualType)} to ${this.typeToString(expectedType)}` +
448
+ ` (use an explicit cast: 'as ${this.typeToString(expectedType)}')`, stmt);
449
+ }
450
+ else if (!this.typesMatch(expectedType, actualType)) {
451
+ this.report(`Type mismatch: expected ${this.typeToString(expectedType)}, got ${this.typeToString(actualType)}`, stmt);
452
+ }
392
453
  }
393
454
  }
394
455
  checkReturnStmt(stmt) {
@@ -398,7 +459,12 @@ class TypeChecker {
398
459
  if (stmt.value) {
399
460
  const actualType = this.inferType(stmt.value, expectedType);
400
461
  this.checkExpr(stmt.value, expectedType);
401
- if (!this.typesMatch(expectedType, actualType)) {
462
+ if (this.isNumericMismatch(expectedType, actualType)) {
463
+ // Explicit numeric conversion required for return statements
464
+ this.report(`Return type mismatch: cannot implicitly convert ${this.typeToString(actualType)} to ${this.typeToString(expectedType)}` +
465
+ ` (use an explicit cast: 'as ${this.typeToString(expectedType)}')`, stmt);
466
+ }
467
+ else if (!this.typesMatch(expectedType, actualType)) {
402
468
  this.report(`Return type mismatch: expected ${this.typeToString(expectedType)}, got ${this.typeToString(actualType)}`, stmt);
403
469
  }
404
470
  }
@@ -483,7 +549,10 @@ class TypeChecker {
483
549
  }
484
550
  this.checkExpr(part.expr);
485
551
  const partType = this.inferType(part.expr);
486
- if (!(partType.kind === 'named' && (partType.name === 'int' || partType.name === 'string' || partType.name === 'format_string'))) {
552
+ // Skip check if type is unknown (void) struct field access not yet fully inferred
553
+ const isUnknown = partType.kind === 'named' && partType.name === 'void';
554
+ if (!isUnknown &&
555
+ !(partType.kind === 'named' && (partType.name === 'int' || partType.name === 'string' || partType.name === 'format_string'))) {
487
556
  this.report(`f-string placeholder must be int or string, got ${this.typeToString(partType)}`, part.expr);
488
557
  }
489
558
  }
@@ -493,9 +562,28 @@ class TypeChecker {
493
562
  this.checkExpr(elem);
494
563
  }
495
564
  break;
565
+ case 'tuple_lit':
566
+ if (expr.elements.length < 2 || expr.elements.length > 8) {
567
+ this.report(`Tuple must have 2-8 elements, got ${expr.elements.length}`, expr);
568
+ }
569
+ for (const elem of expr.elements) {
570
+ this.checkExpr(elem);
571
+ }
572
+ break;
496
573
  case 'lambda':
497
574
  this.checkLambdaExpr(expr, expectedType);
498
575
  break;
576
+ case 'path_expr':
577
+ if (!this.enums.has(expr.enumName)) {
578
+ this.report(`Unknown enum '${expr.enumName}'`, expr);
579
+ }
580
+ else {
581
+ const variants = this.enums.get(expr.enumName);
582
+ if (!variants.has(expr.variant)) {
583
+ this.report(`Enum '${expr.enumName}' has no variant '${expr.variant}'`, expr);
584
+ }
585
+ }
586
+ break;
499
587
  case 'blockpos':
500
588
  break;
501
589
  // Literals don't need checking
@@ -530,6 +618,16 @@ class TypeChecker {
530
618
  // Check if function exists and arg count matches
531
619
  const fn = this.functions.get(expr.fn);
532
620
  if (fn) {
621
+ // Generic functions: skip param-type checking (monomorphizer handles it)
622
+ if (fn.typeParams && fn.typeParams.length > 0) {
623
+ const requiredParams = fn.params.filter(param => !param.default).length;
624
+ if (expr.args.length < requiredParams || expr.args.length > fn.params.length) {
625
+ this.report(`Function '${expr.fn}' expects ${requiredParams}-${fn.params.length} arguments, got ${expr.args.length}`, expr);
626
+ }
627
+ for (const arg of expr.args)
628
+ this.checkExpr(arg);
629
+ return;
630
+ }
533
631
  const requiredParams = fn.params.filter(param => !param.default).length;
534
632
  if (expr.args.length < requiredParams || expr.args.length > fn.params.length) {
535
633
  const expectedRange = requiredParams === fn.params.length
@@ -810,7 +908,15 @@ class TypeChecker {
810
908
  return this.normalizeType(implMethod.returnType);
811
909
  }
812
910
  const fn = this.functions.get(expr.fn);
813
- return fn?.returnType ?? INT_TYPE;
911
+ if (fn) {
912
+ // For generic functions, the return type may be a type param (e.g. T).
913
+ // If we have an expected type from context, trust it; otherwise return int as default.
914
+ if (fn.typeParams && fn.typeParams.length > 0) {
915
+ return expectedType ?? INT_TYPE;
916
+ }
917
+ return this.normalizeType(fn.returnType);
918
+ }
919
+ return INT_TYPE;
814
920
  }
815
921
  case 'static_call': {
816
922
  const method = this.implMethods.get(expr.type)?.get(expr.method);
@@ -823,6 +929,11 @@ class TypeChecker {
823
929
  }
824
930
  return { kind: 'named', name: 'void' };
825
931
  }
932
+ case 'path_expr':
933
+ if (this.enums.has(expr.enumName)) {
934
+ return { kind: 'enum', name: expr.enumName };
935
+ }
936
+ return { kind: 'named', name: 'void' };
826
937
  case 'member':
827
938
  if (expr.obj.kind === 'ident' && this.enums.has(expr.obj.name)) {
828
939
  return { kind: 'enum', name: expr.obj.name };
@@ -851,6 +962,11 @@ class TypeChecker {
851
962
  if (expr.op === '!')
852
963
  return { kind: 'named', name: 'bool' };
853
964
  return this.inferType(expr.operand);
965
+ case 'selector': {
966
+ // Infer entity type from the selector
967
+ const entityType = this.inferEntityTypeFromSelector(expr.sel);
968
+ return { kind: 'selector', entityType: entityType ?? undefined };
969
+ }
854
970
  case 'array_lit':
855
971
  if (expr.elements.length > 0) {
856
972
  return { kind: 'array', elem: this.inferType(expr.elements[0]) };
@@ -864,6 +980,22 @@ class TypeChecker {
864
980
  }
865
981
  }
866
982
  return { kind: 'named', name: 'void' };
983
+ case 'tuple_lit':
984
+ return {
985
+ kind: 'tuple',
986
+ elements: expr.elements.map(e => this.inferType(e)),
987
+ };
988
+ case 'some_lit': {
989
+ // Some(expr) → Option<T> where T is inferred from inner value
990
+ const innerType = this.inferType(expr.value, expectedType?.kind === 'option' ? expectedType.inner : undefined);
991
+ return { kind: 'option', inner: innerType };
992
+ }
993
+ case 'none_lit': {
994
+ // None → Option<T>, use expected type if available
995
+ if (expectedType?.kind === 'option')
996
+ return expectedType;
997
+ return { kind: 'option', inner: { kind: 'named', name: 'void' } };
998
+ }
867
999
  case 'lambda':
868
1000
  return this.inferLambdaType(expr, expectedType && this.normalizeType(expectedType).kind === 'function_type'
869
1001
  ? this.normalizeType(expectedType)
@@ -954,14 +1086,54 @@ class TypeChecker {
954
1086
  getCurrentSelfType() {
955
1087
  return this.selfTypeStack[this.selfTypeStack.length - 1];
956
1088
  }
1089
+ /** Returns true if expected/actual are a numeric type mismatch (int vs float). */
1090
+ isNumericMismatch(expected, actual) {
1091
+ if (expected.kind !== 'named' || actual.kind !== 'named')
1092
+ return false;
1093
+ const numericPairs = [
1094
+ ['int', 'float'], ['float', 'int'],
1095
+ ['int', 'double'], ['double', 'int'],
1096
+ ['float', 'double'], ['double', 'float'],
1097
+ ];
1098
+ return numericPairs.some(([e, a]) => expected.name === e && actual.name === a);
1099
+ }
957
1100
  typesMatch(expected, actual) {
1101
+ // Enum values are backed by int — allow enum where int is expected and vice versa
1102
+ if (expected.kind === 'named' && expected.name === 'int' && actual.kind === 'enum') {
1103
+ return true;
1104
+ }
1105
+ if (expected.kind === 'enum' && actual.kind === 'named' && actual.name === 'int') {
1106
+ return true;
1107
+ }
1108
+ // Selector/entity cross-kind compatibility (must come before kind guard)
1109
+ if (expected.kind === 'selector' && actual.kind === 'entity') {
1110
+ return true; // entity is a valid selector
1111
+ }
1112
+ if (expected.kind === 'entity' && actual.kind === 'selector') {
1113
+ return true; // selector is a valid entity context
1114
+ }
1115
+ if (expected.kind === 'entity' && actual.kind === 'entity') {
1116
+ return this.isEntitySubtype(actual.entityType, expected.entityType);
1117
+ }
1118
+ if (expected.kind === 'selector' && actual.kind === 'selector') {
1119
+ return true; // any entity subtype is compatible
1120
+ }
958
1121
  if (expected.kind !== actual.kind)
959
1122
  return false;
960
1123
  if (expected.kind === 'named' && actual.kind === 'named') {
961
1124
  // void matches anything (for inferred types)
962
1125
  if (actual.name === 'void')
963
1126
  return true;
964
- return expected.name === actual.name;
1127
+ if (expected.name === actual.name)
1128
+ return true;
1129
+ // int→float/double implicit promotion in function calls (not for let/return — handled separately)
1130
+ const numericPromotion = [
1131
+ ['int', 'float'], ['int', 'double'], ['float', 'double'],
1132
+ ['float', 'int'], ['double', 'int'], ['double', 'float'],
1133
+ ];
1134
+ if (numericPromotion.some(([e, a]) => expected.name === e && actual.name === a))
1135
+ return true;
1136
+ return false;
965
1137
  }
966
1138
  if (expected.kind === 'array' && actual.kind === 'array') {
967
1139
  return this.typesMatch(expected.elem, actual.elem);
@@ -977,12 +1149,15 @@ class TypeChecker {
977
1149
  expected.params.every((param, index) => this.typesMatch(param, actual.params[index])) &&
978
1150
  this.typesMatch(expected.return, actual.return);
979
1151
  }
980
- // Entity type matching with subtype support
981
- if (expected.kind === 'entity' && actual.kind === 'entity') {
982
- return this.isEntitySubtype(actual.entityType, expected.entityType);
1152
+ if (expected.kind === 'tuple' && actual.kind === 'tuple') {
1153
+ return expected.elements.length === actual.elements.length &&
1154
+ expected.elements.every((elem, i) => this.typesMatch(elem, actual.elements[i]));
983
1155
  }
984
- // Selector matches any entity type
985
- if (expected.kind === 'selector' && actual.kind === 'entity') {
1156
+ if (expected.kind === 'option' && actual.kind === 'option') {
1157
+ return this.typesMatch(expected.inner, actual.inner);
1158
+ }
1159
+ // Option<T> is compatible with None (void inner) or partially inferred types
1160
+ if (expected.kind === 'option' && actual.kind === 'named' && actual.name === 'void') {
986
1161
  return true;
987
1162
  }
988
1163
  return false;
@@ -1003,6 +1178,10 @@ class TypeChecker {
1003
1178
  return type.entityType;
1004
1179
  case 'selector':
1005
1180
  return 'selector';
1181
+ case 'tuple':
1182
+ return `(${type.elements.map(e => this.typeToString(e)).join(', ')})`;
1183
+ case 'option':
1184
+ return `Option<${this.typeToString(type.inner)}>`;
1006
1185
  default:
1007
1186
  return 'unknown';
1008
1187
  }
@@ -1011,6 +1190,12 @@ class TypeChecker {
1011
1190
  if (type.kind === 'array') {
1012
1191
  return { kind: 'array', elem: this.normalizeType(type.elem) };
1013
1192
  }
1193
+ if (type.kind === 'option') {
1194
+ return { kind: 'option', inner: this.normalizeType(type.inner) };
1195
+ }
1196
+ if (type.kind === 'tuple') {
1197
+ return { kind: 'tuple', elements: type.elements.map(e => this.normalizeType(e)) };
1198
+ }
1014
1199
  if (type.kind === 'function_type') {
1015
1200
  return {
1016
1201
  kind: 'function_type',
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Minecraft version target enumeration.
3
+ *
4
+ * Encoded as: major * 1000 + minor (patch is ignored for feature gating).
5
+ * e.g., 1.20.2 → 20002, 1.21 → 21000, 1.21.4 → 21004
6
+ */
7
+ export declare enum McVersion {
8
+ v1_19 = 19000,
9
+ v1_20 = 20000,
10
+ v1_20_2 = 20002,
11
+ v1_20_4 = 20004,
12
+ v1_21 = 21000,
13
+ v1_21_4 = 21004
14
+ }
15
+ /**
16
+ * Parse a version string like "1.20.2" or "1.21" into a McVersion number.
17
+ * Throws if the string is not a valid Minecraft version.
18
+ */
19
+ export declare function parseMcVersion(s: string): McVersion;
20
+ /**
21
+ * Compare two McVersion values. Returns negative if a < b, 0 if equal, positive if a > b.
22
+ */
23
+ export declare function compareMcVersion(a: McVersion, b: McVersion): number;
24
+ export declare const DEFAULT_MC_VERSION = McVersion.v1_21;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * Minecraft version target enumeration.
4
+ *
5
+ * Encoded as: major * 1000 + minor (patch is ignored for feature gating).
6
+ * e.g., 1.20.2 → 20002, 1.21 → 21000, 1.21.4 → 21004
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DEFAULT_MC_VERSION = exports.McVersion = void 0;
10
+ exports.parseMcVersion = parseMcVersion;
11
+ exports.compareMcVersion = compareMcVersion;
12
+ var McVersion;
13
+ (function (McVersion) {
14
+ McVersion[McVersion["v1_19"] = 19000] = "v1_19";
15
+ McVersion[McVersion["v1_20"] = 20000] = "v1_20";
16
+ McVersion[McVersion["v1_20_2"] = 20002] = "v1_20_2";
17
+ McVersion[McVersion["v1_20_4"] = 20004] = "v1_20_4";
18
+ McVersion[McVersion["v1_21"] = 21000] = "v1_21";
19
+ McVersion[McVersion["v1_21_4"] = 21004] = "v1_21_4";
20
+ })(McVersion || (exports.McVersion = McVersion = {}));
21
+ /**
22
+ * Parse a version string like "1.20.2" or "1.21" into a McVersion number.
23
+ * Throws if the string is not a valid Minecraft version.
24
+ */
25
+ function parseMcVersion(s) {
26
+ const parts = s.trim().split('.');
27
+ if (parts.length < 2 || parts.length > 3) {
28
+ throw new Error(`Invalid MC version: "${s}" — expected format "1.20" or "1.20.2"`);
29
+ }
30
+ const [majorStr, minorStr, patchStr = '0'] = parts;
31
+ const major = parseInt(majorStr, 10);
32
+ const minor = parseInt(minorStr, 10);
33
+ const patch = parseInt(patchStr, 10);
34
+ if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
35
+ throw new Error(`Invalid MC version: "${s}" — non-numeric component`);
36
+ }
37
+ if (major !== 1) {
38
+ throw new Error(`Invalid MC version: "${s}" — only Minecraft 1.x is supported`);
39
+ }
40
+ return minor * 1000 + patch;
41
+ }
42
+ /**
43
+ * Compare two McVersion values. Returns negative if a < b, 0 if equal, positive if a > b.
44
+ */
45
+ function compareMcVersion(a, b) {
46
+ return a - b;
47
+ }
48
+ exports.DEFAULT_MC_VERSION = McVersion.v1_21;
49
+ //# sourceMappingURL=mc-version.js.map