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.
- package/.github/workflows/ci.yml +11 -0
- package/CHANGELOG.md +18 -9
- package/README-benchmarks.md +48 -0
- package/README-vscode-test.md +251 -0
- package/RELEASE_NOTES.md +74 -0
- package/ROADMAP.md +131 -167
- package/benchmarks/_shared.ts +468 -0
- package/benchmarks/baseline.json +2816 -0
- package/benchmarks/baseline.md +13 -0
- package/benchmarks/compiler-perf.report.json +207 -0
- package/benchmarks/compiler-perf.ts +76 -0
- package/benchmarks/results.md +13 -0
- package/benchmarks/stdlib-complexity.report.json +2606 -0
- package/benchmarks/stdlib-complexity.ts +54 -0
- package/benchmarks/stdlib-size.md +57 -0
- package/benchmarks/stdlib-size.ts +91 -0
- package/coverage-report.md +177 -0
- package/dist/src/__tests__/budget.test.js +4 -0
- package/dist/src/__tests__/cache/cache-behavior.test.d.ts +10 -0
- package/dist/src/__tests__/cache/cache-behavior.test.js +425 -0
- package/dist/src/__tests__/cache-extra.test.d.ts +5 -0
- package/dist/src/__tests__/cache-extra.test.js +211 -0
- package/dist/src/__tests__/cli-init.test.d.ts +1 -0
- package/dist/src/__tests__/cli-init.test.js +97 -0
- package/dist/src/__tests__/cli-publish.test.d.ts +9 -0
- package/dist/src/__tests__/cli-publish.test.js +189 -0
- package/dist/src/__tests__/cli.test.js +76 -0
- package/dist/src/__tests__/compile-preprocess.test.d.ts +11 -0
- package/dist/src/__tests__/compile-preprocess.test.js +328 -0
- package/dist/src/__tests__/compiler/break-stmt.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/break-stmt.test.js +58 -0
- package/dist/src/__tests__/compiler/const-decl.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/const-decl.test.js +123 -0
- package/dist/src/__tests__/compiler/continue-stmt.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/continue-stmt.test.js +67 -0
- package/dist/src/__tests__/compiler/coroutine-extended.test.d.ts +17 -0
- package/dist/src/__tests__/compiler/coroutine-extended.test.js +565 -0
- package/dist/src/__tests__/compiler/deprecated.test.d.ts +4 -0
- package/dist/src/__tests__/compiler/deprecated.test.js +285 -0
- package/dist/src/__tests__/compiler/do-while.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/do-while.test.js +120 -0
- package/dist/src/__tests__/compiler/enum-payload.test.d.ts +9 -0
- package/dist/src/__tests__/compiler/enum-payload.test.js +272 -0
- package/dist/src/__tests__/compiler/interface.test.d.ts +10 -0
- package/dist/src/__tests__/compiler/interface.test.js +258 -0
- package/dist/src/__tests__/compiler/labeled-loops.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/labeled-loops.test.js +263 -0
- package/dist/src/__tests__/compiler/match-string.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/match-string.test.js +43 -0
- package/dist/src/__tests__/compiler/memoize.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/memoize.test.js +113 -0
- package/dist/src/__tests__/compiler/method-chain.test.d.ts +5 -0
- package/dist/src/__tests__/compiler/method-chain.test.js +115 -0
- package/dist/src/__tests__/compiler/module-import.test.d.ts +12 -0
- package/dist/src/__tests__/compiler/module-import.test.js +261 -0
- package/dist/src/__tests__/compiler/option-extensions.test.d.ts +6 -0
- package/dist/src/__tests__/compiler/option-extensions.test.js +191 -0
- package/dist/src/__tests__/compiler/profile-decorator.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/profile-decorator.test.js +69 -0
- package/dist/src/__tests__/compiler/string-advanced.test.d.ts +7 -0
- package/dist/src/__tests__/compiler/string-advanced.test.js +281 -0
- package/dist/src/__tests__/compiler/struct-extends.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/struct-extends.test.js +95 -0
- package/dist/src/__tests__/compiler/throttle-retry.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/throttle-retry.test.js +166 -0
- package/dist/src/__tests__/compiler/tuple-type.test.d.ts +10 -0
- package/dist/src/__tests__/compiler/tuple-type.test.js +229 -0
- package/dist/src/__tests__/compiler/watch-decorator.test.d.ts +1 -0
- package/dist/src/__tests__/compiler/watch-decorator.test.js +65 -0
- package/dist/src/__tests__/config/project-config.test.d.ts +1 -0
- package/dist/src/__tests__/config/project-config.test.js +199 -0
- package/dist/src/__tests__/config-decorator.test.d.ts +8 -0
- package/dist/src/__tests__/config-decorator.test.js +142 -0
- package/dist/src/__tests__/diagnostics-extra.test.d.ts +6 -0
- package/dist/src/__tests__/diagnostics-extra.test.js +132 -0
- package/dist/src/__tests__/emit/compile-branches.test.d.ts +1 -0
- package/dist/src/__tests__/emit/compile-branches.test.js +123 -0
- package/dist/src/__tests__/emit/compile-coverage.test.d.ts +25 -0
- package/dist/src/__tests__/emit/compile-coverage.test.js +617 -0
- package/dist/src/__tests__/emit/compile-extra-branches.test.d.ts +12 -0
- package/dist/src/__tests__/emit/compile-extra-branches.test.js +225 -0
- package/dist/src/__tests__/emit/compile-mocked-branches.test.d.ts +0 -0
- package/dist/src/__tests__/emit/compile-mocked-branches.test.js +238 -0
- package/dist/src/__tests__/emit/execute-chain.test.d.ts +10 -0
- package/dist/src/__tests__/emit/execute-chain.test.js +94 -0
- package/dist/src/__tests__/emit/index.test.js +2 -1
- package/dist/src/__tests__/emit/modules-branches.test.d.ts +1 -0
- package/dist/src/__tests__/emit/modules-branches.test.js +88 -0
- package/dist/src/__tests__/emit/modules-coverage.test.d.ts +15 -0
- package/dist/src/__tests__/emit/modules-coverage.test.js +221 -0
- package/dist/src/__tests__/emit/modules-errors.test.d.ts +12 -0
- package/dist/src/__tests__/emit/modules-errors.test.js +169 -0
- package/dist/src/__tests__/emit/modules-rewrite.test.d.ts +17 -0
- package/dist/src/__tests__/emit/modules-rewrite.test.js +204 -0
- package/dist/src/__tests__/emit/source-map.test.d.ts +1 -0
- package/dist/src/__tests__/emit/source-map.test.js +167 -0
- package/dist/src/__tests__/enum.test.js +9 -4
- package/dist/src/__tests__/error-recovery.test.d.ts +7 -0
- package/dist/src/__tests__/error-recovery.test.js +217 -0
- package/dist/src/__tests__/events-types-extra.test.d.ts +10 -0
- package/dist/src/__tests__/events-types-extra.test.js +91 -0
- package/dist/src/__tests__/events-types.test.d.ts +4 -0
- package/dist/src/__tests__/events-types.test.js +56 -0
- package/dist/src/__tests__/formatter.test.js +13 -5
- package/dist/src/__tests__/hir/lower-extra.test.d.ts +9 -0
- package/dist/src/__tests__/hir/lower-extra.test.js +140 -0
- package/dist/src/__tests__/hir/monomorphize-extra.test.d.ts +15 -0
- package/dist/src/__tests__/hir/monomorphize-extra.test.js +200 -0
- package/dist/src/__tests__/hir/monomorphize-extra2.test.d.ts +16 -0
- package/dist/src/__tests__/hir/monomorphize-extra2.test.js +316 -0
- package/dist/src/__tests__/incremental.test.js +10 -2
- package/dist/src/__tests__/index-extra.test.d.ts +10 -0
- package/dist/src/__tests__/index-extra.test.js +71 -0
- package/dist/src/__tests__/lexer.test.js +2 -2
- package/dist/src/__tests__/lint/rules.test.d.ts +5 -0
- package/dist/src/__tests__/lint/rules.test.js +208 -0
- package/dist/src/__tests__/lir/lower.test.js +29 -0
- package/dist/src/__tests__/lir/verify.test.js +30 -0
- package/dist/src/__tests__/lsp/completion.test.d.ts +7 -0
- package/dist/src/__tests__/lsp/completion.test.js +583 -0
- package/dist/src/__tests__/lsp/definition.test.d.ts +7 -0
- package/dist/src/__tests__/lsp/definition.test.js +454 -0
- package/dist/src/__tests__/lsp/diagnostics.test.d.ts +10 -0
- package/dist/src/__tests__/lsp/diagnostics.test.js +98 -0
- package/dist/src/__tests__/lsp/hover-docs.test.d.ts +10 -0
- package/dist/src/__tests__/lsp/hover-docs.test.js +210 -0
- package/dist/src/__tests__/lsp.test.js +4 -1
- package/dist/src/__tests__/mc-integration/item-entity-events.test.js +4 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +4 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.d.ts +13 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1227 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.d.ts +13 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1509 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.d.ts +14 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1374 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.d.ts +10 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +759 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.d.ts +13 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +855 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage.test.js +4 -0
- package/dist/src/__tests__/mc-integration/syntax-coverage.test.js +4 -0
- package/dist/src/__tests__/mc-validator-coverage.test.d.ts +13 -0
- package/dist/src/__tests__/mc-validator-coverage.test.js +296 -0
- package/dist/src/__tests__/mc-validator-extra.test.d.ts +13 -0
- package/dist/src/__tests__/mc-validator-extra.test.js +245 -0
- package/dist/src/__tests__/mir/lower-extra.test.d.ts +20 -0
- package/dist/src/__tests__/mir/lower-extra.test.js +361 -0
- package/dist/src/__tests__/mir/lower-extra2.test.d.ts +17 -0
- package/dist/src/__tests__/mir/lower-extra2.test.js +317 -0
- package/dist/src/__tests__/mir/lower-extra3.test.d.ts +19 -0
- package/dist/src/__tests__/mir/lower-extra3.test.js +249 -0
- package/dist/src/__tests__/mir/lower-extra4.test.d.ts +23 -0
- package/dist/src/__tests__/mir/lower-extra4.test.js +606 -0
- package/dist/src/__tests__/mir/lower-extra5.test.d.ts +25 -0
- package/dist/src/__tests__/mir/lower-extra5.test.js +543 -0
- package/dist/src/__tests__/mir/lower-extra6.test.d.ts +16 -0
- package/dist/src/__tests__/mir/lower-extra6.test.js +471 -0
- package/dist/src/__tests__/mir/lower-extra7.test.d.ts +35 -0
- package/dist/src/__tests__/mir/lower-extra7.test.js +921 -0
- package/dist/src/__tests__/mir/lower-extra8.test.d.ts +19 -0
- package/dist/src/__tests__/mir/lower-extra8.test.js +626 -0
- package/dist/src/__tests__/mir/lower-extra9.test.d.ts +14 -0
- package/dist/src/__tests__/mir/lower-extra9.test.js +717 -0
- package/dist/src/__tests__/optimizer/auto-inline.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer/auto-inline.test.js +176 -0
- package/dist/src/__tests__/optimizer/cse.test.d.ts +4 -0
- package/dist/src/__tests__/optimizer/cse.test.js +178 -0
- package/dist/src/__tests__/optimizer/inline_fn.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer/inline_fn.test.js +221 -0
- package/dist/src/__tests__/optimizer/licm.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer/licm.test.js +244 -0
- package/dist/src/__tests__/optimizer/optimizer-extended.test.d.ts +12 -0
- package/dist/src/__tests__/optimizer/optimizer-extended.test.js +993 -0
- package/dist/src/__tests__/optimizer/strength-reduction.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer/strength-reduction.test.js +86 -0
- package/dist/src/__tests__/optimizer/tco.test.d.ts +14 -0
- package/dist/src/__tests__/optimizer/tco.test.js +203 -0
- package/dist/src/__tests__/parser-coverage.test.d.ts +25 -0
- package/dist/src/__tests__/parser-coverage.test.js +491 -0
- package/dist/src/__tests__/parser-extra.test.d.ts +6 -0
- package/dist/src/__tests__/parser-extra.test.js +451 -0
- package/dist/src/__tests__/parser.test.js +12 -0
- package/dist/src/__tests__/repl-extra.test.d.ts +13 -0
- package/dist/src/__tests__/repl-extra.test.js +174 -0
- package/dist/src/__tests__/repl-server-extra.test.d.ts +10 -0
- package/dist/src/__tests__/repl-server-extra.test.js +161 -0
- package/dist/src/__tests__/repl-server.test.d.ts +6 -0
- package/dist/src/__tests__/repl-server.test.js +146 -0
- package/dist/src/__tests__/runtime-extra.test.d.ts +15 -0
- package/dist/src/__tests__/runtime-extra.test.js +732 -0
- package/dist/src/__tests__/singleton-decorator.test.d.ts +11 -0
- package/dist/src/__tests__/singleton-decorator.test.js +260 -0
- package/dist/src/__tests__/sourcemap.test.js +1 -1
- package/dist/src/__tests__/stdlib/advanced.test.d.ts +5 -0
- package/dist/src/__tests__/stdlib/advanced.test.js +301 -0
- package/dist/src/__tests__/stdlib/bigint.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/bigint.test.js +83 -0
- package/dist/src/__tests__/stdlib/bits.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/bits.test.js +96 -0
- package/dist/src/__tests__/stdlib/bossbar.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/bossbar.test.js +72 -0
- package/dist/src/__tests__/stdlib/color.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/color.test.js +84 -0
- package/dist/src/__tests__/stdlib/combat.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/combat.test.js +64 -0
- package/dist/src/__tests__/stdlib/cooldown.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/cooldown.test.js +64 -0
- package/dist/src/__tests__/stdlib/dialog.test.js +15 -7
- package/dist/src/__tests__/stdlib/ecs.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/ecs.test.js +81 -0
- package/dist/src/__tests__/stdlib/effects.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/effects.test.js +72 -0
- package/dist/src/__tests__/stdlib/events.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/events.test.js +55 -0
- package/dist/src/__tests__/stdlib/expr.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/expr.test.js +77 -0
- package/dist/src/__tests__/stdlib/fft.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/fft.test.js +82 -0
- package/dist/src/__tests__/stdlib/graph.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/graph.test.js +102 -0
- package/dist/src/__tests__/stdlib/interactions.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/interactions.test.js +60 -0
- package/dist/src/__tests__/stdlib/inventory.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/inventory.test.js +68 -0
- package/dist/src/__tests__/stdlib/linalg.test.d.ts +5 -0
- package/dist/src/__tests__/stdlib/linalg.test.js +78 -0
- package/dist/src/__tests__/stdlib/map.test.d.ts +1 -0
- package/dist/src/__tests__/stdlib/map.test.js +84 -0
- package/dist/src/__tests__/stdlib/math.test.js +19 -6
- package/dist/src/__tests__/stdlib/math_hp.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/math_hp.test.js +80 -0
- package/dist/src/__tests__/stdlib/mobs.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/mobs.test.js +61 -0
- package/dist/src/__tests__/stdlib/noise.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/noise.test.js +73 -0
- package/dist/src/__tests__/stdlib/ode.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/ode.test.js +68 -0
- package/dist/src/__tests__/stdlib/parabola.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/parabola.test.js +77 -0
- package/dist/src/__tests__/stdlib/particles.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/particles.test.js +68 -0
- package/dist/src/__tests__/stdlib/physics.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/physics.test.js +76 -0
- package/dist/src/__tests__/stdlib/player.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/player.test.js +64 -0
- package/dist/src/__tests__/stdlib/quaternion.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/quaternion.test.js +73 -0
- package/dist/src/__tests__/stdlib/queue.test.d.ts +1 -0
- package/dist/src/__tests__/stdlib/queue.test.js +97 -0
- package/dist/src/__tests__/stdlib/random.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/random.test.js +76 -0
- package/dist/src/__tests__/stdlib/result.test.d.ts +12 -0
- package/dist/src/__tests__/stdlib/result.test.js +329 -0
- package/dist/src/__tests__/stdlib/scheduler.test.js +19 -8
- package/dist/src/__tests__/stdlib/set_int.test.d.ts +1 -0
- package/dist/src/__tests__/stdlib/set_int.test.js +88 -0
- package/dist/src/__tests__/stdlib/sets.test.d.ts +6 -0
- package/dist/src/__tests__/stdlib/sets.test.js +60 -0
- package/dist/src/__tests__/stdlib/signal.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/signal.test.js +84 -0
- package/dist/src/__tests__/stdlib/spawn.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/spawn.test.js +68 -0
- package/dist/src/__tests__/stdlib/string.test.d.ts +12 -0
- package/dist/src/__tests__/stdlib/string.test.js +231 -0
- package/dist/src/__tests__/stdlib/strings.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/strings.test.js +83 -0
- package/dist/src/__tests__/stdlib/tags.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/tags.test.js +57 -0
- package/dist/src/__tests__/stdlib/teams.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/teams.test.js +72 -0
- package/dist/src/__tests__/stdlib/timer.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/timer.test.js +79 -0
- package/dist/src/__tests__/stdlib/vec.test.d.ts +5 -0
- package/dist/src/__tests__/stdlib/vec.test.js +94 -0
- package/dist/src/__tests__/stdlib/world.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib/world.test.js +72 -0
- package/dist/src/__tests__/struct-display.test.d.ts +1 -0
- package/dist/src/__tests__/struct-display.test.js +64 -0
- package/dist/src/__tests__/test-framework/runner.test.d.ts +10 -0
- package/dist/src/__tests__/test-framework/runner.test.js +193 -0
- package/dist/src/__tests__/tuner/adapters.test.d.ts +14 -0
- package/dist/src/__tests__/tuner/adapters.test.js +194 -0
- package/dist/src/__tests__/tuner/simulator-extra.test.d.ts +4 -0
- package/dist/src/__tests__/tuner/simulator-extra.test.js +193 -0
- package/dist/src/__tests__/typechecker-coverage.test.d.ts +30 -0
- package/dist/src/__tests__/typechecker-coverage.test.js +627 -0
- package/dist/src/__tests__/typechecker.test.js +3 -3
- package/dist/src/__tests__/watch-decorator.test.d.ts +1 -0
- package/dist/src/__tests__/watch-decorator.test.js +54 -0
- package/dist/src/ast/types.d.ts +102 -3
- package/dist/src/cache/incremental.d.ts +13 -14
- package/dist/src/cache/incremental.js +106 -89
- package/dist/src/cache/index.d.ts +8 -2
- package/dist/src/cache/index.js +18 -6
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/cli.js +466 -17
- package/dist/src/config/project-config.d.ts +29 -0
- package/dist/src/config/project-config.js +180 -0
- package/dist/src/diagnostics/index.d.ts +9 -0
- package/dist/src/diagnostics/index.js +18 -1
- package/dist/src/emit/compile.d.ts +10 -0
- package/dist/src/emit/compile.js +395 -50
- package/dist/src/emit/index.d.ts +40 -0
- package/dist/src/emit/index.js +307 -14
- package/dist/src/emit/modules.js +21 -3
- package/dist/src/emit/sourcemap.d.ts +23 -27
- package/dist/src/emit/sourcemap.js +52 -30
- package/dist/src/formatter/index.js +33 -8
- package/dist/src/hir/deprecated.d.ts +13 -0
- package/dist/src/hir/deprecated.js +218 -0
- package/dist/src/hir/lower.js +114 -8
- package/dist/src/hir/monomorphize.js +22 -2
- package/dist/src/hir/types.d.ts +65 -1
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +18 -3
- package/dist/src/lexer/index.d.ts +2 -1
- package/dist/src/lexer/index.js +39 -3
- package/dist/src/lint/index.d.ts +45 -0
- package/dist/src/lint/index.js +930 -0
- package/dist/src/lir/lower.js +29 -2
- package/dist/src/lir/types.d.ts +2 -0
- package/dist/src/lsp/server.js +92 -5
- package/dist/src/mir/lower.js +775 -34
- package/dist/src/mir/macro.js +36 -2
- package/dist/src/mir/types.d.ts +12 -0
- package/dist/src/mir/verify.js +9 -0
- package/dist/src/optimizer/auto-inline.d.ts +2 -0
- package/dist/src/optimizer/auto-inline.js +67 -0
- package/dist/src/optimizer/cse.d.ts +20 -0
- package/dist/src/optimizer/cse.js +234 -0
- package/dist/src/optimizer/inline.d.ts +26 -0
- package/dist/src/optimizer/inline.js +286 -0
- package/dist/src/optimizer/interprocedural.js +4 -0
- package/dist/src/optimizer/licm.d.ts +32 -0
- package/dist/src/optimizer/licm.js +371 -0
- package/dist/src/optimizer/pipeline.js +12 -2
- package/dist/src/optimizer/strength_reduction.d.ts +15 -0
- package/dist/src/optimizer/strength_reduction.js +90 -0
- package/dist/src/optimizer/tco.d.ts +53 -0
- package/dist/src/optimizer/tco.js +238 -0
- package/dist/src/parser/index.d.ts +32 -0
- package/dist/src/parser/index.js +421 -59
- package/dist/src/repl-server.d.ts +13 -0
- package/dist/src/repl-server.js +127 -0
- package/dist/src/structs/expand.d.ts +15 -0
- package/dist/src/structs/expand.js +46 -0
- package/dist/src/testing/runner.d.ts +40 -0
- package/dist/src/testing/runner.js +237 -0
- package/dist/src/typechecker/index.d.ts +3 -0
- package/dist/src/typechecker/index.js +254 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/doc-drafts/redscript-docs/docs/en/stdlib/graph.md +104 -0
- package/doc-drafts/redscript-docs/docs/en/stdlib/parabola.md +113 -0
- package/doc-drafts/redscript-docs/docs/en/stdlib/pathfind.md +104 -0
- package/doc-drafts/redscript-docs/docs/en/stdlib/physics.md +134 -0
- package/doc-drafts/redscript-docs/docs/en/stdlib/quaternion.md +135 -0
- package/doc-drafts/redscript-docs/docs/zh/stdlib/graph.md +104 -0
- package/doc-drafts/redscript-docs/docs/zh/stdlib/parabola.md +113 -0
- package/doc-drafts/redscript-docs/docs/zh/stdlib/pathfind.md +104 -0
- package/doc-drafts/redscript-docs/docs/zh/stdlib/physics.md +134 -0
- package/doc-drafts/redscript-docs/docs/zh/stdlib/quaternion.md +135 -0
- package/docs/stdlib/result.md +156 -0
- package/docs/stdlib/result.zh.md +156 -0
- package/editors/vscode/fixtures/test.mcrs +7 -0
- package/editors/vscode/out/extension.js +2095 -225
- package/editors/vscode/out/lsp-server.js +519 -51
- package/editors/vscode/package-lock.json +9 -4
- package/editors/vscode/package.json +1 -1
- package/examples/display-demo.mcrs +64 -0
- package/examples/game/racing.mcrs +301 -0
- package/examples/game/tower_defense.mcrs +311 -0
- package/examples/math/physics_sim.mcrs +322 -0
- package/examples/rpg/boss_fight.mcrs +313 -0
- package/examples/rpg/health_system.mcrs +237 -0
- package/examples/rpg/inventory.mcrs +265 -0
- package/examples/util/debug_hud.mcrs +279 -0
- package/jest.config.js +10 -0
- package/package.json +12 -3
- package/playground/index.html +823 -0
- package/scripts/gen-docs.ts +533 -0
- package/scripts/update-redscript-docs-stdlib.sh +770 -0
- package/src/__tests__/budget.test.ts +5 -0
- package/src/__tests__/cache/cache-behavior.test.ts +480 -0
- package/src/__tests__/cache-extra.test.ts +199 -0
- package/src/__tests__/cli-docs.test.ts +77 -0
- package/src/__tests__/cli-init.test.ts +91 -0
- package/src/__tests__/cli-publish.test.ts +190 -0
- package/src/__tests__/cli.test.ts +117 -1
- package/src/__tests__/compile-preprocess.test.ts +366 -0
- package/src/__tests__/compiler/break-stmt.test.ts +66 -0
- package/src/__tests__/compiler/const-decl.test.ts +141 -0
- package/src/__tests__/compiler/continue-stmt.test.ts +81 -0
- package/src/__tests__/compiler/coroutine-extended.test.ts +723 -0
- package/src/__tests__/compiler/deprecated.test.ts +305 -0
- package/src/__tests__/compiler/do-while.test.ts +130 -0
- package/src/__tests__/compiler/enum-payload.test.ts +299 -0
- package/src/__tests__/compiler/interface.test.ts +287 -0
- package/src/__tests__/compiler/labeled-loops.test.ts +279 -0
- package/src/__tests__/compiler/match-string.test.ts +45 -0
- package/src/__tests__/compiler/memoize.test.ts +126 -0
- package/src/__tests__/compiler/method-chain.test.ts +121 -0
- package/src/__tests__/compiler/module-import.test.ts +240 -0
- package/src/__tests__/compiler/option-extensions.test.ts +207 -0
- package/src/__tests__/compiler/profile-decorator.test.ts +79 -0
- package/src/__tests__/compiler/string-advanced.test.ts +310 -0
- package/src/__tests__/compiler/struct-extends.test.ts +109 -0
- package/src/__tests__/compiler/throttle-retry.test.ts +191 -0
- package/src/__tests__/compiler/tuple-type.test.ts +263 -0
- package/src/__tests__/compiler/watch-decorator.test.ts +72 -0
- package/src/__tests__/config/project-config.test.ts +181 -0
- package/src/__tests__/config-decorator.test.ts +157 -0
- package/src/__tests__/diagnostics-extra.test.ts +155 -0
- package/src/__tests__/emit/compile-branches.test.ts +135 -0
- package/src/__tests__/emit/compile-coverage.test.ts +696 -0
- package/src/__tests__/emit/compile-extra-branches.test.ts +228 -0
- package/src/__tests__/emit/compile-mocked-branches.test.ts +249 -0
- package/src/__tests__/emit/compile.test.ts +6 -1
- package/src/__tests__/emit/execute-chain.test.ts +114 -0
- package/src/__tests__/emit/index.test.ts +2 -1
- package/src/__tests__/emit/modules-branches.test.ts +90 -0
- package/src/__tests__/emit/modules-coverage.test.ts +241 -0
- package/src/__tests__/emit/modules-errors.test.ts +192 -0
- package/src/__tests__/emit/modules-rewrite.test.ts +232 -0
- package/src/__tests__/emit/source-map.test.ts +152 -0
- package/src/__tests__/enum.test.ts +9 -4
- package/src/__tests__/error-recovery.test.ts +226 -0
- package/src/__tests__/events-types-extra.test.ts +110 -0
- package/src/__tests__/events-types.test.ts +66 -0
- package/src/__tests__/formatter.test.ts +15 -5
- package/src/__tests__/generics.test.ts +16 -9
- package/src/__tests__/hir/lower-extra.test.ts +151 -0
- package/src/__tests__/hir/monomorphize-coverage.test.ts +432 -0
- package/src/__tests__/hir/monomorphize-extra.test.ts +220 -0
- package/src/__tests__/hir/monomorphize-extra2.test.ts +350 -0
- package/src/__tests__/impl.test.ts +12 -8
- package/src/__tests__/incremental.test.ts +10 -2
- package/src/__tests__/index-extra.test.ts +79 -0
- package/src/__tests__/lexer.test.ts +2 -2
- package/src/__tests__/lint/hir-coverage.test.ts +1716 -0
- package/src/__tests__/lint/rules-coverage.test.ts +598 -0
- package/src/__tests__/lint/rules.test.ts +230 -0
- package/src/__tests__/lir/lower.test.ts +33 -0
- package/src/__tests__/lir/verify.test.ts +33 -0
- package/src/__tests__/lsp/completion.test.ts +687 -0
- package/src/__tests__/lsp/definition.test.ts +499 -0
- package/src/__tests__/lsp/diagnostics.test.ts +108 -0
- package/src/__tests__/lsp/hover-docs.test.ts +222 -0
- package/src/__tests__/lsp.test.ts +4 -1
- package/src/__tests__/mc-integration/item-entity-events.test.ts +5 -0
- package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +5 -0
- package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1105 -0
- package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1366 -0
- package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1245 -0
- package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +755 -0
- package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +771 -0
- package/src/__tests__/mc-integration/stdlib-coverage.test.ts +5 -0
- package/src/__tests__/mc-integration/syntax-coverage.test.ts +5 -0
- package/src/__tests__/mc-validator-coverage.test.ts +325 -0
- package/src/__tests__/mc-validator-extra.test.ts +252 -0
- package/src/__tests__/mir/lower-extra.test.ts +402 -0
- package/src/__tests__/mir/lower-extra2.test.ts +348 -0
- package/src/__tests__/mir/lower-extra3.test.ts +277 -0
- package/src/__tests__/mir/lower-extra4.test.ts +636 -0
- package/src/__tests__/mir/lower-extra5.test.ts +612 -0
- package/src/__tests__/mir/lower-extra6.test.ts +520 -0
- package/src/__tests__/mir/lower-extra7.test.ts +1045 -0
- package/src/__tests__/mir/lower-extra8.test.ts +704 -0
- package/src/__tests__/mir/lower-extra9.test.ts +821 -0
- package/src/__tests__/optimizer/auto-inline.test.ts +206 -0
- package/src/__tests__/optimizer/cse.test.ts +195 -0
- package/src/__tests__/optimizer/inline_fn.test.ts +263 -0
- package/src/__tests__/optimizer/licm.test.ts +358 -0
- package/src/__tests__/optimizer/nbt-coalesce.test.ts +147 -0
- package/src/__tests__/optimizer/optimizer-extended.test.ts +1081 -0
- package/src/__tests__/optimizer/scoreboard-batch.test.ts +141 -0
- package/src/__tests__/optimizer/strength-reduction.test.ts +111 -0
- package/src/__tests__/optimizer/tco-coverage.test.ts +309 -0
- package/src/__tests__/optimizer/tco.test.ts +238 -0
- package/src/__tests__/option.test.ts +14 -7
- package/src/__tests__/parser-coverage.test.ts +576 -0
- package/src/__tests__/parser-extra.test.ts +531 -0
- package/src/__tests__/parser.test.ts +14 -0
- package/src/__tests__/repl-extra.test.ts +195 -0
- package/src/__tests__/repl-server-extra.test.ts +150 -0
- package/src/__tests__/repl-server.test.ts +122 -0
- package/src/__tests__/runtime-extra.test.ts +862 -0
- package/src/__tests__/singleton-decorator.test.ts +285 -0
- package/src/__tests__/sourcemap.test.ts +1 -1
- package/src/__tests__/stdlib/advanced.test.ts +312 -0
- package/src/__tests__/stdlib/bigint.test.ts +57 -0
- package/src/__tests__/stdlib/bits.test.ts +75 -0
- package/src/__tests__/stdlib/bossbar.test.ts +45 -0
- package/src/__tests__/stdlib/color.test.ts +60 -0
- package/src/__tests__/stdlib/combat.test.ts +35 -0
- package/src/__tests__/stdlib/cooldown.test.ts +35 -0
- package/src/__tests__/stdlib/dialog.test.ts +14 -6
- package/src/__tests__/stdlib/ecs.test.ts +54 -0
- package/src/__tests__/stdlib/effects.test.ts +45 -0
- package/src/__tests__/stdlib/events.test.ts +23 -0
- package/src/__tests__/stdlib/expr.test.ts +48 -0
- package/src/__tests__/stdlib/fft.test.ts +54 -0
- package/src/__tests__/stdlib/graph.test.ts +77 -0
- package/src/__tests__/stdlib/interactions.test.ts +30 -0
- package/src/__tests__/stdlib/inventory.test.ts +40 -0
- package/src/__tests__/stdlib/linalg.test.ts +52 -0
- package/src/__tests__/stdlib/map.test.ts +55 -0
- package/src/__tests__/stdlib/math.test.ts +19 -5
- package/src/__tests__/stdlib/math_hp.test.ts +55 -0
- package/src/__tests__/stdlib/mobs.test.ts +40 -0
- package/src/__tests__/stdlib/noise.test.ts +46 -0
- package/src/__tests__/stdlib/ode.test.ts +40 -0
- package/src/__tests__/stdlib/parabola.test.ts +51 -0
- package/src/__tests__/stdlib/particles.test.ts +40 -0
- package/src/__tests__/stdlib/physics.test.ts +50 -0
- package/src/__tests__/stdlib/player.test.ts +35 -0
- package/src/__tests__/stdlib/quaternion.test.ts +46 -0
- package/src/__tests__/stdlib/queue.test.ts +73 -0
- package/src/__tests__/stdlib/random.test.ts +50 -0
- package/src/__tests__/stdlib/result.test.ts +326 -0
- package/src/__tests__/stdlib/scheduler.test.ts +18 -7
- package/src/__tests__/stdlib/set_int.test.ts +62 -0
- package/src/__tests__/stdlib/sets.test.ts +28 -0
- package/src/__tests__/stdlib/signal.test.ts +60 -0
- package/src/__tests__/stdlib/spawn.test.ts +40 -0
- package/src/__tests__/stdlib/string.test.ts +224 -0
- package/src/__tests__/stdlib/strings.test.ts +55 -0
- package/src/__tests__/stdlib/tags.test.ts +32 -0
- package/src/__tests__/stdlib/teams.test.ts +45 -0
- package/src/__tests__/stdlib/timer.test.ts +53 -0
- package/src/__tests__/stdlib/vec.test.ts +72 -0
- package/src/__tests__/stdlib/world.test.ts +45 -0
- package/src/__tests__/struct-display.test.ts +69 -0
- package/src/__tests__/test-framework/runner.test.ts +208 -0
- package/src/__tests__/tuner/adapters.test.ts +232 -0
- package/src/__tests__/tuner/simulator-extra.test.ts +222 -0
- package/src/__tests__/tuple.test.ts +11 -4
- package/src/__tests__/typechecker-coverage.test.ts +671 -0
- package/src/__tests__/typechecker.test.ts +4 -3
- package/src/__tests__/watch-decorator.test.ts +59 -0
- package/src/ast/types.ts +65 -3
- package/src/cache/incremental.ts +128 -99
- package/src/cache/index.ts +35 -8
- package/src/cli.ts +538 -29
- package/src/config/project-config.ts +176 -0
- package/src/diagnostics/index.ts +22 -0
- package/src/docs.ts +98 -0
- package/src/emit/compile.ts +408 -51
- package/src/emit/index.ts +366 -18
- package/src/emit/modules.ts +19 -3
- package/src/emit/sourcemap.ts +64 -43
- package/src/formatter/index.ts +35 -8
- package/src/hir/deprecated.ts +212 -0
- package/src/hir/lower.ts +128 -8
- package/src/hir/monomorphize.ts +24 -2
- package/src/hir/types.ts +26 -1
- package/src/index.ts +23 -3
- package/src/lexer/index.ts +45 -6
- package/src/lint/index.ts +922 -0
- package/src/lir/lower.ts +30 -2
- package/src/lir/types.ts +4 -0
- package/src/lsp/server.ts +100 -1
- package/src/mir/lower.ts +785 -40
- package/src/mir/macro.ts +30 -2
- package/src/mir/types.ts +13 -0
- package/src/mir/verify.ts +10 -2
- package/src/optimizer/auto-inline.ts +86 -0
- package/src/optimizer/copy_prop.ts +2 -2
- package/src/optimizer/coroutine.ts +3 -3
- package/src/optimizer/cse.ts +205 -0
- package/src/optimizer/dce.ts +2 -2
- package/src/optimizer/inline.ts +335 -0
- package/src/optimizer/interprocedural.ts +5 -1
- package/src/optimizer/licm.ts +454 -0
- package/src/optimizer/nbt-coalesce.ts +109 -0
- package/src/optimizer/pipeline.ts +16 -2
- package/src/optimizer/scoreboard-batch.ts +52 -0
- package/src/optimizer/strength_reduction.ts +95 -0
- package/src/optimizer/tco.ts +267 -0
- package/src/optimizer/unroll.ts +2 -2
- package/src/parser/index.ts +426 -53
- package/src/repl-server.ts +102 -0
- package/src/stdlib/advanced.mcrs +271 -101
- package/src/stdlib/bigint.mcrs +97 -11
- package/src/stdlib/bits.mcrs +75 -12
- package/src/stdlib/bossbar.mcrs +37 -8
- package/src/stdlib/calculus.mcrs +82 -26
- package/src/stdlib/color.mcrs +98 -16
- package/src/stdlib/combat.mcrs +23 -5
- package/src/stdlib/cooldown.mcrs +19 -0
- package/src/stdlib/dialog.mcrs +45 -7
- package/src/stdlib/easing.mcrs +132 -12
- package/src/stdlib/ecs.mcrs +142 -25
- package/src/stdlib/effects.mcrs +88 -12
- package/src/stdlib/events.mcrs +21 -2
- package/src/stdlib/expr.mcrs +18 -3
- package/src/stdlib/fft.mcrs +66 -56
- package/src/stdlib/geometry.mcrs +137 -39
- package/src/stdlib/graph.mcrs +73 -0
- package/src/stdlib/heap.mcrs +49 -8
- package/src/stdlib/i18n/zh.yaml +2891 -0
- package/src/stdlib/interactions.mcrs +43 -20
- package/src/stdlib/inventory.mcrs +14 -3
- package/src/stdlib/linalg.mcrs +185 -30
- package/src/stdlib/list.mcrs +168 -18
- package/src/stdlib/map.mcrs +112 -0
- package/src/stdlib/math.mcrs +68 -18
- package/src/stdlib/math_hp.mcrs +124 -33
- package/src/stdlib/matrix.mcrs +133 -20
- package/src/stdlib/mobs.mcrs +87 -0
- package/src/stdlib/noise.mcrs +65 -21
- package/src/stdlib/ode.mcrs +96 -0
- package/src/stdlib/parabola.mcrs +104 -29
- package/src/stdlib/particles.mcrs +78 -21
- package/src/stdlib/pathfind.mcrs +89 -35
- package/src/stdlib/physics.mcrs +134 -26
- package/src/stdlib/player.mcrs +18 -0
- package/src/stdlib/quaternion.mcrs +213 -9
- package/src/stdlib/queue.mcrs +123 -0
- package/src/stdlib/random.mcrs +63 -18
- package/src/stdlib/result.mcrs +111 -0
- package/src/stdlib/scheduler.mcrs +59 -10
- package/src/stdlib/set_int.mcrs +240 -0
- package/src/stdlib/sets.mcrs +49 -19
- package/src/stdlib/signal.mcrs +151 -79
- package/src/stdlib/sort.mcrs +44 -24
- package/src/stdlib/spawn.mcrs +30 -7
- package/src/stdlib/state.mcrs +40 -5
- package/src/stdlib/strings.mcrs +131 -3
- package/src/stdlib/tags.mcrs +2 -2
- package/src/stdlib/teams.mcrs +22 -10
- package/src/stdlib/timer.mcrs +36 -6
- package/src/stdlib/vec.mcrs +44 -9
- package/src/stdlib/world.mcrs +57 -25
- package/src/structs/expand.ts +64 -0
- package/src/testing/runner.ts +271 -0
- 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 }
|
package/src/stdlib/advanced.mcrs
CHANGED
|
@@ -11,9 +11,11 @@ module library;
|
|
|
11
11
|
|
|
12
12
|
// ─── Category 1: Number theory ───────────────────────────────────────────────
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
164
|
+
/// 1-D value noise with C¹ 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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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) // 100 — c = -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
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
290
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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
|
+
}
|