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,102 @@
1
+ /**
2
+ * RedScript REPL HTTP Server
3
+ *
4
+ * Provides a local HTTP API for compiling RedScript code in real-time.
5
+ *
6
+ * Endpoints:
7
+ * POST /compile { code: string, namespace?: string } → { files: [{path, content}][], error?: string }
8
+ * GET /health → { ok: true }
9
+ */
10
+
11
+ import * as http from 'http'
12
+ import { compile } from './emit/compile'
13
+
14
+ const PORT = 3000
15
+
16
+ function readBody(req: http.IncomingMessage): Promise<string> {
17
+ return new Promise((resolve, reject) => {
18
+ const chunks: Buffer[] = []
19
+ req.on('data', (chunk: Buffer) => chunks.push(chunk))
20
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
21
+ req.on('error', reject)
22
+ })
23
+ }
24
+
25
+ function sendJSON(res: http.ServerResponse, status: number, body: unknown): void {
26
+ const json = JSON.stringify(body)
27
+ res.writeHead(status, {
28
+ 'Content-Type': 'application/json',
29
+ 'Content-Length': Buffer.byteLength(json),
30
+ 'Access-Control-Allow-Origin': '*',
31
+ })
32
+ res.end(json)
33
+ }
34
+
35
+ export const requestHandler = async (req: http.IncomingMessage, res: http.ServerResponse): Promise<void> => {
36
+ // CORS preflight
37
+ if (req.method === 'OPTIONS') {
38
+ res.writeHead(204, {
39
+ 'Access-Control-Allow-Origin': '*',
40
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
41
+ 'Access-Control-Allow-Headers': 'Content-Type',
42
+ })
43
+ res.end()
44
+ return
45
+ }
46
+
47
+ // GET /health
48
+ if (req.method === 'GET' && req.url === '/health') {
49
+ sendJSON(res, 200, { ok: true })
50
+ return
51
+ }
52
+
53
+ // POST /compile
54
+ if (req.method === 'POST' && req.url === '/compile') {
55
+ let body: unknown
56
+ try {
57
+ const raw = await readBody(req)
58
+ body = JSON.parse(raw)
59
+ } catch {
60
+ sendJSON(res, 400, { error: 'Invalid JSON body' })
61
+ return
62
+ }
63
+
64
+ if (typeof body !== 'object' || body === null || !('code' in body)) {
65
+ sendJSON(res, 400, { error: 'Missing required field: code' })
66
+ return
67
+ }
68
+
69
+ const { code, namespace } = body as { code: string; namespace?: string }
70
+
71
+ if (typeof code !== 'string') {
72
+ sendJSON(res, 400, { error: 'Field "code" must be a string' })
73
+ return
74
+ }
75
+
76
+ try {
77
+ const result = compile(code, { namespace: namespace ?? 'redscript' })
78
+ const files = result.files.map(f => ({ path: f.path, content: f.content }))
79
+ sendJSON(res, 200, { files })
80
+ } catch (err: unknown) {
81
+ const message = err instanceof Error ? err.message : String(err)
82
+ sendJSON(res, 200, { files: [], error: message })
83
+ }
84
+ return
85
+ }
86
+
87
+ // 404 fallback
88
+ sendJSON(res, 404, { error: 'Not found' })
89
+ }
90
+
91
+ const server = http.createServer(requestHandler)
92
+
93
+ // Only auto-start when this module is run directly (not when imported by tests)
94
+ if (require.main === module) {
95
+ server.listen(PORT, () => {
96
+ console.log(`RedScript REPL server listening on http://localhost:${PORT}`)
97
+ console.log(' POST /compile — compile RedScript code')
98
+ console.log(' GET /health — health check')
99
+ })
100
+ }
101
+
102
+ export { server }
@@ -11,9 +11,11 @@ module library;
11
11
 
12
12
  // ─── Category 1: Number theory ───────────────────────────────────────────────
13
13
 
