redscript-mc 1.2.26 → 1.2.28
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/README.md +78 -9
- package/README.zh.md +72 -4
- package/dist/__tests__/cli.test.js +13 -13
- package/dist/__tests__/optimizer-advanced.test.js +4 -4
- package/dist/__tests__/stdlib-advanced.test.js +114 -0
- package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/__tests__/stdlib-bigint.test.js +428 -0
- package/dist/cli.js +13 -5
- package/dist/codegen/mcfunction/index.d.ts +4 -0
- package/dist/codegen/mcfunction/index.js +9 -4
- package/dist/compile.d.ts +4 -0
- package/dist/compile.js +9 -1
- package/dist/data/arena/function/__load.mcfunction +6 -0
- package/dist/data/arena/function/__tick.mcfunction +2 -0
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
- package/dist/data/arena/function/arena_tick.mcfunction +11 -0
- package/dist/data/counter/function/__load.mcfunction +5 -0
- package/dist/data/counter/function/__tick.mcfunction +2 -0
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/counter/function/counter_tick.mcfunction +11 -0
- package/dist/data/gcd2/function/__load.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd2/function/abs.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd2/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/__load.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3/function/abs.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/test.mcfunction +7 -0
- package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3nm/function/test.mcfunction +7 -0
- package/dist/data/gcd_test/function/__load.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/abs.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
- package/dist/data/isqrttest/function/__load.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
- package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
- package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
- package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
- package/dist/data/isqrttest/function/test.mcfunction +6 -0
- package/dist/data/mathtest/function/__load.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mathtest/function/abs.mcfunction +6 -0
- package/dist/data/mathtest/function/test.mcfunction +5 -0
- package/dist/data/minecraft/tags/function/load.json +5 -0
- package/dist/data/minecraft/tags/function/tick.json +5 -0
- package/dist/data/mypack/function/__load.mcfunction +13 -0
- package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
- package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/abs.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
- package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
- package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
- package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
- package/dist/data/mypack/function/my_game.mcfunction +10 -0
- package/dist/data/quiz/function/__load.mcfunction +16 -0
- package/dist/data/quiz/function/__tick.mcfunction +6 -0
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/answer_a.mcfunction +4 -0
- package/dist/data/quiz/function/answer_b.mcfunction +4 -0
- package/dist/data/quiz/function/answer_c.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question.mcfunction +7 -0
- package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
- package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
- package/dist/data/reqtest/function/__load.mcfunction +4 -0
- package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
- package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
- package/dist/data/reqtest/function/use_table.mcfunction +4 -0
- package/dist/data/reqtest2/function/__load.mcfunction +3 -0
- package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
- package/dist/data/runtime/function/__load.mcfunction +5 -0
- package/dist/data/runtime/function/__tick.mcfunction +2 -0
- package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
- package/dist/data/shop/function/__load.mcfunction +7 -0
- package/dist/data/shop/function/__tick.mcfunction +3 -0
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
- package/dist/data/swap_test/function/__load.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
- package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
- package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
- package/dist/data/turret/function/__load.mcfunction +5 -0
- package/dist/data/turret/function/__tick.mcfunction +4 -0
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
- package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
- package/dist/data/turret/function/turret_tick.mcfunction +5 -0
- package/dist/gcd2.map.json +15 -0
- package/dist/gcd3.map.json +17 -0
- package/dist/gcd_test.map.json +15 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -6
- package/dist/isqrttest.map.json +15 -0
- package/dist/lowering/index.d.ts +3 -0
- package/dist/lowering/index.js +161 -64
- package/dist/mathtest.map.json +6 -0
- package/dist/mypack.map.json +27 -0
- package/dist/optimizer/commands.d.ts +1 -0
- package/dist/optimizer/commands.js +18 -11
- package/dist/optimizer/structure.d.ts +1 -0
- package/dist/optimizer/structure.js +6 -1
- package/dist/pack.mcmeta +6 -0
- package/dist/reqtest.map.json +4 -0
- package/dist/reqtest2.map.json +4 -0
- package/dist/runtime/index.js +26 -5
- package/dist/runtime.map.json +7 -0
- package/dist/swap_test.map.json +14 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/examples/math-showcase.mcrs +146 -0
- package/examples/readme-demo.mcrs +92 -0
- package/examples/showcase.mcrs +505 -0
- package/package.json +1 -1
- package/src/__tests__/cli.test.ts +13 -13
- package/src/__tests__/optimizer-advanced.test.ts +4 -4
- package/src/__tests__/stdlib-advanced.test.ts +120 -0
- package/src/__tests__/stdlib-bigint.test.ts +427 -0
- package/src/cli.ts +14 -5
- package/src/codegen/mcfunction/index.ts +14 -5
- package/src/compile.ts +15 -2
- package/src/index.ts +17 -7
- package/src/lowering/index.ts +165 -63
- package/src/optimizer/commands.ts +18 -12
- package/src/optimizer/structure.ts +6 -2
- package/src/runtime/index.ts +27 -5
- package/src/stdlib/advanced.mcrs +81 -0
- package/src/stdlib/bigint.mcrs +205 -0
- package/src/stdlib/math.mcrs +19 -6
package/src/lowering/index.ts
CHANGED
|
@@ -29,6 +29,15 @@ import { getBaseSelectorType, areCompatibleTypes, getConcreteSubtypes } from '..
|
|
|
29
29
|
// All builtins support macro parameters - any arg that's a function param
|
|
30
30
|
// will automatically use MC 1.20.2+ macro syntax when needed
|
|
31
31
|
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Scoreboard Objective
|
|
34
|
+
// Set per-compilation via setScoreboardObjective() — defaults to 'rs'.
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
/** Current scoreboard objective. Set once per compile() call. */
|
|
38
|
+
export let LOWERING_OBJ = 'rs'
|
|
39
|
+
export function setScoreboardObjective(obj: string): void { LOWERING_OBJ = obj }
|
|
40
|
+
|
|
32
41
|
// ---------------------------------------------------------------------------
|
|
33
42
|
// Builtin Functions
|
|
34
43
|
// ---------------------------------------------------------------------------
|
|
@@ -50,9 +59,13 @@ const BUILTINS: Record<string, (args: string[]) => string | null> = {
|
|
|
50
59
|
const pos = [x ?? '~', y ?? '~', z ?? '~'].join(' ')
|
|
51
60
|
return nbt ? `summon ${type} ${pos} ${nbt}` : `summon ${type} ${pos}`
|
|
52
61
|
},
|
|
53
|
-
particle: ([name, x, y, z]) => {
|
|
62
|
+
particle: ([name, x, y, z, dx, dy, dz, speed, count]) => {
|
|
54
63
|
const pos = [x ?? '~', y ?? '~', z ?? '~'].join(' ')
|
|
55
|
-
|
|
64
|
+
// dx/dy/dz/speed/count are optional; omit trailing undefineds
|
|
65
|
+
const extra = [dx, dy, dz, speed, count].filter(v => v !== undefined && v !== null)
|
|
66
|
+
return extra.length > 0
|
|
67
|
+
? `particle ${name} ${pos} ${extra.join(' ')}`
|
|
68
|
+
: `particle ${name} ${pos}`
|
|
56
69
|
},
|
|
57
70
|
playsound: ([sound, source, sel, x, y, z, volume, pitch, minVolume]) =>
|
|
58
71
|
['playsound', sound, source, sel, x, y, z, volume, pitch, minVolume].filter(Boolean).join(' '),
|
|
@@ -108,6 +121,7 @@ const BUILTINS: Record<string, (args: string[]) => string | null> = {
|
|
|
108
121
|
clearInterval: () => null, // Special handling
|
|
109
122
|
storage_get_int: () => null, // Special handling (dynamic NBT array read via macro)
|
|
110
123
|
storage_set_array: () => null, // Special handling (write literal NBT array to storage)
|
|
124
|
+
storage_set_int: () => null, // Special handling (dynamic NBT array write via macro)
|
|
111
125
|
}
|
|
112
126
|
|
|
113
127
|
export interface Warning {
|
|
@@ -364,12 +378,24 @@ export class Lowering {
|
|
|
364
378
|
|
|
365
379
|
private preScanExpr(expr: Expr, paramNames: Set<string>, macroParams: Set<string>): void {
|
|
366
380
|
if (expr.kind === 'call' && BUILTINS[expr.fn] !== undefined) {
|
|
367
|
-
//
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
381
|
+
// Only trigger macro param detection for builtins that actually emit
|
|
382
|
+
// MC commands with $(param) inline in the current function body.
|
|
383
|
+
// Special-handled builtins (storage_get_int / storage_set_int / etc.) are
|
|
384
|
+
// declared as `() => null` — they create their own sub-functions for macro
|
|
385
|
+
// indirection and do NOT require the surrounding function to be a macro.
|
|
386
|
+
const handler = BUILTINS[expr.fn]!
|
|
387
|
+
const isSpecialHandled: boolean = (() => {
|
|
388
|
+
try { return (handler as () => string | null)() === null } catch { return false }
|
|
389
|
+
})()
|
|
390
|
+
if (!isSpecialHandled) {
|
|
391
|
+
for (const arg of expr.args) {
|
|
392
|
+
if (arg.kind === 'ident' && paramNames.has(arg.name)) {
|
|
393
|
+
macroParams.add(arg.name)
|
|
394
|
+
}
|
|
371
395
|
}
|
|
372
396
|
}
|
|
397
|
+
// Always recurse into args for nested calls/expressions
|
|
398
|
+
for (const arg of expr.args) this.preScanExpr(arg, paramNames, macroParams)
|
|
373
399
|
return
|
|
374
400
|
}
|
|
375
401
|
// Recurse into sub-expressions for other call types
|
|
@@ -452,6 +478,16 @@ export class Lowering {
|
|
|
452
478
|
if (expr.kind === 'struct_lit' || expr.kind === 'array_lit') {
|
|
453
479
|
return { str: this.exprToSnbt(expr) }
|
|
454
480
|
}
|
|
481
|
+
// Float literals: preserve the float value for MC commands that accept floats
|
|
482
|
+
// (particle spread, playsound volume/pitch, etc.)
|
|
483
|
+
// We do NOT truncate here — that only applies to scoreboard/IR contexts.
|
|
484
|
+
if (expr.kind === 'float_lit') {
|
|
485
|
+
return { str: expr.value.toString() }
|
|
486
|
+
}
|
|
487
|
+
// Unary minus applied to a float literal (e.g. -0.5)
|
|
488
|
+
if (expr.kind === 'unary' && expr.op === '-' && expr.operand.kind === 'float_lit') {
|
|
489
|
+
return { str: (-expr.operand.value).toString() }
|
|
490
|
+
}
|
|
455
491
|
return { str: this.exprToString(expr) }
|
|
456
492
|
}
|
|
457
493
|
|
|
@@ -472,9 +508,9 @@ export class Lowering {
|
|
|
472
508
|
for (let i = 0; i < loweredArgs.length; i++) {
|
|
473
509
|
const operand = loweredArgs[i]
|
|
474
510
|
if (operand.kind === 'const') {
|
|
475
|
-
this.builder.emitRaw(`scoreboard players set $p${i}
|
|
511
|
+
this.builder.emitRaw(`scoreboard players set $p${i} ${LOWERING_OBJ} ${operand.value}`)
|
|
476
512
|
} else if (operand.kind === 'var') {
|
|
477
|
-
this.builder.emitRaw(`scoreboard players operation $p${i}
|
|
513
|
+
this.builder.emitRaw(`scoreboard players operation $p${i} ${LOWERING_OBJ} = ${operand.name} ${LOWERING_OBJ}`)
|
|
478
514
|
}
|
|
479
515
|
}
|
|
480
516
|
|
|
@@ -488,7 +524,7 @@ export class Lowering {
|
|
|
488
524
|
this.builder.emitRaw(`data modify storage rs:macro_args ${macroParam} set value ${operand.value}`)
|
|
489
525
|
} else if (operand.kind === 'var') {
|
|
490
526
|
this.builder.emitRaw(
|
|
491
|
-
`execute store result storage rs:macro_args ${macroParam} int 1 run scoreboard players get ${operand.name}
|
|
527
|
+
`execute store result storage rs:macro_args ${macroParam} int 1 run scoreboard players get ${operand.name} ${LOWERING_OBJ}`
|
|
492
528
|
)
|
|
493
529
|
}
|
|
494
530
|
}
|
|
@@ -498,7 +534,7 @@ export class Lowering {
|
|
|
498
534
|
|
|
499
535
|
// Copy return value (callers may use it)
|
|
500
536
|
const dst = this.builder.freshTemp()
|
|
501
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
537
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} = $ret ${LOWERING_OBJ}`)
|
|
502
538
|
return { kind: 'var', name: dst }
|
|
503
539
|
}
|
|
504
540
|
|
|
@@ -779,7 +815,7 @@ export class Lowering {
|
|
|
779
815
|
const originalTerm = entry.term
|
|
780
816
|
|
|
781
817
|
entry.instrs = [
|
|
782
|
-
{ op: 'raw', cmd: `scoreboard players add ${counterVar}
|
|
818
|
+
{ op: 'raw', cmd: `scoreboard players add ${counterVar} ${LOWERING_OBJ} 1` },
|
|
783
819
|
]
|
|
784
820
|
|
|
785
821
|
// Create conditional jump
|
|
@@ -796,14 +832,14 @@ export class Lowering {
|
|
|
796
832
|
// Add check instruction
|
|
797
833
|
entry.instrs.push({
|
|
798
834
|
op: 'raw',
|
|
799
|
-
cmd: `execute store success score ${counterVar}_check
|
|
835
|
+
cmd: `execute store success score ${counterVar}_check ${LOWERING_OBJ} if score ${counterVar} ${LOWERING_OBJ} matches ${rate}..`,
|
|
800
836
|
})
|
|
801
837
|
|
|
802
838
|
// Body block (original logic + counter reset)
|
|
803
839
|
fn.blocks.push({
|
|
804
840
|
label: bodyLabel,
|
|
805
841
|
instrs: [
|
|
806
|
-
{ op: 'raw', cmd: `scoreboard players set ${counterVar}
|
|
842
|
+
{ op: 'raw', cmd: `scoreboard players set ${counterVar} ${LOWERING_OBJ} 0` },
|
|
807
843
|
...originalInstrs,
|
|
808
844
|
],
|
|
809
845
|
term: originalTerm,
|
|
@@ -930,7 +966,7 @@ export class Lowering {
|
|
|
930
966
|
this.builder.emitRaw(`data modify storage ${path} set value ${fieldValue.value}`)
|
|
931
967
|
} else if (fieldValue.kind === 'var') {
|
|
932
968
|
// Copy from scoreboard to NBT
|
|
933
|
-
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${fieldValue.name}
|
|
969
|
+
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${fieldValue.name} ${LOWERING_OBJ}`)
|
|
934
970
|
}
|
|
935
971
|
}
|
|
936
972
|
return
|
|
@@ -964,7 +1000,7 @@ export class Lowering {
|
|
|
964
1000
|
this.builder.emitRaw(`data modify storage rs:heap ${stmt.name} append value ${elemValue.value}`)
|
|
965
1001
|
} else if (elemValue.kind === 'var') {
|
|
966
1002
|
this.builder.emitRaw(`data modify storage rs:heap ${stmt.name} append value 0`)
|
|
967
|
-
this.builder.emitRaw(`execute store result storage rs:heap ${stmt.name}[-1] int 1 run scoreboard players get ${elemValue.name}
|
|
1003
|
+
this.builder.emitRaw(`execute store result storage rs:heap ${stmt.name}[-1] int 1 run scoreboard players get ${elemValue.name} ${LOWERING_OBJ}`)
|
|
968
1004
|
}
|
|
969
1005
|
}
|
|
970
1006
|
return
|
|
@@ -1015,7 +1051,7 @@ export class Lowering {
|
|
|
1015
1051
|
if (fieldValue.kind === 'const') {
|
|
1016
1052
|
this.builder.emitRaw(`data modify storage ${path} set value ${fieldValue.value}`)
|
|
1017
1053
|
} else if (fieldValue.kind === 'var') {
|
|
1018
|
-
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${fieldValue.name}
|
|
1054
|
+
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${fieldValue.name} ${LOWERING_OBJ}`)
|
|
1019
1055
|
}
|
|
1020
1056
|
}
|
|
1021
1057
|
this.builder.emitReturn({ kind: 'const', value: 0 })
|
|
@@ -1234,9 +1270,9 @@ export class Lowering {
|
|
|
1234
1270
|
this.varMap.set(stmt.varName, loopVar)
|
|
1235
1271
|
const startVal = this.lowerExpr(stmt.start)
|
|
1236
1272
|
if (startVal.kind === 'const') {
|
|
1237
|
-
this.builder.emitRaw(`scoreboard players set ${loopVar}
|
|
1273
|
+
this.builder.emitRaw(`scoreboard players set ${loopVar} ${LOWERING_OBJ} ${startVal.value}`)
|
|
1238
1274
|
} else if (startVal.kind === 'var') {
|
|
1239
|
-
this.builder.emitRaw(`scoreboard players operation ${loopVar}
|
|
1275
|
+
this.builder.emitRaw(`scoreboard players operation ${loopVar} ${LOWERING_OBJ} = ${startVal.name} ${LOWERING_OBJ}`)
|
|
1240
1276
|
}
|
|
1241
1277
|
|
|
1242
1278
|
// Call loop function
|
|
@@ -1259,12 +1295,12 @@ export class Lowering {
|
|
|
1259
1295
|
this.lowerBlock(stmt.body)
|
|
1260
1296
|
|
|
1261
1297
|
// Increment
|
|
1262
|
-
this.builder.emitRaw(`scoreboard players add ${loopVar}
|
|
1298
|
+
this.builder.emitRaw(`scoreboard players add ${loopVar} ${LOWERING_OBJ} 1`)
|
|
1263
1299
|
|
|
1264
1300
|
// Loop condition: execute if score matches ..<end-1> run function
|
|
1265
1301
|
const endVal = this.lowerExpr(stmt.end)
|
|
1266
1302
|
const endNum = endVal.kind === 'const' ? endVal.value - 1 : '?'
|
|
1267
|
-
this.builder.emitRaw(`execute if score ${loopVar}
|
|
1303
|
+
this.builder.emitRaw(`execute if score ${loopVar} ${LOWERING_OBJ} matches ..${endNum} run function ${this.namespace}:${subFnName}`)
|
|
1268
1304
|
|
|
1269
1305
|
if (!this.builder.isBlockSealed()) {
|
|
1270
1306
|
this.builder.emitReturn()
|
|
@@ -1369,13 +1405,13 @@ export class Lowering {
|
|
|
1369
1405
|
}
|
|
1370
1406
|
|
|
1371
1407
|
const subFnName = `${this.currentFn}/match_${this.foreachCounter++}`
|
|
1372
|
-
this.builder.emitRaw(`execute if score ${matchedVar}
|
|
1408
|
+
this.builder.emitRaw(`execute if score ${matchedVar} ${LOWERING_OBJ} matches ..0 if score ${subject} ${LOWERING_OBJ} matches ${matchCondition} run function ${this.namespace}:${subFnName}`)
|
|
1373
1409
|
this.emitMatchArmSubFunction(subFnName, matchedVar, arm.body, true)
|
|
1374
1410
|
}
|
|
1375
1411
|
|
|
1376
1412
|
if (defaultArm) {
|
|
1377
1413
|
const subFnName = `${this.currentFn}/match_${this.foreachCounter++}`
|
|
1378
|
-
this.builder.emitRaw(`execute if score ${matchedVar}
|
|
1414
|
+
this.builder.emitRaw(`execute if score ${matchedVar} ${LOWERING_OBJ} matches ..0 run function ${this.namespace}:${subFnName}`)
|
|
1379
1415
|
this.emitMatchArmSubFunction(subFnName, matchedVar, defaultArm.body, false)
|
|
1380
1416
|
}
|
|
1381
1417
|
}
|
|
@@ -1393,7 +1429,7 @@ export class Lowering {
|
|
|
1393
1429
|
|
|
1394
1430
|
this.builder.startBlock('entry')
|
|
1395
1431
|
if (setMatched) {
|
|
1396
|
-
this.builder.emitRaw(`scoreboard players set ${matchedVar}
|
|
1432
|
+
this.builder.emitRaw(`scoreboard players set ${matchedVar} ${LOWERING_OBJ} 1`)
|
|
1397
1433
|
}
|
|
1398
1434
|
this.lowerBlock(body)
|
|
1399
1435
|
if (!this.builder.isBlockSealed()) {
|
|
@@ -1432,7 +1468,7 @@ export class Lowering {
|
|
|
1432
1468
|
|
|
1433
1469
|
this.builder.emitAssign(indexVar, { kind: 'const', value: 0 })
|
|
1434
1470
|
this.builder.emitAssign(oneVar, { kind: 'const', value: 1 })
|
|
1435
|
-
this.builder.emitRaw(`execute store result score ${lengthVar}
|
|
1471
|
+
this.builder.emitRaw(`execute store result score ${lengthVar} ${LOWERING_OBJ} run data get storage rs:heap ${arrayName}`)
|
|
1436
1472
|
|
|
1437
1473
|
const checkLabel = this.builder.freshLabel('foreach_array_check')
|
|
1438
1474
|
const bodyLabel = this.builder.freshLabel('foreach_array_body')
|
|
@@ -1449,7 +1485,7 @@ export class Lowering {
|
|
|
1449
1485
|
this.builder.emitAssign(bindingVar, element)
|
|
1450
1486
|
this.lowerBlock(stmt.body)
|
|
1451
1487
|
if (!this.builder.isBlockSealed()) {
|
|
1452
|
-
this.builder.emitRaw(`scoreboard players operation ${indexVar}
|
|
1488
|
+
this.builder.emitRaw(`scoreboard players operation ${indexVar} ${LOWERING_OBJ} += ${oneVar} ${LOWERING_OBJ}`)
|
|
1453
1489
|
this.builder.emitJump(checkLabel)
|
|
1454
1490
|
}
|
|
1455
1491
|
|
|
@@ -1828,7 +1864,7 @@ export class Lowering {
|
|
|
1828
1864
|
if (mapped && mapped.startsWith('@e[tag=__rs_obj_')) {
|
|
1829
1865
|
// World object field access → scoreboard get
|
|
1830
1866
|
const dst = this.builder.freshTemp()
|
|
1831
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
1867
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} = ${mapped} ${LOWERING_OBJ}`)
|
|
1832
1868
|
return { kind: 'var', name: dst }
|
|
1833
1869
|
}
|
|
1834
1870
|
|
|
@@ -1837,14 +1873,14 @@ export class Lowering {
|
|
|
1837
1873
|
const path = `rs:heap ${structName}_${expr.obj.name}.${expr.field}`
|
|
1838
1874
|
const dst = this.builder.freshTemp()
|
|
1839
1875
|
// Read from NBT storage into scoreboard
|
|
1840
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
1876
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${path}`)
|
|
1841
1877
|
return { kind: 'var', name: dst }
|
|
1842
1878
|
}
|
|
1843
1879
|
|
|
1844
1880
|
// Array length property
|
|
1845
1881
|
if (varType?.kind === 'array' && expr.field === 'len') {
|
|
1846
1882
|
const dst = this.builder.freshTemp()
|
|
1847
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
1883
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage rs:heap ${expr.obj.name}`)
|
|
1848
1884
|
return { kind: 'var', name: dst }
|
|
1849
1885
|
}
|
|
1850
1886
|
}
|
|
@@ -1863,9 +1899,9 @@ export class Lowering {
|
|
|
1863
1899
|
const value = this.lowerExpr(expr.value)
|
|
1864
1900
|
if (expr.op === '=') {
|
|
1865
1901
|
if (value.kind === 'const') {
|
|
1866
|
-
this.builder.emitRaw(`scoreboard players set ${mapped}
|
|
1902
|
+
this.builder.emitRaw(`scoreboard players set ${mapped} ${LOWERING_OBJ} ${value.value}`)
|
|
1867
1903
|
} else if (value.kind === 'var') {
|
|
1868
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1904
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} = ${value.name} ${LOWERING_OBJ}`)
|
|
1869
1905
|
}
|
|
1870
1906
|
} else {
|
|
1871
1907
|
// Compound assignment
|
|
@@ -1874,9 +1910,9 @@ export class Lowering {
|
|
|
1874
1910
|
if (value.kind === 'const') {
|
|
1875
1911
|
const constTemp = this.builder.freshTemp()
|
|
1876
1912
|
this.builder.emitAssign(constTemp, value)
|
|
1877
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1913
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} ${opMap[binOp]} ${constTemp} ${LOWERING_OBJ}`)
|
|
1878
1914
|
} else if (value.kind === 'var') {
|
|
1879
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1915
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} ${opMap[binOp]} ${value.name} ${LOWERING_OBJ}`)
|
|
1880
1916
|
}
|
|
1881
1917
|
}
|
|
1882
1918
|
return { kind: 'const', value: 0 }
|
|
@@ -1891,15 +1927,15 @@ export class Lowering {
|
|
|
1891
1927
|
if (value.kind === 'const') {
|
|
1892
1928
|
this.builder.emitRaw(`data modify storage ${path} set value ${value.value}`)
|
|
1893
1929
|
} else if (value.kind === 'var') {
|
|
1894
|
-
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${value.name}
|
|
1930
|
+
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${value.name} ${LOWERING_OBJ}`)
|
|
1895
1931
|
}
|
|
1896
1932
|
} else {
|
|
1897
1933
|
// Compound assignment: read, modify, write back
|
|
1898
1934
|
const dst = this.builder.freshTemp()
|
|
1899
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
1935
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${path}`)
|
|
1900
1936
|
const binOp = expr.op.slice(0, -1)
|
|
1901
1937
|
this.builder.emitBinop(dst, { kind: 'var', name: dst }, binOp as any, value)
|
|
1902
|
-
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${dst}
|
|
1938
|
+
this.builder.emitRaw(`execute store result storage ${path} int 1 run scoreboard players get ${dst} ${LOWERING_OBJ}`)
|
|
1903
1939
|
}
|
|
1904
1940
|
return { kind: 'const', value: 0 }
|
|
1905
1941
|
}
|
|
@@ -1932,13 +1968,13 @@ export class Lowering {
|
|
|
1932
1968
|
this.builder.emitAssign(dst, left)
|
|
1933
1969
|
const rightVar = this.operandToVar(right)
|
|
1934
1970
|
// dst = dst && right → if dst != 0 then dst = right
|
|
1935
|
-
this.builder.emitRaw(`execute if score ${dst}
|
|
1971
|
+
this.builder.emitRaw(`execute if score ${dst} ${LOWERING_OBJ} matches 1.. run scoreboard players operation ${dst} ${LOWERING_OBJ} = ${rightVar} ${LOWERING_OBJ}`)
|
|
1936
1972
|
} else {
|
|
1937
1973
|
// Short-circuit OR
|
|
1938
1974
|
this.builder.emitAssign(dst, left)
|
|
1939
1975
|
const rightVar = this.operandToVar(right)
|
|
1940
1976
|
// dst = dst || right → if dst == 0 then dst = right
|
|
1941
|
-
this.builder.emitRaw(`execute if score ${dst}
|
|
1977
|
+
this.builder.emitRaw(`execute if score ${dst} ${LOWERING_OBJ} matches ..0 run scoreboard players operation ${dst} ${LOWERING_OBJ} = ${rightVar} ${LOWERING_OBJ}`)
|
|
1942
1978
|
}
|
|
1943
1979
|
return { kind: 'var', name: dst }
|
|
1944
1980
|
}
|
|
@@ -1957,15 +1993,15 @@ export class Lowering {
|
|
|
1957
1993
|
// Divide by 1000 to correct for double scaling
|
|
1958
1994
|
const constDiv = this.builder.freshTemp()
|
|
1959
1995
|
this.builder.emitAssign(constDiv, { kind: 'const', value: 1000 })
|
|
1960
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
1996
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} /= ${constDiv} ${LOWERING_OBJ}`)
|
|
1961
1997
|
} else {
|
|
1962
1998
|
// Division: a * 1000 / b
|
|
1963
1999
|
const constMul = this.builder.freshTemp()
|
|
1964
2000
|
this.builder.emitAssign(constMul, { kind: 'const', value: 1000 })
|
|
1965
2001
|
this.builder.emitAssign(dst, left)
|
|
1966
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
2002
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} *= ${constMul} ${LOWERING_OBJ}`)
|
|
1967
2003
|
const rightVar = this.operandToVar(right)
|
|
1968
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
2004
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} /= ${rightVar} ${LOWERING_OBJ}`)
|
|
1969
2005
|
}
|
|
1970
2006
|
return { kind: 'var', name: dst }
|
|
1971
2007
|
}
|
|
@@ -2044,7 +2080,7 @@ export class Lowering {
|
|
|
2044
2080
|
const storagePath = this.getStringStoragePath(expr.args[0])
|
|
2045
2081
|
if (storagePath) {
|
|
2046
2082
|
const dst = this.builder.freshTemp()
|
|
2047
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2083
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storagePath}`)
|
|
2048
2084
|
return { kind: 'var', name: dst }
|
|
2049
2085
|
}
|
|
2050
2086
|
|
|
@@ -2082,7 +2118,7 @@ export class Lowering {
|
|
|
2082
2118
|
const entity = this.exprToString(expr.args[0])
|
|
2083
2119
|
const tagName = this.exprToString(expr.args[1])
|
|
2084
2120
|
const dst = this.builder.freshTemp()
|
|
2085
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2121
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} if entity ${entity}[tag=${tagName}]`)
|
|
2086
2122
|
return { kind: 'var', name: dst }
|
|
2087
2123
|
}
|
|
2088
2124
|
|
|
@@ -2097,7 +2133,7 @@ export class Lowering {
|
|
|
2097
2133
|
this.builder.emitRaw(`data modify storage rs:heap ${arrName} append value ${value.value}`)
|
|
2098
2134
|
} else if (value.kind === 'var') {
|
|
2099
2135
|
this.builder.emitRaw(`data modify storage rs:heap ${arrName} append value 0`)
|
|
2100
|
-
this.builder.emitRaw(`execute store result storage rs:heap ${arrName}[-1] int 1 run scoreboard players get ${value.name}
|
|
2136
|
+
this.builder.emitRaw(`execute store result storage rs:heap ${arrName}[-1] int 1 run scoreboard players get ${value.name} ${LOWERING_OBJ}`)
|
|
2101
2137
|
}
|
|
2102
2138
|
}
|
|
2103
2139
|
return { kind: 'const', value: 0 }
|
|
@@ -2107,7 +2143,7 @@ export class Lowering {
|
|
|
2107
2143
|
const arrName = this.getArrayStorageName(expr.args[0])
|
|
2108
2144
|
const dst = this.builder.freshTemp()
|
|
2109
2145
|
if (arrName) {
|
|
2110
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2146
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage rs:heap ${arrName}[-1]`)
|
|
2111
2147
|
this.builder.emitRaw(`data remove storage rs:heap ${arrName}[-1]`)
|
|
2112
2148
|
} else {
|
|
2113
2149
|
this.builder.emitAssign(dst, { kind: 'const', value: 0 })
|
|
@@ -2407,7 +2443,7 @@ export class Lowering {
|
|
|
2407
2443
|
const dst = this.builder.freshTemp()
|
|
2408
2444
|
const min = args[0] ? this.exprToLiteral(args[0]) : '0'
|
|
2409
2445
|
const max = args[1] ? this.exprToLiteral(args[1]) : '100'
|
|
2410
|
-
this.builder.emitRaw(`scoreboard players random ${dst}
|
|
2446
|
+
this.builder.emitRaw(`scoreboard players random ${dst} ${LOWERING_OBJ} ${min} ${max}`)
|
|
2411
2447
|
return { kind: 'var', name: dst }
|
|
2412
2448
|
}
|
|
2413
2449
|
|
|
@@ -2416,7 +2452,7 @@ export class Lowering {
|
|
|
2416
2452
|
const dst = this.builder.freshTemp()
|
|
2417
2453
|
const min = args[0] ? this.exprToLiteral(args[0]) : '0'
|
|
2418
2454
|
const max = args[1] ? this.exprToLiteral(args[1]) : '100'
|
|
2419
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2455
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run random value ${min} ${max}`)
|
|
2420
2456
|
return { kind: 'var', name: dst }
|
|
2421
2457
|
}
|
|
2422
2458
|
|
|
@@ -2433,7 +2469,7 @@ export class Lowering {
|
|
|
2433
2469
|
const dst = this.builder.freshTemp()
|
|
2434
2470
|
const player = this.exprToTargetString(args[0])
|
|
2435
2471
|
const objective = this.resolveScoreboardObjective(args[0], args[1], callSpan)
|
|
2436
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2472
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run scoreboard players get ${player} ${objective}`)
|
|
2437
2473
|
return { kind: 'var', name: dst }
|
|
2438
2474
|
}
|
|
2439
2475
|
|
|
@@ -2447,7 +2483,7 @@ export class Lowering {
|
|
|
2447
2483
|
} else if (value.kind === 'var') {
|
|
2448
2484
|
// Read directly from the computed scoreboard temp. Routing through a fresh
|
|
2449
2485
|
// temp here breaks once optimization removes the apparently-dead assign.
|
|
2450
|
-
this.builder.emitRaw(`execute store result score ${player} ${objective} run scoreboard players get ${value.name}
|
|
2486
|
+
this.builder.emitRaw(`execute store result score ${player} ${objective} run scoreboard players get ${value.name} ${LOWERING_OBJ}`)
|
|
2451
2487
|
}
|
|
2452
2488
|
return { kind: 'const', value: 0 }
|
|
2453
2489
|
}
|
|
@@ -2523,7 +2559,7 @@ export class Lowering {
|
|
|
2523
2559
|
|
|
2524
2560
|
if (name === 'bossbar_get_value') {
|
|
2525
2561
|
const dst = this.builder.freshTemp()
|
|
2526
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2562
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run bossbar get ${this.exprToString(args[0])} value`)
|
|
2527
2563
|
return { kind: 'var', name: dst }
|
|
2528
2564
|
}
|
|
2529
2565
|
|
|
@@ -2570,7 +2606,7 @@ export class Lowering {
|
|
|
2570
2606
|
: this.exprToString(args[1])
|
|
2571
2607
|
const path = this.exprToString(args[2])
|
|
2572
2608
|
const scale = args[3] ? this.exprToString(args[3]) : '1'
|
|
2573
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2609
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get ${targetType} ${target} ${path} ${scale}`)
|
|
2574
2610
|
return { kind: 'var', name: dst }
|
|
2575
2611
|
}
|
|
2576
2612
|
|
|
@@ -2580,7 +2616,7 @@ export class Lowering {
|
|
|
2580
2616
|
// array_key : e.g. "sin"
|
|
2581
2617
|
// index : integer index (const or runtime)
|
|
2582
2618
|
//
|
|
2583
|
-
// Const index: execute store result score $dst
|
|
2619
|
+
// Const index: execute store result score $dst ${LOWERING_OBJ} run data get storage math:tables sin[N] 1
|
|
2584
2620
|
// Runtime index: macro sub-function via rs:heap, mirrors readArrayElement.
|
|
2585
2621
|
if (name === 'storage_get_int') {
|
|
2586
2622
|
const storageNs = this.exprToString(args[0]) // "math:tables"
|
|
@@ -2590,7 +2626,7 @@ export class Lowering {
|
|
|
2590
2626
|
|
|
2591
2627
|
if (indexOperand.kind === 'const') {
|
|
2592
2628
|
this.builder.emitRaw(
|
|
2593
|
-
`execute store result score ${dst}
|
|
2629
|
+
`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storageNs} ${arrayKey}[${indexOperand.value}] 1`
|
|
2594
2630
|
)
|
|
2595
2631
|
} else {
|
|
2596
2632
|
// Runtime index: store the index into rs:heap under a unique key,
|
|
@@ -2601,7 +2637,7 @@ export class Lowering {
|
|
|
2601
2637
|
? indexOperand.name
|
|
2602
2638
|
: this.operandToVar(indexOperand)
|
|
2603
2639
|
this.builder.emitRaw(
|
|
2604
|
-
`execute store result storage rs:heap ${macroKey} int 1 run scoreboard players get ${indexVar}
|
|
2640
|
+
`execute store result storage rs:heap ${macroKey} int 1 run scoreboard players get ${indexVar} ${LOWERING_OBJ}`
|
|
2605
2641
|
)
|
|
2606
2642
|
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
2607
2643
|
// Prefix \x01 is a sentinel for the MC macro '$' line-start marker.
|
|
@@ -2610,7 +2646,7 @@ export class Lowering {
|
|
|
2610
2646
|
// Codegen replaces \x01 → '$' when emitting the mc function file.
|
|
2611
2647
|
this.emitRawSubFunction(
|
|
2612
2648
|
subFnName,
|
|
2613
|
-
`\x01execute store result score ${dst}
|
|
2649
|
+
`\x01execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storageNs} ${arrayKey}[$(${macroKey})] 1`
|
|
2614
2650
|
)
|
|
2615
2651
|
}
|
|
2616
2652
|
return { kind: 'var', name: dst }
|
|
@@ -2629,6 +2665,64 @@ export class Lowering {
|
|
|
2629
2665
|
return { kind: 'const', value: 0 }
|
|
2630
2666
|
}
|
|
2631
2667
|
|
|
2668
|
+
// storage_set_int(storage_ns, array_key, index, value) -> void
|
|
2669
|
+
// Writes one integer element into an NBT int-array stored in data storage.
|
|
2670
|
+
// storage_ns : e.g. "rs:bigint"
|
|
2671
|
+
// array_key : e.g. "a"
|
|
2672
|
+
// index : element index (const or runtime)
|
|
2673
|
+
// value : integer value to write (const or runtime)
|
|
2674
|
+
//
|
|
2675
|
+
// Const index + const value:
|
|
2676
|
+
// execute store result storage <ns> <key>[N] int 1 run scoreboard players set $const_V ${LOWERING_OBJ} V
|
|
2677
|
+
// Runtime index or value: macro sub-function via rs:heap
|
|
2678
|
+
if (name === 'storage_set_int') {
|
|
2679
|
+
const storageNs = this.exprToString(args[0])
|
|
2680
|
+
const arrayKey = this.exprToString(args[1])
|
|
2681
|
+
const indexOperand = this.lowerExpr(args[2])
|
|
2682
|
+
const valueOperand = this.lowerExpr(args[3])
|
|
2683
|
+
|
|
2684
|
+
if (indexOperand.kind === 'const') {
|
|
2685
|
+
// Static index — use execute store result to write to the fixed slot
|
|
2686
|
+
const valVar = valueOperand.kind === 'var'
|
|
2687
|
+
? valueOperand.name
|
|
2688
|
+
: this.operandToVar(valueOperand)
|
|
2689
|
+
this.builder.emitRaw(
|
|
2690
|
+
`execute store result storage ${storageNs} ${arrayKey}[${indexOperand.value}] int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2691
|
+
)
|
|
2692
|
+
} else {
|
|
2693
|
+
// Runtime index: we need a macro sub-function.
|
|
2694
|
+
// Store index + value into rs:heap, call macro that does:
|
|
2695
|
+
// $data modify storage <ns> <key>[$(idx_key)] set value $(val_key)
|
|
2696
|
+
const macroIdxKey = `__ssi_i_${this.foreachCounter++}`
|
|
2697
|
+
const macroValKey = `__ssi_v_${this.foreachCounter++}` // kept to pin valVar in optimizer
|
|
2698
|
+
const subFnName = `${this.currentFn}/__ssi_${this.foreachCounter++}`
|
|
2699
|
+
const indexVar = indexOperand.kind === 'var'
|
|
2700
|
+
? indexOperand.name
|
|
2701
|
+
: this.operandToVar(indexOperand)
|
|
2702
|
+
const valVar = valueOperand.kind === 'var'
|
|
2703
|
+
? valueOperand.name
|
|
2704
|
+
: this.operandToVar(valueOperand)
|
|
2705
|
+
this.builder.emitRaw(
|
|
2706
|
+
`execute store result storage rs:heap ${macroIdxKey} int 1 run scoreboard players get ${indexVar} ${LOWERING_OBJ}`
|
|
2707
|
+
)
|
|
2708
|
+
// Pin valVar in the optimizer's read-set so the assignment is not dead-code-eliminated.
|
|
2709
|
+
// The value is stored to rs:heap but NOT used by the macro (the macro reads the scoreboard
|
|
2710
|
+
// slot directly to avoid the MC 'data modify set value $(n)' macro substitution bug).
|
|
2711
|
+
this.builder.emitRaw(
|
|
2712
|
+
`execute store result storage rs:heap ${macroValKey} int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2713
|
+
)
|
|
2714
|
+
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
2715
|
+
// Use execute store result (not 'data modify set value $(val)') to avoid MC macro
|
|
2716
|
+
// substitution bugs with numeric values. The scoreboard slot ${valVar} is hardcoded
|
|
2717
|
+
// into the macro sub-function at compile time — only the array index is macro-substituted.
|
|
2718
|
+
this.emitRawSubFunction(
|
|
2719
|
+
subFnName,
|
|
2720
|
+
`\x01execute store result storage ${storageNs} ${arrayKey}[$(${macroIdxKey})] int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2721
|
+
)
|
|
2722
|
+
}
|
|
2723
|
+
return { kind: 'const', value: 0 }
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2632
2726
|
// data_merge(target, nbt) — merge NBT into entity/block/storage
|
|
2633
2727
|
// data_merge(@s, { Invisible: 1b, Silent: 1b })
|
|
2634
2728
|
if (name === 'data_merge') {
|
|
@@ -2673,7 +2767,7 @@ export class Lowering {
|
|
|
2673
2767
|
const dst = this.builder.freshTemp()
|
|
2674
2768
|
const setId = this.exprToString(args[0])
|
|
2675
2769
|
const value = this.exprToString(args[1])
|
|
2676
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2770
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} if data storage rs:sets ${setId}[{value:${value}}]`)
|
|
2677
2771
|
return { kind: 'var', name: dst }
|
|
2678
2772
|
}
|
|
2679
2773
|
|
|
@@ -2990,7 +3084,7 @@ export class Lowering {
|
|
|
2990
3084
|
return
|
|
2991
3085
|
}
|
|
2992
3086
|
|
|
2993
|
-
components.push({ score: { name: this.operandToVar(operand), objective:
|
|
3087
|
+
components.push({ score: { name: this.operandToVar(operand), objective: LOWERING_OBJ } })
|
|
2994
3088
|
}
|
|
2995
3089
|
|
|
2996
3090
|
private exprToString(expr: Expr): string {
|
|
@@ -3156,12 +3250,20 @@ export class Lowering {
|
|
|
3156
3250
|
|
|
3157
3251
|
private exprToScoreboardObjective(expr: Expr, span?: Span): string {
|
|
3158
3252
|
if (expr.kind === 'mc_name') {
|
|
3159
|
-
|
|
3253
|
+
// 'rs' is the canonical token for the current RS scoreboard objective.
|
|
3254
|
+
// Resolve to LOWERING_OBJ so it respects --scoreboard / namespace default.
|
|
3255
|
+
return expr.value === 'rs' ? LOWERING_OBJ : expr.value
|
|
3160
3256
|
}
|
|
3161
3257
|
|
|
3162
3258
|
const objective = this.exprToString(expr)
|
|
3163
3259
|
if (objective.startsWith('#') || objective.includes('.')) {
|
|
3164
|
-
|
|
3260
|
+
if (objective.startsWith('#')) {
|
|
3261
|
+
const name = objective.slice(1)
|
|
3262
|
+
// '#rs' is the canonical way to reference the current RS scoreboard objective.
|
|
3263
|
+
// Resolve to LOWERING_OBJ so it tracks the --scoreboard option.
|
|
3264
|
+
return name === 'rs' ? LOWERING_OBJ : name
|
|
3265
|
+
}
|
|
3266
|
+
return objective
|
|
3165
3267
|
}
|
|
3166
3268
|
|
|
3167
3269
|
return `${this.getObjectiveNamespace(span)}.${objective}`
|
|
@@ -3181,7 +3283,7 @@ export class Lowering {
|
|
|
3181
3283
|
return this.namespace
|
|
3182
3284
|
}
|
|
3183
3285
|
|
|
3184
|
-
return this.isStdlibFile(filePath) ?
|
|
3286
|
+
return this.isStdlibFile(filePath) ? LOWERING_OBJ : this.namespace
|
|
3185
3287
|
}
|
|
3186
3288
|
|
|
3187
3289
|
private tryGetStdlibInternalObjective(playerExpr: Expr | undefined, objectiveExpr: Expr, span?: Span): string | null {
|
|
@@ -3200,7 +3302,7 @@ export class Lowering {
|
|
|
3200
3302
|
}
|
|
3201
3303
|
|
|
3202
3304
|
const hash = this.shortHash(this.serializeCallSite(this.currentStdlibCallSite))
|
|
3203
|
-
return
|
|
3305
|
+
return `${LOWERING_OBJ}._${resourceBase}_${hash}`
|
|
3204
3306
|
}
|
|
3205
3307
|
|
|
3206
3308
|
private getStdlibInternalResourceBase(playerExpr: Expr | undefined): string | null {
|
|
@@ -3522,18 +3624,18 @@ export class Lowering {
|
|
|
3522
3624
|
const dst = this.builder.freshTemp()
|
|
3523
3625
|
|
|
3524
3626
|
if (index.kind === 'const') {
|
|
3525
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
3627
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage rs:heap ${arrayName}[${index.value}]`)
|
|
3526
3628
|
return { kind: 'var', name: dst }
|
|
3527
3629
|
}
|
|
3528
3630
|
|
|
3529
3631
|
const macroKey = `__rs_index_${this.foreachCounter++}`
|
|
3530
3632
|
const subFnName = `${this.currentFn}/array_get_${this.foreachCounter++}`
|
|
3531
3633
|
const indexVar = index.kind === 'var' ? index.name : this.operandToVar(index)
|
|
3532
|
-
this.builder.emitRaw(`execute store result storage rs:heap ${macroKey} int 1 run scoreboard players get ${indexVar}
|
|
3634
|
+
this.builder.emitRaw(`execute store result storage rs:heap ${macroKey} int 1 run scoreboard players get ${indexVar} ${LOWERING_OBJ}`)
|
|
3533
3635
|
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
3534
3636
|
this.emitRawSubFunction(
|
|
3535
3637
|
subFnName,
|
|
3536
|
-
`\x01execute store result score ${dst}
|
|
3638
|
+
`\x01execute store result score ${dst} ${LOWERING_OBJ} run data get storage rs:heap ${arrayName}[$(${macroKey})]`
|
|
3537
3639
|
)
|
|
3538
3640
|
return { kind: 'var', name: dst }
|
|
3539
3641
|
}
|