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
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+ /**
3
+ * Loop-Invariant Code Motion (LICM) — MIR optimization pass.
4
+ *
5
+ * For each natural loop (detected by the loop_header / loop_body / loop_latch
6
+ * naming convention used by the RedScript HIR→MIR lowering), instructions
7
+ * whose operands are not modified inside the loop and that have no side
8
+ * effects are hoisted to a newly-inserted preheader block that jumps to the
9
+ * loop header.
10
+ *
11
+ * Algorithm:
12
+ * 1. Identify all loops via the loop_header block naming convention.
13
+ * 2. Collect all temps defined anywhere in the loop (variant set).
14
+ * 3. Walk each loop block's instructions; an instruction is loop-invariant
15
+ * when:
16
+ * a. It has no side effects (no call, nbt_write, score_write, etc.).
17
+ * b. Every operand is either a constant OR a temp not in the variant set.
18
+ * 4. Insert a fresh preheader block before the loop header, redirect the
19
+ * predecessor(s) of the header (excluding the back-edge latch) to the
20
+ * preheader, and move the hoisted instructions there.
21
+ * 5. Remove hoisted instructions from their original blocks.
22
+ * 6. Recompute predecessor lists.
23
+ *
24
+ * Limitations:
25
+ * - Only handles the canonical loop shape produced by the RedScript compiler
26
+ * (loop_header / loop_body / loop_latch block id prefixes).
27
+ * - Requires that the loop have exactly one non-back-edge predecessor of
28
+ * the header (i.e. one entry edge).
29
+ * - Does not hoist instructions that could trap (div/mod with a variable
30
+ * denominator) — we conservatively keep those in place.
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.licm = licm;
34
+ // ---------------------------------------------------------------------------
35
+ // Public API
36
+ // ---------------------------------------------------------------------------
37
+ function licm(fn) {
38
+ let current = fn;
39
+ let changed = true;
40
+ // Iterate to fixpoint — multiple loops, or newly-exposed invariants
41
+ while (changed) {
42
+ changed = false;
43
+ const result = tryHoistOne(current);
44
+ if (result !== current) {
45
+ current = result;
46
+ changed = true;
47
+ }
48
+ }
49
+ return current;
50
+ }
51
+ function tryHoistOne(fn) {
52
+ const blockMap = new Map(fn.blocks.map(b => [b.id, b]));
53
+ for (const block of fn.blocks) {
54
+ if (!block.id.startsWith('loop_header'))
55
+ continue;
56
+ const info = analyzeLoop(fn, blockMap, block);
57
+ if (!info)
58
+ continue;
59
+ const hoisted = collectInvariant(info, blockMap);
60
+ if (hoisted.length === 0)
61
+ continue;
62
+ return applyHoist(fn, blockMap, info, hoisted);
63
+ }
64
+ return fn;
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Loop detection
68
+ // ---------------------------------------------------------------------------
69
+ function analyzeLoop(fn, blockMap, header) {
70
+ // Header must branch (loop condition check)
71
+ if (header.term.kind !== 'branch')
72
+ return null;
73
+ // Find the latch: the block that jumps back to the header
74
+ const latchId = findLatch(fn, header.id);
75
+ if (!latchId)
76
+ return null;
77
+ // Find the non-back-edge predecessor (the block that first enters the loop)
78
+ const preHeaderPredId = findPreHeaderPred(fn, header.id, latchId);
79
+ if (!preHeaderPredId)
80
+ return null;
81
+ // Collect all loop block ids: header + any block reachable from header
82
+ // that can reach the latch (simple: everything up to and including latch)
83
+ const loopBlockIds = collectLoopBlocks(fn, blockMap, header.id, latchId);
84
+ return { headerId: header.id, loopBlockIds, preHeaderPredId, latchId };
85
+ }
86
+ /** Find the latch: a predecessor of header that is dominated by header.
87
+ * In the canonical shape, it's the block with id prefix loop_latch that
88
+ * jumps back to the header. Fall back to any predecessor != preheader. */
89
+ function findLatch(fn, headerId) {
90
+ for (const block of fn.blocks) {
91
+ if (block.id.startsWith('loop_latch')) {
92
+ const targets = getTermTargets(block.term);
93
+ if (targets.includes(headerId))
94
+ return block.id;
95
+ }
96
+ }
97
+ // Fallback: any predecessor that comes after the header in block order
98
+ // (a back-edge in the CFG)
99
+ const headerIdx = fn.blocks.findIndex(b => b.id === headerId);
100
+ for (let i = headerIdx + 1; i < fn.blocks.length; i++) {
101
+ const block = fn.blocks[i];
102
+ const targets = getTermTargets(block.term);
103
+ if (targets.includes(headerId))
104
+ return block.id;
105
+ }
106
+ return null;
107
+ }
108
+ /** Find the single non-latch predecessor of the header. */
109
+ function findPreHeaderPred(fn, headerId, latchId) {
110
+ const preds = [];
111
+ for (const block of fn.blocks) {
112
+ if (block.id === latchId)
113
+ continue;
114
+ const targets = getTermTargets(block.term);
115
+ if (targets.includes(headerId))
116
+ preds.push(block.id);
117
+ }
118
+ return preds.length === 1 ? preds[0] : null;
119
+ }
120
+ /** BFS/DFS: collect all block ids that are in the loop (header..latch). */
121
+ function collectLoopBlocks(fn, blockMap, headerId, latchId) {
122
+ const result = new Set();
123
+ const queue = [headerId];
124
+ while (queue.length > 0) {
125
+ const id = queue.shift();
126
+ if (result.has(id))
127
+ continue;
128
+ result.add(id);
129
+ if (id === latchId)
130
+ continue; // don't expand past the latch's targets
131
+ const block = blockMap.get(id);
132
+ if (!block)
133
+ continue;
134
+ for (const target of getTermTargets(block.term)) {
135
+ // Only follow edges that stay inside the loop (don't chase the exit edge)
136
+ // Heuristic: follow targets that have 'loop_' prefix or are the latch
137
+ if (!result.has(target) && isLoopBlock(target, headerId)) {
138
+ queue.push(target);
139
+ }
140
+ }
141
+ }
142
+ return result;
143
+ }
144
+ function isLoopBlock(id, headerId) {
145
+ // A block belongs to the loop if it has a loop_ prefix derived from the same
146
+ // loop as headerId, or is the header itself.
147
+ if (id === headerId)
148
+ return true;
149
+ // Extract the loop suffix from headerId: "loop_header" or "loop_header_N"
150
+ const suffix = headerId.replace(/^loop_header/, '');
151
+ return (id.startsWith('loop_body' + suffix) ||
152
+ id.startsWith('loop_latch' + suffix) ||
153
+ id.startsWith('loop_header' + suffix) ||
154
+ // Nested loop blocks will have further prefixes — include them
155
+ id.startsWith('loop_') && id.includes(suffix));
156
+ }
157
+ function collectInvariant(info, blockMap) {
158
+ // Step 1: collect the set of all temps defined (written) anywhere in the loop
159
+ const variantTemps = new Set();
160
+ for (const id of info.loopBlockIds) {
161
+ const block = blockMap.get(id);
162
+ if (!block)
163
+ continue;
164
+ for (const instr of block.instrs) {
165
+ const dst = getInstrDst(instr);
166
+ if (dst !== null)
167
+ variantTemps.add(dst);
168
+ }
169
+ // Terminator dsts (there are none in practice, but be safe)
170
+ const termDst = getInstrDst(block.term);
171
+ if (termDst !== null)
172
+ variantTemps.add(termDst);
173
+ }
174
+ // Step 2: iteratively find invariant instructions
175
+ // (an instr whose operands are all non-variant can itself be treated as
176
+ // non-variant after it is removed, exposing further candidates)
177
+ const hoisted = [];
178
+ let changed = true;
179
+ const removedKeys = new Set(); // "blockId:index"
180
+ while (changed) {
181
+ changed = false;
182
+ for (const id of info.loopBlockIds) {
183
+ const block = blockMap.get(id);
184
+ if (!block)
185
+ continue;
186
+ for (let i = 0; i < block.instrs.length; i++) {
187
+ const key = `${id}:${i}`;
188
+ if (removedKeys.has(key))
189
+ continue;
190
+ const instr = block.instrs[i];
191
+ const dst = getInstrDst(instr);
192
+ // Must have a dst (otherwise it's a side-effectful no-dst instr)
193
+ if (dst === null)
194
+ continue;
195
+ // Must not have side effects
196
+ if (hasSideEffects(instr))
197
+ continue;
198
+ // Skip div/mod with variable denominator (potential trap)
199
+ if ((instr.kind === 'div' || instr.kind === 'mod') && instr.b.kind === 'temp')
200
+ continue;
201
+ // All source operands must be invariant (not in variantTemps)
202
+ if (!allOperandsInvariant(instr, variantTemps))
203
+ continue;
204
+ // This instruction is loop-invariant — hoist it
205
+ hoisted.push({ fromBlockId: id, instrIndex: i, instr });
206
+ removedKeys.add(key);
207
+ // After hoisting, the dst is no longer variant inside the loop
208
+ variantTemps.delete(dst);
209
+ changed = true;
210
+ }
211
+ }
212
+ }
213
+ return hoisted;
214
+ }
215
+ function allOperandsInvariant(instr, variantTemps) {
216
+ for (const op of getSourceOperands(instr)) {
217
+ if (op.kind === 'temp' && variantTemps.has(op.name))
218
+ return false;
219
+ }
220
+ return true;
221
+ }
222
+ // ---------------------------------------------------------------------------
223
+ // Applying the hoist
224
+ // ---------------------------------------------------------------------------
225
+ function applyHoist(fn, blockMap, info, hoisted) {
226
+ const { headerId, preHeaderPredId, latchId } = info;
227
+ // Build a key set for quick lookup: "blockId:instrIndex"
228
+ const hoistedKeys = new Set(hoisted.map(h => `${h.fromBlockId}:${h.instrIndex}`));
229
+ // Collect hoisted instrs in order (they were collected left-to-right)
230
+ const hoistedInstrs = hoisted.map(h => h.instr);
231
+ // Insert a fresh preheader block
232
+ const preHeaderId = headerId.replace('loop_header', 'loop_preheader');
233
+ const preHeaderBlock = {
234
+ id: preHeaderId,
235
+ instrs: hoistedInstrs,
236
+ term: { kind: 'jump', target: headerId },
237
+ preds: [], // will be recomputed
238
+ };
239
+ // Rewrite the predecessor's jump from header → preHeader
240
+ const newBlocks = [];
241
+ for (const block of fn.blocks) {
242
+ if (block.id === preHeaderPredId) {
243
+ // Redirect its outgoing edge(s) from headerId to preHeaderId
244
+ newBlocks.push({
245
+ ...block,
246
+ term: redirectTerm(block.term, headerId, preHeaderId),
247
+ });
248
+ // Insert the new preheader right after this block
249
+ newBlocks.push(preHeaderBlock);
250
+ }
251
+ else {
252
+ // Remove hoisted instructions from their source blocks
253
+ if (info.loopBlockIds.has(block.id)) {
254
+ const newInstrs = block.instrs.filter((_, i) => !hoistedKeys.has(`${block.id}:${i}`));
255
+ newBlocks.push({ ...block, instrs: newInstrs });
256
+ }
257
+ else {
258
+ newBlocks.push(block);
259
+ }
260
+ }
261
+ }
262
+ return { ...fn, blocks: recomputePreds(newBlocks) };
263
+ }
264
+ function redirectTerm(term, from, to) {
265
+ switch (term.kind) {
266
+ case 'jump':
267
+ return term.target === from ? { ...term, target: to } : term;
268
+ case 'branch':
269
+ return {
270
+ ...term,
271
+ then: term.then === from ? to : term.then,
272
+ else: term.else === from ? to : term.else,
273
+ };
274
+ default:
275
+ return term;
276
+ }
277
+ }
278
+ // ---------------------------------------------------------------------------
279
+ // Helpers
280
+ // ---------------------------------------------------------------------------
281
+ function hasSideEffects(instr) {
282
+ return (instr.kind === 'call' ||
283
+ instr.kind === 'call_macro' ||
284
+ instr.kind === 'call_context' ||
285
+ instr.kind === 'nbt_write' ||
286
+ instr.kind === 'nbt_write_dynamic' ||
287
+ instr.kind === 'score_write');
288
+ }
289
+ function getInstrDst(instr) {
290
+ switch (instr.kind) {
291
+ case 'const':
292
+ case 'copy':
293
+ case 'add':
294
+ case 'sub':
295
+ case 'mul':
296
+ case 'div':
297
+ case 'mod':
298
+ case 'neg':
299
+ case 'cmp':
300
+ case 'and':
301
+ case 'or':
302
+ case 'not':
303
+ case 'nbt_read':
304
+ case 'nbt_read_dynamic':
305
+ case 'nbt_list_len':
306
+ case 'string_match':
307
+ case 'score_read':
308
+ return instr.dst;
309
+ case 'call':
310
+ case 'call_macro':
311
+ return instr.dst;
312
+ default:
313
+ return null;
314
+ }
315
+ }
316
+ function getSourceOperands(instr) {
317
+ switch (instr.kind) {
318
+ case 'copy':
319
+ case 'neg':
320
+ case 'not':
321
+ return [instr.src];
322
+ case 'add':
323
+ case 'sub':
324
+ case 'mul':
325
+ case 'div':
326
+ case 'mod':
327
+ case 'cmp':
328
+ case 'and':
329
+ case 'or':
330
+ return [instr.a, instr.b];
331
+ case 'nbt_write':
332
+ return [instr.src];
333
+ case 'nbt_write_dynamic':
334
+ return [instr.indexSrc, instr.valueSrc];
335
+ case 'nbt_read_dynamic':
336
+ return [instr.indexSrc];
337
+ case 'call':
338
+ return [...instr.args];
339
+ case 'call_macro':
340
+ return instr.args.map(a => a.value);
341
+ case 'branch':
342
+ return [instr.cond];
343
+ case 'return':
344
+ return instr.value ? [instr.value] : [];
345
+ case 'score_write':
346
+ return [instr.src];
347
+ default:
348
+ return [];
349
+ }
350
+ }
351
+ function getTermTargets(term) {
352
+ switch (term.kind) {
353
+ case 'jump': return [term.target];
354
+ case 'branch': return [term.then, term.else];
355
+ default: return [];
356
+ }
357
+ }
358
+ function recomputePreds(blocks) {
359
+ const predMap = new Map();
360
+ for (const b of blocks)
361
+ predMap.set(b.id, []);
362
+ for (const block of blocks) {
363
+ for (const target of getTermTargets(block.term)) {
364
+ const preds = predMap.get(target);
365
+ if (preds)
366
+ preds.push(block.id);
367
+ }
368
+ }
369
+ return blocks.map(b => ({ ...b, preds: predMap.get(b.id) ?? [] }));
370
+ }
371
+ //# sourceMappingURL=licm.js.map
@@ -13,13 +13,18 @@ exports.selectorCache = void 0;
13
13
  exports.optimizeFunction = optimizeFunction;
