redscript-mc 2.6.2 → 3.0.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 (636) hide show
  1. package/.github/workflows/ci.yml +11 -0
  2. package/CHANGELOG.md +18 -9
  3. package/README-benchmarks.md +48 -0
  4. package/README-vscode-test.md +251 -0
  5. package/RELEASE_NOTES.md +74 -0
  6. package/ROADMAP.md +131 -167
  7. package/benchmarks/_shared.ts +468 -0
  8. package/benchmarks/baseline.json +2816 -0
  9. package/benchmarks/baseline.md +13 -0
  10. package/benchmarks/compiler-perf.report.json +207 -0
  11. package/benchmarks/compiler-perf.ts +76 -0
  12. package/benchmarks/results.md +13 -0
  13. package/benchmarks/stdlib-complexity.report.json +2606 -0
  14. package/benchmarks/stdlib-complexity.ts +54 -0
  15. package/benchmarks/stdlib-size.md +57 -0
  16. package/benchmarks/stdlib-size.ts +91 -0
  17. package/coverage-report.md +177 -0
  18. package/dist/src/__tests__/budget.test.js +4 -0
  19. package/dist/src/__tests__/cache/cache-behavior.test.d.ts +10 -0
  20. package/dist/src/__tests__/cache/cache-behavior.test.js +425 -0
  21. package/dist/src/__tests__/cache-extra.test.d.ts +5 -0
  22. package/dist/src/__tests__/cache-extra.test.js +211 -0
  23. package/dist/src/__tests__/cli-init.test.d.ts +1 -0
  24. package/dist/src/__tests__/cli-init.test.js +97 -0
  25. package/dist/src/__tests__/cli-publish.test.d.ts +9 -0
  26. package/dist/src/__tests__/cli-publish.test.js +189 -0
  27. package/dist/src/__tests__/cli.test.js +76 -0
  28. package/dist/src/__tests__/compile-preprocess.test.d.ts +11 -0
  29. package/dist/src/__tests__/compile-preprocess.test.js +328 -0
  30. package/dist/src/__tests__/compiler/break-stmt.test.d.ts +1 -0
  31. package/dist/src/__tests__/compiler/break-stmt.test.js +58 -0
  32. package/dist/src/__tests__/compiler/const-decl.test.d.ts +1 -0
  33. package/dist/src/__tests__/compiler/const-decl.test.js +123 -0
  34. package/dist/src/__tests__/compiler/continue-stmt.test.d.ts +1 -0
  35. package/dist/src/__tests__/compiler/continue-stmt.test.js +67 -0
  36. package/dist/src/__tests__/compiler/coroutine-extended.test.d.ts +17 -0
  37. package/dist/src/__tests__/compiler/coroutine-extended.test.js +565 -0
  38. package/dist/src/__tests__/compiler/deprecated.test.d.ts +4 -0
  39. package/dist/src/__tests__/compiler/deprecated.test.js +285 -0
  40. package/dist/src/__tests__/compiler/do-while.test.d.ts +1 -0
  41. package/dist/src/__tests__/compiler/do-while.test.js +120 -0
  42. package/dist/src/__tests__/compiler/enum-payload.test.d.ts +9 -0
  43. package/dist/src/__tests__/compiler/enum-payload.test.js +272 -0
  44. package/dist/src/__tests__/compiler/interface.test.d.ts +10 -0
  45. package/dist/src/__tests__/compiler/interface.test.js +258 -0
  46. package/dist/src/__tests__/compiler/labeled-loops.test.d.ts +1 -0
  47. package/dist/src/__tests__/compiler/labeled-loops.test.js +263 -0
  48. package/dist/src/__tests__/compiler/match-string.test.d.ts +1 -0
  49. package/dist/src/__tests__/compiler/match-string.test.js +43 -0
  50. package/dist/src/__tests__/compiler/memoize.test.d.ts +1 -0
  51. package/dist/src/__tests__/compiler/memoize.test.js +113 -0
  52. package/dist/src/__tests__/compiler/method-chain.test.d.ts +5 -0
  53. package/dist/src/__tests__/compiler/method-chain.test.js +115 -0
  54. package/dist/src/__tests__/compiler/module-import.test.d.ts +12 -0
  55. package/dist/src/__tests__/compiler/module-import.test.js +261 -0
  56. package/dist/src/__tests__/compiler/option-extensions.test.d.ts +6 -0
  57. package/dist/src/__tests__/compiler/option-extensions.test.js +191 -0
  58. package/dist/src/__tests__/compiler/profile-decorator.test.d.ts +1 -0
  59. package/dist/src/__tests__/compiler/profile-decorator.test.js +69 -0
  60. package/dist/src/__tests__/compiler/string-advanced.test.d.ts +7 -0
  61. package/dist/src/__tests__/compiler/string-advanced.test.js +281 -0
  62. package/dist/src/__tests__/compiler/struct-extends.test.d.ts +1 -0
  63. package/dist/src/__tests__/compiler/struct-extends.test.js +95 -0
  64. package/dist/src/__tests__/compiler/throttle-retry.test.d.ts +1 -0
  65. package/dist/src/__tests__/compiler/throttle-retry.test.js +166 -0
  66. package/dist/src/__tests__/compiler/tuple-type.test.d.ts +10 -0
  67. package/dist/src/__tests__/compiler/tuple-type.test.js +229 -0
  68. package/dist/src/__tests__/compiler/watch-decorator.test.d.ts +1 -0
  69. package/dist/src/__tests__/compiler/watch-decorator.test.js +65 -0
  70. package/dist/src/__tests__/config/project-config.test.d.ts +1 -0
  71. package/dist/src/__tests__/config/project-config.test.js +199 -0
  72. package/dist/src/__tests__/config-decorator.test.d.ts +8 -0
  73. package/dist/src/__tests__/config-decorator.test.js +142 -0
  74. package/dist/src/__tests__/diagnostics-extra.test.d.ts +6 -0
  75. package/dist/src/__tests__/diagnostics-extra.test.js +132 -0
  76. package/dist/src/__tests__/emit/compile-branches.test.d.ts +1 -0
  77. package/dist/src/__tests__/emit/compile-branches.test.js +123 -0
  78. package/dist/src/__tests__/emit/compile-coverage.test.d.ts +25 -0
  79. package/dist/src/__tests__/emit/compile-coverage.test.js +617 -0
  80. package/dist/src/__tests__/emit/compile-extra-branches.test.d.ts +12 -0
  81. package/dist/src/__tests__/emit/compile-extra-branches.test.js +225 -0
  82. package/dist/src/__tests__/emit/compile-mocked-branches.test.d.ts +0 -0
  83. package/dist/src/__tests__/emit/compile-mocked-branches.test.js +238 -0
  84. package/dist/src/__tests__/emit/execute-chain.test.d.ts +10 -0
  85. package/dist/src/__tests__/emit/execute-chain.test.js +94 -0
  86. package/dist/src/__tests__/emit/index.test.js +2 -1
  87. package/dist/src/__tests__/emit/modules-branches.test.d.ts +1 -0
  88. package/dist/src/__tests__/emit/modules-branches.test.js +88 -0
  89. package/dist/src/__tests__/emit/modules-coverage.test.d.ts +15 -0
  90. package/dist/src/__tests__/emit/modules-coverage.test.js +221 -0
  91. package/dist/src/__tests__/emit/modules-errors.test.d.ts +12 -0
  92. package/dist/src/__tests__/emit/modules-errors.test.js +169 -0
  93. package/dist/src/__tests__/emit/modules-rewrite.test.d.ts +17 -0
  94. package/dist/src/__tests__/emit/modules-rewrite.test.js +204 -0
  95. package/dist/src/__tests__/emit/source-map.test.d.ts +1 -0
  96. package/dist/src/__tests__/emit/source-map.test.js +167 -0
  97. package/dist/src/__tests__/enum.test.js +9 -4
  98. package/dist/src/__tests__/error-recovery.test.d.ts +7 -0
  99. package/dist/src/__tests__/error-recovery.test.js +217 -0
  100. package/dist/src/__tests__/events-types-extra.test.d.ts +10 -0
  101. package/dist/src/__tests__/events-types-extra.test.js +91 -0
  102. package/dist/src/__tests__/events-types.test.d.ts +4 -0
  103. package/dist/src/__tests__/events-types.test.js +56 -0
  104. package/dist/src/__tests__/formatter.test.js +13 -5
  105. package/dist/src/__tests__/hir/lower-extra.test.d.ts +9 -0
  106. package/dist/src/__tests__/hir/lower-extra.test.js +140 -0
  107. package/dist/src/__tests__/hir/monomorphize-extra.test.d.ts +15 -0
  108. package/dist/src/__tests__/hir/monomorphize-extra.test.js +200 -0
  109. package/dist/src/__tests__/hir/monomorphize-extra2.test.d.ts +16 -0
  110. package/dist/src/__tests__/hir/monomorphize-extra2.test.js +316 -0
  111. package/dist/src/__tests__/incremental.test.js +10 -2
  112. package/dist/src/__tests__/index-extra.test.d.ts +10 -0
  113. package/dist/src/__tests__/index-extra.test.js +71 -0
  114. package/dist/src/__tests__/lexer.test.js +2 -2
  115. package/dist/src/__tests__/lint/rules.test.d.ts +5 -0
  116. package/dist/src/__tests__/lint/rules.test.js +208 -0
  117. package/dist/src/__tests__/lir/lower.test.js +29 -0
  118. package/dist/src/__tests__/lir/verify.test.js +30 -0
  119. package/dist/src/__tests__/lsp/completion.test.d.ts +7 -0
  120. package/dist/src/__tests__/lsp/completion.test.js +583 -0
  121. package/dist/src/__tests__/lsp/definition.test.d.ts +7 -0
  122. package/dist/src/__tests__/lsp/definition.test.js +454 -0
  123. package/dist/src/__tests__/lsp/diagnostics.test.d.ts +10 -0
  124. package/dist/src/__tests__/lsp/diagnostics.test.js +98 -0
  125. package/dist/src/__tests__/lsp/hover-docs.test.d.ts +10 -0
  126. package/dist/src/__tests__/lsp/hover-docs.test.js +210 -0
  127. package/dist/src/__tests__/lsp.test.js +4 -1
  128. package/dist/src/__tests__/mc-integration/item-entity-events.test.js +4 -0
  129. package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +4 -0
  130. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.d.ts +13 -0
  131. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1227 -0
  132. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.d.ts +13 -0
  133. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1509 -0
  134. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.d.ts +14 -0
  135. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1374 -0
  136. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.d.ts +10 -0
  137. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +759 -0
  138. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.d.ts +13 -0
  139. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +855 -0
  140. package/dist/src/__tests__/mc-integration/stdlib-coverage.test.js +4 -0
  141. package/dist/src/__tests__/mc-integration/syntax-coverage.test.js +4 -0
  142. package/dist/src/__tests__/mc-validator-coverage.test.d.ts +13 -0
  143. package/dist/src/__tests__/mc-validator-coverage.test.js +296 -0
  144. package/dist/src/__tests__/mc-validator-extra.test.d.ts +13 -0
  145. package/dist/src/__tests__/mc-validator-extra.test.js +245 -0
  146. package/dist/src/__tests__/mir/lower-extra.test.d.ts +20 -0
  147. package/dist/src/__tests__/mir/lower-extra.test.js +361 -0
  148. package/dist/src/__tests__/mir/lower-extra2.test.d.ts +17 -0
  149. package/dist/src/__tests__/mir/lower-extra2.test.js +317 -0
  150. package/dist/src/__tests__/mir/lower-extra3.test.d.ts +19 -0
  151. package/dist/src/__tests__/mir/lower-extra3.test.js +249 -0
  152. package/dist/src/__tests__/mir/lower-extra4.test.d.ts +23 -0
  153. package/dist/src/__tests__/mir/lower-extra4.test.js +606 -0
  154. package/dist/src/__tests__/mir/lower-extra5.test.d.ts +25 -0
  155. package/dist/src/__tests__/mir/lower-extra5.test.js +543 -0
  156. package/dist/src/__tests__/mir/lower-extra6.test.d.ts +16 -0
  157. package/dist/src/__tests__/mir/lower-extra6.test.js +471 -0
  158. package/dist/src/__tests__/mir/lower-extra7.test.d.ts +35 -0
  159. package/dist/src/__tests__/mir/lower-extra7.test.js +921 -0
  160. package/dist/src/__tests__/mir/lower-extra8.test.d.ts +19 -0
  161. package/dist/src/__tests__/mir/lower-extra8.test.js +626 -0
  162. package/dist/src/__tests__/mir/lower-extra9.test.d.ts +14 -0
  163. package/dist/src/__tests__/mir/lower-extra9.test.js +717 -0
  164. package/dist/src/__tests__/optimizer/auto-inline.test.d.ts +1 -0
  165. package/dist/src/__tests__/optimizer/auto-inline.test.js +176 -0
  166. package/dist/src/__tests__/optimizer/cse.test.d.ts +4 -0
  167. package/dist/src/__tests__/optimizer/cse.test.js +178 -0
  168. package/dist/src/__tests__/optimizer/inline_fn.test.d.ts +1 -0
  169. package/dist/src/__tests__/optimizer/inline_fn.test.js +221 -0
  170. package/dist/src/__tests__/optimizer/licm.test.d.ts +1 -0
  171. package/dist/src/__tests__/optimizer/licm.test.js +244 -0
  172. package/dist/src/__tests__/optimizer/optimizer-extended.test.d.ts +12 -0
  173. package/dist/src/__tests__/optimizer/optimizer-extended.test.js +993 -0
  174. package/dist/src/__tests__/optimizer/strength-reduction.test.d.ts +1 -0
  175. package/dist/src/__tests__/optimizer/strength-reduction.test.js +86 -0
  176. package/dist/src/__tests__/optimizer/tco.test.d.ts +14 -0
  177. package/dist/src/__tests__/optimizer/tco.test.js +203 -0
  178. package/dist/src/__tests__/parser-coverage.test.d.ts +25 -0
  179. package/dist/src/__tests__/parser-coverage.test.js +491 -0
  180. package/dist/src/__tests__/parser-extra.test.d.ts +6 -0
  181. package/dist/src/__tests__/parser-extra.test.js +451 -0
  182. package/dist/src/__tests__/parser.test.js +12 -0
  183. package/dist/src/__tests__/repl-extra.test.d.ts +13 -0
  184. package/dist/src/__tests__/repl-extra.test.js +174 -0
  185. package/dist/src/__tests__/repl-server-extra.test.d.ts +10 -0
  186. package/dist/src/__tests__/repl-server-extra.test.js +161 -0
  187. package/dist/src/__tests__/repl-server.test.d.ts +6 -0
  188. package/dist/src/__tests__/repl-server.test.js +146 -0
  189. package/dist/src/__tests__/runtime-extra.test.d.ts +15 -0
  190. package/dist/src/__tests__/runtime-extra.test.js +732 -0
  191. package/dist/src/__tests__/singleton-decorator.test.d.ts +11 -0
  192. package/dist/src/__tests__/singleton-decorator.test.js +260 -0
  193. package/dist/src/__tests__/sourcemap.test.js +1 -1
  194. package/dist/src/__tests__/stdlib/advanced.test.d.ts +5 -0
  195. package/dist/src/__tests__/stdlib/advanced.test.js +301 -0
  196. package/dist/src/__tests__/stdlib/bigint.test.d.ts +4 -0
  197. package/dist/src/__tests__/stdlib/bigint.test.js +83 -0
  198. package/dist/src/__tests__/stdlib/bits.test.d.ts +4 -0
  199. package/dist/src/__tests__/stdlib/bits.test.js +96 -0
  200. package/dist/src/__tests__/stdlib/bossbar.test.d.ts +4 -0
  201. package/dist/src/__tests__/stdlib/bossbar.test.js +72 -0
  202. package/dist/src/__tests__/stdlib/color.test.d.ts +4 -0
  203. package/dist/src/__tests__/stdlib/color.test.js +84 -0
  204. package/dist/src/__tests__/stdlib/combat.test.d.ts +4 -0
  205. package/dist/src/__tests__/stdlib/combat.test.js +64 -0
  206. package/dist/src/__tests__/stdlib/cooldown.test.d.ts +4 -0
  207. package/dist/src/__tests__/stdlib/cooldown.test.js +64 -0
  208. package/dist/src/__tests__/stdlib/dialog.test.js +15 -7
  209. package/dist/src/__tests__/stdlib/ecs.test.d.ts +4 -0
  210. package/dist/src/__tests__/stdlib/ecs.test.js +81 -0
  211. package/dist/src/__tests__/stdlib/effects.test.d.ts +4 -0
  212. package/dist/src/__tests__/stdlib/effects.test.js +72 -0
  213. package/dist/src/__tests__/stdlib/events.test.d.ts +4 -0
  214. package/dist/src/__tests__/stdlib/events.test.js +55 -0
  215. package/dist/src/__tests__/stdlib/expr.test.d.ts +4 -0
  216. package/dist/src/__tests__/stdlib/expr.test.js +77 -0
  217. package/dist/src/__tests__/stdlib/fft.test.d.ts +4 -0
  218. package/dist/src/__tests__/stdlib/fft.test.js +82 -0
  219. package/dist/src/__tests__/stdlib/graph.test.d.ts +4 -0
  220. package/dist/src/__tests__/stdlib/graph.test.js +102 -0
  221. package/dist/src/__tests__/stdlib/interactions.test.d.ts +4 -0
  222. package/dist/src/__tests__/stdlib/interactions.test.js +60 -0
  223. package/dist/src/__tests__/stdlib/inventory.test.d.ts +4 -0
  224. package/dist/src/__tests__/stdlib/inventory.test.js +68 -0
  225. package/dist/src/__tests__/stdlib/linalg.test.d.ts +5 -0
  226. package/dist/src/__tests__/stdlib/linalg.test.js +78 -0
  227. package/dist/src/__tests__/stdlib/map.test.d.ts +1 -0
  228. package/dist/src/__tests__/stdlib/map.test.js +84 -0
  229. package/dist/src/__tests__/stdlib/math.test.js +19 -6
  230. package/dist/src/__tests__/stdlib/math_hp.test.d.ts +4 -0
  231. package/dist/src/__tests__/stdlib/math_hp.test.js +80 -0
  232. package/dist/src/__tests__/stdlib/mobs.test.d.ts +4 -0
  233. package/dist/src/__tests__/stdlib/mobs.test.js +61 -0
  234. package/dist/src/__tests__/stdlib/noise.test.d.ts +4 -0
  235. package/dist/src/__tests__/stdlib/noise.test.js +73 -0
  236. package/dist/src/__tests__/stdlib/ode.test.d.ts +4 -0
  237. package/dist/src/__tests__/stdlib/ode.test.js +68 -0
  238. package/dist/src/__tests__/stdlib/parabola.test.d.ts +4 -0
  239. package/dist/src/__tests__/stdlib/parabola.test.js +77 -0
  240. package/dist/src/__tests__/stdlib/particles.test.d.ts +4 -0
  241. package/dist/src/__tests__/stdlib/particles.test.js +68 -0
  242. package/dist/src/__tests__/stdlib/physics.test.d.ts +4 -0
  243. package/dist/src/__tests__/stdlib/physics.test.js +76 -0
  244. package/dist/src/__tests__/stdlib/player.test.d.ts +4 -0
  245. package/dist/src/__tests__/stdlib/player.test.js +64 -0
  246. package/dist/src/__tests__/stdlib/quaternion.test.d.ts +4 -0
  247. package/dist/src/__tests__/stdlib/quaternion.test.js +73 -0
  248. package/dist/src/__tests__/stdlib/queue.test.d.ts +1 -0
  249. package/dist/src/__tests__/stdlib/queue.test.js +97 -0
  250. package/dist/src/__tests__/stdlib/random.test.d.ts +4 -0
  251. package/dist/src/__tests__/stdlib/random.test.js +76 -0
  252. package/dist/src/__tests__/stdlib/result.test.d.ts +12 -0
  253. package/dist/src/__tests__/stdlib/result.test.js +329 -0
  254. package/dist/src/__tests__/stdlib/scheduler.test.js +19 -8
  255. package/dist/src/__tests__/stdlib/set_int.test.d.ts +1 -0
  256. package/dist/src/__tests__/stdlib/set_int.test.js +88 -0
  257. package/dist/src/__tests__/stdlib/sets.test.d.ts +6 -0
  258. package/dist/src/__tests__/stdlib/sets.test.js +60 -0
  259. package/dist/src/__tests__/stdlib/signal.test.d.ts +4 -0
  260. package/dist/src/__tests__/stdlib/signal.test.js +84 -0
  261. package/dist/src/__tests__/stdlib/spawn.test.d.ts +4 -0
  262. package/dist/src/__tests__/stdlib/spawn.test.js +68 -0
  263. package/dist/src/__tests__/stdlib/string.test.d.ts +12 -0
  264. package/dist/src/__tests__/stdlib/string.test.js +231 -0
  265. package/dist/src/__tests__/stdlib/strings.test.d.ts +4 -0
  266. package/dist/src/__tests__/stdlib/strings.test.js +83 -0
  267. package/dist/src/__tests__/stdlib/tags.test.d.ts +4 -0
  268. package/dist/src/__tests__/stdlib/tags.test.js +57 -0
  269. package/dist/src/__tests__/stdlib/teams.test.d.ts +4 -0
  270. package/dist/src/__tests__/stdlib/teams.test.js +72 -0
  271. package/dist/src/__tests__/stdlib/timer.test.d.ts +4 -0
  272. package/dist/src/__tests__/stdlib/timer.test.js +79 -0
  273. package/dist/src/__tests__/stdlib/vec.test.d.ts +5 -0
  274. package/dist/src/__tests__/stdlib/vec.test.js +94 -0
  275. package/dist/src/__tests__/stdlib/world.test.d.ts +4 -0
  276. package/dist/src/__tests__/stdlib/world.test.js +72 -0
  277. package/dist/src/__tests__/struct-display.test.d.ts +1 -0
  278. package/dist/src/__tests__/struct-display.test.js +64 -0
  279. package/dist/src/__tests__/test-framework/runner.test.d.ts +10 -0
  280. package/dist/src/__tests__/test-framework/runner.test.js +193 -0
  281. package/dist/src/__tests__/tuner/adapters.test.d.ts +14 -0
  282. package/dist/src/__tests__/tuner/adapters.test.js +194 -0
  283. package/dist/src/__tests__/tuner/simulator-extra.test.d.ts +4 -0
  284. package/dist/src/__tests__/tuner/simulator-extra.test.js +193 -0
  285. package/dist/src/__tests__/typechecker-coverage.test.d.ts +30 -0
  286. package/dist/src/__tests__/typechecker-coverage.test.js +627 -0
  287. package/dist/src/__tests__/typechecker.test.js +3 -3
  288. package/dist/src/__tests__/watch-decorator.test.d.ts +1 -0
  289. package/dist/src/__tests__/watch-decorator.test.js +54 -0
  290. package/dist/src/ast/types.d.ts +102 -3
  291. package/dist/src/cache/incremental.d.ts +13 -14
  292. package/dist/src/cache/incremental.js +106 -89
  293. package/dist/src/cache/index.d.ts +8 -2
  294. package/dist/src/cache/index.js +18 -6
  295. package/dist/src/cli.d.ts +1 -0
  296. package/dist/src/cli.js +466 -17
  297. package/dist/src/config/project-config.d.ts +29 -0
  298. package/dist/src/config/project-config.js +180 -0
  299. package/dist/src/diagnostics/index.d.ts +9 -0
  300. package/dist/src/diagnostics/index.js +18 -1
  301. package/dist/src/emit/compile.d.ts +10 -0
  302. package/dist/src/emit/compile.js +395 -50
  303. package/dist/src/emit/index.d.ts +40 -0
  304. package/dist/src/emit/index.js +307 -14
  305. package/dist/src/emit/modules.js +21 -3
  306. package/dist/src/emit/sourcemap.d.ts +23 -27
  307. package/dist/src/emit/sourcemap.js +52 -30
  308. package/dist/src/formatter/index.js +33 -8
  309. package/dist/src/hir/deprecated.d.ts +13 -0
  310. package/dist/src/hir/deprecated.js +218 -0
  311. package/dist/src/hir/lower.js +114 -8
  312. package/dist/src/hir/monomorphize.js +22 -2
  313. package/dist/src/hir/types.d.ts +65 -1
  314. package/dist/src/index.d.ts +6 -0
  315. package/dist/src/index.js +18 -3
  316. package/dist/src/lexer/index.d.ts +2 -1
  317. package/dist/src/lexer/index.js +39 -3
  318. package/dist/src/lint/index.d.ts +45 -0
  319. package/dist/src/lint/index.js +930 -0
  320. package/dist/src/lir/lower.js +29 -2
  321. package/dist/src/lir/types.d.ts +2 -0
  322. package/dist/src/lsp/server.js +92 -5
  323. package/dist/src/mir/lower.js +775 -34
  324. package/dist/src/mir/macro.js +36 -2
  325. package/dist/src/mir/types.d.ts +12 -0
  326. package/dist/src/mir/verify.js +9 -0
  327. package/dist/src/optimizer/auto-inline.d.ts +2 -0
  328. package/dist/src/optimizer/auto-inline.js +67 -0
  329. package/dist/src/optimizer/cse.d.ts +20 -0
  330. package/dist/src/optimizer/cse.js +234 -0
  331. package/dist/src/optimizer/inline.d.ts +26 -0
  332. package/dist/src/optimizer/inline.js +286 -0
  333. package/dist/src/optimizer/interprocedural.js +4 -0
  334. package/dist/src/optimizer/licm.d.ts +32 -0
  335. package/dist/src/optimizer/licm.js +371 -0
  336. package/dist/src/optimizer/pipeline.js +12 -2
  337. package/dist/src/optimizer/strength_reduction.d.ts +15 -0
  338. package/dist/src/optimizer/strength_reduction.js +90 -0
  339. package/dist/src/optimizer/tco.d.ts +53 -0
  340. package/dist/src/optimizer/tco.js +238 -0
  341. package/dist/src/parser/index.d.ts +32 -0
  342. package/dist/src/parser/index.js +421 -59
  343. package/dist/src/repl-server.d.ts +13 -0
  344. package/dist/src/repl-server.js +127 -0
  345. package/dist/src/structs/expand.d.ts +15 -0
  346. package/dist/src/structs/expand.js +46 -0
  347. package/dist/src/testing/runner.d.ts +40 -0
  348. package/dist/src/testing/runner.js +237 -0
  349. package/dist/src/typechecker/index.d.ts +3 -0
  350. package/dist/src/typechecker/index.js +254 -9
  351. package/dist/tsconfig.tsbuildinfo +1 -1
  352. package/doc-drafts/redscript-docs/docs/en/stdlib/graph.md +104 -0
  353. package/doc-drafts/redscript-docs/docs/en/stdlib/parabola.md +113 -0
  354. package/doc-drafts/redscript-docs/docs/en/stdlib/pathfind.md +104 -0
  355. package/doc-drafts/redscript-docs/docs/en/stdlib/physics.md +134 -0
  356. package/doc-drafts/redscript-docs/docs/en/stdlib/quaternion.md +135 -0
  357. package/doc-drafts/redscript-docs/docs/zh/stdlib/graph.md +104 -0
  358. package/doc-drafts/redscript-docs/docs/zh/stdlib/parabola.md +113 -0
  359. package/doc-drafts/redscript-docs/docs/zh/stdlib/pathfind.md +104 -0
  360. package/doc-drafts/redscript-docs/docs/zh/stdlib/physics.md +134 -0
  361. package/doc-drafts/redscript-docs/docs/zh/stdlib/quaternion.md +135 -0
  362. package/docs/stdlib/result.md +156 -0
  363. package/docs/stdlib/result.zh.md +156 -0
  364. package/editors/vscode/fixtures/test.mcrs +7 -0
  365. package/editors/vscode/out/extension.js +2095 -225
  366. package/editors/vscode/out/lsp-server.js +519 -51
  367. package/editors/vscode/package-lock.json +9 -4
  368. package/editors/vscode/package.json +1 -1
  369. package/examples/display-demo.mcrs +64 -0
  370. package/examples/game/racing.mcrs +301 -0
  371. package/examples/game/tower_defense.mcrs +311 -0
  372. package/examples/math/physics_sim.mcrs +322 -0
  373. package/examples/rpg/boss_fight.mcrs +313 -0
  374. package/examples/rpg/health_system.mcrs +237 -0
  375. package/examples/rpg/inventory.mcrs +265 -0
  376. package/examples/util/debug_hud.mcrs +279 -0
  377. package/jest.config.js +10 -0
  378. package/package.json +12 -3
  379. package/playground/index.html +823 -0
  380. package/scripts/gen-docs.ts +533 -0
  381. package/scripts/update-redscript-docs-stdlib.sh +770 -0
  382. package/src/__tests__/budget.test.ts +5 -0
  383. package/src/__tests__/cache/cache-behavior.test.ts +480 -0
  384. package/src/__tests__/cache-extra.test.ts +199 -0
  385. package/src/__tests__/cli-docs.test.ts +77 -0
  386. package/src/__tests__/cli-init.test.ts +91 -0
  387. package/src/__tests__/cli-publish.test.ts +190 -0
  388. package/src/__tests__/cli.test.ts +117 -1
  389. package/src/__tests__/compile-preprocess.test.ts +366 -0
  390. package/src/__tests__/compiler/break-stmt.test.ts +66 -0
  391. package/src/__tests__/compiler/const-decl.test.ts +141 -0
  392. package/src/__tests__/compiler/continue-stmt.test.ts +81 -0
  393. package/src/__tests__/compiler/coroutine-extended.test.ts +723 -0
  394. package/src/__tests__/compiler/deprecated.test.ts +305 -0
  395. package/src/__tests__/compiler/do-while.test.ts +130 -0
  396. package/src/__tests__/compiler/enum-payload.test.ts +299 -0
  397. package/src/__tests__/compiler/interface.test.ts +287 -0
  398. package/src/__tests__/compiler/labeled-loops.test.ts +279 -0
  399. package/src/__tests__/compiler/match-string.test.ts +45 -0
  400. package/src/__tests__/compiler/memoize.test.ts +126 -0
  401. package/src/__tests__/compiler/method-chain.test.ts +121 -0
  402. package/src/__tests__/compiler/module-import.test.ts +240 -0
  403. package/src/__tests__/compiler/option-extensions.test.ts +207 -0
  404. package/src/__tests__/compiler/profile-decorator.test.ts +79 -0
  405. package/src/__tests__/compiler/string-advanced.test.ts +310 -0
  406. package/src/__tests__/compiler/struct-extends.test.ts +109 -0
  407. package/src/__tests__/compiler/throttle-retry.test.ts +191 -0
  408. package/src/__tests__/compiler/tuple-type.test.ts +263 -0
  409. package/src/__tests__/compiler/watch-decorator.test.ts +72 -0
  410. package/src/__tests__/config/project-config.test.ts +181 -0
  411. package/src/__tests__/config-decorator.test.ts +157 -0
  412. package/src/__tests__/diagnostics-extra.test.ts +155 -0
  413. package/src/__tests__/emit/compile-branches.test.ts +135 -0
  414. package/src/__tests__/emit/compile-coverage.test.ts +696 -0
  415. package/src/__tests__/emit/compile-extra-branches.test.ts +228 -0
  416. package/src/__tests__/emit/compile-mocked-branches.test.ts +249 -0
  417. package/src/__tests__/emit/compile.test.ts +6 -1
  418. package/src/__tests__/emit/execute-chain.test.ts +114 -0
  419. package/src/__tests__/emit/index.test.ts +2 -1
  420. package/src/__tests__/emit/modules-branches.test.ts +90 -0
  421. package/src/__tests__/emit/modules-coverage.test.ts +241 -0
  422. package/src/__tests__/emit/modules-errors.test.ts +192 -0
  423. package/src/__tests__/emit/modules-rewrite.test.ts +232 -0
  424. package/src/__tests__/emit/source-map.test.ts +152 -0
  425. package/src/__tests__/enum.test.ts +9 -4
  426. package/src/__tests__/error-recovery.test.ts +226 -0
  427. package/src/__tests__/events-types-extra.test.ts +110 -0
  428. package/src/__tests__/events-types.test.ts +66 -0
  429. package/src/__tests__/formatter.test.ts +15 -5
  430. package/src/__tests__/generics.test.ts +16 -9
  431. package/src/__tests__/hir/lower-extra.test.ts +151 -0
  432. package/src/__tests__/hir/monomorphize-coverage.test.ts +432 -0
  433. package/src/__tests__/hir/monomorphize-extra.test.ts +220 -0
  434. package/src/__tests__/hir/monomorphize-extra2.test.ts +350 -0
  435. package/src/__tests__/impl.test.ts +12 -8
  436. package/src/__tests__/incremental.test.ts +10 -2
  437. package/src/__tests__/index-extra.test.ts +79 -0
  438. package/src/__tests__/lexer.test.ts +2 -2
  439. package/src/__tests__/lint/hir-coverage.test.ts +1716 -0
  440. package/src/__tests__/lint/rules-coverage.test.ts +598 -0
  441. package/src/__tests__/lint/rules.test.ts +230 -0
  442. package/src/__tests__/lir/lower.test.ts +33 -0
  443. package/src/__tests__/lir/verify.test.ts +33 -0
  444. package/src/__tests__/lsp/completion.test.ts +687 -0
  445. package/src/__tests__/lsp/definition.test.ts +499 -0
  446. package/src/__tests__/lsp/diagnostics.test.ts +108 -0
  447. package/src/__tests__/lsp/hover-docs.test.ts +222 -0
  448. package/src/__tests__/lsp.test.ts +4 -1
  449. package/src/__tests__/mc-integration/item-entity-events.test.ts +5 -0
  450. package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +5 -0
  451. package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1105 -0
  452. package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1366 -0
  453. package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1245 -0
  454. package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +755 -0
  455. package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +771 -0
  456. package/src/__tests__/mc-integration/stdlib-coverage.test.ts +5 -0
  457. package/src/__tests__/mc-integration/syntax-coverage.test.ts +5 -0
  458. package/src/__tests__/mc-validator-coverage.test.ts +325 -0
  459. package/src/__tests__/mc-validator-extra.test.ts +252 -0
  460. package/src/__tests__/mir/lower-extra.test.ts +402 -0
  461. package/src/__tests__/mir/lower-extra2.test.ts +348 -0
  462. package/src/__tests__/mir/lower-extra3.test.ts +277 -0
  463. package/src/__tests__/mir/lower-extra4.test.ts +636 -0
  464. package/src/__tests__/mir/lower-extra5.test.ts +612 -0
  465. package/src/__tests__/mir/lower-extra6.test.ts +520 -0
  466. package/src/__tests__/mir/lower-extra7.test.ts +1045 -0
  467. package/src/__tests__/mir/lower-extra8.test.ts +704 -0
  468. package/src/__tests__/mir/lower-extra9.test.ts +821 -0
  469. package/src/__tests__/optimizer/auto-inline.test.ts +206 -0
  470. package/src/__tests__/optimizer/cse.test.ts +195 -0
  471. package/src/__tests__/optimizer/inline_fn.test.ts +263 -0
  472. package/src/__tests__/optimizer/licm.test.ts +358 -0
  473. package/src/__tests__/optimizer/nbt-coalesce.test.ts +147 -0
  474. package/src/__tests__/optimizer/optimizer-extended.test.ts +1081 -0
  475. package/src/__tests__/optimizer/scoreboard-batch.test.ts +141 -0
  476. package/src/__tests__/optimizer/strength-reduction.test.ts +111 -0
  477. package/src/__tests__/optimizer/tco-coverage.test.ts +309 -0
  478. package/src/__tests__/optimizer/tco.test.ts +238 -0
  479. package/src/__tests__/option.test.ts +14 -7
  480. package/src/__tests__/parser-coverage.test.ts +576 -0
  481. package/src/__tests__/parser-extra.test.ts +531 -0
  482. package/src/__tests__/parser.test.ts +14 -0
  483. package/src/__tests__/repl-extra.test.ts +195 -0
  484. package/src/__tests__/repl-server-extra.test.ts +150 -0
  485. package/src/__tests__/repl-server.test.ts +122 -0
  486. package/src/__tests__/runtime-extra.test.ts +862 -0
  487. package/src/__tests__/singleton-decorator.test.ts +285 -0
  488. package/src/__tests__/sourcemap.test.ts +1 -1
  489. package/src/__tests__/stdlib/advanced.test.ts +312 -0
  490. package/src/__tests__/stdlib/bigint.test.ts +57 -0
  491. package/src/__tests__/stdlib/bits.test.ts +75 -0
  492. package/src/__tests__/stdlib/bossbar.test.ts +45 -0
  493. package/src/__tests__/stdlib/color.test.ts +60 -0
  494. package/src/__tests__/stdlib/combat.test.ts +35 -0
  495. package/src/__tests__/stdlib/cooldown.test.ts +35 -0
  496. package/src/__tests__/stdlib/dialog.test.ts +14 -6
  497. package/src/__tests__/stdlib/ecs.test.ts +54 -0
  498. package/src/__tests__/stdlib/effects.test.ts +45 -0
  499. package/src/__tests__/stdlib/events.test.ts +23 -0
  500. package/src/__tests__/stdlib/expr.test.ts +48 -0
  501. package/src/__tests__/stdlib/fft.test.ts +54 -0
  502. package/src/__tests__/stdlib/graph.test.ts +77 -0
  503. package/src/__tests__/stdlib/interactions.test.ts +30 -0
  504. package/src/__tests__/stdlib/inventory.test.ts +40 -0
  505. package/src/__tests__/stdlib/linalg.test.ts +52 -0
  506. package/src/__tests__/stdlib/map.test.ts +55 -0
  507. package/src/__tests__/stdlib/math.test.ts +19 -5
  508. package/src/__tests__/stdlib/math_hp.test.ts +55 -0
  509. package/src/__tests__/stdlib/mobs.test.ts +40 -0
  510. package/src/__tests__/stdlib/noise.test.ts +46 -0
  511. package/src/__tests__/stdlib/ode.test.ts +40 -0
  512. package/src/__tests__/stdlib/parabola.test.ts +51 -0
  513. package/src/__tests__/stdlib/particles.test.ts +40 -0
  514. package/src/__tests__/stdlib/physics.test.ts +50 -0
  515. package/src/__tests__/stdlib/player.test.ts +35 -0
  516. package/src/__tests__/stdlib/quaternion.test.ts +46 -0
  517. package/src/__tests__/stdlib/queue.test.ts +73 -0
  518. package/src/__tests__/stdlib/random.test.ts +50 -0
  519. package/src/__tests__/stdlib/result.test.ts +326 -0
  520. package/src/__tests__/stdlib/scheduler.test.ts +18 -7
  521. package/src/__tests__/stdlib/set_int.test.ts +62 -0
  522. package/src/__tests__/stdlib/sets.test.ts +28 -0
  523. package/src/__tests__/stdlib/signal.test.ts +60 -0
  524. package/src/__tests__/stdlib/spawn.test.ts +40 -0
  525. package/src/__tests__/stdlib/string.test.ts +224 -0
  526. package/src/__tests__/stdlib/strings.test.ts +55 -0
  527. package/src/__tests__/stdlib/tags.test.ts +32 -0
  528. package/src/__tests__/stdlib/teams.test.ts +45 -0
  529. package/src/__tests__/stdlib/timer.test.ts +53 -0
  530. package/src/__tests__/stdlib/vec.test.ts +72 -0
  531. package/src/__tests__/stdlib/world.test.ts +45 -0
  532. package/src/__tests__/struct-display.test.ts +69 -0
  533. package/src/__tests__/test-framework/runner.test.ts +208 -0
  534. package/src/__tests__/tuner/adapters.test.ts +232 -0
  535. package/src/__tests__/tuner/simulator-extra.test.ts +222 -0
  536. package/src/__tests__/tuple.test.ts +11 -4
  537. package/src/__tests__/typechecker-coverage.test.ts +671 -0
  538. package/src/__tests__/typechecker.test.ts +4 -3
  539. package/src/__tests__/watch-decorator.test.ts +59 -0
  540. package/src/ast/types.ts +65 -3
  541. package/src/cache/incremental.ts +128 -99
  542. package/src/cache/index.ts +35 -8
  543. package/src/cli.ts +538 -29
  544. package/src/config/project-config.ts +176 -0
  545. package/src/diagnostics/index.ts +22 -0
  546. package/src/docs.ts +98 -0
  547. package/src/emit/compile.ts +408 -51
  548. package/src/emit/index.ts +366 -18
  549. package/src/emit/modules.ts +19 -3
  550. package/src/emit/sourcemap.ts +64 -43
  551. package/src/formatter/index.ts +35 -8
  552. package/src/hir/deprecated.ts +212 -0
  553. package/src/hir/lower.ts +128 -8
  554. package/src/hir/monomorphize.ts +24 -2
  555. package/src/hir/types.ts +26 -1
  556. package/src/index.ts +23 -3
  557. package/src/lexer/index.ts +45 -6
  558. package/src/lint/index.ts +922 -0
  559. package/src/lir/lower.ts +30 -2
  560. package/src/lir/types.ts +4 -0
  561. package/src/lsp/server.ts +100 -1
  562. package/src/mir/lower.ts +785 -40
  563. package/src/mir/macro.ts +30 -2
  564. package/src/mir/types.ts +13 -0
  565. package/src/mir/verify.ts +10 -2
  566. package/src/optimizer/auto-inline.ts +86 -0
  567. package/src/optimizer/copy_prop.ts +2 -2
  568. package/src/optimizer/coroutine.ts +3 -3
  569. package/src/optimizer/cse.ts +205 -0
  570. package/src/optimizer/dce.ts +2 -2
  571. package/src/optimizer/inline.ts +335 -0
  572. package/src/optimizer/interprocedural.ts +5 -1
  573. package/src/optimizer/licm.ts +454 -0
  574. package/src/optimizer/nbt-coalesce.ts +109 -0
  575. package/src/optimizer/pipeline.ts +16 -2
  576. package/src/optimizer/scoreboard-batch.ts +52 -0
  577. package/src/optimizer/strength_reduction.ts +95 -0
  578. package/src/optimizer/tco.ts +267 -0
  579. package/src/optimizer/unroll.ts +2 -2
  580. package/src/parser/index.ts +426 -53
  581. package/src/repl-server.ts +102 -0
  582. package/src/stdlib/advanced.mcrs +271 -101
  583. package/src/stdlib/bigint.mcrs +97 -11
  584. package/src/stdlib/bits.mcrs +75 -12
  585. package/src/stdlib/bossbar.mcrs +37 -8
  586. package/src/stdlib/calculus.mcrs +82 -26
  587. package/src/stdlib/color.mcrs +98 -16
  588. package/src/stdlib/combat.mcrs +23 -5
  589. package/src/stdlib/cooldown.mcrs +19 -0
  590. package/src/stdlib/dialog.mcrs +45 -7
  591. package/src/stdlib/easing.mcrs +132 -12
  592. package/src/stdlib/ecs.mcrs +142 -25
  593. package/src/stdlib/effects.mcrs +88 -12
  594. package/src/stdlib/events.mcrs +21 -2
  595. package/src/stdlib/expr.mcrs +18 -3
  596. package/src/stdlib/fft.mcrs +66 -56
  597. package/src/stdlib/geometry.mcrs +137 -39
  598. package/src/stdlib/graph.mcrs +73 -0
  599. package/src/stdlib/heap.mcrs +49 -8
  600. package/src/stdlib/i18n/zh.yaml +2891 -0
  601. package/src/stdlib/interactions.mcrs +43 -20
  602. package/src/stdlib/inventory.mcrs +14 -3
  603. package/src/stdlib/linalg.mcrs +185 -30
  604. package/src/stdlib/list.mcrs +168 -18
  605. package/src/stdlib/map.mcrs +112 -0
  606. package/src/stdlib/math.mcrs +68 -18
  607. package/src/stdlib/math_hp.mcrs +124 -33
  608. package/src/stdlib/matrix.mcrs +133 -20
  609. package/src/stdlib/mobs.mcrs +87 -0
  610. package/src/stdlib/noise.mcrs +65 -21
  611. package/src/stdlib/ode.mcrs +96 -0
  612. package/src/stdlib/parabola.mcrs +104 -29
  613. package/src/stdlib/particles.mcrs +78 -21
  614. package/src/stdlib/pathfind.mcrs +89 -35
  615. package/src/stdlib/physics.mcrs +134 -26
  616. package/src/stdlib/player.mcrs +18 -0
  617. package/src/stdlib/quaternion.mcrs +213 -9
  618. package/src/stdlib/queue.mcrs +123 -0
  619. package/src/stdlib/random.mcrs +63 -18
  620. package/src/stdlib/result.mcrs +111 -0
  621. package/src/stdlib/scheduler.mcrs +59 -10
  622. package/src/stdlib/set_int.mcrs +240 -0
  623. package/src/stdlib/sets.mcrs +49 -19
  624. package/src/stdlib/signal.mcrs +151 -79
  625. package/src/stdlib/sort.mcrs +44 -24
  626. package/src/stdlib/spawn.mcrs +30 -7
  627. package/src/stdlib/state.mcrs +40 -5
  628. package/src/stdlib/strings.mcrs +131 -3
  629. package/src/stdlib/tags.mcrs +2 -2
  630. package/src/stdlib/teams.mcrs +22 -10
  631. package/src/stdlib/timer.mcrs +36 -6
  632. package/src/stdlib/vec.mcrs +44 -9
  633. package/src/stdlib/world.mcrs +57 -25
  634. package/src/structs/expand.ts +64 -0
  635. package/src/testing/runner.ts +271 -0
  636. package/src/typechecker/index.ts +273 -9
