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
package/src/typechecker/index.ts
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* Collects errors but doesn't block compilation (warn mode).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { Program, FnDecl, Stmt, Expr, TypeNode, Block, EntityTypeName, EntitySelector } from '../ast/types'
|
|
8
|
+
import type { Program, FnDecl, Stmt, Expr, TypeNode, Block, EntityTypeName, EntitySelector, InterfaceDecl, InterfaceMethod } from '../ast/types'
|
|
9
9
|
import { DiagnosticError, DiagnosticCollector } from '../diagnostics'
|
|
10
10
|
import { getEventParamSpecs, isEventTypeName } from '../events/types'
|
|
11
|
+
import { expandStructDeclarations } from '../structs/expand'
|
|
11
12
|
|
|
12
13
|
interface ScopeSymbol {
|
|
13
14
|
type: TypeNode
|
|
@@ -107,6 +108,10 @@ const STRING_TYPE: TypeNode = { kind: 'named', name: 'string' }
|
|
|
107
108
|
const FORMAT_STRING_TYPE: TypeNode = { kind: 'named', name: 'format_string' }
|
|
108
109
|
|
|
109
110
|
const BUILTIN_SIGNATURES: Record<string, BuiltinSignature> = {
|
|
111
|
+
assert: {
|
|
112
|
+
params: [{ kind: 'named', name: 'bool' }],
|
|
113
|
+
return: VOID_TYPE,
|
|
114
|
+
},
|
|
110
115
|
setTimeout: {
|
|
111
116
|
params: [INT_TYPE, { kind: 'function_type', params: [], return: VOID_TYPE }],
|
|
112
117
|
return: VOID_TYPE,
|
|
@@ -119,6 +124,14 @@ const BUILTIN_SIGNATURES: Record<string, BuiltinSignature> = {
|
|
|
119
124
|
params: [INT_TYPE],
|
|
120
125
|
return: VOID_TYPE,
|
|
121
126
|
},
|
|
127
|
+
int_to_str: {
|
|
128
|
+
params: [INT_TYPE],
|
|
129
|
+
return: STRING_TYPE,
|
|
130
|
+
},
|
|
131
|
+
bool_to_str: {
|
|
132
|
+
params: [{ kind: 'named', name: 'bool' }],
|
|
133
|
+
return: STRING_TYPE,
|
|
134
|
+
},
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
// ---------------------------------------------------------------------------
|
|
@@ -133,6 +146,8 @@ export class TypeChecker {
|
|
|
133
146
|
private implMethods: Map<string, Map<string, FnDecl>> = new Map()
|
|
134
147
|
private structs: Map<string, Map<string, TypeNode>> = new Map()
|
|
135
148
|
private enums: Map<string, Map<string, number>> = new Map()
|
|
149
|
+
// enumName → variantName → field list (for payload variants)
|
|
150
|
+
private enumPayloads: Map<string, Map<string, { name: string; type: TypeNode }[]>> = new Map()
|
|
136
151
|
private consts: Map<string, TypeNode> = new Map()
|
|
137
152
|
private globals: Map<string, TypeNode> = new Map()
|
|
138
153
|
private currentFn: FnDecl | null = null
|
|
@@ -144,6 +159,9 @@ export class TypeChecker {
|
|
|
144
159
|
private loopDepth = 0
|
|
145
160
|
private condDepth = 0
|
|
146
161
|
|
|
162
|
+
// interface name → InterfaceDecl
|
|
163
|
+
private interfaces: Map<string, InterfaceDecl> = new Map()
|
|
164
|
+
|
|
147
165
|
private readonly richTextBuiltins = new Map<string, { messageIndex: number }>([
|
|
148
166
|
['say', { messageIndex: 0 }],
|
|
149
167
|
['announce', { messageIndex: 0 }],
|
|
@@ -194,6 +212,11 @@ export class TypeChecker {
|
|
|
194
212
|
this.functions.set(fn.name, fn)
|
|
195
213
|
}
|
|
196
214
|
|
|
215
|
+
// Register interface declarations
|
|
216
|
+
for (const iface of program.interfaces ?? []) {
|
|
217
|
+
this.interfaces.set(iface.name, iface)
|
|
218
|
+
}
|
|
219
|
+
|
|
197
220
|
// Register global variables (mutable) so functions can reference and assign them
|
|
198
221
|
for (const global of program.globals ?? []) {
|
|
199
222
|
this.globals.set(global.name, this.normalizeType(global.type))
|
|
@@ -221,20 +244,62 @@ export class TypeChecker {
|
|
|
221
244
|
}
|
|
222
245
|
}
|
|
223
246
|
|
|
224
|
-
|
|
247
|
+
const expandedStructs = expandStructDeclarations(program.structs ?? [], ({ message, node }) => {
|
|
248
|
+
this.report(message, node)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
for (const struct of expandedStructs) {
|
|
225
252
|
const fields = new Map<string, TypeNode>()
|
|
226
253
|
for (const field of struct.fields) {
|
|
227
254
|
fields.set(field.name, field.type)
|
|
228
255
|
}
|
|
229
256
|
this.structs.set(struct.name, fields)
|
|
257
|
+
|
|
258
|
+
// @singleton structs get synthetic static get() and set(gs) methods
|
|
259
|
+
if (struct.isSingleton) {
|
|
260
|
+
const structType: TypeNode = { kind: 'struct', name: struct.name }
|
|
261
|
+
let singletonMethods = this.implMethods.get(struct.name)
|
|
262
|
+
if (!singletonMethods) {
|
|
263
|
+
singletonMethods = new Map()
|
|
264
|
+
this.implMethods.set(struct.name, singletonMethods)
|
|
265
|
+
}
|
|
266
|
+
const voidType: TypeNode = { kind: 'named', name: 'void' }
|
|
267
|
+
// Synthetic get() — no params, returns struct
|
|
268
|
+
singletonMethods.set('get', {
|
|
269
|
+
name: 'get',
|
|
270
|
+
params: [],
|
|
271
|
+
returnType: structType,
|
|
272
|
+
decorators: [],
|
|
273
|
+
body: [],
|
|
274
|
+
typeParams: undefined,
|
|
275
|
+
isLibraryFn: true,
|
|
276
|
+
})
|
|
277
|
+
// Synthetic set(gs: StructName) — takes struct, returns void
|
|
278
|
+
singletonMethods.set('set', {
|
|
279
|
+
name: 'set',
|
|
280
|
+
params: [{ name: 'gs', type: structType }],
|
|
281
|
+
returnType: voidType,
|
|
282
|
+
decorators: [],
|
|
283
|
+
body: [],
|
|
284
|
+
typeParams: undefined,
|
|
285
|
+
isLibraryFn: true,
|
|
286
|
+
})
|
|
287
|
+
}
|
|
230
288
|
}
|
|
231
289
|
|
|
232
290
|
for (const enumDecl of program.enums ?? []) {
|
|
233
291
|
const variants = new Map<string, number>()
|
|
292
|
+
const payloads = new Map<string, { name: string; type: TypeNode }[]>()
|
|
234
293
|
for (const variant of enumDecl.variants) {
|
|
235
294
|
variants.set(variant.name, variant.value ?? 0)
|
|
295
|
+
if (variant.fields && variant.fields.length > 0) {
|
|
296
|
+
payloads.set(variant.name, variant.fields)
|
|
297
|
+
}
|
|
236
298
|
}
|
|
237
299
|
this.enums.set(enumDecl.name, variants)
|
|
300
|
+
if (payloads.size > 0) {
|
|
301
|
+
this.enumPayloads.set(enumDecl.name, payloads)
|
|
302
|
+
}
|
|
238
303
|
}
|
|
239
304
|
|
|
240
305
|
for (const constDecl of program.consts ?? []) {
|
|
@@ -249,6 +314,24 @@ export class TypeChecker {
|
|
|
249
314
|
this.consts.set(constDecl.name, constType)
|
|
250
315
|
}
|
|
251
316
|
|
|
317
|
+
// Verify that each `impl <Interface> for <Struct>` satisfies all interface methods
|
|
318
|
+
for (const implBlock of program.implBlocks ?? []) {
|
|
319
|
+
if (!implBlock.traitName) continue
|
|
320
|
+
const iface = this.interfaces.get(implBlock.traitName)
|
|
321
|
+
if (!iface) continue // Unknown trait — not our concern here (could be built-in like Display)
|
|
322
|
+
|
|
323
|
+
const implementedMethods = new Set(implBlock.methods.map(m => m.name))
|
|
324
|
+
for (const required of iface.methods) {
|
|
325
|
+
if (!implementedMethods.has(required.name)) {
|
|
326
|
+
const span = implBlock.span ?? required.span
|
|
327
|
+
this.report(
|
|
328
|
+
`Struct '${implBlock.typeName}' does not implement required method '${required.name}' from interface '${implBlock.traitName}'`,
|
|
329
|
+
span ?? { line: 1, col: 1 }
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
252
335
|
// Second pass: type check function bodies
|
|
253
336
|
for (const fn of program.declarations) {
|
|
254
337
|
this.checkFunction(fn)
|
|
@@ -310,6 +393,76 @@ export class TypeChecker {
|
|
|
310
393
|
}
|
|
311
394
|
|
|
312
395
|
private checkFunctionDecorators(fn: FnDecl): void {
|
|
396
|
+
const watchDecorators = fn.decorators.filter(decorator => decorator.name === 'watch')
|
|
397
|
+
if (watchDecorators.length > 1) {
|
|
398
|
+
this.report(`Function '${fn.name}' cannot have multiple @watch decorators`, fn)
|
|
399
|
+
return
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (watchDecorators.length === 1) {
|
|
403
|
+
const objective = watchDecorators[0].args?.objective
|
|
404
|
+
if (!objective) {
|
|
405
|
+
this.report(`Function '${fn.name}' is missing a scoreboard objective in @watch("...")`, fn)
|
|
406
|
+
return
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (fn.params.length > 0) {
|
|
410
|
+
this.report(`@watch handler '${fn.name}' cannot declare parameters`, fn)
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const throttleDecorators = fn.decorators.filter(decorator => decorator.name === 'throttle')
|
|
415
|
+
if (throttleDecorators.length > 1) {
|
|
416
|
+
this.report(`Function '${fn.name}' cannot have multiple @throttle decorators`, fn)
|
|
417
|
+
return
|
|
418
|
+
}
|
|
419
|
+
if (throttleDecorators.length === 1) {
|
|
420
|
+
const ticks = throttleDecorators[0].args?.ticks
|
|
421
|
+
if (ticks === undefined || ticks <= 0) {
|
|
422
|
+
this.report(`@throttle on '${fn.name}' requires ticks=N (positive integer)`, fn)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const retryDecorators = fn.decorators.filter(decorator => decorator.name === 'retry')
|
|
427
|
+
if (retryDecorators.length > 1) {
|
|
428
|
+
this.report(`Function '${fn.name}' cannot have multiple @retry decorators`, fn)
|
|
429
|
+
return
|
|
430
|
+
}
|
|
431
|
+
if (retryDecorators.length === 1) {
|
|
432
|
+
const max = retryDecorators[0].args?.max
|
|
433
|
+
if (max === undefined || max <= 0) {
|
|
434
|
+
this.report(`@retry on '${fn.name}' requires max=N (positive integer)`, fn)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const profileDecorators = fn.decorators.filter(decorator => decorator.name === 'profile')
|
|
439
|
+
if (profileDecorators.length > 1) {
|
|
440
|
+
this.report(`Function '${fn.name}' cannot have multiple @profile decorators`, fn)
|
|
441
|
+
return
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (profileDecorators.length === 1 && (profileDecorators[0].rawArgs?.length || profileDecorators[0].args && Object.keys(profileDecorators[0].args).length > 0)) {
|
|
445
|
+
this.report(`@profile decorator on '${fn.name}' does not accept arguments`, fn)
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const memoizeDecorators = fn.decorators.filter(decorator => decorator.name === 'memoize')
|
|
450
|
+
if (memoizeDecorators.length > 1) {
|
|
451
|
+
this.report(`Function '${fn.name}' cannot have multiple @memoize decorators`, fn)
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
if (memoizeDecorators.length === 1) {
|
|
455
|
+
if (fn.params.length !== 1) {
|
|
456
|
+
this.report(`@memoize on '${fn.name}' requires exactly one parameter`, fn)
|
|
457
|
+
} else {
|
|
458
|
+
const paramType = fn.params[0].type
|
|
459
|
+
const isInt = paramType.kind === 'named' && paramType.name === 'int'
|
|
460
|
+
if (!isInt) {
|
|
461
|
+
this.report(`@memoize on '${fn.name}' only supports int parameters (got '${paramType.kind === 'named' ? paramType.name : paramType.kind}')`, fn)
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
313
466
|
const eventDecorators = fn.decorators.filter(decorator => decorator.name === 'on')
|
|
314
467
|
if (eventDecorators.length === 0) {
|
|
315
468
|
return
|
|
@@ -430,9 +583,23 @@ export class TypeChecker {
|
|
|
430
583
|
!this.typesMatch(subjectType, patternType)) {
|
|
431
584
|
this.report('Match arm pattern type must match subject type', arm.pattern.expr)
|
|
432
585
|
}
|
|
586
|
+
this.checkBlock(arm.body)
|
|
587
|
+
} else if (arm.pattern.kind === 'PatEnum') {
|
|
588
|
+
const pat = arm.pattern
|
|
589
|
+
const variantPayloads = this.enumPayloads.get(pat.enumName)?.get(pat.variant) ?? []
|
|
590
|
+
// Bind pattern variables to their declared field types in arm scope
|
|
591
|
+
const savedScope = new Map(this.scope)
|
|
592
|
+
for (let i = 0; i < pat.bindings.length; i++) {
|
|
593
|
+
const fieldDef = variantPayloads[i]
|
|
594
|
+
const bindingType: TypeNode = fieldDef ? fieldDef.type : { kind: 'named', name: 'int' }
|
|
595
|
+
this.scope.set(pat.bindings[i], { type: bindingType, mutable: false })
|
|
596
|
+
}
|
|
597
|
+
this.checkBlock(arm.body)
|
|
598
|
+
this.scope = savedScope
|
|
599
|
+
} else {
|
|
600
|
+
// PatSome / PatNone / PatInt / PatWild are structurally typed — no extra scope needed
|
|
601
|
+
this.checkBlock(arm.body)
|
|
433
602
|
}
|
|
434
|
-
// PatSome / PatNone / PatInt / PatWild are structurally typed — no expr to check
|
|
435
|
-
this.checkBlock(arm.body)
|
|
436
603
|
}
|
|
437
604
|
break
|
|
438
605
|
case 'as_block': {
|
|
@@ -477,6 +644,22 @@ export class TypeChecker {
|
|
|
477
644
|
case 'raw':
|
|
478
645
|
// Raw commands are not type checked
|
|
479
646
|
break
|
|
647
|
+
case 'break':
|
|
648
|
+
case 'continue':
|
|
649
|
+
case 'break_label':
|
|
650
|
+
case 'continue_label':
|
|
651
|
+
// Control flow — no sub-expressions to check
|
|
652
|
+
break
|
|
653
|
+
case 'labeled_loop':
|
|
654
|
+
// Recurse into the labeled loop body
|
|
655
|
+
this.loopDepth++
|
|
656
|
+
this.checkStmt(stmt.body)
|
|
657
|
+
this.loopDepth--
|
|
658
|
+
break
|
|
659
|
+
case 'const_decl':
|
|
660
|
+
// Local const: register in scope as immutable with its declared type
|
|
661
|
+
this.scope.set(stmt.name, { type: stmt.type, mutable: false })
|
|
662
|
+
break
|
|
480
663
|
}
|
|
481
664
|
}
|
|
482
665
|
|
|
@@ -625,8 +808,8 @@ export class TypeChecker {
|
|
|
625
808
|
if (arithmeticOps.includes(expr.op)) {
|
|
626
809
|
const leftType = this.inferType(expr.left)
|
|
627
810
|
const rightType = this.inferType(expr.right)
|
|
628
|
-
const leftIsString = leftType.kind === 'named' && (leftType.name === 'string' || leftType.name === 'format_string')
|
|
629
|
-
const rightIsString = rightType.kind === 'named' && (rightType.name === 'string' || rightType.name === 'format_string')
|
|
811
|
+
const leftIsString = leftType.kind === 'named' && (leftType.name === 'string' || leftType.name === 'format_string') // format_string kept for legacy type annotations
|
|
812
|
+
const rightIsString = rightType.kind === 'named' && (rightType.name === 'string' || rightType.name === 'format_string') // format_string kept for legacy type annotations
|
|
630
813
|
if (leftIsString || rightIsString) {
|
|
631
814
|
// String concatenation with + is not supported. Use f-strings instead.
|
|
632
815
|
this.report(
|
|
@@ -691,7 +874,35 @@ export class TypeChecker {
|
|
|
691
874
|
|
|
692
875
|
case 'struct_lit':
|
|
693
876
|
for (const field of expr.fields) {
|
|
694
|
-
|
|
877
|
+
let fieldType: TypeNode | undefined
|
|
878
|
+
if (expectedType) {
|
|
879
|
+
const normalized = this.normalizeType(expectedType)
|
|
880
|
+
if (normalized.kind === 'struct') {
|
|
881
|
+
const structFields = this.structs.get(normalized.name)
|
|
882
|
+
if (structFields && !structFields.has(field.name)) {
|
|
883
|
+
this.report(`Struct '${normalized.name}' has no field '${field.name}'`, expr)
|
|
884
|
+
} else {
|
|
885
|
+
fieldType = structFields?.get(field.name)
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
this.checkExpr(field.value, fieldType)
|
|
891
|
+
|
|
892
|
+
if (fieldType) {
|
|
893
|
+
const actualType = this.inferType(field.value, fieldType)
|
|
894
|
+
if (this.isNumericMismatch(fieldType, actualType)) {
|
|
895
|
+
this.report(
|
|
896
|
+
`Field '${field.name}' of struct expects ${this.typeToString(fieldType)}, got ${this.typeToString(actualType)}`,
|
|
897
|
+
field.value
|
|
898
|
+
)
|
|
899
|
+
} else if (!this.typesMatch(fieldType, actualType)) {
|
|
900
|
+
this.report(
|
|
901
|
+
`Field '${field.name}' of struct expects ${this.typeToString(fieldType)}, got ${this.typeToString(actualType)}`,
|
|
902
|
+
field.value
|
|
903
|
+
)
|
|
904
|
+
}
|
|
905
|
+
}
|
|
695
906
|
}
|
|
696
907
|
break
|
|
697
908
|
|
|
@@ -754,6 +965,32 @@ export class TypeChecker {
|
|
|
754
965
|
}
|
|
755
966
|
break
|
|
756
967
|
|
|
968
|
+
case 'enum_construct': {
|
|
969
|
+
if (!this.enums.has(expr.enumName)) {
|
|
970
|
+
this.report(`Unknown enum '${expr.enumName}'`, expr)
|
|
971
|
+
break
|
|
972
|
+
}
|
|
973
|
+
const variants = this.enums.get(expr.enumName)!
|
|
974
|
+
if (!variants.has(expr.variant)) {
|
|
975
|
+
this.report(`Enum '${expr.enumName}' has no variant '${expr.variant}'`, expr)
|
|
976
|
+
break
|
|
977
|
+
}
|
|
978
|
+
const variantPayloads = this.enumPayloads.get(expr.enumName)?.get(expr.variant) ?? []
|
|
979
|
+
if (variantPayloads.length === 0 && expr.args.length > 0) {
|
|
980
|
+
this.report(`Enum variant '${expr.enumName}::${expr.variant}' has no payload fields`, expr)
|
|
981
|
+
break
|
|
982
|
+
}
|
|
983
|
+
for (const arg of expr.args) {
|
|
984
|
+
const fieldDef = variantPayloads.find(f => f.name === arg.name)
|
|
985
|
+
if (!fieldDef) {
|
|
986
|
+
this.report(`Unknown field '${arg.name}' for enum variant '${expr.enumName}::${expr.variant}'`, expr)
|
|
987
|
+
} else {
|
|
988
|
+
this.checkExpr(arg.value, fieldDef.type)
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
break
|
|
992
|
+
}
|
|
993
|
+
|
|
757
994
|
case 'blockpos':
|
|
758
995
|
break
|
|
759
996
|
|
|
@@ -883,7 +1120,7 @@ export class TypeChecker {
|
|
|
883
1120
|
const messageType = this.inferType(message)
|
|
884
1121
|
if (
|
|
885
1122
|
messageType.kind !== 'named' ||
|
|
886
|
-
|
|
1123
|
+
messageType.name !== 'string'
|
|
887
1124
|
) {
|
|
888
1125
|
this.report(
|
|
889
1126
|
`Argument ${messageIndex + 1} of '${expr.fn}' expects string or format_string, got ${this.typeToString(messageType)}`,
|
|
@@ -1147,7 +1384,7 @@ export class TypeChecker {
|
|
|
1147
1384
|
this.checkExpr(part.expr)
|
|
1148
1385
|
}
|
|
1149
1386
|
}
|
|
1150
|
-
return
|
|
1387
|
+
return STRING_TYPE
|
|
1151
1388
|
case 'blockpos':
|
|
1152
1389
|
return { kind: 'named', name: 'BlockPos' }
|
|
1153
1390
|
case 'ident':
|
|
@@ -1209,6 +1446,11 @@ export class TypeChecker {
|
|
|
1209
1446
|
return { kind: 'enum', name: expr.enumName }
|
|
1210
1447
|
}
|
|
1211
1448
|
return { kind: 'named', name: 'void' }
|
|
1449
|
+
case 'enum_construct':
|
|
1450
|
+
if (this.enums.has(expr.enumName)) {
|
|
1451
|
+
return { kind: 'enum', name: expr.enumName }
|
|
1452
|
+
}
|
|
1453
|
+
return { kind: 'named', name: 'void' }
|
|
1212
1454
|
case 'member':
|
|
1213
1455
|
if (expr.obj.kind === 'ident' && this.enums.has(expr.obj.name)) {
|
|
1214
1456
|
return { kind: 'enum', name: expr.obj.name }
|
|
@@ -1336,6 +1578,20 @@ export class TypeChecker {
|
|
|
1336
1578
|
return 'entity'
|
|
1337
1579
|
}
|
|
1338
1580
|
|
|
1581
|
+
// Reverse map: parser sometimes remaps method names (e.g. add→set_add) for builtins.
|
|
1582
|
+
// When the receiver is a struct with an impl method matching the original name, use that.
|
|
1583
|
+
private static readonly PARSER_METHOD_REMAP: Record<string, string> = {
|
|
1584
|
+
'set_add': 'add',
|
|
1585
|
+
'set_contains': 'contains',
|
|
1586
|
+
'set_remove': 'remove',
|
|
1587
|
+
'set_clear': 'clear',
|
|
1588
|
+
'__array_push': 'push',
|
|
1589
|
+
'__array_pop': 'pop',
|
|
1590
|
+
'__entity_tag': 'tag',
|
|
1591
|
+
'__entity_untag': 'untag',
|
|
1592
|
+
'__entity_has_tag': 'has_tag',
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1339
1595
|
private resolveInstanceMethod(expr: Extract<Expr, { kind: 'call' }>): FnDecl | null {
|
|
1340
1596
|
const receiver = expr.args[0]
|
|
1341
1597
|
if (!receiver) {
|
|
@@ -1347,7 +1603,10 @@ export class TypeChecker {
|
|
|
1347
1603
|
return null
|
|
1348
1604
|
}
|
|
1349
1605
|
|
|
1606
|
+
// Try the method name as-is first, then try the original (pre-remap) name
|
|
1607
|
+
const methodName = TypeChecker.PARSER_METHOD_REMAP[expr.fn] ?? expr.fn
|
|
1350
1608
|
const method = this.implMethods.get(receiverType.name)?.get(expr.fn)
|
|
1609
|
+
?? this.implMethods.get(receiverType.name)?.get(methodName)
|
|
1351
1610
|
if (!method || method.params[0]?.name !== 'self') {
|
|
1352
1611
|
return null
|
|
1353
1612
|
}
|
|
@@ -1422,6 +1681,11 @@ export class TypeChecker {
|
|
|
1422
1681
|
if (expected.kind === 'selector' && actual.kind === 'selector') {
|
|
1423
1682
|
return true // any entity subtype is compatible
|
|
1424
1683
|
}
|
|
1684
|
+
// Fake player names (#name) are mc_name tokens typed as string — allow them
|
|
1685
|
+
// where a selector is expected, since MC scoreboards accept fake player names.
|
|
1686
|
+
if (expected.kind === 'selector' && actual.kind === 'named' && actual.name === 'string') {
|
|
1687
|
+
return true
|
|
1688
|
+
}
|
|
1425
1689
|
|
|
1426
1690
|
if (expected.kind !== actual.kind) return false
|
|
1427
1691
|
|