redscript-mc 2.0.0 → 2.1.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/.claudeignore +21 -0
- package/README.md +12 -16
- package/README.zh.md +2 -2
- package/dist/cli.js +0 -0
- package/dist/src/__tests__/budget.test.js +261 -0
- package/dist/src/__tests__/diagnostics.test.js +2 -3
- package/dist/src/__tests__/e2e/coroutine.test.d.ts +7 -0
- package/dist/src/__tests__/e2e/coroutine.test.js +132 -0
- package/dist/{src2 → src}/__tests__/e2e/macros.test.js +1 -1
- package/dist/{src2 → src}/__tests__/e2e/migrate.test.js +1 -1
- package/dist/src/__tests__/e2e/stdlib-e2e.test.d.ts +10 -0
- package/dist/src/__tests__/e2e/stdlib-e2e.test.js +324 -0
- package/dist/src/__tests__/enum.test.d.ts +10 -0
- package/dist/src/__tests__/enum.test.js +389 -0
- package/dist/src/__tests__/generics.test.d.ts +14 -0
- package/dist/src/__tests__/generics.test.js +367 -0
- package/dist/{src2 → src}/__tests__/hir/desugar.test.js +2 -2
- package/dist/src/__tests__/incremental.test.d.ts +5 -0
- package/dist/src/__tests__/incremental.test.js +308 -0
- package/dist/src/__tests__/lsp.test.d.ts +7 -0
- package/dist/src/__tests__/lsp.test.js +245 -0
- package/dist/src/__tests__/mc-version.test.d.ts +10 -0
- package/dist/src/__tests__/mc-version.test.js +154 -0
- package/dist/{src2 → src}/__tests__/mir/arithmetic.test.js +2 -2
- package/dist/{src2 → src}/__tests__/mir/control-flow.test.js +2 -2
- package/dist/src/__tests__/modules.test.d.ts +7 -0
- package/dist/src/__tests__/modules.test.js +333 -0
- package/dist/src/__tests__/optimizer/coroutine.test.d.ts +12 -0
- package/dist/src/__tests__/optimizer/coroutine.test.js +251 -0
- package/dist/src/__tests__/optimizer/interprocedural.test.js +145 -0
- package/dist/src/__tests__/optimizer/lir/const_imm.test.js +138 -0
- package/dist/src/__tests__/optimizer/lir/dead_slot.test.js +141 -0
- package/dist/src/__tests__/optimizer/lir/peephole.test.js +126 -0
- package/dist/src/__tests__/optimizer/lir/pipeline.test.js +84 -0
- package/dist/src/__tests__/optimizer/nbt-batch.test.js +110 -0
- package/dist/src/__tests__/optimizer/selector-cache.test.js +103 -0
- package/dist/src/__tests__/optimizer/unroll.test.js +206 -0
- package/dist/src/__tests__/option.test.d.ts +14 -0
- package/dist/src/__tests__/option.test.js +275 -0
- package/dist/src/__tests__/schedule.test.d.ts +7 -0
- package/dist/src/__tests__/schedule.test.js +98 -0
- package/dist/src/__tests__/sourcemap.test.d.ts +7 -0
- package/dist/src/__tests__/sourcemap.test.js +227 -0
- package/dist/src/__tests__/tuple.test.d.ts +11 -0
- package/dist/src/__tests__/tuple.test.js +202 -0
- package/dist/src/__tests__/typechecker-strict.test.d.ts +10 -0
- package/dist/src/__tests__/typechecker-strict.test.js +197 -0
- package/dist/src/ast/types.d.ts +56 -2
- package/dist/src/cache/deps.d.ts +41 -0
- package/dist/src/cache/deps.js +158 -0
- package/dist/src/cache/incremental.d.ts +35 -0
- package/dist/src/cache/incremental.js +165 -0
- package/dist/src/cache/index.d.ts +37 -0
- package/dist/src/cache/index.js +152 -0
- package/dist/src/cli.js +76 -45
- package/dist/src/compile.d.ts +2 -2
- package/dist/src/compile.js +1 -1
- package/dist/src/diagnostics/index.d.ts +1 -1
- package/dist/src/diagnostics/index.js +8 -11
- package/dist/src/emit/compile.d.ts +29 -0
- package/dist/src/emit/compile.js +143 -0
- package/dist/{src2 → src}/emit/index.d.ts +9 -0
- package/dist/{src2 → src}/emit/index.js +59 -8
- package/dist/src/emit/modules.d.ts +29 -0
- package/dist/src/emit/modules.js +492 -0
- package/dist/src/emit/sourcemap.d.ts +53 -0
- package/dist/src/emit/sourcemap.js +73 -0
- package/dist/{src2 → src}/hir/lower.d.ts +1 -1
- package/dist/{src2 → src}/hir/lower.js +22 -1
- package/dist/src/hir/monomorphize.d.ts +22 -0
- package/dist/src/hir/monomorphize.js +379 -0
- package/dist/{src2 → src}/hir/types.d.ts +35 -2
- package/dist/src/index.d.ts +19 -2
- package/dist/src/index.js +36 -14
- package/dist/src/lexer/index.d.ts +1 -1
- package/dist/src/lexer/index.js +1 -0
- package/dist/src/lir/budget.d.ts +37 -0
- package/dist/src/lir/budget.js +280 -0
- package/dist/{src2 → src}/lir/lower.js +19 -0
- package/dist/{src2 → src}/lir/types.d.ts +7 -4
- package/dist/src/lsp/main.d.ts +8 -0
- package/dist/src/lsp/main.js +11 -0
- package/dist/src/lsp/server.d.ts +11 -0
- package/dist/src/lsp/server.js +352 -0
- package/dist/{src2 → src}/mir/lower.d.ts +1 -1
- package/dist/{src2 → src}/mir/lower.js +244 -10
- package/dist/{src2 → src}/mir/types.d.ts +10 -2
- package/dist/src/optimizer/coroutine.d.ts +34 -0
- package/dist/src/optimizer/coroutine.js +789 -0
- package/dist/src/optimizer/dce.d.ts +8 -34
- package/dist/src/optimizer/dce.js +146 -629
- package/dist/src/optimizer/interprocedural.d.ts +14 -0
- package/dist/src/optimizer/interprocedural.js +186 -0
- package/dist/src/optimizer/lir/const_imm.d.ts +12 -0
- package/dist/src/optimizer/lir/const_imm.js +139 -0
- package/dist/src/optimizer/lir/dead_slot.d.ts +14 -0
- package/dist/src/optimizer/lir/dead_slot.js +130 -0
- package/dist/src/optimizer/lir/peephole.d.ts +21 -0
- package/dist/src/optimizer/lir/peephole.js +52 -0
- package/dist/src/optimizer/lir/pipeline.d.ts +10 -0
- package/dist/src/optimizer/lir/pipeline.js +34 -0
- package/dist/src/optimizer/nbt-batch.d.ts +11 -0
- package/dist/src/optimizer/nbt-batch.js +51 -0
- package/dist/{src2 → src}/optimizer/pipeline.d.ts +4 -0
- package/dist/{src2 → src}/optimizer/pipeline.js +17 -1
- package/dist/src/optimizer/selector-cache.d.ts +22 -0
- package/dist/src/optimizer/selector-cache.js +100 -0
- package/dist/src/optimizer/unroll.d.ts +32 -0
- package/dist/src/optimizer/unroll.js +348 -0
- package/dist/src/parser/index.d.ts +8 -0
- package/dist/src/parser/index.js +204 -14
- package/dist/src/repl.d.ts +1 -1
- package/dist/src/typechecker/index.d.ts +4 -0
- package/dist/src/typechecker/index.js +198 -13
- package/dist/src/types/mc-version.d.ts +24 -0
- package/dist/src/types/mc-version.js +49 -0
- package/docs/ROADMAP.md +395 -0
- package/docs/compiler-pipeline-redesign.md +27 -10
- package/editors/vscode/out/extension.js +25176 -8000
- package/editors/vscode/package-lock.json +90 -6
- package/editors/vscode/package.json +3 -2
- package/editors/vscode/src/extension.ts +97 -67
- package/examples/showcase.mcrs +3 -3
- package/jest.config.js +1 -1
- package/package.json +9 -3
- package/src/__tests__/budget.test.ts +297 -0
- package/src/__tests__/diagnostics.test.ts +2 -3
- package/src/__tests__/e2e/coroutine.test.ts +142 -0
- package/{src2 → src}/__tests__/e2e/macros.test.ts +1 -1
- package/{src2 → src}/__tests__/e2e/migrate.test.ts +1 -1
- package/src/__tests__/e2e/stdlib-e2e.test.ts +348 -0
- package/src/__tests__/enum.test.ts +425 -0
- package/src/__tests__/generics.test.ts +390 -0
- package/{src2 → src}/__tests__/hir/desugar.test.ts +2 -2
- package/src/__tests__/incremental.test.ts +337 -0
- package/src/__tests__/lsp.test.ts +270 -0
- package/src/__tests__/mc-version.test.ts +178 -0
- package/{src2 → src}/__tests__/mir/arithmetic.test.ts +2 -2
- package/{src2 → src}/__tests__/mir/control-flow.test.ts +2 -2
- package/src/__tests__/modules.test.ts +365 -0
- package/src/__tests__/optimizer/coroutine.test.ts +312 -0
- package/src/__tests__/optimizer/interprocedural.test.ts +174 -0
- package/src/__tests__/optimizer/lir/const_imm.test.ts +151 -0
- package/src/__tests__/optimizer/lir/dead_slot.test.ts +156 -0
- package/src/__tests__/optimizer/lir/peephole.test.ts +136 -0
- package/src/__tests__/optimizer/lir/pipeline.test.ts +113 -0
- package/src/__tests__/optimizer/nbt-batch.test.ts +119 -0
- package/src/__tests__/optimizer/selector-cache.test.ts +112 -0
- package/src/__tests__/optimizer/unroll.test.ts +231 -0
- package/src/__tests__/option.test.ts +299 -0
- package/src/__tests__/schedule.test.ts +105 -0
- package/src/__tests__/sourcemap.test.ts +254 -0
- package/src/__tests__/tuple.test.ts +220 -0
- package/src/__tests__/typechecker-strict.test.ts +216 -0
- package/src/ast/types.ts +33 -2
- package/src/cache/deps.ts +132 -0
- package/src/cache/incremental.ts +173 -0
- package/src/cache/index.ts +135 -0
- package/src/cli.ts +88 -45
- package/src/compile.ts +2 -2
- package/src/diagnostics/index.ts +8 -11
- package/src/emit/compile.ts +177 -0
- package/{src2 → src}/emit/index.ts +72 -8
- package/src/emit/modules.ts +581 -0
- package/src/emit/sourcemap.ts +101 -0
- package/{src2 → src}/hir/lower.ts +29 -2
- package/src/hir/monomorphize.ts +416 -0
- package/{src2 → src}/hir/types.ts +15 -3
- package/src/index.ts +29 -10
- package/src/lexer/index.ts +2 -1
- package/src/lir/budget.ts +321 -0
- package/{src2 → src}/lir/lower.ts +32 -1
- package/{src2 → src}/lir/types.ts +7 -3
- package/src/lsp/main.ts +9 -0
- package/src/lsp/server.ts +414 -0
- package/{src2 → src}/mir/lower.ts +251 -8
- package/{src2 → src}/mir/types.ts +12 -1
- package/src/optimizer/coroutine.ts +996 -0
- package/{src2 → src}/optimizer/dce.ts +2 -1
- package/src/optimizer/interprocedural.ts +177 -0
- package/src/optimizer/lir/const_imm.ts +143 -0
- package/src/optimizer/lir/dead_slot.ts +123 -0
- package/src/optimizer/lir/peephole.ts +57 -0
- package/src/optimizer/lir/pipeline.ts +37 -0
- package/src/optimizer/nbt-batch.ts +50 -0
- package/{src2 → src}/optimizer/pipeline.ts +16 -1
- package/src/optimizer/selector-cache.ts +103 -0
- package/src/optimizer/unroll.ts +386 -0
- package/src/parser/index.ts +212 -15
- package/src/repl.ts +1 -1
- package/src/stdlib/math.mcrs +4 -4
- package/src/templates/quest.mcrs +4 -4
- package/src/typechecker/index.ts +215 -15
- package/src/types/mc-version.ts +46 -0
- package/tsconfig.json +1 -1
- package/.claude/commands/build-test.md +0 -10
- package/.claude/commands/deploy-demo.md +0 -12
- package/.claude/commands/stage-status.md +0 -13
- package/.claude/settings.json +0 -12
- package/CLAUDE.md +0 -231
- package/dist/__tests__/cli.test.js +0 -278
- package/dist/__tests__/codegen.test.js +0 -152
- package/dist/__tests__/compile-all.test.d.ts +0 -10
- package/dist/__tests__/compile-all.test.js +0 -108
- package/dist/__tests__/dce.test.js +0 -138
- package/dist/__tests__/diagnostics.test.d.ts +0 -4
- package/dist/__tests__/diagnostics.test.js +0 -149
- package/dist/__tests__/e2e.test.d.ts +0 -6
- package/dist/__tests__/e2e.test.js +0 -1847
- package/dist/__tests__/entity-types.test.js +0 -203
- package/dist/__tests__/formatter.test.js +0 -40
- package/dist/__tests__/lexer.test.js +0 -343
- package/dist/__tests__/lowering.test.js +0 -1015
- package/dist/__tests__/macro.test.d.ts +0 -8
- package/dist/__tests__/macro.test.js +0 -305
- package/dist/__tests__/mc-integration.test.d.ts +0 -12
- package/dist/__tests__/mc-integration.test.js +0 -819
- package/dist/__tests__/mc-syntax.test.js +0 -124
- package/dist/__tests__/nbt.test.js +0 -82
- package/dist/__tests__/optimizer-advanced.test.js +0 -124
- package/dist/__tests__/optimizer.test.d.ts +0 -1
- package/dist/__tests__/optimizer.test.js +0 -149
- package/dist/__tests__/parser.test.d.ts +0 -1
- package/dist/__tests__/parser.test.js +0 -807
- package/dist/__tests__/repl.test.d.ts +0 -1
- package/dist/__tests__/repl.test.js +0 -27
- package/dist/__tests__/runtime.test.d.ts +0 -1
- package/dist/__tests__/runtime.test.js +0 -289
- package/dist/__tests__/stdlib-advanced.test.d.ts +0 -4
- package/dist/__tests__/stdlib-advanced.test.js +0 -378
- package/dist/__tests__/stdlib-bigint.test.d.ts +0 -7
- package/dist/__tests__/stdlib-bigint.test.js +0 -428
- package/dist/__tests__/stdlib-math.test.d.ts +0 -7
- package/dist/__tests__/stdlib-math.test.js +0 -352
- package/dist/__tests__/stdlib-vec.test.d.ts +0 -4
- package/dist/__tests__/stdlib-vec.test.js +0 -264
- package/dist/__tests__/structure-optimizer.test.d.ts +0 -1
- package/dist/__tests__/structure-optimizer.test.js +0 -33
- package/dist/__tests__/typechecker.test.d.ts +0 -1
- package/dist/__tests__/typechecker.test.js +0 -552
- package/dist/__tests__/var-allocator.test.d.ts +0 -1
- package/dist/__tests__/var-allocator.test.js +0 -69
- package/dist/ast/types.d.ts +0 -514
- package/dist/ast/types.js +0 -9
- package/dist/builtins/metadata.d.ts +0 -36
- package/dist/builtins/metadata.js +0 -1014
- package/dist/cli.d.ts +0 -11
- package/dist/codegen/cmdblock/index.d.ts +0 -26
- package/dist/codegen/cmdblock/index.js +0 -45
- package/dist/codegen/mcfunction/index.d.ts +0 -40
- package/dist/codegen/mcfunction/index.js +0 -606
- package/dist/codegen/structure/index.d.ts +0 -24
- package/dist/codegen/structure/index.js +0 -279
- package/dist/codegen/var-allocator.d.ts +0 -45
- package/dist/codegen/var-allocator.js +0 -104
- package/dist/compile.d.ts +0 -68
- package/dist/data/arena/function/__load.mcfunction +0 -6
- package/dist/data/arena/function/__tick.mcfunction +0 -2
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +0 -3
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +0 -3
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +0 -7
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +0 -4
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +0 -6
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +0 -4
- package/dist/data/arena/function/announce_leaders.mcfunction +0 -6
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +0 -1
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +0 -4
- package/dist/data/arena/function/arena_tick.mcfunction +0 -11
- package/dist/data/counter/function/__load.mcfunction +0 -5
- package/dist/data/counter/function/__tick.mcfunction +0 -2
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +0 -1
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +0 -3
- package/dist/data/counter/function/counter_tick.mcfunction +0 -11
- package/dist/data/gcd2/function/__load.mcfunction +0 -3
- package/dist/data/gcd2/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/gcd2/function/abs/then_0.mcfunction +0 -5
- package/dist/data/gcd2/function/abs.mcfunction +0 -7
- package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +0 -7
- package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +0 -5
- package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +0 -3
- package/dist/data/gcd2/function/gcd.mcfunction +0 -14
- package/dist/data/gcd3/function/__load.mcfunction +0 -3
- package/dist/data/gcd3/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/gcd3/function/abs/then_0.mcfunction +0 -5
- package/dist/data/gcd3/function/abs.mcfunction +0 -7
- package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +0 -7
- package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +0 -5
- package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +0 -3
- package/dist/data/gcd3/function/gcd.mcfunction +0 -14
- package/dist/data/gcd3/function/test.mcfunction +0 -7
- package/dist/data/gcd3nm/function/__load.mcfunction +0 -3
- package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/gcd3nm/function/abs/then_0.mcfunction +0 -5
- package/dist/data/gcd3nm/function/abs.mcfunction +0 -7
- package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +0 -7
- package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +0 -5
- package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +0 -3
- package/dist/data/gcd3nm/function/gcd.mcfunction +0 -14
- package/dist/data/gcd3nm/function/test.mcfunction +0 -7
- package/dist/data/gcd_test/function/__load.mcfunction +0 -3
- package/dist/data/gcd_test/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/gcd_test/function/abs/then_0.mcfunction +0 -5
- package/dist/data/gcd_test/function/abs.mcfunction +0 -7
- package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +0 -7
- package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +0 -5
- package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +0 -3
- package/dist/data/gcd_test/function/gcd.mcfunction +0 -14
- package/dist/data/isqrttest/function/__load.mcfunction +0 -6
- package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +0 -12
- package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +0 -5
- package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +0 -3
- package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +0 -4
- package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +0 -6
- package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +0 -3
- package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +0 -3
- package/dist/data/isqrttest/function/isqrt.mcfunction +0 -7
- package/dist/data/isqrttest/function/test.mcfunction +0 -6
- package/dist/data/mathtest/function/__load.mcfunction +0 -3
- package/dist/data/mathtest/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/mathtest/function/abs/then_0.mcfunction +0 -5
- package/dist/data/mathtest/function/abs.mcfunction +0 -6
- package/dist/data/mathtest/function/test.mcfunction +0 -5
- package/dist/data/minecraft/tags/function/load.json +0 -5
- package/dist/data/minecraft/tags/function/tick.json +0 -5
- package/dist/data/mypack/function/__load.mcfunction +0 -13
- package/dist/data/mypack/function/_atan_init.mcfunction +0 -2
- package/dist/data/mypack/function/abs/merge_2.mcfunction +0 -3
- package/dist/data/mypack/function/abs/then_0.mcfunction +0 -5
- package/dist/data/mypack/function/abs.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +0 -2
- package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +0 -19
- package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +0 -4
- package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +0 -6
- package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +0 -3
- package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +0 -5
- package/dist/data/mypack/function/atan2_fixed.mcfunction +0 -7
- package/dist/data/mypack/function/my_game.mcfunction +0 -10
- package/dist/data/quiz/function/__load.mcfunction +0 -16
- package/dist/data/quiz/function/__tick.mcfunction +0 -6
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +0 -4
- package/dist/data/quiz/function/answer_a.mcfunction +0 -4
- package/dist/data/quiz/function/answer_b.mcfunction +0 -4
- package/dist/data/quiz/function/answer_c.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +0 -5
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +0 -5
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +0 -1
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +0 -2
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +0 -2
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +0 -4
- package/dist/data/quiz/function/ask_question.mcfunction +0 -7
- package/dist/data/quiz/function/finish_quiz.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +0 -3
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +0 -8
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +0 -2
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +0 -5
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +0 -6
- package/dist/data/quiz/function/handle_answer.mcfunction +0 -11
- package/dist/data/quiz/function/start_quiz.mcfunction +0 -5
- package/dist/data/reqtest/function/__load.mcfunction +0 -4
- package/dist/data/reqtest/function/_table_init.mcfunction +0 -2
- package/dist/data/reqtest/function/no_trig.mcfunction +0 -3
- package/dist/data/reqtest/function/use_table.mcfunction +0 -4
- package/dist/data/reqtest2/function/__load.mcfunction +0 -3
- package/dist/data/reqtest2/function/no_trig.mcfunction +0 -3
- package/dist/data/runtime/function/__load.mcfunction +0 -5
- package/dist/data/runtime/function/__tick.mcfunction +0 -2
- package/dist/data/runtime/function/counter_tick/then_0.mcfunction +0 -3
- package/dist/data/runtime/function/counter_tick.mcfunction +0 -13
- package/dist/data/shop/function/__load.mcfunction +0 -7
- package/dist/data/shop/function/__tick.mcfunction +0 -3
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +0 -5
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +0 -5
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +0 -3
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +0 -2
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +0 -4
- package/dist/data/shop/function/complete_purchase.mcfunction +0 -7
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +0 -3
- package/dist/data/swap_test/function/__load.mcfunction +0 -3
- package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +0 -7
- package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +0 -5
- package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +0 -3
- package/dist/data/swap_test/function/gcd_old.mcfunction +0 -8
- package/dist/data/turret/function/__load.mcfunction +0 -5
- package/dist/data/turret/function/__tick.mcfunction +0 -4
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +0 -4
- package/dist/data/turret/function/deploy_turret.mcfunction +0 -8
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +0 -2
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +0 -3
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +0 -1
- package/dist/data/turret/function/turret_tick.mcfunction +0 -5
- package/dist/diagnostics/index.d.ts +0 -44
- package/dist/diagnostics/index.js +0 -140
- package/dist/events/types.d.ts +0 -35
- package/dist/events/types.js +0 -59
- package/dist/formatter/index.d.ts +0 -1
- package/dist/formatter/index.js +0 -26
- package/dist/gcd2.map.json +0 -15
- package/dist/gcd3.map.json +0 -17
- package/dist/gcd_test.map.json +0 -15
- package/dist/index.d.ts +0 -62
- package/dist/ir/builder.d.ts +0 -33
- package/dist/ir/builder.js +0 -99
- package/dist/ir/types.d.ts +0 -132
- package/dist/ir/types.js +0 -15
- package/dist/isqrttest.map.json +0 -15
- package/dist/lexer/index.d.ts +0 -37
- package/dist/lexer/index.js +0 -569
- package/dist/lowering/index.d.ts +0 -188
- package/dist/lowering/index.js +0 -3405
- package/dist/mathtest.map.json +0 -6
- package/dist/mc-test/client.d.ts +0 -128
- package/dist/mc-test/client.js +0 -174
- package/dist/mc-test/runner.d.ts +0 -28
- package/dist/mc-test/runner.js +0 -150
- package/dist/mc-test/setup.d.ts +0 -11
- package/dist/mc-test/setup.js +0 -98
- package/dist/mc-validator/index.d.ts +0 -17
- package/dist/mc-validator/index.js +0 -322
- package/dist/mypack.map.json +0 -27
- package/dist/nbt/index.d.ts +0 -86
- package/dist/nbt/index.js +0 -250
- package/dist/optimizer/commands.d.ts +0 -38
- package/dist/optimizer/commands.js +0 -451
- package/dist/optimizer/dce.d.ts +0 -34
- package/dist/optimizer/dce.js +0 -639
- package/dist/optimizer/passes.d.ts +0 -34
- package/dist/optimizer/passes.js +0 -243
- package/dist/optimizer/structure.d.ts +0 -9
- package/dist/optimizer/structure.js +0 -356
- package/dist/pack.mcmeta +0 -6
- package/dist/parser/index.d.ts +0 -93
- package/dist/parser/index.js +0 -1687
- package/dist/repl.d.ts +0 -16
- package/dist/repl.js +0 -165
- package/dist/reqtest.map.json +0 -4
- package/dist/reqtest2.map.json +0 -4
- package/dist/runtime/index.d.ts +0 -107
- package/dist/runtime/index.js +0 -1409
- package/dist/runtime.map.json +0 -7
- package/dist/src/__tests__/codegen.test.d.ts +0 -1
- package/dist/src/__tests__/codegen.test.js +0 -152
- package/dist/src/__tests__/e2e.test.d.ts +0 -6
- package/dist/src/__tests__/e2e.test.js +0 -1789
- package/dist/src/__tests__/entity-types.test.d.ts +0 -1
- package/dist/src/__tests__/entity-types.test.js +0 -203
- package/dist/src/__tests__/lowering.test.d.ts +0 -1
- package/dist/src/__tests__/lowering.test.js +0 -1015
- package/dist/src/__tests__/macro.test.d.ts +0 -8
- package/dist/src/__tests__/macro.test.js +0 -306
- package/dist/src/__tests__/nbt.test.d.ts +0 -1
- package/dist/src/__tests__/nbt.test.js +0 -82
- package/dist/src/__tests__/optimizer-advanced.test.d.ts +0 -1
- package/dist/src/__tests__/optimizer-advanced.test.js +0 -124
- package/dist/src/__tests__/optimizer.test.d.ts +0 -1
- package/dist/src/__tests__/optimizer.test.js +0 -149
- package/dist/src/__tests__/runtime.test.d.ts +0 -1
- package/dist/src/__tests__/runtime.test.js +0 -289
- package/dist/src/__tests__/stdlib-advanced.test.d.ts +0 -4
- package/dist/src/__tests__/stdlib-advanced.test.js +0 -374
- package/dist/src/__tests__/stdlib-bigint.test.d.ts +0 -7
- package/dist/src/__tests__/stdlib-bigint.test.js +0 -426
- package/dist/src/__tests__/stdlib-math.test.d.ts +0 -7
- package/dist/src/__tests__/stdlib-math.test.js +0 -351
- package/dist/src/__tests__/stdlib-vec.test.d.ts +0 -4
- package/dist/src/__tests__/stdlib-vec.test.js +0 -263
- package/dist/src/__tests__/structure-optimizer.test.d.ts +0 -1
- package/dist/src/__tests__/structure-optimizer.test.js +0 -33
- package/dist/src/__tests__/var-allocator.test.d.ts +0 -1
- package/dist/src/__tests__/var-allocator.test.js +0 -69
- package/dist/src/codegen/cmdblock/index.d.ts +0 -26
- package/dist/src/codegen/cmdblock/index.js +0 -45
- package/dist/src/codegen/mcfunction/index.d.ts +0 -40
- package/dist/src/codegen/mcfunction/index.js +0 -606
- package/dist/src/codegen/structure/index.d.ts +0 -24
- package/dist/src/codegen/structure/index.js +0 -279
- package/dist/src/codegen/var-allocator.d.ts +0 -45
- package/dist/src/codegen/var-allocator.js +0 -104
- package/dist/src/ir/builder.d.ts +0 -33
- package/dist/src/ir/builder.js +0 -99
- package/dist/src/ir/types.d.ts +0 -132
- package/dist/src/ir/types.js +0 -15
- package/dist/src/lowering/index.d.ts +0 -188
- package/dist/src/lowering/index.js +0 -3405
- package/dist/src/optimizer/commands.d.ts +0 -38
- package/dist/src/optimizer/commands.js +0 -451
- package/dist/src/optimizer/passes.d.ts +0 -34
- package/dist/src/optimizer/passes.js +0 -243
- package/dist/src/optimizer/structure.d.ts +0 -9
- package/dist/src/optimizer/structure.js +0 -356
- package/dist/src2/__tests__/optimizer/dce.test.d.ts +0 -1
- package/dist/src2/emit/compile.d.ts +0 -19
- package/dist/src2/emit/compile.js +0 -80
- package/dist/src2/optimizer/dce.d.ts +0 -8
- package/dist/src2/optimizer/dce.js +0 -155
- package/dist/swap_test.map.json +0 -14
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/typechecker/index.d.ts +0 -61
- package/dist/typechecker/index.js +0 -1034
- package/dist/types/entity-hierarchy.d.ts +0 -29
- package/dist/types/entity-hierarchy.js +0 -107
- package/src2/emit/compile.ts +0 -99
- /package/dist/{__tests__/cli.test.d.ts → src/__tests__/budget.test.d.ts} +0 -0
- /package/dist/{src2 → src}/__tests__/e2e/basic.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/e2e/basic.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/e2e/macros.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/e2e/migrate.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/hir/desugar.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/lir/lower.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/lir/lower.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/lir/types.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/lir/types.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/lir/verify.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/lir/verify.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/mir/arithmetic.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/mir/control-flow.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/mir/verify.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/mir/verify.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/block_merge.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/branch_simplify.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/constant_fold.test.js +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/copy_prop.test.js +0 -0
- /package/dist/{__tests__ → src/__tests__/optimizer}/dce.test.d.ts +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/dce.test.js +0 -0
- /package/dist/{__tests__/codegen.test.d.ts → src/__tests__/optimizer/interprocedural.test.d.ts} +0 -0
- /package/dist/{__tests__/entity-types.test.d.ts → src/__tests__/optimizer/lir/const_imm.test.d.ts} +0 -0
- /package/dist/{__tests__/formatter.test.d.ts → src/__tests__/optimizer/lir/dead_slot.test.d.ts} +0 -0
- /package/dist/{__tests__/lexer.test.d.ts → src/__tests__/optimizer/lir/peephole.test.d.ts} +0 -0
- /package/dist/{src2/__tests__/optimizer → src/__tests__/optimizer/lir}/pipeline.test.d.ts +0 -0
- /package/dist/{__tests__/lowering.test.d.ts → src/__tests__/optimizer/nbt-batch.test.d.ts} +0 -0
- /package/dist/{__tests__/mc-syntax.test.d.ts → src/__tests__/optimizer/pipeline.test.d.ts} +0 -0
- /package/dist/{src2 → src}/__tests__/optimizer/pipeline.test.js +0 -0
- /package/dist/{__tests__/nbt.test.d.ts → src/__tests__/optimizer/selector-cache.test.d.ts} +0 -0
- /package/dist/{__tests__/optimizer-advanced.test.d.ts → src/__tests__/optimizer/unroll.test.d.ts} +0 -0
- /package/dist/{src2 → src}/hir/types.js +0 -0
- /package/dist/{src2 → src}/lir/lower.d.ts +0 -0
- /package/dist/{src2 → src}/lir/types.js +0 -0
- /package/dist/{src2 → src}/lir/verify.d.ts +0 -0
- /package/dist/{src2 → src}/lir/verify.js +0 -0
- /package/dist/{src2 → src}/mir/macro.d.ts +0 -0
- /package/dist/{src2 → src}/mir/macro.js +0 -0
- /package/dist/{src2 → src}/mir/types.js +0 -0
- /package/dist/{src2 → src}/mir/verify.d.ts +0 -0
- /package/dist/{src2 → src}/mir/verify.js +0 -0
- /package/dist/{src2 → src}/optimizer/block_merge.d.ts +0 -0
- /package/dist/{src2 → src}/optimizer/block_merge.js +0 -0
- /package/dist/{src2 → src}/optimizer/branch_simplify.d.ts +0 -0
- /package/dist/{src2 → src}/optimizer/branch_simplify.js +0 -0
- /package/dist/{src2 → src}/optimizer/constant_fold.d.ts +0 -0
- /package/dist/{src2 → src}/optimizer/constant_fold.js +0 -0
- /package/dist/{src2 → src}/optimizer/copy_prop.d.ts +0 -0
- /package/dist/{src2 → src}/optimizer/copy_prop.js +0 -0
- /package/{src2 → src}/__tests__/e2e/basic.test.ts +0 -0
- /package/{src2 → src}/__tests__/lir/lower.test.ts +0 -0
- /package/{src2 → src}/__tests__/lir/types.test.ts +0 -0
- /package/{src2 → src}/__tests__/lir/verify.test.ts +0 -0
- /package/{src2 → src}/__tests__/mir/verify.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/block_merge.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/branch_simplify.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/constant_fold.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/copy_prop.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/dce.test.ts +0 -0
- /package/{src2 → src}/__tests__/optimizer/pipeline.test.ts +0 -0
- /package/{src2 → src}/lir/verify.ts +0 -0
- /package/{src2 → src}/mir/macro.ts +0 -0
- /package/{src2 → src}/mir/verify.ts +0 -0
- /package/{src2 → src}/optimizer/block_merge.ts +0 -0
- /package/{src2 → src}/optimizer/branch_simplify.ts +0 -0
- /package/{src2 → src}/optimizer/constant_fold.ts +0 -0
- /package/{src2 → src}/optimizer/copy_prop.ts +0 -0
package/CLAUDE.md
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
# RedScript Compiler — Claude Project Context
|
|
2
|
-
|
|
3
|
-
RedScript is a statically-typed programming language that compiles to Minecraft
|
|
4
|
-
Java Edition datapacks (`.mcfunction` files). It targets the MC scoreboard/NBT
|
|
5
|
-
runtime and generates commands that run inside the MC game engine.
|
|
6
|
-
|
|
7
|
-
**npm package:** `redscript-mc` | **VSCode extension:** `redscript-vscode`
|
|
8
|
-
**Docs:** https://redscript-docs.pages.dev | **IDE:** https://redscript-ide.pages.dev
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Build & Test
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm run build # tsc compile
|
|
16
|
-
npm test # jest (920 tests, ~35 s)
|
|
17
|
-
npm run build && npm test # always run together after changes
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
**Tests must be green before any commit.** Current baseline: 920/920.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Rules
|
|
25
|
-
|
|
26
|
-
- **`trash` not `rm`** — always use `trash` for deletions (recoverable)
|
|
27
|
-
- **Plain `git commit`** — GPG signing is passwordless, no flags needed
|
|
28
|
-
- **`git pull --rebase` before every push**
|
|
29
|
-
- **Remove Co-Authored-By** from commit messages before pushing
|
|
30
|
-
- **Small, frequent commits** — one logical unit per commit; do not batch
|
|
31
|
-
- **Never include Co-Authored-By** — strip it from every commit message before committing
|
|
32
|
-
- **Good commit granularity examples:**
|
|
33
|
-
- ✅ `feat(mir): add MIRInstr type definitions`
|
|
34
|
-
- ✅ `feat(mir): implement HIR→MIR lowering for if/else → branch`
|
|
35
|
-
- ✅ `feat(mir): implement HIR→MIR lowering for while → loop CFG`
|
|
36
|
-
- ✅ `feat(mir): add MIR verifier`
|
|
37
|
-
- ✅ `test(mir): arithmetic lowering tests`
|
|
38
|
-
- ✅ `test(mir): control-flow CFG shape tests`
|
|
39
|
-
- ❌ `feat(stage3): implement Stage 3 MIR` (too big — splits into at least 4-6 commits)
|
|
40
|
-
- **Lowercase MC function names** — MC rejects uppercase paths
|
|
41
|
-
- **File extension:** `.mcrs`
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Current Architecture (v1.2.x — pre-refactor)
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
src/
|
|
49
|
-
lexer/index.ts Tokenizer
|
|
50
|
-
parser/index.ts Recursive-descent parser → AST
|
|
51
|
-
lowering/index.ts AST → IR ⚠️ 3500 lines, stages 2+3+5 merged
|
|
52
|
-
ir/index.ts IR types (2-address)
|
|
53
|
-
optimizer/
|
|
54
|
-
passes.ts Optimization passes (2-addr IR, regex-based)
|
|
55
|
-
commands.ts Scoreboard command regex patterns
|
|
56
|
-
structure.ts Structural analysis
|
|
57
|
-
codegen/
|
|
58
|
-
mcfunction/index.ts IR → .mcfunction text
|
|
59
|
-
compile.ts Top-level compile() entry point
|
|
60
|
-
cli.ts CLI
|
|
61
|
-
runtime/index.ts MCRuntime simulator (used by tests)
|
|
62
|
-
stdlib/ math.mcrs, vec.mcrs, advanced.mcrs, bigint.mcrs, timer.mcrs
|
|
63
|
-
__tests__/ 920 Jest tests
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Key identifiers:**
|
|
67
|
-
- Scoreboard objective default: `` `__${namespace}` `` (avoids multi-datapack collision)
|
|
68
|
-
- Macro sentinel: `\x01` at start of raw IR cmd string → codegen converts to `$`
|
|
69
|
-
- IR variable naming: `$fnname_varname` (function-scoped to avoid cross-fn collision)
|
|
70
|
-
- `LOWERING_OBJ` export in `src/lowering/index.ts`: the current objective name
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Planned Refactor (next major version)
|
|
75
|
-
|
|
76
|
-
**Full specification:** `docs/compiler-pipeline-redesign.md` (1700+ lines)
|
|
77
|
-
**Optimization ideas:** `docs/optimization-ideas.md` (1076 lines)
|
|
78
|
-
|
|
79
|
-
### 7-stage pipeline
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
Source → [Stage 1] AST → [Stage 2] HIR → [Stage 3] MIR (3-addr CFG)
|
|
83
|
-
→ [Stage 4] MIR optimized → [Stage 5] LIR (MC 2-addr)
|
|
84
|
-
→ [Stage 6] LIR optimized → [Stage 7] .mcfunction
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Implementation approach
|
|
88
|
-
|
|
89
|
-
- New code goes in `src2/` on branch `refactor/pipeline-v2`
|
|
90
|
-
- `src/` (current compiler) stays untouched until `src2/` passes 920/920
|
|
91
|
-
- Stage by stage: write unit tests for each stage, pass them, then move on
|
|
92
|
-
- 920 e2e tests only all-green at Stage 7 completion — partial pass mid-refactor is normal
|
|
93
|
-
- Adapt if stage boundaries feel wrong; design is a guide, not a contract
|
|
94
|
-
|
|
95
|
-
### MIR/LIR specs are in the design doc
|
|
96
|
-
The exact TypeScript types for `MIRInstr`, `LIRInstr`, `MIRBlock`, etc. are
|
|
97
|
-
fully specified in `docs/compiler-pipeline-redesign.md`. Read it before
|
|
98
|
-
implementing any stage.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Language Quick Reference
|
|
103
|
-
|
|
104
|
-
```redscript
|
|
105
|
-
// Types: int, float (×1000 fixed-point), bool, string, void
|
|
106
|
-
// MC types: selector<entity>, selector<player>, BlockPos
|
|
107
|
-
|
|
108
|
-
let x: int = 0;
|
|
109
|
-
const MAX: int = 100;
|
|
110
|
-
fn add(a: int, b: int): int { return a + b; }
|
|
111
|
-
|
|
112
|
-
// Structs (value type — fields are scoreboard slots, no heap, no references)
|
|
113
|
-
struct Vec2 { x: int; y: int; }
|
|
114
|
-
impl Vec2 { fn length_sq(self): int { return self.x * self.x + self.y * self.y; } }
|
|
115
|
-
|
|
116
|
-
// Decorators
|
|
117
|
-
@tick fn _tick() { ... } // runs every MC tick
|
|
118
|
-
@load fn _load() { ... } // runs on /reload
|
|
119
|
-
export fn public_api() { ... } // survives DCE
|
|
120
|
-
|
|
121
|
-
// MC-specific
|
|
122
|
-
foreach (p in @e[tag=foo]) at @s { ... }
|
|
123
|
-
kill(@e[tag=screen]);
|
|
124
|
-
particle("minecraft:end_rod", ^px, ^py, ^5, 0.02, 0.02, 0.02, 0.0, 10);
|
|
125
|
-
|
|
126
|
-
// Macro functions (auto-detected when params appear in ^ coords)
|
|
127
|
-
fn draw_pt(px: float, py: float) {
|
|
128
|
-
particle("minecraft:end_rod", ^px, ^py, ^5, 0.02, 0.02, 0.02, 0.0, 10);
|
|
129
|
-
}
|
|
130
|
-
// Compiles to: function ns:draw_pt with storage rs:macro_args
|
|
131
|
-
|
|
132
|
-
// Math stdlib (fixed-point ×1000)
|
|
133
|
-
let s: int = sin_fixed(45); // = 707 (sin(45°) × 1000)
|
|
134
|
-
let r: int = sqrt_fixed(2000); // = 1414 (√2 × 1000)
|
|
135
|
-
let m: int = mulfix(a, b); // = (a × b) / 1000
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## Known Bugs / Technical Debt
|
|
141
|
-
|
|
142
|
-
- `redscript check` hardcodes `namespace = 'redscript'`; doesn't run TypeChecker
|
|
143
|
-
- TypeChecker is "warn mode" — type errors don't block compilation
|
|
144
|
-
- `watch` mode recompiles all files on any change (no incremental)
|
|
145
|
-
- Timer stdlib is single-instance only (shared fake player names)
|
|
146
|
-
- Optimizer passes use regex on raw command strings — fragile
|
|
147
|
-
- All of the above are addressed in the refactor plan
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Test Server
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
# Server: Paper 1.21.4, port 25561
|
|
155
|
-
cd ~/mc-test-server
|
|
156
|
-
/opt/homebrew/opt/openjdk@21/bin/java -jar paper.jar --nogui
|
|
157
|
-
|
|
158
|
-
# Deploy
|
|
159
|
-
node dist/cli.js compile examples/readme-demo.mcrs \
|
|
160
|
-
-o ~/mc-test-server/world/datapacks/rsdemo --namespace rsdemo
|
|
161
|
-
# then in-game: /reload && /function rsdemo:start
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## Useful Files
|
|
167
|
-
|
|
168
|
-
| File | Purpose |
|
|
169
|
-
|---|---|
|
|
170
|
-
| `docs/compiler-pipeline-redesign.md` | Full refactor spec (read this first) |
|
|
171
|
-
| `docs/optimization-ideas.md` | Optimization pass catalogue |
|
|
172
|
-
| `examples/readme-demo.mcrs` | Sine wave particle demo |
|
|
173
|
-
| `examples/math-showcase.mcrs` | Math stdlib showcase |
|
|
174
|
-
| `src/stdlib/math.mcrs` | sin/cos/sqrt/mulfix/divfix |
|
|
175
|
-
| `src/__tests__/` | 920 Jest tests — do not break these |
|
|
176
|
-
| `src/runtime/index.ts` | MCRuntime (scoreboard + NBT simulator) |
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## Profiler (planned)
|
|
181
|
-
|
|
182
|
-
`MCRuntime` will gain a profiling mode (`{ profiling: { enabled: true } }`):
|
|
183
|
-
- Per-function command counts
|
|
184
|
-
- Error analysis vs JS float ground truth for math functions
|
|
185
|
-
- Coroutine BATCH auto-calibration
|
|
186
|
-
|
|
187
|
-
See `docs/compiler-pipeline-redesign.md` → "MCRuntime Profiler" section.
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## VSCode Extension & npm Package Maintenance
|
|
192
|
-
|
|
193
|
-
### npm package (`redscript-mc`)
|
|
194
|
-
|
|
195
|
-
Claude can maintain fully:
|
|
196
|
-
- Version bumps via `npm version patch/minor/major` in root `package.json`
|
|
197
|
-
- Publishing: push to main → CI handles it automatically
|
|
198
|
-
- The 920 tests verify CLI behavior end-to-end
|
|
199
|
-
|
|
200
|
-
### VSCode extension (`editors/vscode/`)
|
|
201
|
-
|
|
202
|
-
**What Claude can verify automatically:**
|
|
203
|
-
```bash
|
|
204
|
-
cd editors/vscode
|
|
205
|
-
npm run build # esbuild bundle must succeed
|
|
206
|
-
vsce package # .vsix must build without errors
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Grammar unit tests (if set up with `vscode-tmgrammar-test`):
|
|
210
|
-
```bash
|
|
211
|
-
# Tests that specific source lines tokenize as expected
|
|
212
|
-
# e.g. "fn foo(x: int): int" → keyword.fn, entity.function, etc.
|
|
213
|
-
npm test
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**What Claude cannot verify:** visual rendering, hover UI, color themes,
|
|
217
|
-
real-time IntelliSense behavior. These require a running VS Code instance.
|
|
218
|
-
|
|
219
|
-
**Division of labor:**
|
|
220
|
-
- Claude: grammar files, manifest, version sync, CI publish, update tokens on syntax changes
|
|
221
|
-
- You: visual check before major releases (`code --install-extension *.vsix`)
|
|
222
|
-
|
|
223
|
-
**When syntax changes (e.g. `->` → `:`, `@keep` → `export`):**
|
|
224
|
-
Claude must update `editors/vscode/syntaxes/redscript.tmLanguage.json`
|
|
225
|
-
to match the new grammar, then rebuild and repackage.
|
|
226
|
-
|
|
227
|
-
**CI publish flow:**
|
|
228
|
-
Push to main → `publish-extension-on-ci.yml` auto-bumps patch version and
|
|
229
|
-
publishes via `VSCE_PAT` secret. Manual minor/major bump: edit
|
|
230
|
-
`editors/vscode/package.json` version directly before pushing.
|
|
231
|
-
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
const index_1 = require("../index");
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const os = __importStar(require("os"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const child_process_1 = require("child_process");
|
|
41
|
-
// Note: watch command is tested manually as it's an interactive long-running process
|
|
42
|
-
describe('CLI API', () => {
|
|
43
|
-
describe('imports', () => {
|
|
44
|
-
it('compiles a file with imported helpers', () => {
|
|
45
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-imports-'));
|
|
46
|
-
const libPath = path.join(tempDir, 'lib.mcrs');
|
|
47
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
48
|
-
fs.writeFileSync(libPath, 'fn double(x: int) -> int { return x + x; }\n');
|
|
49
|
-
fs.writeFileSync(mainPath, 'import "./lib.mcrs"\n\nfn main() { let value: int = double(2); }\n');
|
|
50
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
51
|
-
const result = (0, index_1.compile)(source, { namespace: 'imports', filePath: mainPath });
|
|
52
|
-
expect(result.files.length).toBeGreaterThan(0);
|
|
53
|
-
expect(result.ir.functions.some(fn => fn.name === 'double')).toBe(true);
|
|
54
|
-
expect(result.ir.functions.some(fn => fn.name === 'main')).toBe(true);
|
|
55
|
-
});
|
|
56
|
-
it('deduplicates circular imports', () => {
|
|
57
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-circular-'));
|
|
58
|
-
const aPath = path.join(tempDir, 'a.mcrs');
|
|
59
|
-
const bPath = path.join(tempDir, 'b.mcrs');
|
|
60
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
61
|
-
fs.writeFileSync(aPath, 'import "./b.mcrs"\n\nfn from_a() -> int { return 1; }\n');
|
|
62
|
-
fs.writeFileSync(bPath, 'import "./a.mcrs"\n\nfn from_b() -> int { return from_a(); }\n');
|
|
63
|
-
fs.writeFileSync(mainPath, 'import "./a.mcrs"\n\nfn main() { let value: int = from_b(); }\n');
|
|
64
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
65
|
-
const result = (0, index_1.compile)(source, { namespace: 'circular', filePath: mainPath });
|
|
66
|
-
expect(result.ir.functions.filter(fn => fn.name === 'from_a')).toHaveLength(1);
|
|
67
|
-
expect(result.ir.functions.filter(fn => fn.name === 'from_b')).toHaveLength(1);
|
|
68
|
-
});
|
|
69
|
-
it('uses rs-prefixed scoreboard objectives for imported stdlib files', () => {
|
|
70
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-stdlib-'));
|
|
71
|
-
const stdlibDir = path.join(tempDir, 'src', 'stdlib');
|
|
72
|
-
const stdlibPath = path.join(stdlibDir, 'timer.mcrs');
|
|
73
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
74
|
-
fs.mkdirSync(stdlibDir, { recursive: true });
|
|
75
|
-
fs.writeFileSync(stdlibPath, 'fn tick_timer() { scoreboard_set("#rs", "timer_ticks", 1); }\n');
|
|
76
|
-
fs.writeFileSync(mainPath, 'import "./src/stdlib/timer.mcrs"\n\nfn main() { tick_timer(); }\n');
|
|
77
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
78
|
-
const result = (0, index_1.compile)(source, { namespace: 'mygame', filePath: mainPath });
|
|
79
|
-
const tickTimer = result.files.find(file => file.path.endsWith('/tick_timer.mcfunction'));
|
|
80
|
-
expect(tickTimer?.content).toContain('scoreboard players set #rs __mygame.timer_ticks 1');
|
|
81
|
-
});
|
|
82
|
-
it('adds a call-site hash for stdlib internal scoreboard objectives', () => {
|
|
83
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-stdlib-hash-'));
|
|
84
|
-
const stdlibDir = path.join(tempDir, 'src', 'stdlib');
|
|
85
|
-
const stdlibPath = path.join(stdlibDir, 'timer.mcrs');
|
|
86
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
87
|
-
fs.mkdirSync(stdlibDir, { recursive: true });
|
|
88
|
-
fs.writeFileSync(stdlibPath, [
|
|
89
|
-
'fn timer_start(name: string, duration: int) {',
|
|
90
|
-
' scoreboard_set("timer_ticks", #rs, duration);',
|
|
91
|
-
' scoreboard_set("timer_active", #rs, 1);',
|
|
92
|
-
'}',
|
|
93
|
-
'',
|
|
94
|
-
].join('\n'));
|
|
95
|
-
fs.writeFileSync(mainPath, [
|
|
96
|
-
'import "./src/stdlib/timer.mcrs"',
|
|
97
|
-
'',
|
|
98
|
-
'fn main() {',
|
|
99
|
-
' timer_start("x", 100);',
|
|
100
|
-
' timer_start("x", 100);',
|
|
101
|
-
'}',
|
|
102
|
-
'',
|
|
103
|
-
].join('\n'));
|
|
104
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
105
|
-
const result = (0, index_1.compile)(source, { namespace: 'mygame', filePath: mainPath });
|
|
106
|
-
const timerFns = result.files.filter(file => /timer_start__callsite_[0-9a-f]{4}\.mcfunction$/.test(file.path));
|
|
107
|
-
expect(timerFns).toHaveLength(2);
|
|
108
|
-
const objectives = timerFns
|
|
109
|
-
.flatMap(file => [...file.content.matchAll(/mygame\._timer_([0-9a-f]{4})/g)].map(match => match[0]));
|
|
110
|
-
expect(new Set(objectives).size).toBe(2);
|
|
111
|
-
});
|
|
112
|
-
it('Timer::new creates timer', () => {
|
|
113
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-new-'));
|
|
114
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
115
|
-
const timerPath = path.resolve(process.cwd(), 'src/stdlib/timer.mcrs');
|
|
116
|
-
fs.writeFileSync(mainPath, [
|
|
117
|
-
`import "${timerPath}"`,
|
|
118
|
-
'',
|
|
119
|
-
'fn main() {',
|
|
120
|
-
' let timer: Timer = Timer::new(20);',
|
|
121
|
-
'}',
|
|
122
|
-
'',
|
|
123
|
-
].join('\n'));
|
|
124
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
125
|
-
const result = (0, index_1.compile)(source, { namespace: 'timernew', filePath: mainPath });
|
|
126
|
-
expect(result.typeErrors).toEqual([]);
|
|
127
|
-
const newFn = result.files.find(file => file.path.endsWith('/Timer_new.mcfunction'));
|
|
128
|
-
expect(newFn?.content).toContain('scoreboard players set timer_ticks __timernew 0');
|
|
129
|
-
expect(newFn?.content).toContain('scoreboard players set timer_active __timernew 0');
|
|
130
|
-
});
|
|
131
|
-
it('Timer.start/pause/reset', () => {
|
|
132
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-state-'));
|
|
133
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
134
|
-
const timerPath = path.resolve(process.cwd(), 'src/stdlib/timer.mcrs');
|
|
135
|
-
fs.writeFileSync(mainPath, [
|
|
136
|
-
`import "${timerPath}"`,
|
|
137
|
-
'',
|
|
138
|
-
'fn main() {',
|
|
139
|
-
' let timer: Timer = Timer::new(20);',
|
|
140
|
-
' timer.start();',
|
|
141
|
-
' timer.pause();',
|
|
142
|
-
' timer.reset();',
|
|
143
|
-
'}',
|
|
144
|
-
'',
|
|
145
|
-
].join('\n'));
|
|
146
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
147
|
-
const result = (0, index_1.compile)(source, { namespace: 'timerstate', filePath: mainPath });
|
|
148
|
-
expect(result.typeErrors).toEqual([]);
|
|
149
|
-
const startFn = result.files.find(file => file.path.endsWith('/Timer_start.mcfunction'));
|
|
150
|
-
const pauseFn = result.files.find(file => file.path.endsWith('/Timer_pause.mcfunction'));
|
|
151
|
-
const resetFn = result.files.find(file => file.path.endsWith('/Timer_reset.mcfunction'));
|
|
152
|
-
expect(startFn?.content).toContain('scoreboard players set timer_active __timerstate 1');
|
|
153
|
-
expect(pauseFn?.content).toContain('scoreboard players set timer_active __timerstate 0');
|
|
154
|
-
expect(resetFn?.content).toContain('scoreboard players set timer_ticks __timerstate 0');
|
|
155
|
-
});
|
|
156
|
-
it('Timer.done returns bool', () => {
|
|
157
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-done-'));
|
|
158
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
159
|
-
const timerPath = path.resolve(process.cwd(), 'src/stdlib/timer.mcrs');
|
|
160
|
-
fs.writeFileSync(mainPath, [
|
|
161
|
-
`import "${timerPath}"`,
|
|
162
|
-
'',
|
|
163
|
-
'fn main() {',
|
|
164
|
-
' let timer: Timer = Timer::new(20);',
|
|
165
|
-
' let finished: bool = timer.done();',
|
|
166
|
-
' if (finished) {',
|
|
167
|
-
' say("done");',
|
|
168
|
-
' }',
|
|
169
|
-
'}',
|
|
170
|
-
'',
|
|
171
|
-
].join('\n'));
|
|
172
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
173
|
-
const result = (0, index_1.compile)(source, { namespace: 'timerdone', filePath: mainPath });
|
|
174
|
-
expect(result.typeErrors).toEqual([]);
|
|
175
|
-
const doneFn = result.files.find(file => file.path.endsWith('/Timer_done.mcfunction'));
|
|
176
|
-
const mainFn = result.files.find(file => file.path.endsWith('/main.mcfunction'));
|
|
177
|
-
expect(doneFn?.content).toContain('scoreboard players get timer_ticks __timerdone');
|
|
178
|
-
expect(doneFn?.content).toContain('return run scoreboard players get');
|
|
179
|
-
expect(mainFn?.content).toContain('execute if score $main_finished __timerdone matches 1..');
|
|
180
|
-
});
|
|
181
|
-
it('Timer.tick increments', () => {
|
|
182
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-timer-tick-'));
|
|
183
|
-
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
184
|
-
const timerPath = path.resolve(process.cwd(), 'src/stdlib/timer.mcrs');
|
|
185
|
-
fs.writeFileSync(mainPath, [
|
|
186
|
-
`import "${timerPath}"`,
|
|
187
|
-
'',
|
|
188
|
-
'fn main() {',
|
|
189
|
-
' let timer: Timer = Timer::new(20);',
|
|
190
|
-
' timer.start();',
|
|
191
|
-
' timer.tick();',
|
|
192
|
-
'}',
|
|
193
|
-
'',
|
|
194
|
-
].join('\n'));
|
|
195
|
-
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
196
|
-
const result = (0, index_1.compile)(source, { namespace: 'timertick', filePath: mainPath });
|
|
197
|
-
expect(result.typeErrors).toEqual([]);
|
|
198
|
-
const tickOutput = result.files
|
|
199
|
-
.filter(file => file.path.includes('/Timer_tick'))
|
|
200
|
-
.map(file => file.content)
|
|
201
|
-
.join('\n');
|
|
202
|
-
expect(tickOutput).toContain('scoreboard players get timer_active __timertick');
|
|
203
|
-
expect(tickOutput).toContain('scoreboard players get timer_ticks __timertick');
|
|
204
|
-
expect(tickOutput).toContain(' += $const_1 __timertick');
|
|
205
|
-
expect(tickOutput).toContain('execute store result score timer_ticks __timertick run scoreboard players get $_');
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
describe('compile()', () => {
|
|
209
|
-
it('compiles simple source', () => {
|
|
210
|
-
const source = 'fn test() { say("hello"); }';
|
|
211
|
-
const result = (0, index_1.compile)(source, { namespace: 'mypack' });
|
|
212
|
-
expect(result.files.length).toBeGreaterThan(0);
|
|
213
|
-
expect(result.ast.namespace).toBe('mypack');
|
|
214
|
-
expect(result.ir.functions.length).toBe(1);
|
|
215
|
-
});
|
|
216
|
-
it('uses default namespace', () => {
|
|
217
|
-
const source = 'fn test() {}';
|
|
218
|
-
const result = (0, index_1.compile)(source);
|
|
219
|
-
expect(result.ast.namespace).toBe('redscript');
|
|
220
|
-
});
|
|
221
|
-
it('generates correct file structure', () => {
|
|
222
|
-
const source = 'fn test() { say("hello"); }';
|
|
223
|
-
const result = (0, index_1.compile)(source, { namespace: 'game' });
|
|
224
|
-
const paths = result.files.map(f => f.path);
|
|
225
|
-
expect(paths).toContain('pack.mcmeta');
|
|
226
|
-
expect(paths).toContain('data/game/function/__load.mcfunction');
|
|
227
|
-
expect(paths.some(p => p.includes('test.mcfunction'))).toBe(true);
|
|
228
|
-
});
|
|
229
|
-
it('collects optimizer stats', () => {
|
|
230
|
-
const source = `
|
|
231
|
-
fn build() {
|
|
232
|
-
foreach (turret in @e[tag=turret]) {
|
|
233
|
-
let range: int = scoreboard_get("config", "turret_range");
|
|
234
|
-
if (range > 0) {
|
|
235
|
-
if (range > -1) {
|
|
236
|
-
say("ready");
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
`;
|
|
242
|
-
const result = (0, index_1.compile)(source, { namespace: 'stats' });
|
|
243
|
-
expect(result.stats?.licmHoists).toBeGreaterThan(0);
|
|
244
|
-
expect(result.stats?.totalCommandsBefore).toBeGreaterThan(result.stats?.totalCommandsAfter ?? 0);
|
|
245
|
-
expect(result.stats?.deadCodeRemoved).toBeGreaterThanOrEqual(0);
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
describe('--stats flag', () => {
|
|
249
|
-
it('prints optimizer statistics', () => {
|
|
250
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-stats-'));
|
|
251
|
-
const inputPath = path.join(tempDir, 'input.mcrs');
|
|
252
|
-
const outputDir = path.join(tempDir, 'out');
|
|
253
|
-
fs.writeFileSync(inputPath, 'fn build() { setblock((0, 64, 0), "minecraft:stone"); setblock((1, 64, 0), "minecraft:stone"); }');
|
|
254
|
-
const stdout = (0, child_process_1.execFileSync)(process.execPath, ['-r', 'ts-node/register', path.join(process.cwd(), 'src/cli.ts'), 'compile', inputPath, '-o', outputDir, '--stats'], { cwd: process.cwd(), encoding: 'utf-8' });
|
|
255
|
-
expect(stdout).toContain('Optimizations applied:');
|
|
256
|
-
expect(stdout).toContain('setblock batching:');
|
|
257
|
-
expect(stdout).toContain('Total mcfunction commands:');
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
describe('check()', () => {
|
|
261
|
-
it('returns null for valid source', () => {
|
|
262
|
-
const source = 'fn test() { say("hello"); }';
|
|
263
|
-
const error = (0, index_1.check)(source);
|
|
264
|
-
expect(error).toBeNull();
|
|
265
|
-
});
|
|
266
|
-
it('returns error for invalid source', () => {
|
|
267
|
-
const source = 'fn test( { say("hello"); }'; // Missing )
|
|
268
|
-
const error = (0, index_1.check)(source);
|
|
269
|
-
expect(error).toBeInstanceOf(Error);
|
|
270
|
-
});
|
|
271
|
-
it('returns error for syntax errors', () => {
|
|
272
|
-
const source = 'fn test() { let x = ; }'; // Missing value
|
|
273
|
-
const error = (0, index_1.check)(source);
|
|
274
|
-
expect(error).toBeInstanceOf(Error);
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
//# sourceMappingURL=cli.test.js.map
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const mcfunction_1 = require("../codegen/mcfunction");
|
|
4
|
-
describe('generateDatapack', () => {
|
|
5
|
-
it('generates pack.mcmeta', () => {
|
|
6
|
-
const mod = { namespace: 'test', functions: [], globals: [] };
|
|
7
|
-
const files = (0, mcfunction_1.generateDatapack)(mod);
|
|
8
|
-
const meta = files.find(f => f.path === 'pack.mcmeta');
|
|
9
|
-
expect(meta).toBeDefined();
|
|
10
|
-
expect(JSON.parse(meta.content).pack.pack_format).toBe(26);
|
|
11
|
-
});
|
|
12
|
-
it('generates __load.mcfunction with objective setup', () => {
|
|
13
|
-
const mod = { namespace: 'mypack', functions: [], globals: [{ name: 'counter', init: 0 }] };
|
|
14
|
-
const files = (0, mcfunction_1.generateDatapack)(mod);
|
|
15
|
-
const load = files.find(f => f.path.includes('__load.mcfunction'));
|
|
16
|
-
expect(load?.content).toContain('scoreboard objectives add rs dummy');
|
|
17
|
-
expect(load?.content).toContain('scoreboard players set $counter rs 0');
|
|
18
|
-
});
|
|
19
|
-
it('generates function file for simple add(a, b)', () => {
|
|
20
|
-
// IR now uses { kind: 'param', index: i } for param-copy instructions,
|
|
21
|
-
// matching what the lowering emits. Pass mangle:false so we can check
|
|
22
|
-
// readable names without worrying about sequential mangled names.
|
|
23
|
-
const mod = {
|
|
24
|
-
namespace: 'mypack',
|
|
25
|
-
globals: [],
|
|
26
|
-
functions: [{
|
|
27
|
-
name: 'add',
|
|
28
|
-
params: ['$a', '$b'],
|
|
29
|
-
locals: ['$a', '$b', '$result'],
|
|
30
|
-
blocks: [{
|
|
31
|
-
label: 'entry',
|
|
32
|
-
instrs: [
|
|
33
|
-
// param-copy instructions (what the lowering now emits)
|
|
34
|
-
{ op: 'assign', dst: '$a', src: { kind: 'param', index: 0 } },
|
|
35
|
-
{ op: 'assign', dst: '$b', src: { kind: 'param', index: 1 } },
|
|
36
|
-
{ op: 'binop', dst: '$result', lhs: { kind: 'var', name: '$a' }, bop: '+', rhs: { kind: 'var', name: '$b' } },
|
|
37
|
-
],
|
|
38
|
-
term: { op: 'return', value: { kind: 'var', name: '$result' } },
|
|
39
|
-
}],
|
|
40
|
-
}],
|
|
41
|
-
};
|
|
42
|
-
const files = (0, mcfunction_1.generateDatapackWithStats)(mod, { mangle: false }).files;
|
|
43
|
-
const fn = files.find(f => f.path.includes('add.mcfunction'));
|
|
44
|
-
expect(fn).toBeDefined();
|
|
45
|
-
// param setup emitted from the IR
|
|
46
|
-
expect(fn.content).toContain('scoreboard players operation $a rs = $p0 rs');
|
|
47
|
-
expect(fn.content).toContain('scoreboard players operation $b rs = $p1 rs');
|
|
48
|
-
// Should have add operation
|
|
49
|
-
expect(fn.content).toContain('+=');
|
|
50
|
-
});
|
|
51
|
-
it('generates tick tag for tick loop function', () => {
|
|
52
|
-
const mod = {
|
|
53
|
-
namespace: 'mypack',
|
|
54
|
-
globals: [],
|
|
55
|
-
functions: [{
|
|
56
|
-
name: 'game_loop',
|
|
57
|
-
params: [],
|
|
58
|
-
locals: [],
|
|
59
|
-
blocks: [{ label: 'entry', instrs: [], term: { op: 'return' } }],
|
|
60
|
-
isTickLoop: true,
|
|
61
|
-
}],
|
|
62
|
-
};
|
|
63
|
-
const files = (0, mcfunction_1.generateDatapack)(mod);
|
|
64
|
-
// tick.json should point to __tick
|
|
65
|
-
const tickTag = files.find(f => f.path.includes('tick.json'));
|
|
66
|
-
expect(tickTag).toBeDefined();
|
|
67
|
-
expect(JSON.parse(tickTag.content).values).toContain('mypack:__tick');
|
|
68
|
-
// __tick.mcfunction should call the game_loop function
|
|
69
|
-
const tickFn = files.find(f => f.path.includes('__tick.mcfunction'));
|
|
70
|
-
expect(tickFn).toBeDefined();
|
|
71
|
-
expect(tickFn.content).toContain('function mypack:game_loop');
|
|
72
|
-
});
|
|
73
|
-
it('generates conditional branches with execute if/unless', () => {
|
|
74
|
-
const mod = {
|
|
75
|
-
namespace: 'mypack',
|
|
76
|
-
globals: [],
|
|
77
|
-
functions: [{
|
|
78
|
-
name: 'check',
|
|
79
|
-
params: [],
|
|
80
|
-
locals: ['cond'],
|
|
81
|
-
blocks: [
|
|
82
|
-
{
|
|
83
|
-
label: 'entry',
|
|
84
|
-
instrs: [
|
|
85
|
-
{ op: 'assign', dst: 'cond', src: { kind: 'const', value: 1 } },
|
|
86
|
-
],
|
|
87
|
-
term: { op: 'jump_if', cond: 'cond', then: 'then_block', else_: 'else_block' },
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
label: 'then_block',
|
|
91
|
-
instrs: [{ op: 'raw', cmd: 'say hello' }],
|
|
92
|
-
term: { op: 'return' },
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
label: 'else_block',
|
|
96
|
-
instrs: [{ op: 'raw', cmd: 'say goodbye' }],
|
|
97
|
-
term: { op: 'return' },
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
}],
|
|
101
|
-
};
|
|
102
|
-
const files = (0, mcfunction_1.generateDatapack)(mod);
|
|
103
|
-
const entry = files.find(f => f.path.endsWith('check.mcfunction'));
|
|
104
|
-
expect(entry?.content).toContain('execute if score $cond rs matches 1..');
|
|
105
|
-
expect(entry?.content).toContain('execute if score $cond rs matches ..0');
|
|
106
|
-
});
|
|
107
|
-
it('generates advancement json for event decorators', () => {
|
|
108
|
-
const mod = {
|
|
109
|
-
namespace: 'mypack',
|
|
110
|
-
globals: [],
|
|
111
|
-
functions: [{
|
|
112
|
-
name: 'on_mine_diamond',
|
|
113
|
-
params: [],
|
|
114
|
-
locals: [],
|
|
115
|
-
blocks: [{ label: 'entry', instrs: [], term: { op: 'return' } }],
|
|
116
|
-
eventTrigger: { kind: 'advancement', value: 'story/mine_diamond' },
|
|
117
|
-
}],
|
|
118
|
-
};
|
|
119
|
-
const result = (0, mcfunction_1.generateDatapackWithStats)(mod);
|
|
120
|
-
const advancement = result.advancements.find(f => f.path === 'data/mypack/advancements/on_advancement_on_mine_diamond.json');
|
|
121
|
-
expect(advancement).toBeDefined();
|
|
122
|
-
const json = JSON.parse(advancement.content);
|
|
123
|
-
expect(json.criteria.trigger.trigger).toBe('minecraft:story/mine_diamond');
|
|
124
|
-
expect(json.rewards.function).toBe('mypack:on_mine_diamond');
|
|
125
|
-
});
|
|
126
|
-
it('generates static event dispatcher in __tick', () => {
|
|
127
|
-
const mod = {
|
|
128
|
-
namespace: 'mypack',
|
|
129
|
-
globals: [],
|
|
130
|
-
functions: [{
|
|
131
|
-
name: 'handle_death',
|
|
132
|
-
params: [],
|
|
133
|
-
locals: [],
|
|
134
|
-
blocks: [{ label: 'entry', instrs: [], term: { op: 'return' } }],
|
|
135
|
-
eventHandler: { eventType: 'PlayerDeath', tag: 'rs.just_died' },
|
|
136
|
-
}, {
|
|
137
|
-
name: 'handle_death_2',
|
|
138
|
-
params: [],
|
|
139
|
-
locals: [],
|
|
140
|
-
blocks: [{ label: 'entry', instrs: [], term: { op: 'return' } }],
|
|
141
|
-
eventHandler: { eventType: 'PlayerDeath', tag: 'rs.just_died' },
|
|
142
|
-
}],
|
|
143
|
-
};
|
|
144
|
-
const files = (0, mcfunction_1.generateDatapack)(mod);
|
|
145
|
-
const tickFn = files.find(f => f.path.includes('__tick.mcfunction'));
|
|
146
|
-
expect(tickFn).toBeDefined();
|
|
147
|
-
expect(tickFn.content).toContain('execute as @a[tag=rs.just_died] run function mypack:handle_death');
|
|
148
|
-
expect(tickFn.content).toContain('execute as @a[tag=rs.just_died] run function mypack:handle_death_2');
|
|
149
|
-
expect(tickFn.content).toContain('tag @a[tag=rs.just_died] remove rs.just_died');
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
//# sourceMappingURL=codegen.test.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compile-all smoke test
|
|
3
|
-
*
|
|
4
|
-
* Finds every .mcrs file in the repo (excluding declaration files and node_modules)
|
|
5
|
-
* and verifies that each one compiles without errors via the CLI (which handles
|
|
6
|
-
* `import` statements, unlike the bare `compile()` function).
|
|
7
|
-
*
|
|
8
|
-
* This catches regressions where a language change breaks existing source files.
|
|
9
|
-
*/
|
|
10
|
-
export {};
|