14
14
  exports.optimizeModule = optimizeModule;
15
15
  const constant_fold_1 = require("./constant_fold");
16
+ const strength_reduction_1 = require("./strength_reduction");
16
17
  const copy_prop_1 = require("./copy_prop");
17
18
  const dce_1 = require("./dce");
18
19
  const block_merge_1 = require("./block_merge");
19
20
  const branch_simplify_1 = require("./branch_simplify");
20
21
  const unroll_1 = require("./unroll");
22
+ const licm_1 = require("./licm");
21
23
  const nbt_batch_1 = require("./nbt-batch");
22
24
  const interprocedural_1 = require("./interprocedural");
25
+ const auto_inline_1 = require("./auto-inline");
26
+ const inline_1 = require("./inline");
27
+ const cse_1 = require("./cse");
23
28
  // selectorCache is intentionally excluded from the default pipeline:
24
29
  // it emits synthetic __sel_cleanup_* / __sel_tag_* call_context instructions
25
30
  // that require codegen support before being used end-to-end.
@@ -27,8 +32,11 @@ var selector_cache_1 = require("./selector-cache");
27
32
  Object.defineProperty(exports, "selectorCache", { enumerable: true, get: function () { return selector_cache_1.selectorCache; } });
28
33
  const defaultPasses = [
29
34
  unroll_1.loopUnroll,
35
+ licm_1.licm,
30
36
  nbt_batch_1.nbtBatchRead,
31
37
  constant_fold_1.constantFold,
38
+ strength_reduction_1.strengthReduction,
39
+ cse_1.cse,
32
40
  copy_prop_1.copyProp,
33
41
  branch_simplify_1.branchSimplify,
34
42
  dce_1.dce,
@@ -48,9 +56,11 @@ function optimizeFunction(fn, passes = defaultPasses) {
48
56
  return current;
49
57
  }
50
58
  function optimizeModule(mod, passes) {
59
+ // Module-level pass: inline @inline-marked functions before per-function opts
60
+ const inlined = (0, auto_inline_1.autoInlineSmallFunctions)((0, inline_1.inlinePass)(mod));
51
61
  const perFnOptimized = {
52
- ...mod,
53
- functions: mod.functions.map(fn => optimizeFunction(fn, passes)),
62
+ ...inlined,
63
+ functions: inlined.functions.map(fn => optimizeFunction(fn, passes)),
54
64
  };
55
65
  // Module-level pass: interprocedural constant propagation
56
66
  return (0, interprocedural_1.interproceduralConstProp)(perFnOptimized);
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Strength Reduction — MIR algebraic simplification pass.
3
+ *
4
+ * Rewrites expensive or redundant arithmetic into cheaper equivalents:
5
+ * - x * 2 -> x + x
6
+ * - x * 1 -> x
7
+ * - x * 0 -> 0
8
+ * - x + 0 -> x
9
+ * - x - 0 -> x
10
+ * - x / 1 -> x
11
+ * - x ^ 1 -> x
12
+ * - x * -1 -> -x
13
+ */
14
+ import type { MIRFunction } from '../mir/types';
15
+ export declare function strengthReduction(fn: MIRFunction): MIRFunction;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /**
3
+ * Strength Reduction — MIR algebraic simplification pass.
4
+ *
5
+ * Rewrites expensive or redundant arithmetic into cheaper equivalents:
6
+ * - x * 2 -> x + x
7
+ * - x * 1 -> x
8
+ * - x * 0 -> 0
9
+ * - x + 0 -> x
10
+ * - x - 0 -> x
11
+ * - x / 1 -> x
12
+ * - x ^ 1 -> x
13
+ * - x * -1 -> -x
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.strengthReduction = strengthReduction;
17
+ function strengthReduction(fn) {
18
+ return {
19
+ ...fn,
20
+ blocks: fn.blocks.map(rewriteBlock),
21
+ };
22
+ }
23
+ function rewriteBlock(block) {
24
+ return {
25
+ ...block,
26
+ instrs: block.instrs.map(instr => rewriteInstr(instr) ?? instr),
27
+ };
28
+ }
29
+ function rewriteInstr(instr) {
30
+ const powInstr = asPowInstr(instr);
31
+ if (powInstr && isConst(powInstr.b, 1))
32
+ return makeCopy(powInstr.dst, powInstr.a, powInstr.sourceLoc);
33
+ switch (instr.kind) {
34
+ case 'mul':
35
+ return rewriteMul(instr);
36
+ case 'add':
37
+ if (isConst(instr.a, 0))
38
+ return makeCopy(instr.dst, instr.b, instr.sourceLoc);
39
+ if (isConst(instr.b, 0))
40
+ return makeCopy(instr.dst, instr.a, instr.sourceLoc);
41
+ return null;
42
+ case 'sub':
43
+ if (isConst(instr.b, 0))
44
+ return makeCopy(instr.dst, instr.a, instr.sourceLoc);
45
+ return null;
46
+ case 'div':
47
+ if (isConst(instr.b, 1))
48
+ return makeCopy(instr.dst, instr.a, instr.sourceLoc);
49
+ return null;
50
+ default:
51
+ return null;
52
+ }
53
+ }
54
+ function rewriteMul(instr) {
55
+ if (isConst(instr.a, 0) || isConst(instr.b, 0))
56
+ return makeConst(instr.dst, 0, instr.sourceLoc);
57
+ if (isConst(instr.a, 1))
58
+ return makeCopy(instr.dst, instr.b, instr.sourceLoc);
59
+ if (isConst(instr.b, 1))
60
+ return makeCopy(instr.dst, instr.a, instr.sourceLoc);
61
+ if (isConst(instr.a, -1))
62
+ return makeNeg(instr.dst, instr.b, instr.sourceLoc);
63
+ if (isConst(instr.b, -1))
64
+ return makeNeg(instr.dst, instr.a, instr.sourceLoc);
65
+ if (isConst(instr.a, 2))
66
+ return makeAdd(instr.dst, instr.b, instr.b, instr.sourceLoc);
67
+ if (isConst(instr.b, 2))
68
+ return makeAdd(instr.dst, instr.a, instr.a, instr.sourceLoc);
69
+ return null;
70
+ }
71
+ function isConst(op, value) {
72
+ return op.kind === 'const' && op.value === value;
73
+ }
74
+ function asPowInstr(instr) {
75
+ const candidate = instr;
76
+ return candidate.kind === 'pow' ? candidate : null;
77
+ }
78
+ function makeCopy(dst, src, sourceLoc) {
79
+ return sourceLoc ? { kind: 'copy', dst, src, sourceLoc } : { kind: 'copy', dst, src };
80
+ }
81
+ function makeConst(dst, value, sourceLoc) {
82
+ return sourceLoc ? { kind: 'const', dst, value, sourceLoc } : { kind: 'const', dst, value };
83
+ }
84
+ function makeNeg(dst, src, sourceLoc) {
85
+ return sourceLoc ? { kind: 'neg', dst, src, sourceLoc } : { kind: 'neg', dst, src };
86
+ }
87
+ function makeAdd(dst, a, b, sourceLoc) {
88
+ return sourceLoc ? { kind: 'add', dst, a, b, sourceLoc } : { kind: 'add', dst, a, b };
89
+ }
90
+ //# sourceMappingURL=strength_reduction.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Tail Call Optimization (TCO) — MIR optimization pass.
3
+ *
4
+ * Detects direct self-tail-calls and converts them into loops, eliminating
5
+ * the recursive function call entirely.
6
+ *
7
+ * ## Definition
8
+ * A tail call is a `call` instruction whose result is immediately returned
9
+ * in the same block (i.e., the block's terminator is `return` and the last
10
+ * non-terminator instruction is `call dst fn args` where fn === current fn,
11
+ * and the return value is that dst temp).
12
+ *
13
+ * ## Transformation
14
+ * Given a function like:
15
+ *
16
+ * fn factorial(n, acc):
17
+ * entry:
18
+ * t0 = cmp le n 1
19
+ * branch t0 → base_case, recurse
20
+ * base_case:
21
+ * return acc
22
+ * recurse:
23
+ * t1 = mul acc n
24
+ * t2 = sub n 1
25
+ * t3 = call factorial(t2, t1) ← tail call
26
+ * return t3
27
+ *
28
+ * We:
29
+ * 1. Create a new "__tco_entry" preamble block that copies original params
30
+ * into "loop parameter" temps (__lp0, __lp1, ...) and jumps to the
31
+ * original entry block.
32
+ * 2. In all blocks (including entry), substitute uses of original param
33
+ * temps with loop params, so subsequent iterations use updated values.
34
+ * 3. In tail-call blocks: evaluate call args (to avoid aliasing), assign
35
+ * results to loop params, and jump back to original entry — no call emitted.
36
+ */
37
+ import type { MIRFunction, BlockId } from '../mir/types';
38
+ /**
39
+ * Attempt to apply TCO to a single function.
40
+ * Returns the transformed function if any tail calls were optimized,
41
+ * or the original function unchanged if no self-tail-calls were found.
42
+ */
43
+ export declare function tailCallOptimize(fn: MIRFunction): MIRFunction;
44
+ /**
45
+ * Returns a list of tail-call block descriptors for every block that contains
46
+ * a self-tail-call: the last non-terminator instruction is a `call` to the
47
+ * same function, and the block terminator is `return` of that call's result.
48
+ */
49
+ export declare function findTailCallBlocks(fn: MIRFunction): Array<{
50
+ blockId: BlockId;
51
+ callIdx: number;
52
+ argCount: number;
53
+ }>;