@@ -9207,6 +9207,8 @@ var KEYWORDS = {
9207
9207
  while: "while",
9208
9208
  for: "for",
9209
9209
  foreach: "foreach",
9210
+ do: "do",
9211
+ repeat: "repeat",
9210
9212
  match: "match",
9211
9213
  return: "return",
9212
9214
  break: "break",
@@ -9226,6 +9228,8 @@ var KEYWORDS = {
9226
9228
  unless: "unless",
9227
9229
  declare: "declare",
9228
9230
  export: "export",
9231
+ import: "import",
9232
+ interface: "interface",
9229
9233
  int: "int",
9230
9234
  bool: "bool",
9231
9235
  float: "float",
@@ -9471,7 +9475,13 @@ var Lexer = class {
9471
9475
  return;
9472
9476
  }
9473
9477
  if (char === '"') {
9474
- this.scanString(startLine, startCol);
9478
+ if (this.peek() === '"' && this.peek(1) === '"') {
9479
+ this.advance();
9480
+ this.advance();
9481
+ this.scanMultiLineString(startLine, startCol);
9482
+ } else {
9483
+ this.scanString(startLine, startCol);
9484
+ }
9475
9485
  return;
9476
9486
  }
9477
9487
  if (char === "#") {
@@ -9539,6 +9549,26 @@ var Lexer = class {
9539
9549
  }
9540
9550
  return result;
9541
9551
  }
9552
+ scanMultiLineString(startLine, startCol) {
9553
+ let value = "";
9554
+ while (!this.isAtEnd()) {
9555
+ if (this.peek() === '"' && this.peek(1) === '"' && this.peek(2) === '"') {
9556
+ this.advance();
9557
+ this.advance();
9558
+ this.advance();
9559
+ break;
9560
+ }
9561
+ if (this.peek() === "\\" && this.peek(1) === '"') {
9562
+ this.advance();
9563
+ value += this.advance();
9564
+ continue;
9565
+ }
9566
+ value += this.advance();
9567
+ }
9568
+ if (value.startsWith("\n")) value = value.slice(1);
9569
+ if (value.endsWith("\n")) value = value.slice(0, -1);
9570
+ this.addToken("string_lit", value, startLine, startCol);
9571
+ }
9542
9572
  scanString(startLine, startCol) {
9543
9573
  let value = "";
9544
9574
  let interpolationDepth = 0;
@@ -9782,6 +9812,8 @@ var Parser = class _Parser {
9782
9812
  this.inLibraryMode = false;
9783
9813
  /** Warnings accumulated during parsing (e.g. deprecated keyword usage). */
9784
9814
  this.warnings = [];
9815
+ /** Parse errors collected during error-recovery mode. */
9816
+ this.parseErrors = [];
9785
9817
  this.tokens = tokens;
9786
9818
  this.sourceLines = source?.split("\n") ?? [];
9787
9819
  this.filePath = filePath;
@@ -9852,6 +9884,60 @@ var Parser = class _Parser {
9852
9884
  return { kind: "eof", value: "", line: span.line, col: span.col };
9853
9885
  }
9854
9886
  // -------------------------------------------------------------------------
9887
+ // Error Recovery
9888
+ // -------------------------------------------------------------------------
9889
+ /**
9890
+ * Synchronize to the next top-level declaration boundary after a parse error.
9891
+ * Skips tokens until we find a keyword that starts a top-level declaration,
9892
+ * or a `}` (end of a block), or EOF.
9893
+ */
9894
+ syncToNextDecl() {
9895
+ const TOP_LEVEL_KEYWORDS = /* @__PURE__ */ new Set([
9896
+ "fn",
9897
+ "struct",
9898
+ "impl",
9899
+ "enum",
9900
+ "const",
9901
+ "let",
9902
+ "export",
9903
+ "declare",
9904
+ "import",
9905
+ "namespace",
9906
+ "module"
9907
+ ]);
9908
+ while (!this.check("eof")) {
9909
+ const kind = this.peek().kind;
9910
+ if (kind === "}") {
9911
+ this.advance();
9912
+ return;
9913
+ }
9914
+ if (TOP_LEVEL_KEYWORDS.has(kind)) {
9915
+ return;
9916
+ }
9917
+ if (kind === "ident" && this.peek().value === "import") {
9918
+ return;
9919
+ }
9920
+ this.advance();
9921
+ }
9922
+ }
9923
+ /**
9924
+ * Synchronize to the next statement boundary inside a block after a parse error.
9925
+ * Skips tokens until we reach `;`, `}`, or EOF.
9926
+ */
9927
+ syncToNextStmt() {
9928
+ while (!this.check("eof")) {
9929
+ const kind = this.peek().kind;
9930
+ if (kind === ";") {
9931
+ this.advance();
9932
+ return;
9933
+ }
9934
+ if (kind === "}") {
9935
+ return;
9936
+ }
9937
+ this.advance();
9938
+ }
9939
+ }
9940
+ // -------------------------------------------------------------------------
9855
9941
  // Program
9856
9942
  // -------------------------------------------------------------------------
9857
9943
  parse(defaultNamespace = "redscript") {
@@ -9863,6 +9949,7 @@ var Parser = class _Parser {
9863
9949
  const enums = [];
9864
9950
  const consts = [];
9865
9951
  const imports = [];
9952
+ const interfaces = [];
9866
9953
  let isLibrary = false;
9867
9954
  let moduleName;
9868
9955
  if (this.check("namespace")) {
@@ -9883,40 +9970,74 @@ var Parser = class _Parser {
9883
9970
  this.match(";");
9884
9971
  }
9885
9972
  while (!this.check("eof")) {
9886
- if (this.check("let")) {
9887
- globals.push(this.parseGlobalDecl(true));
9888
- } else if (this.check("struct")) {
9889
- structs.push(this.parseStructDecl());
9890
- } else if (this.check("impl")) {
9891
- implBlocks.push(this.parseImplBlock());
9892
- } else if (this.check("enum")) {
9893
- enums.push(this.parseEnumDecl());
9894
- } else if (this.check("const")) {
9895
- consts.push(this.parseConstDecl());
9896
- } else if (this.check("declare")) {
9897
- this.advance();
9898
- this.parseDeclareStub();
9899
- } else if (this.check("export")) {
9900
- declarations.push(this.parseExportedFnDecl());
9901
- } else if (this.check("ident") && this.peek().value === "import") {
9902
- this.advance();
9903
- const importToken = this.peek();
9904
- const modName = this.expect("ident").value;
9905
- this.expect("::");
9906
- let symbol;
9907
- if (this.check("*")) {
9973
+ try {
9974
+ if (this.check("decorator") && this.peek().value.startsWith("@config")) {
9975
+ const decorToken = this.advance();
9976
+ const decorator = this.parseDecoratorValue(decorToken.value);
9977
+ if (!this.check("let")) {
9978
+ this.error("@config decorator must be followed by a let declaration");
9979
+ }
9980
+ const g = this.parseGlobalDecl(true);
9981
+ g.configKey = decorator.args?.configKey;
9982
+ g.configDefault = decorator.args?.configDefault;
9983
+ globals.push(g);
9984
+ } else if (this.check("let")) {
9985
+ globals.push(this.parseGlobalDecl(true));
9986
+ } else if (this.check("decorator") && this.peek().value === "@singleton") {
9987
+ this.advance();
9988
+ if (!this.check("struct")) {
9989
+ this.error("@singleton decorator must be followed by a struct declaration");
9990
+ }
9991
+ const s = this.parseStructDecl();
9992
+ s.isSingleton = true;
9993
+ structs.push(s);
9994
+ } else if (this.check("struct")) {
9995
+ structs.push(this.parseStructDecl());
9996
+ } else if (this.check("impl")) {
9997
+ implBlocks.push(this.parseImplBlock());
9998
+ } else if (this.check("interface")) {
9999
+ interfaces.push(this.parseInterfaceDecl());
10000
+ } else if (this.check("enum")) {
10001
+ enums.push(this.parseEnumDecl());
10002
+ } else if (this.check("const")) {
10003
+ consts.push(this.parseConstDecl());
10004
+ } else if (this.check("declare")) {
9908
10005
  this.advance();
9909
- symbol = "*";
10006
+ this.parseDeclareStub();
10007
+ } else if (this.check("export")) {
10008
+ declarations.push(this.parseExportedFnDecl());
10009
+ } else if (this.check("import") || this.check("ident") && this.peek().value === "import") {
10010
+ this.advance();
10011
+ const importToken = this.peek();
10012
+ const modName = this.expect("ident").value;
10013
+ if (this.check("::")) {
10014
+ this.advance();
10015
+ let symbol;
10016
+ if (this.check("*")) {
10017
+ this.advance();
10018
+ symbol = "*";
10019
+ } else {
10020
+ symbol = this.expect("ident").value;
10021
+ }
10022
+ this.match(";");
10023
+ imports.push(this.withLoc({ moduleName: modName, symbol }, importToken));
10024
+ } else {
10025
+ this.match(";");
10026
+ imports.push(this.withLoc({ moduleName: modName, symbol: void 0 }, importToken));
10027
+ }
9910
10028
  } else {
9911
- symbol = this.expect("ident").value;
10029
+ declarations.push(this.parseFnDecl());
10030
+ }
10031
+ } catch (err) {
10032
+ if (err instanceof DiagnosticError) {
10033
+ this.parseErrors.push(err);
10034
+ this.syncToNextDecl();
10035
+ } else {
10036
+ throw err;
9912
10037
  }
9913
- this.match(";");
9914
- imports.push(this.withLoc({ moduleName: modName, symbol }, importToken));
9915
- } else {
9916
- declarations.push(this.parseFnDecl());
9917
10038
  }
9918
10039
  }
9919
- return { namespace, moduleName, globals, declarations, structs, implBlocks, enums, consts, imports, isLibrary };
10040
+ return { namespace, moduleName, globals, declarations, structs, implBlocks, enums, consts, imports, interfaces, isLibrary };
9920
10041
  }
9921
10042
  // -------------------------------------------------------------------------
9922
10043
  // Struct Declaration
@@ -9945,6 +10066,19 @@ var Parser = class _Parser {
9945
10066
  while (!this.check("}") && !this.check("eof")) {
9946
10067
  const variantToken = this.expect("ident");
9947
10068
  const variant = { name: variantToken.value };
10069
+ if (this.check("(")) {
10070
+ this.advance();
10071
+ const fields = [];
10072
+ while (!this.check(")") && !this.check("eof")) {
10073
+ const fieldName = this.expect("ident").value;
10074
+ this.expect(":");
10075
+ const fieldType = this.parseType();
10076
+ fields.push({ name: fieldName, type: fieldType });
10077
+ if (!this.match(",")) break;
10078
+ }
10079
+ this.expect(")");
10080
+ variant.fields = fields;
10081
+ }
9948
10082
  if (this.match("=")) {
9949
10083
  const valueToken = this.expect("int_lit");
9950
10084
  variant.value = parseInt(valueToken.value, 10);
@@ -9962,14 +10096,72 @@ var Parser = class _Parser {
9962
10096
  }
9963
10097
  parseImplBlock() {
9964
10098
  const implToken = this.expect("impl");
9965
- const typeName = this.expect("ident").value;
10099
+ let traitName;
10100
+ let typeName;
10101
+ const firstName = this.expect("ident").value;
10102
+ if (this.match("for")) {
10103
+ traitName = firstName;
10104
+ typeName = this.expect("ident").value;
10105
+ } else {
10106
+ typeName = firstName;
10107
+ }
9966
10108
  this.expect("{");
9967
10109
  const methods = [];
9968
10110
  while (!this.check("}") && !this.check("eof")) {
9969
10111
  methods.push(this.parseFnDecl(typeName));
9970
10112
  }
9971
10113
  this.expect("}");
9972
- return this.withLoc({ kind: "impl_block", typeName, methods }, implToken);
10114
+ return this.withLoc({ kind: "impl_block", traitName, typeName, methods }, implToken);
10115
+ }
10116
+ /**
10117
+ * Parse an interface declaration:
10118
+ * interface <Name> {
10119
+ * fn <method>(<params>): <retType>
10120
+ * ...
10121
+ * }
10122
+ * Method signatures have no body — they are prototype-only.
10123
+ */
10124
+ parseInterfaceDecl() {
10125
+ const ifaceToken = this.expect("interface");
10126
+ const name = this.expect("ident").value;
10127
+ this.expect("{");
10128
+ const methods = [];
10129
+ while (!this.check("}") && !this.check("eof")) {
10130
+ const fnToken = this.expect("fn");
10131
+ const methodName = this.expect("ident").value;
10132
+ this.expect("(");
10133
+ const params = this.parseInterfaceParams();
10134
+ this.expect(")");
10135
+ let returnType;
10136
+ if (this.match(":")) {
10137
+ returnType = this.parseType();
10138
+ }
10139
+ methods.push(this.withLoc({ name: methodName, params, returnType }, fnToken));
10140
+ }
10141
+ this.expect("}");
10142
+ return this.withLoc({ name, methods }, ifaceToken);
10143
+ }
10144
+ /**
10145
+ * Parse interface method params — like parseParams but allows bare `self`
10146
+ * (no `:` required for the first param named 'self').
10147
+ */
10148
+ parseInterfaceParams() {
10149
+ const params = [];
10150
+ if (!this.check(")")) {
10151
+ do {
10152
+ const paramToken = this.expect("ident");
10153
+ const paramName = paramToken.value;
10154
+ let type;
10155
+ if (params.length === 0 && paramName === "self" && !this.check(":")) {
10156
+ type = { kind: "named", name: "void" };
10157
+ } else {
10158
+ this.expect(":");
10159
+ type = this.parseType();
10160
+ }
10161
+ params.push(this.withLoc({ name: paramName, type }, paramToken));
10162
+ } while (this.match(","));
10163
+ }
10164
+ return params;
9973
10165
  }
9974
10166
  parseConstDecl() {
9975
10167
  const constToken = this.expect("const");
@@ -9989,8 +10181,12 @@ var Parser = class _Parser {
9989
10181
  const name = this.expect("ident").value;
9990
10182
  this.expect(":");
9991
10183
  const type = this.parseType();
9992
- this.expect("=");
9993
- const init = this.parseExpr();
10184
+ let init;
10185
+ if (this.match("=")) {
10186
+ init = this.parseExpr();
10187
+ } else {
10188
+ init = { kind: "int_lit", value: 0 };
10189
+ }
9994
10190
  this.match(";");
9995
10191
  return this.withLoc({ kind: "global", name, type, init, mutable }, token);
9996
10192
  }
@@ -10006,6 +10202,7 @@ var Parser = class _Parser {
10006
10202
  }
10007
10203
  parseFnDecl(implTypeName) {
10008
10204
  const decorators = this.parseDecorators();
10205
+ const watchObjective = decorators.find((decorator) => decorator.name === "watch")?.args?.objective;
10009
10206
  let isExported;
10010
10207
  const filteredDecorators = decorators.filter((d) => {
10011
10208
  if (d.name === "keep") {
@@ -10043,7 +10240,8 @@ var Parser = class _Parser {
10043
10240
  decorators: filteredDecorators,
10044
10241
  body,
10045
10242
  isLibraryFn: this.inLibraryMode || void 0,
10046
- isExported
10243
+ isExported,
10244
+ watchObjective
10047
10245
  },
10048
10246
  fnToken
10049
10247
  );
@@ -10076,7 +10274,7 @@ var Parser = class _Parser {
10076
10274
  return decorators;
10077
10275
  }
10078
10276
  parseDecoratorValue(value) {
10079
- const match = value.match(/^@(\w+)(?:\(([^)]*)\))?$/);
10277
+ const match = value.match(/^@(\w+)(?:\((.*)\))?$/s);
10080
10278
  if (!match) {
10081
10279
  this.error(`Invalid decorator: ${value}`);
10082
10280
  }
@@ -10085,6 +10283,9 @@ var Parser = class _Parser {
10085
10283
  if (!argsStr) {
10086
10284
  return { name };
10087
10285
  }
10286
+ if (name === "profile") {
10287
+ this.error("@profile decorator does not accept arguments");
10288
+ }
10088
10289
  const args = {};
10089
10290
  if (name === "on") {
10090
10291
  const eventTypeMatch = argsStr.match(/^([A-Za-z_][A-Za-z0-9_]*)$/);
@@ -10093,10 +10294,12 @@ var Parser = class _Parser {
10093
10294
  return { name, args };
10094
10295
  }
10095
10296
  }
10096
- if (name === "on_trigger" || name === "on_advancement" || name === "on_craft" || name === "on_join_team") {
10297
+ if (name === "watch" || name === "on_trigger" || name === "on_advancement" || name === "on_craft" || name === "on_join_team") {
10097
10298
  const strMatch = argsStr.match(/^"([^"]*)"$/);
10098
10299
  if (strMatch) {
10099
- if (name === "on_trigger") {
10300
+ if (name === "watch") {
10301
+ args.objective = strMatch[1];
10302
+ } else if (name === "on_trigger") {
10100
10303
  args.trigger = strMatch[1];
10101
10304
  } else if (name === "on_advancement") {
10102
10305
  args.advancement = strMatch[1];
@@ -10108,6 +10311,24 @@ var Parser = class _Parser {
10108
10311
  return { name, args };
10109
10312
  }
10110
10313
  }
10314
+ if (name === "config") {
10315
+ const configMatch = argsStr.match(/^"([^"]+)"\s*,\s*default\s*:\s*(-?\d+(?:\.\d+)?)$/);
10316
+ if (configMatch) {
10317
+ return { name, args: { configKey: configMatch[1], configDefault: parseFloat(configMatch[2]) } };
10318
+ }
10319
+ const keyOnlyMatch = argsStr.match(/^"([^"]+)"$/);
10320
+ if (keyOnlyMatch) {
10321
+ return { name, args: { configKey: keyOnlyMatch[1] } };
10322
+ }
10323
+ this.error(`Invalid @config syntax. Expected: @config("key", default: value) or @config("key")`);
10324
+ }
10325
+ if (name === "deprecated") {
10326
+ const strMatch = argsStr.match(/^"([^"]*)"$/);
10327
+ if (strMatch) {
10328
+ return { name, args: { message: strMatch[1] } };
10329
+ }
10330
+ return { name, args: {} };
10331
+ }
10111
10332
  if (name === "require_on_load") {
10112
10333
  const rawArgs = [];
10113
10334
  for (const part of argsStr.split(",")) {
@@ -10245,7 +10466,16 @@ var Parser = class _Parser {
10245
10466
  this.expect("{");
10246
10467
  const stmts = [];
10247
10468
  while (!this.check("}") && !this.check("eof")) {
10248
- stmts.push(this.parseStmt());
10469
+ try {
10470
+ stmts.push(this.parseStmt());
10471
+ } catch (err) {
10472
+ if (err instanceof DiagnosticError) {
10473
+ this.parseErrors.push(err);
10474
+ this.syncToNextStmt();
10475
+ } else {
10476
+ throw err;
10477
+ }
10478
+ }
10249
10479
  }
10250
10480
  this.expect("}");
10251
10481
  return stmts;
@@ -10254,6 +10484,9 @@ var Parser = class _Parser {
10254
10484
  if (this.check("let")) {
10255
10485
  return this.parseLetStmt();
10256
10486
  }
10487
+ if (this.check("const")) {
10488
+ return this.parseLocalConstDecl();
10489
+ }
10257
10490
  if (this.check("return")) {
10258
10491
  return this.parseReturnStmt();
10259
10492
  }
@@ -10273,6 +10506,12 @@ var Parser = class _Parser {
10273
10506
  if (this.check("while")) {
10274
10507
  return this.parseWhileStmt();
10275
10508
  }
10509
+ if (this.check("do")) {
10510
+ return this.parseDoWhileStmt();
10511
+ }
10512
+ if (this.check("repeat")) {
10513
+ return this.parseRepeatStmt();
10514
+ }
10276
10515
  if (this.check("for")) {
10277
10516
  return this.parseForStmt();
10278
10517
  }
@@ -10327,6 +10566,16 @@ var Parser = class _Parser {
10327
10566
  this.match(";");
10328
10567
  return this.withLoc({ kind: "let", name, type, init }, letToken);
10329
10568
  }
10569
+ parseLocalConstDecl() {
10570
+ const constToken = this.expect("const");
10571
+ const name = this.expect("ident").value;
10572
+ this.expect(":");
10573
+ const type = this.parseType();
10574
+ this.expect("=");
10575
+ const value = this.parseExpr();
10576
+ this.match(";");
10577
+ return this.withLoc({ kind: "const_decl", name, type, value }, constToken);
10578
+ }
10330
10579
  parseReturnStmt() {
10331
10580
  const returnToken = this.expect("return");
10332
10581
  let value;
@@ -10357,9 +10606,7 @@ var Parser = class _Parser {
10357
10606
  }
10358
10607
  return this.withLoc({ kind: "if_let_some", binding, init, then: then2, else_: else_2 }, ifToken);
10359
10608
  }
10360
- this.expect("(");
10361
- const cond = this.parseExpr();
10362
- this.expect(")");
10609
+ const cond = this.parseParenOptionalCond();
10363
10610
  const then = this.parseBlock();
10364
10611
  let else_;
10365
10612
  if (this.match("else")) {
@@ -10373,12 +10620,44 @@ var Parser = class _Parser {
10373
10620
  }
10374
10621
  parseWhileStmt() {
10375
10622
  const whileToken = this.expect("while");
10376
- this.expect("(");
10377
- const cond = this.parseExpr();
10378
- this.expect(")");
10623
+ if (this.check("let") && this.peek(1).kind === "ident" && this.peek(1).value === "Some") {
10624
+ this.advance();
10625
+ this.advance();
10626
+ this.expect("(");
10627
+ const binding = this.expect("ident").value;
10628
+ this.expect(")");
10629
+ this.expect("=");
10630
+ const init = this.parseExpr();
10631
+ const body2 = this.parseBlock();
10632
+ return this.withLoc({ kind: "while_let_some", binding, init, body: body2 }, whileToken);
10633
+ }
10634
+ const cond = this.parseParenOptionalCond();
10379
10635
  const body = this.parseBlock();
10380
10636
  return this.withLoc({ kind: "while", cond, body }, whileToken);
10381
10637
  }
10638
+ parseDoWhileStmt() {
10639
+ const doToken = this.expect("do");
10640
+ const body = this.parseBlock();
10641
+ this.expect("while");
10642
+ const cond = this.parseParenOptionalCond();
10643
+ this.match(";");
10644
+ return this.withLoc({ kind: "do_while", cond, body }, doToken);
10645
+ }
10646
+ parseRepeatStmt() {
10647
+ const repeatToken = this.expect("repeat");
10648
+ const countToken = this.expect("int_lit");
10649
+ const count = parseInt(countToken.value, 10);
10650
+ const body = this.parseBlock();
10651
+ return this.withLoc({ kind: "repeat", count, body }, repeatToken);
10652
+ }
10653
+ parseParenOptionalCond() {
10654
+ if (this.match("(")) {
10655
+ const cond = this.parseExpr();
10656
+ this.expect(")");
10657
+ return cond;
10658
+ }
10659
+ return this.parseExpr();
10660
+ }
10382
10661
  parseForStmt() {
10383
10662
  const forToken = this.expect("for");
10384
10663
  if (this.check("ident") && this.peek(1).kind === "in") {
@@ -10495,6 +10774,21 @@ var Parser = class _Parser {
10495
10774
  this.expect(")");
10496
10775
  return { kind: "PatSome", binding };
10497
10776
  }
10777
+ if (this.check("ident") && this.peek(1).kind === "::") {
10778
+ const enumName = this.advance().value;
10779
+ this.expect("::");
10780
+ const variant = this.expect("ident").value;
10781
+ const bindings = [];
10782
+ if (this.check("(")) {
10783
+ this.advance();
10784
+ while (!this.check(")") && !this.check("eof")) {
10785
+ bindings.push(this.expect("ident").value);
10786
+ if (!this.match(",")) break;
10787
+ }
10788
+ this.expect(")");
10789
+ }
10790
+ return { kind: "PatEnum", enumName, variant, bindings };
10791
+ }
10498
10792
  if (this.check("int_lit")) {
10499
10793
  const tok = this.advance();
10500
10794
  return { kind: "PatInt", value: parseInt(tok.value, 10) };
@@ -10838,6 +11132,15 @@ var Parser = class _Parser {
10838
11132
  continue;
10839
11133
  }
10840
11134
  if (expr.kind === "member") {
11135
+ if (expr.field === "unwrap_or") {
11136
+ const defaultExpr = this.parseExpr();
11137
+ this.expect(")");
11138
+ expr = this.withLoc(
11139
+ { kind: "unwrap_or", opt: expr.obj, default_: defaultExpr },
11140
+ this.getLocToken(expr) ?? openParenToken
11141
+ );
11142
+ continue;
11143
+ }
10841
11144
  const methodMap = {
10842
11145
  "tag": "__entity_tag",
10843
11146
  "untag": "__entity_untag",
@@ -10930,6 +11233,20 @@ var Parser = class _Parser {
10930
11233
  this.expect("::");
10931
11234
  const memberToken = this.expect("ident");
10932
11235
  if (this.check("(")) {
11236
+ const isNamedArgs = this.peek(1).kind === "ident" && this.peek(2).kind === ":";
11237
+ if (isNamedArgs) {
11238
+ this.advance();
11239
+ const args2 = [];
11240
+ while (!this.check(")") && !this.check("eof")) {
11241
+ const fieldName = this.expect("ident").value;
11242
+ this.expect(":");
11243
+ const value = this.parseExpr();
11244
+ args2.push({ name: fieldName, value });
11245
+ if (!this.match(",")) break;
11246
+ }
11247
+ this.expect(")");
11248
+ return this.withLoc({ kind: "enum_construct", enumName: typeToken.value, variant: memberToken.value, args: args2 }, typeToken);
11249
+ }
10933
11250
  this.advance();
10934
11251
  const args = this.parseArgs();
10935
11252
  this.expect(")");
@@ -11693,7 +12010,6 @@ var MC_TYPE_TO_ENTITY = {
11693
12010
  var VOID_TYPE = { kind: "named", name: "void" };
11694
12011
  var INT_TYPE = { kind: "named", name: "int" };
11695
12012
  var STRING_TYPE = { kind: "named", name: "string" };
11696
- var FORMAT_STRING_TYPE = { kind: "named", name: "format_string" };
11697
12013
  var BUILTIN_SIGNATURES = {
11698
12014
  setTimeout: {
11699
12015
  params: [INT_TYPE, { kind: "function_type", params: [], return: VOID_TYPE }],
@@ -11706,15 +12022,25 @@ var BUILTIN_SIGNATURES = {
11706
12022
  clearInterval: {
11707
12023
  params: [INT_TYPE],
11708
12024
  return: VOID_TYPE
12025
+ },
12026
+ int_to_str: {
12027
+ params: [INT_TYPE],
12028
+ return: STRING_TYPE
12029
+ },
12030
+ bool_to_str: {
12031
+ params: [{ kind: "named", name: "bool" }],
12032
+ return: STRING_TYPE
11709
12033
  }
11710
12034
  };
11711
- var TypeChecker = class {
12035
+ var TypeChecker = class _TypeChecker {
11712
12036
  constructor(source, filePath) {
11713
12037
  this.lintWarnings = [];
11714
12038
  this.functions = /* @__PURE__ */ new Map();
11715
12039
  this.implMethods = /* @__PURE__ */ new Map();
11716
12040
  this.structs = /* @__PURE__ */ new Map();
11717
12041
  this.enums = /* @__PURE__ */ new Map();
12042
+ // enumName → variantName → field list (for payload variants)
12043
+ this.enumPayloads = /* @__PURE__ */ new Map();
11718
12044
  this.consts = /* @__PURE__ */ new Map();
11719
12045
  this.globals = /* @__PURE__ */ new Map();
11720
12046
  this.currentFn = null;
@@ -11725,6 +12051,8 @@ var TypeChecker = class {
11725
12051
  // Depth of loop/conditional nesting (for static-allocation enforcement)
11726
12052
  this.loopDepth = 0;
11727
12053
  this.condDepth = 0;
12054
+ // interface name → InterfaceDecl
12055
+ this.interfaces = /* @__PURE__ */ new Map();
11728
12056
  this.richTextBuiltins = /* @__PURE__ */ new Map([
11729
12057
  ["say", { messageIndex: 0 }],
11730
12058
  ["announce", { messageIndex: 0 }],
@@ -11766,6 +12094,9 @@ var TypeChecker = class {
11766
12094
  for (const fn of program.declarations) {
11767
12095
  this.functions.set(fn.name, fn);
11768
12096
  }
12097
+ for (const iface of program.interfaces ?? []) {
12098
+ this.interfaces.set(iface.name, iface);
12099
+ }
11769
12100
  for (const global of program.globals ?? []) {
11770
12101
  this.globals.set(global.name, this.normalizeType(global.type));
11771
12102
  }
@@ -11795,13 +12126,47 @@ var TypeChecker = class {
11795
12126
  fields.set(field.name, field.type);
11796
12127
  }
11797
12128
  this.structs.set(struct.name, fields);
12129
+ if (struct.isSingleton) {
12130
+ const structType = { kind: "struct", name: struct.name };
12131
+ let singletonMethods = this.implMethods.get(struct.name);
12132
+ if (!singletonMethods) {
12133
+ singletonMethods = /* @__PURE__ */ new Map();
12134
+ this.implMethods.set(struct.name, singletonMethods);
12135
+ }
12136
+ const voidType = { kind: "named", name: "void" };
12137
+ singletonMethods.set("get", {
12138
+ name: "get",
12139
+ params: [],
12140
+ returnType: structType,
12141
+ decorators: [],
12142
+ body: [],
12143
+ typeParams: void 0,
12144
+ isLibraryFn: true
12145
+ });
12146
+ singletonMethods.set("set", {
12147
+ name: "set",
12148
+ params: [{ name: "gs", type: structType }],
12149
+ returnType: voidType,
12150
+ decorators: [],
12151
+ body: [],
12152
+ typeParams: void 0,
12153
+ isLibraryFn: true
12154
+ });
12155
+ }
11798
12156
  }
11799
12157
  for (const enumDecl of program.enums ?? []) {
11800
12158
  const variants = /* @__PURE__ */ new Map();
12159
+ const payloads = /* @__PURE__ */ new Map();
11801
12160
  for (const variant of enumDecl.variants) {
11802
12161
  variants.set(variant.name, variant.value ?? 0);
12162
+ if (variant.fields && variant.fields.length > 0) {
12163
+ payloads.set(variant.name, variant.fields);
12164
+ }
11803
12165
  }
11804
12166
  this.enums.set(enumDecl.name, variants);
12167
+ if (payloads.size > 0) {
12168
+ this.enumPayloads.set(enumDecl.name, payloads);
12169
+ }
11805
12170
  }
11806
12171
  for (const constDecl of program.consts ?? []) {
11807
12172
  const constType = this.normalizeType(constDecl.type);
@@ -11814,6 +12179,21 @@ var TypeChecker = class {
11814
12179
  }
11815
12180
  this.consts.set(constDecl.name, constType);
11816
12181
  }
12182
+ for (const implBlock of program.implBlocks ?? []) {
12183
+ if (!implBlock.traitName) continue;
12184
+ const iface = this.interfaces.get(implBlock.traitName);
12185
+ if (!iface) continue;
12186
+ const implementedMethods = new Set(implBlock.methods.map((m) => m.name));
12187
+ for (const required of iface.methods) {
12188
+ if (!implementedMethods.has(required.name)) {
12189
+ const span = implBlock.span ?? required.span;
12190
+ this.report(
12191
+ `Struct '${implBlock.typeName}' does not implement required method '${required.name}' from interface '${implBlock.traitName}'`,
12192
+ span ?? { line: 1, col: 1 }
12193
+ );
12194
+ }
12195
+ }
12196
+ }
11817
12197
  for (const fn of program.declarations) {
11818
12198
  this.checkFunction(fn);
11819
12199
  }
@@ -11859,6 +12239,30 @@ var TypeChecker = class {
11859
12239
  this.currentReturnType = null;
11860
12240
  }
11861
12241
  checkFunctionDecorators(fn) {
12242
+ const watchDecorators = fn.decorators.filter((decorator) => decorator.name === "watch");
12243
+ if (watchDecorators.length > 1) {
12244
+ this.report(`Function '${fn.name}' cannot have multiple @watch decorators`, fn);
12245
+ return;
12246
+ }
12247
+ if (watchDecorators.length === 1) {
12248
+ const objective = watchDecorators[0].args?.objective;
12249
+ if (!objective) {
12250
+ this.report(`Function '${fn.name}' is missing a scoreboard objective in @watch("...")`, fn);
12251
+ return;
12252
+ }
12253
+ if (fn.params.length > 0) {
12254
+ this.report(`@watch handler '${fn.name}' cannot declare parameters`, fn);
12255
+ }
12256
+ }
12257
+ const profileDecorators = fn.decorators.filter((decorator) => decorator.name === "profile");
12258
+ if (profileDecorators.length > 1) {
12259
+ this.report(`Function '${fn.name}' cannot have multiple @profile decorators`, fn);
12260
+ return;
12261
+ }
12262
+ if (profileDecorators.length === 1 && (profileDecorators[0].rawArgs?.length || profileDecorators[0].args && Object.keys(profileDecorators[0].args).length > 0)) {
12263
+ this.report(`@profile decorator on '${fn.name}' does not accept arguments`, fn);
12264
+ return;
12265
+ }
11862
12266
  const eventDecorators = fn.decorators.filter((decorator) => decorator.name === "on");
11863
12267
  if (eventDecorators.length === 0) {
11864
12268
  return;
@@ -11968,8 +12372,21 @@ var TypeChecker = class {
11968
12372
  if (!isUnknown(subjectType) && !isUnknown(patternType) && !this.typesMatch(subjectType, patternType)) {
11969
12373
  this.report("Match arm pattern type must match subject type", arm.pattern.expr);
11970
12374
  }
12375
+ this.checkBlock(arm.body);
12376
+ } else if (arm.pattern.kind === "PatEnum") {
12377
+ const pat = arm.pattern;
12378
+ const variantPayloads = this.enumPayloads.get(pat.enumName)?.get(pat.variant) ?? [];
12379
+ const savedScope = new Map(this.scope);
12380
+ for (let i = 0; i < pat.bindings.length; i++) {
12381
+ const fieldDef = variantPayloads[i];
12382
+ const bindingType = fieldDef ? fieldDef.type : { kind: "named", name: "int" };
12383
+ this.scope.set(pat.bindings[i], { type: bindingType, mutable: false });
12384
+ }
12385
+ this.checkBlock(arm.body);
12386
+ this.scope = savedScope;
12387
+ } else {
12388
+ this.checkBlock(arm.body);
11971
12389
  }
11972
- this.checkBlock(arm.body);
11973
12390
  }
11974
12391
  break;
11975
12392
  case "as_block": {
@@ -12008,6 +12425,9 @@ var TypeChecker = class {
12008
12425
  break;
12009
12426
  case "raw":
12010
12427
  break;
12428
+ case "const_decl":
12429
+ this.scope.set(stmt.name, { type: stmt.type, mutable: false });
12430
+ break;
12011
12431
  }
12012
12432
  }
12013
12433
  checkLetDestructStmt(stmt) {
@@ -12234,6 +12654,31 @@ var TypeChecker = class {
12234
12654
  }
12235
12655
  }
12236
12656
  break;
12657
+ case "enum_construct": {
12658
+ if (!this.enums.has(expr.enumName)) {
12659
+ this.report(`Unknown enum '${expr.enumName}'`, expr);
12660
+ break;
12661
+ }
12662
+ const variants = this.enums.get(expr.enumName);
12663
+ if (!variants.has(expr.variant)) {
12664
+ this.report(`Enum '${expr.enumName}' has no variant '${expr.variant}'`, expr);
12665
+ break;
12666
+ }
12667
+ const variantPayloads = this.enumPayloads.get(expr.enumName)?.get(expr.variant) ?? [];
12668
+ if (variantPayloads.length === 0 && expr.args.length > 0) {
12669
+ this.report(`Enum variant '${expr.enumName}::${expr.variant}' has no payload fields`, expr);
12670
+ break;
12671
+ }
12672
+ for (const arg of expr.args) {
12673
+ const fieldDef = variantPayloads.find((f) => f.name === arg.name);
12674
+ if (!fieldDef) {
12675
+ this.report(`Unknown field '${arg.name}' for enum variant '${expr.enumName}::${expr.variant}'`, expr);
12676
+ } else {
12677
+ this.checkExpr(arg.value, fieldDef.type);
12678
+ }
12679
+ }
12680
+ break;
12681
+ }
12237
12682
  case "blockpos":
12238
12683
  break;
12239
12684
  // Literals don't need checking
@@ -12345,7 +12790,7 @@ var TypeChecker = class {
12345
12790
  return;
12346
12791
  }
12347
12792
  const messageType = this.inferType(message);
12348
- if (messageType.kind !== "named" || messageType.name !== "string" && messageType.name !== "format_string") {
12793
+ if (messageType.kind !== "named" || messageType.name !== "string") {
12349
12794
  this.report(
12350
12795
  `Argument ${messageIndex + 1} of '${expr.fn}' expects string or format_string, got ${this.typeToString(messageType)}`,
12351
12796
  message
@@ -12570,7 +13015,7 @@ var TypeChecker = class {
12570
13015
  this.checkExpr(part.expr);
12571
13016
  }
12572
13017
  }
12573
- return FORMAT_STRING_TYPE;
13018
+ return STRING_TYPE;
12574
13019
  case "blockpos":
12575
13020
  return { kind: "named", name: "BlockPos" };
12576
13021
  case "ident":
@@ -12630,6 +13075,11 @@ var TypeChecker = class {
12630
13075
  return { kind: "enum", name: expr.enumName };
12631
13076
  }
12632
13077
  return { kind: "named", name: "void" };
13078
+ case "enum_construct":
13079
+ if (this.enums.has(expr.enumName)) {
13080
+ return { kind: "enum", name: expr.enumName };
13081
+ }
13082
+ return { kind: "named", name: "void" };
12633
13083
  case "member":
12634
13084
  if (expr.obj.kind === "ident" && this.enums.has(expr.obj.name)) {
12635
13085
  return { kind: "enum", name: expr.obj.name };
@@ -12735,6 +13185,21 @@ var TypeChecker = class {
12735
13185
  }
12736
13186
  return "entity";
12737
13187
  }
13188
+ static {
13189
+ // Reverse map: parser sometimes remaps method names (e.g. add→set_add) for builtins.
13190
+ // When the receiver is a struct with an impl method matching the original name, use that.
13191
+ this.PARSER_METHOD_REMAP = {
13192
+ "set_add": "add",
13193
+ "set_contains": "contains",
13194
+ "set_remove": "remove",
13195
+ "set_clear": "clear",
13196
+ "__array_push": "push",
13197
+ "__array_pop": "pop",
13198
+ "__entity_tag": "tag",
13199
+ "__entity_untag": "untag",
13200
+ "__entity_has_tag": "has_tag"
13201
+ };
13202
+ }
12738
13203
  resolveInstanceMethod(expr) {
12739
13204
  const receiver = expr.args[0];
12740
13205
  if (!receiver) {
@@ -12744,7 +13209,8 @@ var TypeChecker = class {
12744
13209
  if (receiverType.kind !== "struct") {
12745
13210
  return null;
12746
13211
  }
12747
- const method = this.implMethods.get(receiverType.name)?.get(expr.fn);
13212
+ const methodName = _TypeChecker.PARSER_METHOD_REMAP[expr.fn] ?? expr.fn;
13213
+ const method = this.implMethods.get(receiverType.name)?.get(expr.fn) ?? this.implMethods.get(receiverType.name)?.get(methodName);
12748
13214
  if (!method || method.params[0]?.name !== "self") {
12749
13215
  return null;
12750
13216
  }
@@ -13961,6 +14427,7 @@ function toDiagnostic(err) {
13961
14427
  var DECORATOR_DOCS = {
13962
14428
  tick: "Runs every game tick.\n\n**Optional args:** `rate=N` (every N ticks, e.g. `@tick(rate=20)` = once per second)\n\nExample: `@tick fn every_tick() {}` or `@tick(rate=20) fn every_second() {}`",
13963
14429
  load: "Runs once on `/reload`. Use for initialization.\n\nExample: `@load fn init() { scoreboard_create(...) }`",
14430
+ watch: 'Runs when a scoreboard objective changes for a player.\n\n**Required arg:** objective name.\n\nExample: `@watch("rs.kills") fn on_kill_change() {}`',
13964
14431
  coroutine: "Wraps a loop to spread execution across multiple ticks.\n\n**Required arg:** `batch=N` \u2014 iterations per tick.\n\nExample: `@coroutine(batch=10) fn scan_blocks() { for i in 0..1000 { ... } }`",
13965
14432
  schedule: "Schedules the function to run after a delay.\n\n**Required arg:** `ticks=N`\n\nExample: `@schedule(ticks=100) fn delayed() {}`",
13966
14433
  on_trigger: 'Runs when a player executes `/trigger <name>`.\n\n**Required arg:** trigger objective name.\n\nExample: `@on_trigger("shop") fn open_shop() {}`',
@@ -14107,6 +14574,7 @@ var TYPE_COMPLETIONS = [
14107
14574
  }));
14108
14575
  var DECORATOR_COMPLETIONS = [
14109
14576
  { label: "@tick", detail: "Run every game tick (~20 Hz)", insertText: "tick" },
14577
+ { label: "@watch", detail: "Run when a scoreboard objective changes", insertText: "watch" },
14110
14578
  { label: "@load", detail: "Run on /reload (initialization)", insertText: "load" },
14111
14579
  { label: "@on_trigger", detail: "Run when a player uses /trigger", insertText: "on_trigger" },
14112
14580
  { label: "@schedule", detail: "Schedule function after N ticks", insertText: "schedule" },