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
|
@@ -9207,6 +9207,8 @@ var KEYWORDS = {
|
|
|
9207
9207
|
while: "while",
|
|
9208
9208
|
for: "for",
|
|
9209
9209
|
foreach: "foreach",
|
|
9210
|
+
do: "do",
|
|
9211
|
+
repeat: "repeat",
|
|
9210
9212
|
match: "match",
|
|
9211
9213
|
return: "return",
|
|
9212
9214
|
break: "break",
|
|
@@ -9226,6 +9228,8 @@ var KEYWORDS = {
|
|
|
9226
9228
|
unless: "unless",
|
|
9227
9229
|
declare: "declare",
|
|
9228
9230
|
export: "export",
|
|
9231
|
+
import: "import",
|
|
9232
|
+
interface: "interface",
|
|
9229
9233
|
int: "int",
|
|
9230
9234
|
bool: "bool",
|
|
9231
9235
|
float: "float",
|
|
@@ -9471,7 +9475,13 @@ var Lexer = class {
|
|
|
9471
9475
|
return;
|
|
9472
9476
|
}
|
|
9473
9477
|
if (char === '"') {
|
|
9474
|
-
this.
|
|
9478
|
+
if (this.peek() === '"' && this.peek(1) === '"') {
|
|
9479
|
+
this.advance();
|
|
9480
|
+
this.advance();
|
|
9481
|
+
this.scanMultiLineString(startLine, startCol);
|
|
9482
|
+
} else {
|
|
9483
|
+
this.scanString(startLine, startCol);
|
|
9484
|
+
}
|
|
9475
9485
|
return;
|
|
9476
9486
|
}
|
|
9477
9487
|
if (char === "#") {
|
|
@@ -9539,6 +9549,26 @@ var Lexer = class {
|
|
|
9539
9549
|
}
|
|
9540
9550
|
return result;
|
|
9541
9551
|
}
|
|
9552
|
+
scanMultiLineString(startLine, startCol) {
|
|
9553
|
+
let value = "";
|
|
9554
|
+
while (!this.isAtEnd()) {
|
|
9555
|
+
if (this.peek() === '"' && this.peek(1) === '"' && this.peek(2) === '"') {
|
|
9556
|
+
this.advance();
|
|
9557
|
+
this.advance();
|
|
9558
|
+
this.advance();
|
|
9559
|
+
break;
|
|
9560
|
+
}
|
|
9561
|
+
if (this.peek() === "\\" && this.peek(1) === '"') {
|
|
9562
|
+
this.advance();
|
|
9563
|
+
value += this.advance();
|
|
9564
|
+
continue;
|
|
9565
|
+
}
|
|
9566
|
+
value += this.advance();
|
|
9567
|
+
}
|
|
9568
|
+
if (value.startsWith("\n")) value = value.slice(1);
|
|
9569
|
+
if (value.endsWith("\n")) value = value.slice(0, -1);
|
|
9570
|
+
this.addToken("string_lit", value, startLine, startCol);
|
|
9571
|
+
}
|
|
9542
9572
|
scanString(startLine, startCol) {
|
|
9543
9573
|
let value = "";
|
|
9544
9574
|
let interpolationDepth = 0;
|
|
@@ -9782,6 +9812,8 @@ var Parser = class _Parser {
|
|
|
9782
9812
|
this.inLibraryMode = false;
|
|
9783
9813
|
/** Warnings accumulated during parsing (e.g. deprecated keyword usage). */
|
|
9784
9814
|
this.warnings = [];
|
|
9815
|
+
/** Parse errors collected during error-recovery mode. */
|
|
9816
|
+
this.parseErrors = [];
|
|
9785
9817
|
this.tokens = tokens;
|
|
9786
9818
|
this.sourceLines = source?.split("\n") ?? [];
|
|
9787
9819
|
this.filePath = filePath;
|
|
@@ -9852,6 +9884,60 @@ var Parser = class _Parser {
|
|
|
9852
9884
|
return { kind: "eof", value: "", line: span.line, col: span.col };
|
|
9853
9885
|
}
|
|
9854
9886
|
// -------------------------------------------------------------------------
|
|
9887
|
+
// Error Recovery
|
|
9888
|
+
// -------------------------------------------------------------------------
|
|
9889
|
+
/**
|
|
9890
|
+
* Synchronize to the next top-level declaration boundary after a parse error.
|
|
9891
|
+
* Skips tokens until we find a keyword that starts a top-level declaration,
|
|
9892
|
+
* or a `}` (end of a block), or EOF.
|
|
9893
|
+
*/
|
|
9894
|
+
syncToNextDecl() {
|
|
9895
|
+
const TOP_LEVEL_KEYWORDS = /* @__PURE__ */ new Set([
|
|
9896
|
+
"fn",
|
|
9897
|
+
"struct",
|
|
9898
|
+
"impl",
|
|
9899
|
+
"enum",
|
|
9900
|
+
"const",
|
|
9901
|
+
"let",
|
|
9902
|
+
"export",
|
|
9903
|
+
"declare",
|
|
9904
|
+
"import",
|
|
9905
|
+
"namespace",
|
|
9906
|
+
"module"
|
|
9907
|
+
]);
|
|
9908
|
+
while (!this.check("eof")) {
|
|
9909
|
+
const kind = this.peek().kind;
|
|
9910
|
+
if (kind === "}") {
|
|
9911
|
+
this.advance();
|
|
9912
|
+
return;
|
|
9913
|
+
}
|
|
9914
|
+
if (TOP_LEVEL_KEYWORDS.has(kind)) {
|
|
9915
|
+
return;
|
|
9916
|
+
}
|
|
9917
|
+
if (kind === "ident" && this.peek().value === "import") {
|
|
9918
|
+
return;
|
|
9919
|
+
}
|
|
9920
|
+
this.advance();
|
|
9921
|
+
}
|
|
9922
|
+
}
|
|
9923
|
+
/**
|
|
9924
|
+
* Synchronize to the next statement boundary inside a block after a parse error.
|
|
9925
|
+
* Skips tokens until we reach `;`, `}`, or EOF.
|
|
9926
|
+
*/
|
|
9927
|
+
syncToNextStmt() {
|
|
9928
|
+
while (!this.check("eof")) {
|
|
9929
|
+
const kind = this.peek().kind;
|
|
9930
|
+
if (kind === ";") {
|
|
9931
|
+
this.advance();
|
|
9932
|
+
return;
|
|
9933
|
+
}
|
|
9934
|
+
if (kind === "}") {
|
|
9935
|
+
return;
|
|
9936
|
+
}
|
|
9937
|
+
this.advance();
|
|
9938
|
+
}
|
|
9939
|
+
}
|
|
9940
|
+
// -------------------------------------------------------------------------
|
|
9855
9941
|
// Program
|
|
9856
9942
|
// -------------------------------------------------------------------------
|
|
9857
9943
|
parse(defaultNamespace = "redscript") {
|
|
@@ -9863,6 +9949,7 @@ var Parser = class _Parser {
|
|
|
9863
9949
|
const enums = [];
|
|
9864
9950
|
const consts = [];
|
|
9865
9951
|
const imports = [];
|
|
9952
|
+
const interfaces = [];
|
|
9866
9953
|
let isLibrary = false;
|
|
9867
9954
|
let moduleName;
|
|
9868
9955
|
if (this.check("namespace")) {
|
|
@@ -9883,40 +9970,74 @@ var Parser = class _Parser {
|
|
|
9883
9970
|
this.match(";");
|
|
9884
9971
|
}
|
|
9885
9972
|
while (!this.check("eof")) {
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
this.
|
|
9898
|
-
|
|
9899
|
-
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
if (this.check("
|
|
9973
|
+
try {
|
|
9974
|
+
if (this.check("decorator") && this.peek().value.startsWith("@config")) {
|
|
9975
|
+
const decorToken = this.advance();
|
|
9976
|
+
const decorator = this.parseDecoratorValue(decorToken.value);
|
|
9977
|
+
if (!this.check("let")) {
|
|
9978
|
+
this.error("@config decorator must be followed by a let declaration");
|
|
9979
|
+
}
|
|
9980
|
+
const g = this.parseGlobalDecl(true);
|
|
9981
|
+
g.configKey = decorator.args?.configKey;
|
|
9982
|
+
g.configDefault = decorator.args?.configDefault;
|
|
9983
|
+
globals.push(g);
|
|
9984
|
+
} else if (this.check("let")) {
|
|
9985
|
+
globals.push(this.parseGlobalDecl(true));
|
|
9986
|
+
} else if (this.check("decorator") && this.peek().value === "@singleton") {
|
|
9987
|
+
this.advance();
|
|
9988
|
+
if (!this.check("struct")) {
|
|
9989
|
+
this.error("@singleton decorator must be followed by a struct declaration");
|
|
9990
|
+
}
|
|
9991
|
+
const s = this.parseStructDecl();
|
|
9992
|
+
s.isSingleton = true;
|
|
9993
|
+
structs.push(s);
|
|
9994
|
+
} else if (this.check("struct")) {
|
|
9995
|
+
structs.push(this.parseStructDecl());
|
|
9996
|
+
} else if (this.check("impl")) {
|
|
9997
|
+
implBlocks.push(this.parseImplBlock());
|
|
9998
|
+
} else if (this.check("interface")) {
|
|
9999
|
+
interfaces.push(this.parseInterfaceDecl());
|
|
10000
|
+
} else if (this.check("enum")) {
|
|
10001
|
+
enums.push(this.parseEnumDecl());
|
|
10002
|
+
} else if (this.check("const")) {
|
|
10003
|
+
consts.push(this.parseConstDecl());
|
|
10004
|
+
} else if (this.check("declare")) {
|
|
9908
10005
|
this.advance();
|
|
9909
|
-
|
|
10006
|
+
this.parseDeclareStub();
|
|
10007
|
+
} else if (this.check("export")) {
|
|
10008
|
+
declarations.push(this.parseExportedFnDecl());
|
|
10009
|
+
} else if (this.check("import") || this.check("ident") && this.peek().value === "import") {
|
|
10010
|
+
this.advance();
|
|
10011
|
+
const importToken = this.peek();
|
|
10012
|
+
const modName = this.expect("ident").value;
|
|
10013
|
+
if (this.check("::")) {
|
|
10014
|
+
this.advance();
|
|
10015
|
+
let symbol;
|
|
10016
|
+
if (this.check("*")) {
|
|
10017
|
+
this.advance();
|
|
10018
|
+
symbol = "*";
|
|
10019
|
+
} else {
|
|
10020
|
+
symbol = this.expect("ident").value;
|
|
10021
|
+
}
|
|
10022
|
+
this.match(";");
|
|
10023
|
+
imports.push(this.withLoc({ moduleName: modName, symbol }, importToken));
|
|
10024
|
+
} else {
|
|
10025
|
+
this.match(";");
|
|
10026
|
+
imports.push(this.withLoc({ moduleName: modName, symbol: void 0 }, importToken));
|
|
10027
|
+
}
|
|
9910
10028
|
} else {
|
|
9911
|
-
|
|
10029
|
+
declarations.push(this.parseFnDecl());
|
|
10030
|
+
}
|
|
10031
|
+
} catch (err) {
|
|
10032
|
+
if (err instanceof DiagnosticError) {
|
|
10033
|
+
this.parseErrors.push(err);
|
|
10034
|
+
this.syncToNextDecl();
|
|
10035
|
+
} else {
|
|
10036
|
+
throw err;
|
|
9912
10037
|
}
|
|
9913
|
-
this.match(";");
|
|
9914
|
-
imports.push(this.withLoc({ moduleName: modName, symbol }, importToken));
|
|
9915
|
-
} else {
|
|
9916
|
-
declarations.push(this.parseFnDecl());
|
|
9917
10038
|
}
|
|
9918
10039
|
}
|
|
9919
|
-
return { namespace, moduleName, globals, declarations, structs, implBlocks, enums, consts, imports, isLibrary };
|
|
10040
|
+
return { namespace, moduleName, globals, declarations, structs, implBlocks, enums, consts, imports, interfaces, isLibrary };
|
|
9920
10041
|
}
|
|
9921
10042
|
// -------------------------------------------------------------------------
|
|
9922
10043
|
// Struct Declaration
|
|
@@ -9945,6 +10066,19 @@ var Parser = class _Parser {
|
|
|
9945
10066
|
while (!this.check("}") && !this.check("eof")) {
|
|
9946
10067
|
const variantToken = this.expect("ident");
|
|
9947
10068
|
const variant = { name: variantToken.value };
|
|
10069
|
+
if (this.check("(")) {
|
|
10070
|
+
this.advance();
|
|
10071
|
+
const fields = [];
|
|
10072
|
+
while (!this.check(")") && !this.check("eof")) {
|
|
10073
|
+
const fieldName = this.expect("ident").value;
|
|
10074
|
+
this.expect(":");
|
|
10075
|
+
const fieldType = this.parseType();
|
|
10076
|
+
fields.push({ name: fieldName, type: fieldType });
|
|
10077
|
+
if (!this.match(",")) break;
|
|
10078
|
+
}
|
|
10079
|
+
this.expect(")");
|
|
10080
|
+
variant.fields = fields;
|
|
10081
|
+
}
|
|
9948
10082
|
if (this.match("=")) {
|
|
9949
10083
|
const valueToken = this.expect("int_lit");
|
|
9950
10084
|
variant.value = parseInt(valueToken.value, 10);
|
|
@@ -9962,14 +10096,72 @@ var Parser = class _Parser {
|
|
|
9962
10096
|
}
|
|
9963
10097
|
parseImplBlock() {
|
|
9964
10098
|
const implToken = this.expect("impl");
|
|
9965
|
-
|
|
10099
|
+
let traitName;
|
|
10100
|
+
let typeName;
|
|
10101
|
+
const firstName = this.expect("ident").value;
|
|
10102
|
+
if (this.match("for")) {
|
|
10103
|
+
traitName = firstName;
|
|
10104
|
+
typeName = this.expect("ident").value;
|
|
10105
|
+
} else {
|
|
10106
|
+
typeName = firstName;
|
|
10107
|
+
}
|
|
9966
10108
|
this.expect("{");
|
|
9967
10109
|
const methods = [];
|
|
9968
10110
|
while (!this.check("}") && !this.check("eof")) {
|
|
9969
10111
|
methods.push(this.parseFnDecl(typeName));
|
|
9970
10112
|
}
|
|
9971
10113
|
this.expect("}");
|
|
9972
|
-
return this.withLoc({ kind: "impl_block", typeName, methods }, implToken);
|
|
10114
|
+
return this.withLoc({ kind: "impl_block", traitName, typeName, methods }, implToken);
|
|
10115
|
+
}
|
|
10116
|
+
/**
|
|
10117
|
+
* Parse an interface declaration:
|
|
10118
|
+
* interface <Name> {
|
|
10119
|
+
* fn <method>(<params>): <retType>
|
|
10120
|
+
* ...
|
|
10121
|
+
* }
|
|
10122
|
+
* Method signatures have no body — they are prototype-only.
|
|
10123
|
+
*/
|
|
10124
|
+
parseInterfaceDecl() {
|
|
10125
|
+
const ifaceToken = this.expect("interface");
|
|
10126
|
+
const name = this.expect("ident").value;
|
|
10127
|
+
this.expect("{");
|
|
10128
|
+
const methods = [];
|
|
10129
|
+
while (!this.check("}") && !this.check("eof")) {
|
|
10130
|
+
const fnToken = this.expect("fn");
|
|
10131
|
+
const methodName = this.expect("ident").value;
|
|
10132
|
+
this.expect("(");
|
|
10133
|
+
const params = this.parseInterfaceParams();
|
|
10134
|
+
this.expect(")");
|
|
10135
|
+
let returnType;
|
|
10136
|
+
if (this.match(":")) {
|
|
10137
|
+
returnType = this.parseType();
|
|
10138
|
+
}
|
|
10139
|
+
methods.push(this.withLoc({ name: methodName, params, returnType }, fnToken));
|
|
10140
|
+
}
|
|
10141
|
+
this.expect("}");
|
|
10142
|
+
return this.withLoc({ name, methods }, ifaceToken);
|
|
10143
|
+
}
|
|
10144
|
+
/**
|
|
10145
|
+
* Parse interface method params — like parseParams but allows bare `self`
|
|
10146
|
+
* (no `:` required for the first param named 'self').
|
|
10147
|
+
*/
|
|
10148
|
+
parseInterfaceParams() {
|
|
10149
|
+
const params = [];
|
|
10150
|
+
if (!this.check(")")) {
|
|
10151
|
+
do {
|
|
10152
|
+
const paramToken = this.expect("ident");
|
|
10153
|
+
const paramName = paramToken.value;
|
|
10154
|
+
let type;
|
|
10155
|
+
if (params.length === 0 && paramName === "self" && !this.check(":")) {
|
|
10156
|
+
type = { kind: "named", name: "void" };
|
|
10157
|
+
} else {
|
|
10158
|
+
this.expect(":");
|
|
10159
|
+
type = this.parseType();
|
|
10160
|
+
}
|
|
10161
|
+
params.push(this.withLoc({ name: paramName, type }, paramToken));
|
|
10162
|
+
} while (this.match(","));
|
|
10163
|
+
}
|
|
10164
|
+
return params;
|
|
9973
10165
|
}
|
|
9974
10166
|
parseConstDecl() {
|
|
9975
10167
|
const constToken = this.expect("const");
|
|
@@ -9989,8 +10181,12 @@ var Parser = class _Parser {
|
|
|
9989
10181
|
const name = this.expect("ident").value;
|
|
9990
10182
|
this.expect(":");
|
|
9991
10183
|
const type = this.parseType();
|
|
9992
|
-
|
|
9993
|
-
|
|
10184
|
+
let init;
|
|
10185
|
+
if (this.match("=")) {
|
|
10186
|
+
init = this.parseExpr();
|
|
10187
|
+
} else {
|
|
10188
|
+
init = { kind: "int_lit", value: 0 };
|
|
10189
|
+
}
|
|
9994
10190
|
this.match(";");
|
|
9995
10191
|
return this.withLoc({ kind: "global", name, type, init, mutable }, token);
|
|
9996
10192
|
}
|
|
@@ -10006,6 +10202,7 @@ var Parser = class _Parser {
|
|
|
10006
10202
|
}
|
|
10007
10203
|
parseFnDecl(implTypeName) {
|
|
10008
10204
|
const decorators = this.parseDecorators();
|
|
10205
|
+
const watchObjective = decorators.find((decorator) => decorator.name === "watch")?.args?.objective;
|
|
10009
10206
|
let isExported;
|
|
10010
10207
|
const filteredDecorators = decorators.filter((d) => {
|
|
10011
10208
|
if (d.name === "keep") {
|
|
@@ -10043,7 +10240,8 @@ var Parser = class _Parser {
|
|
|
10043
10240
|
decorators: filteredDecorators,
|
|
10044
10241
|
body,
|
|
10045
10242
|
isLibraryFn: this.inLibraryMode || void 0,
|
|
10046
|
-
isExported
|
|
10243
|
+
isExported,
|
|
10244
|
+
watchObjective
|
|
10047
10245
|
},
|
|
10048
10246
|
fnToken
|
|
10049
10247
|
);
|
|
@@ -10076,7 +10274,7 @@ var Parser = class _Parser {
|
|
|
10076
10274
|
return decorators;
|
|
10077
10275
|
}
|
|
10078
10276
|
parseDecoratorValue(value) {
|
|
10079
|
-
const match = value.match(/^@(\w+)(?:\((
|
|
10277
|
+
const match = value.match(/^@(\w+)(?:\((.*)\))?$/s);
|
|
10080
10278
|
if (!match) {
|
|
10081
10279
|
this.error(`Invalid decorator: ${value}`);
|
|
10082
10280
|
}
|
|
@@ -10085,6 +10283,9 @@ var Parser = class _Parser {
|
|
|
10085
10283
|
if (!argsStr) {
|
|
10086
10284
|
return { name };
|
|
10087
10285
|
}
|
|
10286
|
+
if (name === "profile") {
|
|
10287
|
+
this.error("@profile decorator does not accept arguments");
|
|
10288
|
+
}
|
|
10088
10289
|
const args = {};
|
|
10089
10290
|
if (name === "on") {
|
|
10090
10291
|
const eventTypeMatch = argsStr.match(/^([A-Za-z_][A-Za-z0-9_]*)$/);
|
|
@@ -10093,10 +10294,12 @@ var Parser = class _Parser {
|
|
|
10093
10294
|
return { name, args };
|
|
10094
10295
|
}
|
|
10095
10296
|
}
|
|
10096
|
-
if (name === "on_trigger" || name === "on_advancement" || name === "on_craft" || name === "on_join_team") {
|
|
10297
|
+
if (name === "watch" || name === "on_trigger" || name === "on_advancement" || name === "on_craft" || name === "on_join_team") {
|
|
10097
10298
|
const strMatch = argsStr.match(/^"([^"]*)"$/);
|
|
10098
10299
|
if (strMatch) {
|
|
10099
|
-
if (name === "
|
|
10300
|
+
if (name === "watch") {
|
|
10301
|
+
args.objective = strMatch[1];
|
|
10302
|
+
} else if (name === "on_trigger") {
|
|
10100
10303
|
args.trigger = strMatch[1];
|
|
10101
10304
|
} else if (name === "on_advancement") {
|
|
10102
10305
|
args.advancement = strMatch[1];
|
|
@@ -10108,6 +10311,24 @@ var Parser = class _Parser {
|
|
|
10108
10311
|
return { name, args };
|
|
10109
10312
|
}
|
|
10110
10313
|
}
|
|
10314
|
+
if (name === "config") {
|
|
10315
|
+
const configMatch = argsStr.match(/^"([^"]+)"\s*,\s*default\s*:\s*(-?\d+(?:\.\d+)?)$/);
|
|
10316
|
+
if (configMatch) {
|
|
10317
|
+
return { name, args: { configKey: configMatch[1], configDefault: parseFloat(configMatch[2]) } };
|
|
10318
|
+
}
|
|
10319
|
+
const keyOnlyMatch = argsStr.match(/^"([^"]+)"$/);
|
|
10320
|
+
if (keyOnlyMatch) {
|
|
10321
|
+
return { name, args: { configKey: keyOnlyMatch[1] } };
|
|
10322
|
+
}
|
|
10323
|
+
this.error(`Invalid @config syntax. Expected: @config("key", default: value) or @config("key")`);
|
|
10324
|
+
}
|
|
10325
|
+
if (name === "deprecated") {
|
|
10326
|
+
const strMatch = argsStr.match(/^"([^"]*)"$/);
|
|
10327
|
+
if (strMatch) {
|
|
10328
|
+
return { name, args: { message: strMatch[1] } };
|
|
10329
|
+
}
|
|
10330
|
+
return { name, args: {} };
|
|
10331
|
+
}
|
|
10111
10332
|
if (name === "require_on_load") {
|
|
10112
10333
|
const rawArgs = [];
|
|
10113
10334
|
for (const part of argsStr.split(",")) {
|
|
@@ -10245,7 +10466,16 @@ var Parser = class _Parser {
|
|
|
10245
10466
|
this.expect("{");
|
|
10246
10467
|
const stmts = [];
|
|
10247
10468
|
while (!this.check("}") && !this.check("eof")) {
|
|
10248
|
-
|
|
10469
|
+
try {
|
|
10470
|
+
stmts.push(this.parseStmt());
|
|
10471
|
+
} catch (err) {
|
|
10472
|
+
if (err instanceof DiagnosticError) {
|
|
10473
|
+
this.parseErrors.push(err);
|
|
10474
|
+
this.syncToNextStmt();
|
|
10475
|
+
} else {
|
|
10476
|
+
throw err;
|
|
10477
|
+
}
|
|
10478
|
+
}
|
|
10249
10479
|
}
|
|
10250
10480
|
this.expect("}");
|
|
10251
10481
|
return stmts;
|
|
@@ -10254,6 +10484,9 @@ var Parser = class _Parser {
|
|
|
10254
10484
|
if (this.check("let")) {
|
|
10255
10485
|
return this.parseLetStmt();
|
|
10256
10486
|
}
|
|
10487
|
+
if (this.check("const")) {
|
|
10488
|
+
return this.parseLocalConstDecl();
|
|
10489
|
+
}
|
|
10257
10490
|
if (this.check("return")) {
|
|
10258
10491
|
return this.parseReturnStmt();
|
|
10259
10492
|
}
|
|
@@ -10273,6 +10506,12 @@ var Parser = class _Parser {
|
|
|
10273
10506
|
if (this.check("while")) {
|
|
10274
10507
|
return this.parseWhileStmt();
|
|
10275
10508
|
}
|
|
10509
|
+
if (this.check("do")) {
|
|
10510
|
+
return this.parseDoWhileStmt();
|
|
10511
|
+
}
|
|
10512
|
+
if (this.check("repeat")) {
|
|
10513
|
+
return this.parseRepeatStmt();
|
|
10514
|
+
}
|
|
10276
10515
|
if (this.check("for")) {
|
|
10277
10516
|
return this.parseForStmt();
|
|
10278
10517
|
}
|
|
@@ -10327,6 +10566,16 @@ var Parser = class _Parser {
|
|
|
10327
10566
|
this.match(";");
|
|
10328
10567
|
return this.withLoc({ kind: "let", name, type, init }, letToken);
|
|
10329
10568
|
}
|
|
10569
|
+
parseLocalConstDecl() {
|
|
10570
|
+
const constToken = this.expect("const");
|
|
10571
|
+
const name = this.expect("ident").value;
|
|
10572
|
+
this.expect(":");
|
|
10573
|
+
const type = this.parseType();
|
|
10574
|
+
this.expect("=");
|
|
10575
|
+
const value = this.parseExpr();
|
|
10576
|
+
this.match(";");
|
|
10577
|
+
return this.withLoc({ kind: "const_decl", name, type, value }, constToken);
|
|
10578
|
+
}
|
|
10330
10579
|
parseReturnStmt() {
|
|
10331
10580
|
const returnToken = this.expect("return");
|
|
10332
10581
|
let value;
|
|
@@ -10357,9 +10606,7 @@ var Parser = class _Parser {
|
|
|
10357
10606
|
}
|
|
10358
10607
|
return this.withLoc({ kind: "if_let_some", binding, init, then: then2, else_: else_2 }, ifToken);
|
|
10359
10608
|
}
|
|
10360
|
-
this.
|
|
10361
|
-
const cond = this.parseExpr();
|
|
10362
|
-
this.expect(")");
|
|
10609
|
+
const cond = this.parseParenOptionalCond();
|
|
10363
10610
|
const then = this.parseBlock();
|
|
10364
10611
|
let else_;
|
|
10365
10612
|
if (this.match("else")) {
|
|
@@ -10373,12 +10620,44 @@ var Parser = class _Parser {
|
|
|
10373
10620
|
}
|
|
10374
10621
|
parseWhileStmt() {
|
|
10375
10622
|
const whileToken = this.expect("while");
|
|
10376
|
-
this.
|
|
10377
|
-
|
|
10378
|
-
|
|
10623
|
+
if (this.check("let") && this.peek(1).kind === "ident" && this.peek(1).value === "Some") {
|
|
10624
|
+
this.advance();
|
|
10625
|
+
this.advance();
|
|
10626
|
+
this.expect("(");
|
|
10627
|
+
const binding = this.expect("ident").value;
|
|
10628
|
+
this.expect(")");
|
|
10629
|
+
this.expect("=");
|
|
10630
|
+
const init = this.parseExpr();
|
|
10631
|
+
const body2 = this.parseBlock();
|
|
10632
|
+
return this.withLoc({ kind: "while_let_some", binding, init, body: body2 }, whileToken);
|
|
10633
|
+
}
|
|
10634
|
+
const cond = this.parseParenOptionalCond();
|
|
10379
10635
|
const body = this.parseBlock();
|
|
10380
10636
|
return this.withLoc({ kind: "while", cond, body }, whileToken);
|
|
10381
10637
|
}
|
|
10638
|
+
parseDoWhileStmt() {
|
|
10639
|
+
const doToken = this.expect("do");
|
|
10640
|
+
const body = this.parseBlock();
|
|
10641
|
+
this.expect("while");
|
|
10642
|
+
const cond = this.parseParenOptionalCond();
|
|
10643
|
+
this.match(";");
|
|
10644
|
+
return this.withLoc({ kind: "do_while", cond, body }, doToken);
|
|
10645
|
+
}
|
|
10646
|
+
parseRepeatStmt() {
|
|
10647
|
+
const repeatToken = this.expect("repeat");
|
|
10648
|
+
const countToken = this.expect("int_lit");
|
|
10649
|
+
const count = parseInt(countToken.value, 10);
|
|
10650
|
+
const body = this.parseBlock();
|
|
10651
|
+
return this.withLoc({ kind: "repeat", count, body }, repeatToken);
|
|
10652
|
+
}
|
|
10653
|
+
parseParenOptionalCond() {
|
|
10654
|
+
if (this.match("(")) {
|
|
10655
|
+
const cond = this.parseExpr();
|
|
10656
|
+
this.expect(")");
|
|
10657
|
+
return cond;
|
|
10658
|
+
}
|
|
10659
|
+
return this.parseExpr();
|
|
10660
|
+
}
|
|
10382
10661
|
parseForStmt() {
|
|
10383
10662
|
const forToken = this.expect("for");
|
|
10384
10663
|
if (this.check("ident") && this.peek(1).kind === "in") {
|
|
@@ -10495,6 +10774,21 @@ var Parser = class _Parser {
|
|
|
10495
10774
|
this.expect(")");
|
|
10496
10775
|
return { kind: "PatSome", binding };
|
|
10497
10776
|
}
|
|
10777
|
+
if (this.check("ident") && this.peek(1).kind === "::") {
|
|
10778
|
+
const enumName = this.advance().value;
|
|
10779
|
+
this.expect("::");
|
|
10780
|
+
const variant = this.expect("ident").value;
|
|
10781
|
+
const bindings = [];
|
|
10782
|
+
if (this.check("(")) {
|
|
10783
|
+
this.advance();
|
|
10784
|
+
while (!this.check(")") && !this.check("eof")) {
|
|
10785
|
+
bindings.push(this.expect("ident").value);
|
|
10786
|
+
if (!this.match(",")) break;
|
|
10787
|
+
}
|
|
10788
|
+
this.expect(")");
|
|
10789
|
+
}
|
|
10790
|
+
return { kind: "PatEnum", enumName, variant, bindings };
|
|
10791
|
+
}
|
|
10498
10792
|
if (this.check("int_lit")) {
|
|
10499
10793
|
const tok = this.advance();
|
|
10500
10794
|
return { kind: "PatInt", value: parseInt(tok.value, 10) };
|
|
@@ -10838,6 +11132,15 @@ var Parser = class _Parser {
|
|
|
10838
11132
|
continue;
|
|
10839
11133
|
}
|
|
10840
11134
|
if (expr.kind === "member") {
|
|
11135
|
+
if (expr.field === "unwrap_or") {
|
|
11136
|
+
const defaultExpr = this.parseExpr();
|
|
11137
|
+
this.expect(")");
|
|
11138
|
+
expr = this.withLoc(
|
|
11139
|
+
{ kind: "unwrap_or", opt: expr.obj, default_: defaultExpr },
|
|
11140
|
+
this.getLocToken(expr) ?? openParenToken
|
|
11141
|
+
);
|
|
11142
|
+
continue;
|
|
11143
|
+
}
|
|
10841
11144
|
const methodMap = {
|
|
10842
11145
|
"tag": "__entity_tag",
|
|
10843
11146
|
"untag": "__entity_untag",
|
|
@@ -10930,6 +11233,20 @@ var Parser = class _Parser {
|
|
|
10930
11233
|
this.expect("::");
|
|
10931
11234
|
const memberToken = this.expect("ident");
|
|
10932
11235
|
if (this.check("(")) {
|
|
11236
|
+
const isNamedArgs = this.peek(1).kind === "ident" && this.peek(2).kind === ":";
|
|
11237
|
+
if (isNamedArgs) {
|
|
11238
|
+
this.advance();
|
|
11239
|
+
const args2 = [];
|
|
11240
|
+
while (!this.check(")") && !this.check("eof")) {
|
|
11241
|
+
const fieldName = this.expect("ident").value;
|
|
11242
|
+
this.expect(":");
|
|
11243
|
+
const value = this.parseExpr();
|
|
11244
|
+
args2.push({ name: fieldName, value });
|
|
11245
|
+
if (!this.match(",")) break;
|
|
11246
|
+
}
|
|
11247
|
+
this.expect(")");
|
|
11248
|
+
return this.withLoc({ kind: "enum_construct", enumName: typeToken.value, variant: memberToken.value, args: args2 }, typeToken);
|
|
11249
|
+
}
|
|
10933
11250
|
this.advance();
|
|
10934
11251
|
const args = this.parseArgs();
|
|
10935
11252
|
this.expect(")");
|
|
@@ -11693,7 +12010,6 @@ var MC_TYPE_TO_ENTITY = {
|
|
|
11693
12010
|
var VOID_TYPE = { kind: "named", name: "void" };
|
|
11694
12011
|
var INT_TYPE = { kind: "named", name: "int" };
|
|
11695
12012
|
var STRING_TYPE = { kind: "named", name: "string" };
|
|
11696
|
-
var FORMAT_STRING_TYPE = { kind: "named", name: "format_string" };
|
|
11697
12013
|
var BUILTIN_SIGNATURES = {
|
|
11698
12014
|
setTimeout: {
|
|
11699
12015
|
params: [INT_TYPE, { kind: "function_type", params: [], return: VOID_TYPE }],
|
|
@@ -11706,15 +12022,25 @@ var BUILTIN_SIGNATURES = {
|
|
|
11706
12022
|
clearInterval: {
|
|
11707
12023
|
params: [INT_TYPE],
|
|
11708
12024
|
return: VOID_TYPE
|
|
12025
|
+
},
|
|
12026
|
+
int_to_str: {
|
|
12027
|
+
params: [INT_TYPE],
|
|
12028
|
+
return: STRING_TYPE
|
|
12029
|
+
},
|
|
12030
|
+
bool_to_str: {
|
|
12031
|
+
params: [{ kind: "named", name: "bool" }],
|
|
12032
|
+
return: STRING_TYPE
|
|
11709
12033
|
}
|
|
11710
12034
|
};
|
|
11711
|
-
var TypeChecker = class {
|
|
12035
|
+
var TypeChecker = class _TypeChecker {
|
|
11712
12036
|
constructor(source, filePath) {
|
|
11713
12037
|
this.lintWarnings = [];
|
|
11714
12038
|
this.functions = /* @__PURE__ */ new Map();
|
|
11715
12039
|
this.implMethods = /* @__PURE__ */ new Map();
|
|
11716
12040
|
this.structs = /* @__PURE__ */ new Map();
|
|
11717
12041
|
this.enums = /* @__PURE__ */ new Map();
|
|
12042
|
+
// enumName → variantName → field list (for payload variants)
|
|
12043
|
+
this.enumPayloads = /* @__PURE__ */ new Map();
|
|
11718
12044
|
this.consts = /* @__PURE__ */ new Map();
|
|
11719
12045
|
this.globals = /* @__PURE__ */ new Map();
|
|
11720
12046
|
this.currentFn = null;
|
|
@@ -11725,6 +12051,8 @@ var TypeChecker = class {
|
|
|
11725
12051
|
// Depth of loop/conditional nesting (for static-allocation enforcement)
|
|
11726
12052
|
this.loopDepth = 0;
|
|
11727
12053
|
this.condDepth = 0;
|
|
12054
|
+
// interface name → InterfaceDecl
|
|
12055
|
+
this.interfaces = /* @__PURE__ */ new Map();
|
|
11728
12056
|
this.richTextBuiltins = /* @__PURE__ */ new Map([
|
|
11729
12057
|
["say", { messageIndex: 0 }],
|
|
11730
12058
|
["announce", { messageIndex: 0 }],
|
|
@@ -11766,6 +12094,9 @@ var TypeChecker = class {
|
|
|
11766
12094
|
for (const fn of program.declarations) {
|
|
11767
12095
|
this.functions.set(fn.name, fn);
|
|
11768
12096
|
}
|
|
12097
|
+
for (const iface of program.interfaces ?? []) {
|
|
12098
|
+
this.interfaces.set(iface.name, iface);
|
|
12099
|
+
}
|
|
11769
12100
|
for (const global of program.globals ?? []) {
|
|
11770
12101
|
this.globals.set(global.name, this.normalizeType(global.type));
|
|
11771
12102
|
}
|
|
@@ -11795,13 +12126,47 @@ var TypeChecker = class {
|
|
|
11795
12126
|
fields.set(field.name, field.type);
|
|
11796
12127
|
}
|
|
11797
12128
|
this.structs.set(struct.name, fields);
|
|
12129
|
+
if (struct.isSingleton) {
|
|
12130
|
+
const structType = { kind: "struct", name: struct.name };
|
|
12131
|
+
let singletonMethods = this.implMethods.get(struct.name);
|
|
12132
|
+
if (!singletonMethods) {
|
|
12133
|
+
singletonMethods = /* @__PURE__ */ new Map();
|
|
12134
|
+
this.implMethods.set(struct.name, singletonMethods);
|
|
12135
|
+
}
|
|
12136
|
+
const voidType = { kind: "named", name: "void" };
|
|
12137
|
+
singletonMethods.set("get", {
|
|
12138
|
+
name: "get",
|
|
12139
|
+
params: [],
|
|
12140
|
+
returnType: structType,
|
|
12141
|
+
decorators: [],
|
|
12142
|
+
body: [],
|
|
12143
|
+
typeParams: void 0,
|
|
12144
|
+
isLibraryFn: true
|
|
12145
|
+
});
|
|
12146
|
+
singletonMethods.set("set", {
|
|
12147
|
+
name: "set",
|
|
12148
|
+
params: [{ name: "gs", type: structType }],
|
|
12149
|
+
returnType: voidType,
|
|
12150
|
+
decorators: [],
|
|
12151
|
+
body: [],
|
|
12152
|
+
typeParams: void 0,
|
|
12153
|
+
isLibraryFn: true
|
|
12154
|
+
});
|
|
12155
|
+
}
|
|
11798
12156
|
}
|
|
11799
12157
|
for (const enumDecl of program.enums ?? []) {
|
|
11800
12158
|
const variants = /* @__PURE__ */ new Map();
|
|
12159
|
+
const payloads = /* @__PURE__ */ new Map();
|
|
11801
12160
|
for (const variant of enumDecl.variants) {
|
|
11802
12161
|
variants.set(variant.name, variant.value ?? 0);
|
|
12162
|
+
if (variant.fields && variant.fields.length > 0) {
|
|
12163
|
+
payloads.set(variant.name, variant.fields);
|
|
12164
|
+
}
|
|
11803
12165
|
}
|
|
11804
12166
|
this.enums.set(enumDecl.name, variants);
|
|
12167
|
+
if (payloads.size > 0) {
|
|
12168
|
+
this.enumPayloads.set(enumDecl.name, payloads);
|
|
12169
|
+
}
|
|
11805
12170
|
}
|
|
11806
12171
|
for (const constDecl of program.consts ?? []) {
|
|
11807
12172
|
const constType = this.normalizeType(constDecl.type);
|
|
@@ -11814,6 +12179,21 @@ var TypeChecker = class {
|
|
|
11814
12179
|
}
|
|
11815
12180
|
this.consts.set(constDecl.name, constType);
|
|
11816
12181
|
}
|
|
12182
|
+
for (const implBlock of program.implBlocks ?? []) {
|
|
12183
|
+
if (!implBlock.traitName) continue;
|
|
12184
|
+
const iface = this.interfaces.get(implBlock.traitName);
|
|
12185
|
+
if (!iface) continue;
|
|
12186
|
+
const implementedMethods = new Set(implBlock.methods.map((m) => m.name));
|
|
12187
|
+
for (const required of iface.methods) {
|
|
12188
|
+
if (!implementedMethods.has(required.name)) {
|
|
12189
|
+
const span = implBlock.span ?? required.span;
|
|
12190
|
+
this.report(
|
|
12191
|
+
`Struct '${implBlock.typeName}' does not implement required method '${required.name}' from interface '${implBlock.traitName}'`,
|
|
12192
|
+
span ?? { line: 1, col: 1 }
|
|
12193
|
+
);
|
|
12194
|
+
}
|
|
12195
|
+
}
|
|
12196
|
+
}
|
|
11817
12197
|
for (const fn of program.declarations) {
|
|
11818
12198
|
this.checkFunction(fn);
|
|
11819
12199
|
}
|
|
@@ -11859,6 +12239,30 @@ var TypeChecker = class {
|
|
|
11859
12239
|
this.currentReturnType = null;
|
|
11860
12240
|
}
|
|
11861
12241
|
checkFunctionDecorators(fn) {
|
|
12242
|
+
const watchDecorators = fn.decorators.filter((decorator) => decorator.name === "watch");
|
|
12243
|
+
if (watchDecorators.length > 1) {
|
|
12244
|
+
this.report(`Function '${fn.name}' cannot have multiple @watch decorators`, fn);
|
|
12245
|
+
return;
|
|
12246
|
+
}
|
|
12247
|
+
if (watchDecorators.length === 1) {
|
|
12248
|
+
const objective = watchDecorators[0].args?.objective;
|
|
12249
|
+
if (!objective) {
|
|
12250
|
+
this.report(`Function '${fn.name}' is missing a scoreboard objective in @watch("...")`, fn);
|
|
12251
|
+
return;
|
|
12252
|
+
}
|
|
12253
|
+
if (fn.params.length > 0) {
|
|
12254
|
+
this.report(`@watch handler '${fn.name}' cannot declare parameters`, fn);
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
12257
|
+
const profileDecorators = fn.decorators.filter((decorator) => decorator.name === "profile");
|
|
12258
|
+
if (profileDecorators.length > 1) {
|
|
12259
|
+
this.report(`Function '${fn.name}' cannot have multiple @profile decorators`, fn);
|
|
12260
|
+
return;
|
|
12261
|
+
}
|
|
12262
|
+
if (profileDecorators.length === 1 && (profileDecorators[0].rawArgs?.length || profileDecorators[0].args && Object.keys(profileDecorators[0].args).length > 0)) {
|
|
12263
|
+
this.report(`@profile decorator on '${fn.name}' does not accept arguments`, fn);
|
|
12264
|
+
return;
|
|
12265
|
+
}
|
|
11862
12266
|
const eventDecorators = fn.decorators.filter((decorator) => decorator.name === "on");
|
|
11863
12267
|
if (eventDecorators.length === 0) {
|
|
11864
12268
|
return;
|
|
@@ -11968,8 +12372,21 @@ var TypeChecker = class {
|
|
|
11968
12372
|
if (!isUnknown(subjectType) && !isUnknown(patternType) && !this.typesMatch(subjectType, patternType)) {
|
|
11969
12373
|
this.report("Match arm pattern type must match subject type", arm.pattern.expr);
|
|
11970
12374
|
}
|
|
12375
|
+
this.checkBlock(arm.body);
|
|
12376
|
+
} else if (arm.pattern.kind === "PatEnum") {
|
|
12377
|
+
const pat = arm.pattern;
|
|
12378
|
+
const variantPayloads = this.enumPayloads.get(pat.enumName)?.get(pat.variant) ?? [];
|
|
12379
|
+
const savedScope = new Map(this.scope);
|
|
12380
|
+
for (let i = 0; i < pat.bindings.length; i++) {
|
|
12381
|
+
const fieldDef = variantPayloads[i];
|
|
12382
|
+
const bindingType = fieldDef ? fieldDef.type : { kind: "named", name: "int" };
|
|
12383
|
+
this.scope.set(pat.bindings[i], { type: bindingType, mutable: false });
|
|
12384
|
+
}
|
|
12385
|
+
this.checkBlock(arm.body);
|
|
12386
|
+
this.scope = savedScope;
|
|
12387
|
+
} else {
|
|
12388
|
+
this.checkBlock(arm.body);
|
|
11971
12389
|
}
|
|
11972
|
-
this.checkBlock(arm.body);
|
|
11973
12390
|
}
|
|
11974
12391
|
break;
|
|
11975
12392
|
case "as_block": {
|
|
@@ -12008,6 +12425,9 @@ var TypeChecker = class {
|
|
|
12008
12425
|
break;
|
|
12009
12426
|
case "raw":
|
|
12010
12427
|
break;
|
|
12428
|
+
case "const_decl":
|
|
12429
|
+
this.scope.set(stmt.name, { type: stmt.type, mutable: false });
|
|
12430
|
+
break;
|
|
12011
12431
|
}
|
|
12012
12432
|
}
|
|
12013
12433
|
checkLetDestructStmt(stmt) {
|
|
@@ -12234,6 +12654,31 @@ var TypeChecker = class {
|
|
|
12234
12654
|
}
|
|
12235
12655
|
}
|
|
12236
12656
|
break;
|
|
12657
|
+
case "enum_construct": {
|
|
12658
|
+
if (!this.enums.has(expr.enumName)) {
|
|
12659
|
+
this.report(`Unknown enum '${expr.enumName}'`, expr);
|
|
12660
|
+
break;
|
|
12661
|
+
}
|
|
12662
|
+
const variants = this.enums.get(expr.enumName);
|
|
12663
|
+
if (!variants.has(expr.variant)) {
|
|
12664
|
+
this.report(`Enum '${expr.enumName}' has no variant '${expr.variant}'`, expr);
|
|
12665
|
+
break;
|
|
12666
|
+
}
|
|
12667
|
+
const variantPayloads = this.enumPayloads.get(expr.enumName)?.get(expr.variant) ?? [];
|
|
12668
|
+
if (variantPayloads.length === 0 && expr.args.length > 0) {
|
|
12669
|
+
this.report(`Enum variant '${expr.enumName}::${expr.variant}' has no payload fields`, expr);
|
|
12670
|
+
break;
|
|
12671
|
+
}
|
|
12672
|
+
for (const arg of expr.args) {
|
|
12673
|
+
const fieldDef = variantPayloads.find((f) => f.name === arg.name);
|
|
12674
|
+
if (!fieldDef) {
|
|
12675
|
+
this.report(`Unknown field '${arg.name}' for enum variant '${expr.enumName}::${expr.variant}'`, expr);
|
|
12676
|
+
} else {
|
|
12677
|
+
this.checkExpr(arg.value, fieldDef.type);
|
|
12678
|
+
}
|
|
12679
|
+
}
|
|
12680
|
+
break;
|
|
12681
|
+
}
|
|
12237
12682
|
case "blockpos":
|
|
12238
12683
|
break;
|
|
12239
12684
|
// Literals don't need checking
|
|
@@ -12345,7 +12790,7 @@ var TypeChecker = class {
|
|
|
12345
12790
|
return;
|
|
12346
12791
|
}
|
|
12347
12792
|
const messageType = this.inferType(message);
|
|
12348
|
-
if (messageType.kind !== "named" || messageType.name !== "string"
|
|
12793
|
+
if (messageType.kind !== "named" || messageType.name !== "string") {
|
|
12349
12794
|
this.report(
|
|
12350
12795
|
`Argument ${messageIndex + 1} of '${expr.fn}' expects string or format_string, got ${this.typeToString(messageType)}`,
|
|
12351
12796
|
message
|
|
@@ -12570,7 +13015,7 @@ var TypeChecker = class {
|
|
|
12570
13015
|
this.checkExpr(part.expr);
|
|
12571
13016
|
}
|
|
12572
13017
|
}
|
|
12573
|
-
return
|
|
13018
|
+
return STRING_TYPE;
|
|
12574
13019
|
case "blockpos":
|
|
12575
13020
|
return { kind: "named", name: "BlockPos" };
|
|
12576
13021
|
case "ident":
|
|
@@ -12630,6 +13075,11 @@ var TypeChecker = class {
|
|
|
12630
13075
|
return { kind: "enum", name: expr.enumName };
|
|
12631
13076
|
}
|
|
12632
13077
|
return { kind: "named", name: "void" };
|
|
13078
|
+
case "enum_construct":
|
|
13079
|
+
if (this.enums.has(expr.enumName)) {
|
|
13080
|
+
return { kind: "enum", name: expr.enumName };
|
|
13081
|
+
}
|
|
13082
|
+
return { kind: "named", name: "void" };
|
|
12633
13083
|
case "member":
|
|
12634
13084
|
if (expr.obj.kind === "ident" && this.enums.has(expr.obj.name)) {
|
|
12635
13085
|
return { kind: "enum", name: expr.obj.name };
|
|
@@ -12735,6 +13185,21 @@ var TypeChecker = class {
|
|
|
12735
13185
|
}
|
|
12736
13186
|
return "entity";
|
|
12737
13187
|
}
|
|
13188
|
+
static {
|
|
13189
|
+
// Reverse map: parser sometimes remaps method names (e.g. add→set_add) for builtins.
|
|
13190
|
+
// When the receiver is a struct with an impl method matching the original name, use that.
|
|
13191
|
+
this.PARSER_METHOD_REMAP = {
|
|
13192
|
+
"set_add": "add",
|
|
13193
|
+
"set_contains": "contains",
|
|
13194
|
+
"set_remove": "remove",
|
|
13195
|
+
"set_clear": "clear",
|
|
13196
|
+
"__array_push": "push",
|
|
13197
|
+
"__array_pop": "pop",
|
|
13198
|
+
"__entity_tag": "tag",
|
|
13199
|
+
"__entity_untag": "untag",
|
|
13200
|
+
"__entity_has_tag": "has_tag"
|
|
13201
|
+
};
|
|
13202
|
+
}
|
|
12738
13203
|
resolveInstanceMethod(expr) {
|
|
12739
13204
|
const receiver = expr.args[0];
|
|
12740
13205
|
if (!receiver) {
|
|
@@ -12744,7 +13209,8 @@ var TypeChecker = class {
|
|
|
12744
13209
|
if (receiverType.kind !== "struct") {
|
|
12745
13210
|
return null;
|
|
12746
13211
|
}
|
|
12747
|
-
const
|
|
13212
|
+
const methodName = _TypeChecker.PARSER_METHOD_REMAP[expr.fn] ?? expr.fn;
|
|
13213
|
+
const method = this.implMethods.get(receiverType.name)?.get(expr.fn) ?? this.implMethods.get(receiverType.name)?.get(methodName);
|
|
12748
13214
|
if (!method || method.params[0]?.name !== "self") {
|
|
12749
13215
|
return null;
|
|
12750
13216
|
}
|
|
@@ -13961,6 +14427,7 @@ function toDiagnostic(err) {
|
|
|
13961
14427
|
var DECORATOR_DOCS = {
|
|
13962
14428
|
tick: "Runs every game tick.\n\n**Optional args:** `rate=N` (every N ticks, e.g. `@tick(rate=20)` = once per second)\n\nExample: `@tick fn every_tick() {}` or `@tick(rate=20) fn every_second() {}`",
|
|
13963
14429
|
load: "Runs once on `/reload`. Use for initialization.\n\nExample: `@load fn init() { scoreboard_create(...) }`",
|
|
14430
|
+
watch: 'Runs when a scoreboard objective changes for a player.\n\n**Required arg:** objective name.\n\nExample: `@watch("rs.kills") fn on_kill_change() {}`',
|
|
13964
14431
|
coroutine: "Wraps a loop to spread execution across multiple ticks.\n\n**Required arg:** `batch=N` \u2014 iterations per tick.\n\nExample: `@coroutine(batch=10) fn scan_blocks() { for i in 0..1000 { ... } }`",
|
|
13965
14432
|
schedule: "Schedules the function to run after a delay.\n\n**Required arg:** `ticks=N`\n\nExample: `@schedule(ticks=100) fn delayed() {}`",
|
|
13966
14433
|
on_trigger: 'Runs when a player executes `/trigger <name>`.\n\n**Required arg:** trigger objective name.\n\nExample: `@on_trigger("shop") fn open_shop() {}`',
|
|
@@ -14107,6 +14574,7 @@ var TYPE_COMPLETIONS = [
|
|
|
14107
14574
|
}));
|
|
14108
14575
|
var DECORATOR_COMPLETIONS = [
|
|
14109
14576
|
{ label: "@tick", detail: "Run every game tick (~20 Hz)", insertText: "tick" },
|
|
14577
|
+
{ label: "@watch", detail: "Run when a scoreboard objective changes", insertText: "watch" },
|
|
14110
14578
|
{ label: "@load", detail: "Run on /reload (initialization)", insertText: "load" },
|
|
14111
14579
|
{ label: "@on_trigger", detail: "Run when a player uses /trigger", insertText: "on_trigger" },
|
|
14112
14580
|
{ label: "@schedule", detail: "Schedule function after N ticks", insertText: "schedule" },
|