14
- // Fibonacci number F(n) using simple iteration.
15
- // Overflow: F(46) = 1836311903 ≈ INT_MAX; use n ≤ 46.
16
- // fib(0) == 0, fib(1) == 1, fib(10) == 55
14
+ /// Fibonacci number F(n) using simple iteration.
15
+ /// Overflow: F(46) = 1 836 311 903 ≈ INT_MAX; keep n ≤ 46.
16
+ /// @since 1.0.0
17
+ /// @param n Index (n ≥ 0)
18
+ /// @returns F(n) — fib(0) == 0, fib(1) == 1, fib(10) == 55
17
19
  fn fib(n: int) -> int {
18
20
  if (n <= 0) { return 0; }
19
21
  if (n == 1) { return 1; }
@@ -29,9 +31,14 @@ fn fib(n: int) -> int {
29
31
  return b;
30
32
  }
31
33
 
32
- // Primality test by trial division up to √n.
33
- // Returns 1 if n is prime, 0 otherwise.
34
- // is_prime(2) == 1, is_prime(4) == 0, is_prime(97) == 1
34
+ /// Primality test by trial division up to √n.
35
+ /// @since 1.0.0
36
+ /// @param n Integer to test (n 0)
37
+ /// @returns 1 if n is prime, 0 otherwise
38
+ /// @example
39
+ /// is_prime(2) // 1
40
+ /// is_prime(4) // 0
41
+ /// is_prime(97) // 1
35
42
  fn is_prime(n: int) -> int {
36
43
  if (n < 2) { return 0; }
37
44
  if (n == 2) { return 1; }
@@ -44,10 +51,10 @@ fn is_prime(n: int) -> int {
44
51
  return 1;
45
52
  }
46
53
 
47
- // Number of steps in the Collatz sequence starting at n until reaching 1.
48
- // collatz_steps(1) == 0
49
- // collatz_steps(6) == 8
50
- // collatz_steps(27) == 111 (world record among small numbers)
54
+ /// Number of steps in the Collatz sequence starting at n until reaching 1.
55
+ /// @since 1.0.0
56
+ /// @param n Starting value (n ≥ 1)
57
+ /// @returns Step count — collatz_steps(1) == 0, collatz_steps(6) == 8
51
58
  fn collatz_steps(n: int) -> int {
52
59
  if (n <= 1) { return 0; }
53
60
  let x: int = n;
@@ -63,8 +70,10 @@ fn collatz_steps(n: int) -> int {
63
70
  return steps;
64
71
  }
65
72
 
66
- // Sum of decimal digits. Negative input uses absolute value.
67
- // digit_sum(123) == 6, digit_sum(0) == 0
73
+ /// Sum of decimal digits. Negative input uses the absolute value.
74
+ /// @since 1.0.0
75
+ /// @param n Integer input
76
+ /// @returns Sum of digits — digit_sum(123) == 6, digit_sum(0) == 0
68
77
  fn digit_sum(n: int) -> int {
69
78
  let x: int = n;
70
79
  if (x < 0) { x = 0 - x; }
@@ -77,8 +86,10 @@ fn digit_sum(n: int) -> int {
77
86
  return sum;
78
87
  }
79
88
 
80
- // Count decimal digits. 0 has 1 digit. Negative: counts absolute digits.
81
- // count_digits(0) == 1, count_digits(100) == 3
89
+ /// Count decimal digits of n. 0 has 1 digit; negative values count absolute digits.
90
+ /// @since 1.0.0
91
+ /// @param n Integer input
92
+ /// @returns Digit count — count_digits(0) == 1, count_digits(100) == 3
82
93
  fn count_digits(n: int) -> int {
83
94
  let x: int = n;
84
95
  if (x < 0) { x = 0 - x; }
@@ -91,8 +102,10 @@ fn count_digits(n: int) -> int {
91
102
  return cnt;
92
103
  }
93
104
 
94
- // Reverse the decimal digits of an integer. Sign is preserved.
95
- // reverse_int(12345) == 54321, reverse_int(-42) == -24
105
+ /// Reverse the decimal digits of an integer. Sign is preserved.
106
+ /// @since 1.0.0
107
+ /// @param n Integer input
108
+ /// @returns Digit-reversed integer — reverse_int(12345) == 54321, reverse_int(-42) == -24
96
109
  fn reverse_int(n: int) -> int {
97
110
  let x: int = n;
98
111
  let neg: int = 0;
@@ -106,9 +119,13 @@ fn reverse_int(n: int) -> int {
106
119
  return result;
107
120
  }
108
121
 
109
- // Modular exponentiation: (base ^ exp) mod m using fast O(log exp) squaring.
110
- // IMPORTANT: m must be ≤ 46340 to avoid b*b overflow (46340² < INT_MAX).
111
- // mod_pow(2, 10, 1000) == 24 (1024 mod 1000)
122
+ /// Modular exponentiation: (base ^ exp) mod m using O(log exp) binary squaring.
123
+ /// m must be ≤ 46 340 to avoid `b*b` int32 overflow.
124
+ /// @since 1.0.0
125
+ /// @param base Base value
126
+ /// @param exp Exponent (≥ 0)
127
+ /// @param m Modulus (1 < m ≤ 46340)
128
+ /// @returns (base^exp) mod m — mod_pow(2, 10, 1000) == 24
112
129
  fn mod_pow(base: int, exp: int, m: int) -> int {
113
130
  if (m == 1) { return 0; }
114
131
  let result: int = 1;
@@ -127,10 +144,11 @@ fn mod_pow(base: int, exp: int, m: int) -> int {
127
144
 
128
145
  // ─── Category 2: Hashing & noise ─────────────────────────────────────────────
129
146
 
130
- // Integer hash function. Output is non-negative, range [0, ~2 × 10⁹).
131
- // Deterministic, no randomness — same input always produces the same output.
132
- // Suitable as a seeded pseudo-random value for procedural generation.
133
- // hash_int(0) != hash_int(1), repeatable across runs.
147
+ /// Deterministic integer hash. Output is non-negative [0, ~2×10⁹).
148
+ /// Same input always produces the same output — useful as a seeded pseudo-random value.
149
+ /// @since 1.0.0
150
+ /// @param n Input integer (any value)
151
+ /// @returns Non-negative hash value
134
152
  fn hash_int(n: int) -> int {
135
153
  let h: int = n;
136
154
  if (h < 0) { h = 0 - h; }
@@ -143,9 +161,11 @@ fn hash_int(n: int) -> int {
143
161
  return h;
144
162
  }
145
163
 
146
- // 1D value noise. Input x in fixed-point (scale = 1000).
147
- // Output in [0, 999] — smoothly interpolated between hashed lattice points.
148
- // noise1d(0) == noise1d(0), noise1d(500) is between noise1d(0) and noise1d(1000).
164
+ /// 1-D value noise with continuity via smoothstep interpolation.
165
+ /// Input x is fixed-point (scale = 1000). Output in [0, 999].
166
+ /// @since 1.0.0
167
+ /// @param x Coordinate × 1000 (e.g. 500 = 0.5, 1000 = 1.0)
168
+ /// @returns Smoothly interpolated noise value in [0, 999]
149
169
  fn noise1d(x: int) -> int {
150
170
  let ix: int = x / 1000;
151
171
  let frac: int = x % 1000;
@@ -165,24 +185,30 @@ fn noise1d(x: int) -> int {
165
185
 
166
186
  // ─── Category 3: Curves ──────────────────────────────────────────────────────
167
187
 
168
- // Quadratic Bezier: B(t) = lerp(lerp(p0,p1,t), lerp(p1,p2,t), t)
169
- // De Casteljau's algorithm — numerically stable, safe for large coordinates.
170
- // t in [0, 1000] (fixed-point).
171
- //
172
- // bezier_quad(0, 500, 1000, 0) == 0 (t=0: start)
173
- // bezier_quad(0, 500, 1000, 500) == 500 (t=500: midpoint of curve)
174
- // bezier_quad(0, 500, 1000, 1000) == 1000 (t=1000: end)
175
- // bezier_quad(0, 1000, 0, 500) == 500 (arch at midpoint)
188
+ /// Quadratic Bezier curve evaluated at t using De Casteljau's algorithm.
189
+ /// @since 1.0.0
190
+ /// @param p0 Start control point
191
+ /// @param p1 Middle control point
192
+ /// @param p2 End control point
193
+ /// @param t Parameter × 1000 (0 = start, 1000 = end)
194
+ /// @returns Curve value at t
195
+ /// @example
196
+ /// bezier_quad(0, 500, 1000, 500) // 500 (midpoint)
197
+ /// bezier_quad(0, 1000, 0, 500) // 500 (arch at midpoint)
176
198
  fn bezier_quad(p0: int, p1: int, p2: int, t: int) -> int {
177
199
  let m0: int = lerp(p0, p1, t);
178
200
  let m1: int = lerp(p1, p2, t);
179
201
  return lerp(m0, m1, t);
180
202
  }
181
203
 
182
- // Cubic Bezier: 4-point curve using De Casteljau's algorithm.
183
- // t in [0, 1000].
184
- // bezier_cubic(0, 333, 667, 1000, 0) == 0
185
- // bezier_cubic(0, 333, 667, 1000, 1000) == 1000
204
+ /// Cubic Bezier curve evaluated at t using De Casteljau's algorithm.
205
+ /// @since 1.0.0
206
+ /// @param p0 Control point 0 (start)
207
+ /// @param p1 Control point 1
208
+ /// @param p2 Control point 2
209
+ /// @param p3 Control point 3 (end)
210
+ /// @param t Parameter × 1000 (0 = start, 1000 = end)
211
+ /// @returns Curve value at t
186
212
  fn bezier_cubic(p0: int, p1: int, p2: int, p3: int, t: int) -> int {
187
213
  let m0: int = lerp(p0, p1, t);
188
214
  let m1: int = lerp(p1, p2, t);
@@ -194,22 +220,17 @@ fn bezier_cubic(p0: int, p1: int, p2: int, p3: int, t: int) -> int {
194
220
 
195
221
  // ─── Category 4: Fractals 🤯 ─────────────────────────────────────────────────
196
222
 
197
- // Mandelbrot set iteration count.
198
- //
199
- // cx, cy: fixed-point coordinates of the complex number c = cx/1000 + i*cy/1000
200
- // cx = -2000..1000 (i.e. real part -2.0..1.0)
201
- // cy = -1000..1000 (imaginary part -1.0..1.0)
202
- //
203
- // Returns the number of iterations before |z| > 2 (escape), or max_iter if
204
- // the point is in the Mandelbrot set. Use the return value to colour blocks!
205
- //
206
- // Points in the set: mandelbrot_iter(-1000, 0, 100) == 100 (c = -1+0i)
207
- // Points outside: mandelbrot_iter(1000, 0, 100) == 0 (c = 1+0i, escapes immediately)
208
- // Boundary region: mandelbrot_iter(-500, 500, 50) → varies
209
- //
210
- // Algorithm: z₀ = 0, z_{n+1} = z_n² + c
211
- // z_n = (zr + zi·i), z_n² = zr²−zi² + 2·zr·zi·i
212
- // Escape when |z|² = (zr²+zi²)/10⁶ > 4 ↔ mulfix(zr,zr)+mulfix(zi,zi) > 4000
223
+ /// Mandelbrot set iteration count for complex number c = cx/1000 + i·cy/1000.
224
+ /// Returns the escape iteration count, or max_iter if the point is in the set.
225
+ /// Use the return value to colour blocks!
226
+ /// @since 1.0.0
227
+ /// @param cx Real part × 1000 (range −2000..1000)
228
+ /// @param cy Imaginary part × 1000 (range −1000..1000)
229
+ /// @param max_iter Maximum iteration count
230
+ /// @returns Iterations before |z| > 2, or max_iter if in the set
231
+ /// @example
232
+ /// mandelbrot_iter(-1000, 0, 100) // 100c = -1+0i is in the set
233
+ /// mandelbrot_iter(1000, 0, 100) // 0 c = 1+0i escapes immediately
213
234
  fn mandelbrot_iter(cx: int, cy: int, max_iter: int) -> int {
214
235
  let zr: int = 0;
215
236
  let zi: int = 0;
@@ -227,10 +248,15 @@ fn mandelbrot_iter(cx: int, cy: int, max_iter: int) -> int {
227
248
  return max_iter;
228
249
  }
229
250
 
230
- // Julia set iteration count (generalised Mandelbrot with fixed c and variable z₀).
231
- // z0r, z0i: starting point (fixed-point, scale=1000)
232
- // cr, ci: constant c (fixed-point, scale=1000)
233
- // Same escape condition as mandelbrot_iter.
251
+ /// Julia set iteration count with fixed constant c and variable starting point z₀.
252
+ /// Same escape condition as `mandelbrot_iter`.
253
+ /// @since 1.0.0
254
+ /// @param z0r Real part of starting point × 1000
255
+ /// @param z0i Imaginary part of starting point × 1000
256
+ /// @param cr Real part of constant c × 1000
257
+ /// @param ci Imaginary part of constant c × 1000
258
+ /// @param max_iter Maximum iteration count
259
+ /// @returns Iterations before |z| > 2, or max_iter if in the set
234
260
  fn julia_iter(z0r: int, z0i: int, cr: int, ci: int, max_iter: int) -> int {
235
261
  let zr: int = z0r;
236
262
  let zi: int = z0i;
@@ -250,15 +276,16 @@ fn julia_iter(z0r: int, z0i: int, cr: int, ci: int, max_iter: int) -> int {
250
276
 
251
277
  // ─── Category 5: Geometry experiments ────────────────────────────────────────
252
278
 
253
- // Angle between two 2D vectors in degrees (×1 = degrees, unsigned 0..180).
254
- // Strategy: normalize both vectors to unit (×1000 components), then
255
- // angle = atan2(|cross|, dot) where cross,dot are from the unit vectors.
256
- // Unit vector components are 1000, so cross/dot ≤ 10^6 (no overflow).
257
- // After dividing by 1000 to re-scale, pass to atan2_fixed.
258
- //
259
- // angle_between(1000, 0, 0, 1000) == 90
260
- // angle_between(1000, 0, 1000, 0) == 0
261
- // angle_between(1000, 0, -1000, 0) == 180
279
+ /// Unsigned angle (0–180°) between two 2-D integer vectors.
280
+ /// @since 1.0.0
281
+ /// @param x1 X component of vector 1
282
+ /// @param y1 Y component of vector 1
283
+ /// @param x2 X component of vector 2
284
+ /// @param y2 Y component of vector 2
285
+ /// @returns Angle in whole degrees [0, 180]; 0 for zero-length inputs
286
+ /// @example
287
+ /// angle_between(1000, 0, 0, 1000) // 90
288
+ /// angle_between(1000, 0, -1000, 0) // 180
262
289
  fn angle_between(x1: int, y1: int, x2: int, y2: int) -> int {
263
290
  let nx1: int = normalize2d_x(x1, y1);
264
291
  let ny1: int = normalize2d_y(x1, y1);
@@ -272,13 +299,13 @@ fn angle_between(x1: int, y1: int, x2: int, y2: int) -> int {
272
299
  return atan2_fixed(c, d);
273
300
  }
274
301
 
275
- // Clamp a 2D point to lie within a circle of radius r centred at origin.
276
- // r is in the same units as x, y (raw block coords, NOT fixed-point).
277
- // Returns the clamped x component.
278
- // Note: keep x, y < ~2000 to avoid overflow in normalize2d_x (x * 10^6).
279
- //
280
- // clamp_circle_x(3, 4, 10) == 3 (point at dist 5, inside r=10)
281
- // clamp_circle_x(600, 0, 500) == 500
302
+ /// X component of the point (x, y) clamped to a circle of radius r centred at the origin.
303
+ /// Keep |x|, |y| < ~2000 to avoid overflow in `normalize2d_x`.
304
+ /// @since 1.0.0
305
+ /// @param x X coordinate (raw block coords, not fixed-point)
306
+ /// @param y Y coordinate
307
+ /// @param r Circle radius in the same units as x/y
308
+ /// @returns Clamped X — clamp_circle_x(600, 0, 500) == 500
282
309
  fn clamp_circle_x(x: int, y: int, r: int) -> int {
283
310
  // length2d_fixed returns dist × 1000; compare with r × 1000
284
311
  let dist: int = length2d_fixed(x, y);
@@ -286,17 +313,23 @@ fn clamp_circle_x(x: int, y: int, r: int) -> int {
286
313
  return normalize2d_x(x, y) * r / 1000;
287
314
  }
288
315
 
289
- // Y component of circle clamp.
290
- // clamp_circle_y(0, 600, 500) == 500
316
+ /// Y component of the point (x, y) clamped to a circle of radius r centred at the origin.
317
+ /// @since 1.0.0
318
+ /// @param x X coordinate
319
+ /// @param y Y coordinate
320
+ /// @param r Circle radius
321
+ /// @returns Clamped Y — clamp_circle_y(0, 600, 500) == 500
291
322
  fn clamp_circle_y(x: int, y: int, r: int) -> int {
292
323
  let dist: int = length2d_fixed(x, y);
293
324
  if (dist <= r * 1000) { return y; }
294
325
  return normalize2d_y(x, y) * r / 1000;
295
326
  }
296
327
 
297
- // Newton's method integer square root (alternative to isqrt).
298
- // Converges quadratically; validates our while loop + division.
299
- // newton_sqrt(25) == 5, newton_sqrt(100) == 10, newton_sqrt(2) == 1
328
+ /// Integer square root via Newton's method (alternative to `isqrt`).
329
+ /// Converges quadratically; useful for validating while-loop + division logic.
330
+ /// @since 1.0.0
331
+ /// @param n Non-negative integer
332
+ /// @returns ⌊√n⌋ — newton_sqrt(25) == 5, newton_sqrt(100) == 10
300
333
  fn newton_sqrt(n: int) -> int {
301
334
  if (n <= 0) { return 0; }
302
335
  if (n == 1) { return 1; }
@@ -311,11 +344,15 @@ fn newton_sqrt(n: int) -> int {
311
344
 
312
345
  // ─── Category 3 (cont.): Higher-order Bezier curves ─────────────────────────
313
346
 
314
- // Quartic Bezier: 5-point curve using De Casteljau's algorithm.
315
- // t in [0, 1000].
316
- // bezier_quartic(0, 250, 500, 750, 1000, 0) == 0 (t=0: start)
317
- // bezier_quartic(0, 250, 500, 750, 1000, 1000) == 1000 (t=1: end)
318
- // bezier_quartic(0, 250, 500, 750, 1000, 500) == 500 (midpoint, uniform pts)
347
+ /// Quartic (5-point) Bezier curve evaluated at t using De Casteljau's algorithm.
348
+ /// @since 1.0.0
349
+ /// @param p0 Control point 0 (start)
350
+ /// @param p1 Control point 1
351
+ /// @param p2 Control point 2
352
+ /// @param p3 Control point 3
353
+ /// @param p4 Control point 4 (end)
354
+ /// @param t Parameter × 1000 (0 = start, 1000 = end)
355
+ /// @returns Curve value at t
319
356
  fn bezier_quartic(p0: int, p1: int, p2: int, p3: int, p4: int, t: int) -> int {
320
357
  let m0: int = lerp(p0, p1, t);
321
358
  let m1: int = lerp(p1, p2, t);
@@ -329,12 +366,13 @@ fn bezier_quartic(p0: int, p1: int, p2: int, p3: int, p4: int, t: int) -> int {
329
366
  return lerp(o0, o1, t);
330
367
  }
331
368
 
332
- // bezier_n(pts, n, t): N-order Bezier curve via De Casteljau's algorithm.
333
- // pts: array of n control points (int[], will be modified in-place).
334
- // t in [0, 1000].
335
- // WARNING: modifies pts in-place. Call bezier_n_safe if you need to preserve pts.
336
- // bezier_n([0,333,667,1000], 4, 0) == 0 (t=0: returns pts[0])
337
- // bezier_n([0,333,667,1000], 4, 1000) == 1000 (t=1: returns pts[n-1])
369
+ /// Arbitrary-degree Bezier curve via De Casteljau's algorithm.
370
+ /// Modifies `pts` in-place. Use `bezier_n_safe` to preserve the original array.
371
+ /// @since 1.0.0
372
+ /// @param pts Array of n control points (modified in-place during evaluation)
373
+ /// @param n Number of control points
374
+ /// @param t Parameter × 1000 (0 = start, 1000 = end)
375
+ /// @returns Curve value at t
338
376
  fn bezier_n(pts: int[], n: int, t: int) -> int {
339
377
  let r: int = 0;
340
378
  while (r < n - 1) {
@@ -348,18 +386,22 @@ fn bezier_n(pts: int[], n: int, t: int) -> int {
348
386
  return pts[0];
349
387
  }
350
388
 
351
- // bezier_n_safe(pts, work, n, t): N-order Bezier, non-destructive.
352
- // Copies pts into work (length >= n) then runs bezier_n on work.
353
- // pts is not modified.
389
+ /// Non-destructive arbitrary-degree Bezier curve. Copies `pts` into `work` then evaluates.
390
+ /// @since 1.0.0
391
+ /// @param pts Array of n control points (not modified)
392
+ /// @param work Working buffer of length ≥ n (will be overwritten)
393
+ /// @param n Number of control points
394
+ /// @param t Parameter × 1000 (0 = start, 1000 = end)
395
+ /// @returns Curve value at t
354
396
  fn bezier_n_safe(pts: int[], work: int[], n: int, t: int) -> int {
355
397
  bigint_copy(pts, work, n);
356
398
  return bezier_n(work, n, t);
357
399
  }
358
400
 
359
- // Digital root: repeatedly sum digits until single digit.
360
- // digital_root(493) == 7 (4+9+3=16 → 1+6=7)
361
- // digital_root(9) == 9
362
- // digital_root(0) == 0
401
+ /// Digital root: repeatedly sum digits until a single digit remains.
402
+ /// @since 1.0.0
403
+ /// @param n Non-negative integer
404
+ /// @returns Single-digit root — digital_root(493) == 7, digital_root(0) == 0
363
405
  fn digital_root(n: int) -> int {
364
406
  if (n == 0) { return 0; }
365
407
  let r: int = n % 9;
@@ -367,11 +409,139 @@ fn digital_root(n: int) -> int {
367
409
  return r;
368
410
  }
369
411
 
370
- // Ulam spiral ring number: which concentric square ring is n on?
371
- // Ring 0: n=1; Ring 1: n=2..9 (3×3 square); Ring 2: n=10..25 (5×5); etc.
372
- // Formula: floor((isqrt(n-1) + 1) / 2)
373
- // spiral_ring(1) == 0, spiral_ring(9) == 1, spiral_ring(25) == 2
412
+ /// Ulam spiral ring number: which concentric square ring contains n?
413
+ /// Ring 0: n=1; Ring 1: n=2..9 (3×3); Ring 2: n=10..25 (5×5); etc.
414
+ /// @since 1.0.0
415
+ /// @param n Positive integer
416
+ /// @returns Ring index — spiral_ring(1) == 0, spiral_ring(9) == 1, spiral_ring(25) == 2
374
417
  fn spiral_ring(n: int) -> int {
375
418
  if (n <= 1) { return 0; }
376
419
  return (isqrt(n - 1) + 1) / 2;
377
420
  }
421
+
422
+ // ── Statistics ────────────────────────────────────────────────────────────────
423
+
424
+ /// Median of n integers. Sorts a copy of the array; the original is not modified.
425
+ /// For odd n returns the middle value × 1000. For even n returns the average × 1000.
426
+ /// @since 1.1.0
427
+ /// @param arr Input array (not modified)
428
+ /// @param work Working buffer of length ≥ n (will be overwritten)
429
+ /// @param n Number of elements (must be ≥ 1)
430
+ /// @returns Median × 1000
431
+ fn median(arr: int[], work: int[], n: int) -> int {
432
+ bigint_copy(arr, work, n);
433
+ insertion_sort(work, n);
434
+ if (n % 2 == 1) {
435
+ return work[(n - 1) / 2] * 1000;
436
+ }
437
+ return (work[n / 2 - 1] + work[n / 2]) * 500;
438
+ }
439
+
440
+ /// Most frequent element (mode) in arr[0..n). Tie-breaks toward the smallest value.
441
+ /// @since 1.1.0
442
+ /// @param arr Input array (not modified)
443
+ /// @param work Working buffer of length ≥ n (will be overwritten)
444
+ /// @param n Number of elements (must be ≥ 1)
445
+ /// @returns The modal value
446
+ fn mode(arr: int[], work: int[], n: int) -> int {
447
+ if (n <= 0) { return 0; }
448
+ bigint_copy(arr, work, n);
449
+ insertion_sort(work, n);
450
+ let best_val: int = work[0];
451
+ let best_cnt: int = 1;
452
+ let cur_val: int = work[0];
453
+ let cur_cnt: int = 1;
454
+ let i: int = 1;
455
+ while (i < n) {
456
+ if (work[i] == cur_val) {
457
+ cur_cnt = cur_cnt + 1;
458
+ } else {
459
+ cur_val = work[i];
460
+ cur_cnt = 1;
461
+ }
462
+ if (cur_cnt > best_cnt) {
463
+ best_cnt = cur_cnt;
464
+ best_val = cur_val;
465
+ }
466
+ i = i + 1;
467
+ }
468
+ return best_val;
469
+ }
470
+
471
+ /// Arithmetic mean as fixed-point × 1000.
472
+ /// @since 1.1.0
473
+ /// @param arr Input array of integers
474
+ /// @param n Number of elements (must be ≥ 1)
475
+ /// @returns sum(arr) × 1000 / n; 0 for empty array
476
+ fn mean_fx(arr: int[], n: int) -> int {
477
+ if (n <= 0) { return 0; }
478
+ let sum: int = 0;
479
+ let i: int = 0;
480
+ while (i < n) {
481
+ sum = sum + arr[i];
482
+ i = i + 1;
483
+ }
484
+ return sum * 1000 / n;
485
+ }
486
+
487
+ /// Population standard deviation as fixed-point × 1000.
488
+ /// Uses integer arithmetic; values must fit in int32 before squaring deviations.
489
+ /// @since 1.1.0
490
+ /// @param arr Input array of integers
491
+ /// @param n Number of elements (must be ≥ 2)
492
+ /// @returns √(Σ(xᵢ−mean)² / n) × 1000; 0 for n ≤ 1
493
+ fn std_dev_fx(arr: int[], n: int) -> int {
494
+ if (n <= 1) { return 0; }
495
+ let mean: int = mean_fx(arr, n) / 1000; // integer mean (rounds down)
496
+ let sum_sq: int = 0;
497
+ let i: int = 0;
498
+ while (i < n) {
499
+ let d: int = arr[i] - mean;
500
+ sum_sq = sum_sq + d * d;
501
+ i = i + 1;
502
+ }
503
+ // variance ×1000² to keep precision before sqrt
504
+ let var_fx: int = sum_sq * 1000 / n;
505
+ return newton_sqrt(var_fx);
506
+ }
507
+
508
+ // ── Interpolation ─────────────────────────────────────────────────────────────
509
+
510
+ /// Cubic Hermite spline interpolation between two endpoints with explicit tangents.
511
+ /// @since 1.1.0
512
+ /// @param p0 Start value
513
+ /// @param p1 End value
514
+ /// @param m0 Tangent at p0
515
+ /// @param m1 Tangent at p1
516
+ /// @param t Parameter × 1000 (0 = p0, 1000 = p1)
517
+ /// @returns Interpolated value (same scale as p0/p1)
518
+ fn hermite_spline(p0: int, p1: int, m0: int, m1: int, t: int) -> int {
519
+ let t2: int = t * t / 1000; // t² ×1000
520
+ let t3: int = t2 * t / 1000; // t³ ×1000
521
+
522
+ // h00 = (2t³ − 3t² + 1000) / 1000
523
+ let h00: int = (2 * t3 - 3 * t2 + 1000000) / 1000;
524
+ // h10 = (t³ − 2t² + t) / 1000
525
+ let h10: int = (t3 - 2 * t2 + t * 1000) / 1000000;
526
+ // h01 = (−2t³ + 3t²) / 1000
527
+ let h01: int = (0 - 2 * t3 + 3 * t2) / 1000;
528
+ // h11 = (t³ − t²) / 1000
529
+ let h11: int = (t3 - t2) / 1000000;
530
+
531
+ return p0 * h00 / 1000 + m0 * h10 + p1 * h01 / 1000 + m1 * h11;
532
+ }
533
+
534
+ /// Catmull-Rom spline: interpolates between p1 and p2 with tangents derived from neighbours.
535
+ /// Tangents: m1 = (p2 − p0) / 2, m2 = (p3 − p1) / 2.
536
+ /// @since 1.1.0
537
+ /// @param p0 Point before the segment start
538
+ /// @param p1 Segment start
539
+ /// @param p2 Segment end
540
+ /// @param p3 Point after the segment end
541
+ /// @param t Parameter × 1000 (0 = p1, 1000 = p2)
542
+ /// @returns Interpolated value between p1 and p2
543
+ fn catmull_rom(p0: int, p1: int, p2: int, p3: int, t: int) -> int {
544
+ let m1: int = (p2 - p0) / 2;
545
+ let m2: int = (p3 - p1) / 2;
546
+ return hermite_spline(p1, p2, m1, m2, t);
547
+ }