redscript-mc 1.2.27 → 1.2.29
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 +24 -13
- package/README.zh.md +16 -5
- package/dist/__tests__/cli.test.js +13 -13
- package/dist/__tests__/optimizer-advanced.test.js +4 -4
- 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 +5 -0
- package/dist/compile.js +9 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -6
- package/dist/lowering/index.d.ts +3 -0
- package/dist/lowering/index.js +95 -65
- 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/editors/vscode/out/extension.js +1797 -1157
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/editors/vscode/src/hover.ts +18 -0
- package/editors/vscode/syntaxes/redscript.tmLanguage.json +12 -3
- package/examples/math-showcase.mcrs +146 -0
- package/examples/readme-demo.mcrs +92 -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/cli.ts +14 -5
- package/src/codegen/mcfunction/index.ts +14 -5
- package/src/compile.ts +16 -2
- package/src/index.ts +18 -7
- package/src/lowering/index.ts +95 -64
- package/src/optimizer/commands.ts +18 -12
- package/src/optimizer/structure.ts +6 -2
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ export const version = '1.2.11'
|
|
|
10
10
|
import { Lexer } from './lexer'
|
|
11
11
|
import { Parser } from './parser'
|
|
12
12
|
import { TypeChecker } from './typechecker'
|
|
13
|
-
import { Lowering } from './lowering'
|
|
13
|
+
import { Lowering, setScoreboardObjective } from './lowering'
|
|
14
14
|
import type { Warning } from './lowering'
|
|
15
15
|
import {
|
|
16
16
|
constantFoldingWithStats,
|
|
@@ -36,6 +36,11 @@ export interface CompileOptions {
|
|
|
36
36
|
filePath?: string
|
|
37
37
|
dce?: boolean
|
|
38
38
|
mangle?: boolean
|
|
39
|
+
/** Scoreboard objective used for all variable slots.
|
|
40
|
+
* Defaults to '__<namespace>' (e.g. '__mathshow') to avoid collisions when
|
|
41
|
+
* multiple RedScript datapacks are loaded simultaneously, without occupying
|
|
42
|
+
* the user's own namespace. Override only if you need a specific name. */
|
|
43
|
+
scoreboardObjective?: string
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
export interface CompileResult {
|
|
@@ -101,12 +106,18 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
101
106
|
typeErrors = checker.check(ast)
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
// Configure scoreboard objective for this compilation.
|
|
110
|
+
// Default: use the datapack namespace so each datapack gets its own objective
|
|
111
|
+
// automatically, preventing variable collisions when multiple datapacks coexist.
|
|
112
|
+
const scoreboardObj = options.scoreboardObjective ?? `__${namespace}`
|
|
113
|
+
setScoreboardObjective(scoreboardObj)
|
|
114
|
+
|
|
104
115
|
// Lowering to IR
|
|
105
116
|
const lowering = new Lowering(namespace, preprocessed.ranges)
|
|
106
117
|
const ir = lowering.lower(ast)
|
|
107
118
|
|
|
108
119
|
let optimizedIR: IRModule = ir
|
|
109
|
-
let generated = generateDatapackWithStats(ir, { optimizeCommands: shouldOptimize, mangle })
|
|
120
|
+
let generated = generateDatapackWithStats(ir, { optimizeCommands: shouldOptimize, mangle, scoreboardObjective: scoreboardObj })
|
|
110
121
|
let optimizationStats: OptimizationStats | undefined
|
|
111
122
|
|
|
112
123
|
if (shouldOptimize) {
|
|
@@ -128,10 +139,10 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
128
139
|
const copyPropagatedIR: IRModule = { ...ir, functions: copyPropagatedFunctions }
|
|
129
140
|
optimizedIR = { ...ir, functions: deadCodeEliminatedFunctions }
|
|
130
141
|
|
|
131
|
-
const baselineGenerated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle })
|
|
132
|
-
const beforeDceGenerated = generateDatapackWithStats(copyPropagatedIR, { optimizeCommands: false, mangle })
|
|
133
|
-
const afterDceGenerated = generateDatapackWithStats(optimizedIR, { optimizeCommands: false, mangle })
|
|
134
|
-
generated = generateDatapackWithStats(optimizedIR, { optimizeCommands: true, mangle })
|
|
142
|
+
const baselineGenerated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
|
|
143
|
+
const beforeDceGenerated = generateDatapackWithStats(copyPropagatedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
|
|
144
|
+
const afterDceGenerated = generateDatapackWithStats(optimizedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
|
|
145
|
+
generated = generateDatapackWithStats(optimizedIR, { optimizeCommands: true, mangle, scoreboardObjective: scoreboardObj })
|
|
135
146
|
|
|
136
147
|
stats.deadCodeRemoved =
|
|
137
148
|
countMcfunctionCommands(beforeDceGenerated.files) - countMcfunctionCommands(afterDceGenerated.files)
|
|
@@ -147,7 +158,7 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
147
158
|
optimizationStats = stats
|
|
148
159
|
} else {
|
|
149
160
|
optimizedIR = ir
|
|
150
|
-
generated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle })
|
|
161
|
+
generated = generateDatapackWithStats(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj })
|
|
151
162
|
}
|
|
152
163
|
|
|
153
164
|
return {
|
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(' '),
|
|
@@ -465,6 +478,16 @@ export class Lowering {
|
|
|
465
478
|
if (expr.kind === 'struct_lit' || expr.kind === 'array_lit') {
|
|
466
479
|
return { str: this.exprToSnbt(expr) }
|
|
467
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
|
+
}
|
|
468
491
|
return { str: this.exprToString(expr) }
|
|
469
492
|
}
|
|
470
493
|
|
|
@@ -485,9 +508,9 @@ export class Lowering {
|
|
|
485
508
|
for (let i = 0; i < loweredArgs.length; i++) {
|
|
486
509
|
const operand = loweredArgs[i]
|
|
487
510
|
if (operand.kind === 'const') {
|
|
488
|
-
this.builder.emitRaw(`scoreboard players set $p${i}
|
|
511
|
+
this.builder.emitRaw(`scoreboard players set $p${i} ${LOWERING_OBJ} ${operand.value}`)
|
|
489
512
|
} else if (operand.kind === 'var') {
|
|
490
|
-
this.builder.emitRaw(`scoreboard players operation $p${i}
|
|
513
|
+
this.builder.emitRaw(`scoreboard players operation $p${i} ${LOWERING_OBJ} = ${operand.name} ${LOWERING_OBJ}`)
|
|
491
514
|
}
|
|
492
515
|
}
|
|
493
516
|
|
|
@@ -501,7 +524,7 @@ export class Lowering {
|
|
|
501
524
|
this.builder.emitRaw(`data modify storage rs:macro_args ${macroParam} set value ${operand.value}`)
|
|
502
525
|
} else if (operand.kind === 'var') {
|
|
503
526
|
this.builder.emitRaw(
|
|
504
|
-
`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}`
|
|
505
528
|
)
|
|
506
529
|
}
|
|
507
530
|
}
|
|
@@ -511,7 +534,7 @@ export class Lowering {
|
|
|
511
534
|
|
|
512
535
|
// Copy return value (callers may use it)
|
|
513
536
|
const dst = this.builder.freshTemp()
|
|
514
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
537
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} = $ret ${LOWERING_OBJ}`)
|
|
515
538
|
return { kind: 'var', name: dst }
|
|
516
539
|
}
|
|
517
540
|
|
|
@@ -792,7 +815,7 @@ export class Lowering {
|
|
|
792
815
|
const originalTerm = entry.term
|
|
793
816
|
|
|
794
817
|
entry.instrs = [
|
|
795
|
-
{ op: 'raw', cmd: `scoreboard players add ${counterVar}
|
|
818
|
+
{ op: 'raw', cmd: `scoreboard players add ${counterVar} ${LOWERING_OBJ} 1` },
|
|
796
819
|
]
|
|
797
820
|
|
|
798
821
|
// Create conditional jump
|
|
@@ -809,14 +832,14 @@ export class Lowering {
|
|
|
809
832
|
// Add check instruction
|
|
810
833
|
entry.instrs.push({
|
|
811
834
|
op: 'raw',
|
|
812
|
-
cmd: `execute store success score ${counterVar}_check
|
|
835
|
+
cmd: `execute store success score ${counterVar}_check ${LOWERING_OBJ} if score ${counterVar} ${LOWERING_OBJ} matches ${rate}..`,
|
|
813
836
|
})
|
|
814
837
|
|
|
815
838
|
// Body block (original logic + counter reset)
|
|
816
839
|
fn.blocks.push({
|
|
817
840
|
label: bodyLabel,
|
|
818
841
|
instrs: [
|
|
819
|
-
{ op: 'raw', cmd: `scoreboard players set ${counterVar}
|
|
842
|
+
{ op: 'raw', cmd: `scoreboard players set ${counterVar} ${LOWERING_OBJ} 0` },
|
|
820
843
|
...originalInstrs,
|
|
821
844
|
],
|
|
822
845
|
term: originalTerm,
|
|
@@ -943,7 +966,7 @@ export class Lowering {
|
|
|
943
966
|
this.builder.emitRaw(`data modify storage ${path} set value ${fieldValue.value}`)
|
|
944
967
|
} else if (fieldValue.kind === 'var') {
|
|
945
968
|
// Copy from scoreboard to NBT
|
|
946
|
-
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}`)
|
|
947
970
|
}
|
|
948
971
|
}
|
|
949
972
|
return
|
|
@@ -977,7 +1000,7 @@ export class Lowering {
|
|
|
977
1000
|
this.builder.emitRaw(`data modify storage rs:heap ${stmt.name} append value ${elemValue.value}`)
|
|
978
1001
|
} else if (elemValue.kind === 'var') {
|
|
979
1002
|
this.builder.emitRaw(`data modify storage rs:heap ${stmt.name} append value 0`)
|
|
980
|
-
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}`)
|
|
981
1004
|
}
|
|
982
1005
|
}
|
|
983
1006
|
return
|
|
@@ -1028,7 +1051,7 @@ export class Lowering {
|
|
|
1028
1051
|
if (fieldValue.kind === 'const') {
|
|
1029
1052
|
this.builder.emitRaw(`data modify storage ${path} set value ${fieldValue.value}`)
|
|
1030
1053
|
} else if (fieldValue.kind === 'var') {
|
|
1031
|
-
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}`)
|
|
1032
1055
|
}
|
|
1033
1056
|
}
|
|
1034
1057
|
this.builder.emitReturn({ kind: 'const', value: 0 })
|
|
@@ -1247,9 +1270,9 @@ export class Lowering {
|
|
|
1247
1270
|
this.varMap.set(stmt.varName, loopVar)
|
|
1248
1271
|
const startVal = this.lowerExpr(stmt.start)
|
|
1249
1272
|
if (startVal.kind === 'const') {
|
|
1250
|
-
this.builder.emitRaw(`scoreboard players set ${loopVar}
|
|
1273
|
+
this.builder.emitRaw(`scoreboard players set ${loopVar} ${LOWERING_OBJ} ${startVal.value}`)
|
|
1251
1274
|
} else if (startVal.kind === 'var') {
|
|
1252
|
-
this.builder.emitRaw(`scoreboard players operation ${loopVar}
|
|
1275
|
+
this.builder.emitRaw(`scoreboard players operation ${loopVar} ${LOWERING_OBJ} = ${startVal.name} ${LOWERING_OBJ}`)
|
|
1253
1276
|
}
|
|
1254
1277
|
|
|
1255
1278
|
// Call loop function
|
|
@@ -1272,12 +1295,12 @@ export class Lowering {
|
|
|
1272
1295
|
this.lowerBlock(stmt.body)
|
|
1273
1296
|
|
|
1274
1297
|
// Increment
|
|
1275
|
-
this.builder.emitRaw(`scoreboard players add ${loopVar}
|
|
1298
|
+
this.builder.emitRaw(`scoreboard players add ${loopVar} ${LOWERING_OBJ} 1`)
|
|
1276
1299
|
|
|
1277
1300
|
// Loop condition: execute if score matches ..<end-1> run function
|
|
1278
1301
|
const endVal = this.lowerExpr(stmt.end)
|
|
1279
1302
|
const endNum = endVal.kind === 'const' ? endVal.value - 1 : '?'
|
|
1280
|
-
this.builder.emitRaw(`execute if score ${loopVar}
|
|
1303
|
+
this.builder.emitRaw(`execute if score ${loopVar} ${LOWERING_OBJ} matches ..${endNum} run function ${this.namespace}:${subFnName}`)
|
|
1281
1304
|
|
|
1282
1305
|
if (!this.builder.isBlockSealed()) {
|
|
1283
1306
|
this.builder.emitReturn()
|
|
@@ -1382,13 +1405,13 @@ export class Lowering {
|
|
|
1382
1405
|
}
|
|
1383
1406
|
|
|
1384
1407
|
const subFnName = `${this.currentFn}/match_${this.foreachCounter++}`
|
|
1385
|
-
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}`)
|
|
1386
1409
|
this.emitMatchArmSubFunction(subFnName, matchedVar, arm.body, true)
|
|
1387
1410
|
}
|
|
1388
1411
|
|
|
1389
1412
|
if (defaultArm) {
|
|
1390
1413
|
const subFnName = `${this.currentFn}/match_${this.foreachCounter++}`
|
|
1391
|
-
this.builder.emitRaw(`execute if score ${matchedVar}
|
|
1414
|
+
this.builder.emitRaw(`execute if score ${matchedVar} ${LOWERING_OBJ} matches ..0 run function ${this.namespace}:${subFnName}`)
|
|
1392
1415
|
this.emitMatchArmSubFunction(subFnName, matchedVar, defaultArm.body, false)
|
|
1393
1416
|
}
|
|
1394
1417
|
}
|
|
@@ -1406,7 +1429,7 @@ export class Lowering {
|
|
|
1406
1429
|
|
|
1407
1430
|
this.builder.startBlock('entry')
|
|
1408
1431
|
if (setMatched) {
|
|
1409
|
-
this.builder.emitRaw(`scoreboard players set ${matchedVar}
|
|
1432
|
+
this.builder.emitRaw(`scoreboard players set ${matchedVar} ${LOWERING_OBJ} 1`)
|
|
1410
1433
|
}
|
|
1411
1434
|
this.lowerBlock(body)
|
|
1412
1435
|
if (!this.builder.isBlockSealed()) {
|
|
@@ -1445,7 +1468,7 @@ export class Lowering {
|
|
|
1445
1468
|
|
|
1446
1469
|
this.builder.emitAssign(indexVar, { kind: 'const', value: 0 })
|
|
1447
1470
|
this.builder.emitAssign(oneVar, { kind: 'const', value: 1 })
|
|
1448
|
-
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}`)
|
|
1449
1472
|
|
|
1450
1473
|
const checkLabel = this.builder.freshLabel('foreach_array_check')
|
|
1451
1474
|
const bodyLabel = this.builder.freshLabel('foreach_array_body')
|
|
@@ -1462,7 +1485,7 @@ export class Lowering {
|
|
|
1462
1485
|
this.builder.emitAssign(bindingVar, element)
|
|
1463
1486
|
this.lowerBlock(stmt.body)
|
|
1464
1487
|
if (!this.builder.isBlockSealed()) {
|
|
1465
|
-
this.builder.emitRaw(`scoreboard players operation ${indexVar}
|
|
1488
|
+
this.builder.emitRaw(`scoreboard players operation ${indexVar} ${LOWERING_OBJ} += ${oneVar} ${LOWERING_OBJ}`)
|
|
1466
1489
|
this.builder.emitJump(checkLabel)
|
|
1467
1490
|
}
|
|
1468
1491
|
|
|
@@ -1841,7 +1864,7 @@ export class Lowering {
|
|
|
1841
1864
|
if (mapped && mapped.startsWith('@e[tag=__rs_obj_')) {
|
|
1842
1865
|
// World object field access → scoreboard get
|
|
1843
1866
|
const dst = this.builder.freshTemp()
|
|
1844
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
1867
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} = ${mapped} ${LOWERING_OBJ}`)
|
|
1845
1868
|
return { kind: 'var', name: dst }
|
|
1846
1869
|
}
|
|
1847
1870
|
|
|
@@ -1850,14 +1873,14 @@ export class Lowering {
|
|
|
1850
1873
|
const path = `rs:heap ${structName}_${expr.obj.name}.${expr.field}`
|
|
1851
1874
|
const dst = this.builder.freshTemp()
|
|
1852
1875
|
// Read from NBT storage into scoreboard
|
|
1853
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
1876
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${path}`)
|
|
1854
1877
|
return { kind: 'var', name: dst }
|
|
1855
1878
|
}
|
|
1856
1879
|
|
|
1857
1880
|
// Array length property
|
|
1858
1881
|
if (varType?.kind === 'array' && expr.field === 'len') {
|
|
1859
1882
|
const dst = this.builder.freshTemp()
|
|
1860
|
-
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}`)
|
|
1861
1884
|
return { kind: 'var', name: dst }
|
|
1862
1885
|
}
|
|
1863
1886
|
}
|
|
@@ -1876,9 +1899,9 @@ export class Lowering {
|
|
|
1876
1899
|
const value = this.lowerExpr(expr.value)
|
|
1877
1900
|
if (expr.op === '=') {
|
|
1878
1901
|
if (value.kind === 'const') {
|
|
1879
|
-
this.builder.emitRaw(`scoreboard players set ${mapped}
|
|
1902
|
+
this.builder.emitRaw(`scoreboard players set ${mapped} ${LOWERING_OBJ} ${value.value}`)
|
|
1880
1903
|
} else if (value.kind === 'var') {
|
|
1881
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1904
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} = ${value.name} ${LOWERING_OBJ}`)
|
|
1882
1905
|
}
|
|
1883
1906
|
} else {
|
|
1884
1907
|
// Compound assignment
|
|
@@ -1887,9 +1910,9 @@ export class Lowering {
|
|
|
1887
1910
|
if (value.kind === 'const') {
|
|
1888
1911
|
const constTemp = this.builder.freshTemp()
|
|
1889
1912
|
this.builder.emitAssign(constTemp, value)
|
|
1890
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1913
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} ${opMap[binOp]} ${constTemp} ${LOWERING_OBJ}`)
|
|
1891
1914
|
} else if (value.kind === 'var') {
|
|
1892
|
-
this.builder.emitRaw(`scoreboard players operation ${mapped}
|
|
1915
|
+
this.builder.emitRaw(`scoreboard players operation ${mapped} ${LOWERING_OBJ} ${opMap[binOp]} ${value.name} ${LOWERING_OBJ}`)
|
|
1893
1916
|
}
|
|
1894
1917
|
}
|
|
1895
1918
|
return { kind: 'const', value: 0 }
|
|
@@ -1904,15 +1927,15 @@ export class Lowering {
|
|
|
1904
1927
|
if (value.kind === 'const') {
|
|
1905
1928
|
this.builder.emitRaw(`data modify storage ${path} set value ${value.value}`)
|
|
1906
1929
|
} else if (value.kind === 'var') {
|
|
1907
|
-
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}`)
|
|
1908
1931
|
}
|
|
1909
1932
|
} else {
|
|
1910
1933
|
// Compound assignment: read, modify, write back
|
|
1911
1934
|
const dst = this.builder.freshTemp()
|
|
1912
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
1935
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${path}`)
|
|
1913
1936
|
const binOp = expr.op.slice(0, -1)
|
|
1914
1937
|
this.builder.emitBinop(dst, { kind: 'var', name: dst }, binOp as any, value)
|
|
1915
|
-
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}`)
|
|
1916
1939
|
}
|
|
1917
1940
|
return { kind: 'const', value: 0 }
|
|
1918
1941
|
}
|
|
@@ -1945,13 +1968,13 @@ export class Lowering {
|
|
|
1945
1968
|
this.builder.emitAssign(dst, left)
|
|
1946
1969
|
const rightVar = this.operandToVar(right)
|
|
1947
1970
|
// dst = dst && right → if dst != 0 then dst = right
|
|
1948
|
-
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}`)
|
|
1949
1972
|
} else {
|
|
1950
1973
|
// Short-circuit OR
|
|
1951
1974
|
this.builder.emitAssign(dst, left)
|
|
1952
1975
|
const rightVar = this.operandToVar(right)
|
|
1953
1976
|
// dst = dst || right → if dst == 0 then dst = right
|
|
1954
|
-
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}`)
|
|
1955
1978
|
}
|
|
1956
1979
|
return { kind: 'var', name: dst }
|
|
1957
1980
|
}
|
|
@@ -1970,15 +1993,15 @@ export class Lowering {
|
|
|
1970
1993
|
// Divide by 1000 to correct for double scaling
|
|
1971
1994
|
const constDiv = this.builder.freshTemp()
|
|
1972
1995
|
this.builder.emitAssign(constDiv, { kind: 'const', value: 1000 })
|
|
1973
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
1996
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} /= ${constDiv} ${LOWERING_OBJ}`)
|
|
1974
1997
|
} else {
|
|
1975
1998
|
// Division: a * 1000 / b
|
|
1976
1999
|
const constMul = this.builder.freshTemp()
|
|
1977
2000
|
this.builder.emitAssign(constMul, { kind: 'const', value: 1000 })
|
|
1978
2001
|
this.builder.emitAssign(dst, left)
|
|
1979
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
2002
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} *= ${constMul} ${LOWERING_OBJ}`)
|
|
1980
2003
|
const rightVar = this.operandToVar(right)
|
|
1981
|
-
this.builder.emitRaw(`scoreboard players operation ${dst}
|
|
2004
|
+
this.builder.emitRaw(`scoreboard players operation ${dst} ${LOWERING_OBJ} /= ${rightVar} ${LOWERING_OBJ}`)
|
|
1982
2005
|
}
|
|
1983
2006
|
return { kind: 'var', name: dst }
|
|
1984
2007
|
}
|
|
@@ -2057,7 +2080,7 @@ export class Lowering {
|
|
|
2057
2080
|
const storagePath = this.getStringStoragePath(expr.args[0])
|
|
2058
2081
|
if (storagePath) {
|
|
2059
2082
|
const dst = this.builder.freshTemp()
|
|
2060
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2083
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storagePath}`)
|
|
2061
2084
|
return { kind: 'var', name: dst }
|
|
2062
2085
|
}
|
|
2063
2086
|
|
|
@@ -2095,7 +2118,7 @@ export class Lowering {
|
|
|
2095
2118
|
const entity = this.exprToString(expr.args[0])
|
|
2096
2119
|
const tagName = this.exprToString(expr.args[1])
|
|
2097
2120
|
const dst = this.builder.freshTemp()
|
|
2098
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2121
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} if entity ${entity}[tag=${tagName}]`)
|
|
2099
2122
|
return { kind: 'var', name: dst }
|
|
2100
2123
|
}
|
|
2101
2124
|
|
|
@@ -2110,7 +2133,7 @@ export class Lowering {
|
|
|
2110
2133
|
this.builder.emitRaw(`data modify storage rs:heap ${arrName} append value ${value.value}`)
|
|
2111
2134
|
} else if (value.kind === 'var') {
|
|
2112
2135
|
this.builder.emitRaw(`data modify storage rs:heap ${arrName} append value 0`)
|
|
2113
|
-
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}`)
|
|
2114
2137
|
}
|
|
2115
2138
|
}
|
|
2116
2139
|
return { kind: 'const', value: 0 }
|
|
@@ -2120,7 +2143,7 @@ export class Lowering {
|
|
|
2120
2143
|
const arrName = this.getArrayStorageName(expr.args[0])
|
|
2121
2144
|
const dst = this.builder.freshTemp()
|
|
2122
2145
|
if (arrName) {
|
|
2123
|
-
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]`)
|
|
2124
2147
|
this.builder.emitRaw(`data remove storage rs:heap ${arrName}[-1]`)
|
|
2125
2148
|
} else {
|
|
2126
2149
|
this.builder.emitAssign(dst, { kind: 'const', value: 0 })
|
|
@@ -2420,7 +2443,7 @@ export class Lowering {
|
|
|
2420
2443
|
const dst = this.builder.freshTemp()
|
|
2421
2444
|
const min = args[0] ? this.exprToLiteral(args[0]) : '0'
|
|
2422
2445
|
const max = args[1] ? this.exprToLiteral(args[1]) : '100'
|
|
2423
|
-
this.builder.emitRaw(`scoreboard players random ${dst}
|
|
2446
|
+
this.builder.emitRaw(`scoreboard players random ${dst} ${LOWERING_OBJ} ${min} ${max}`)
|
|
2424
2447
|
return { kind: 'var', name: dst }
|
|
2425
2448
|
}
|
|
2426
2449
|
|
|
@@ -2429,7 +2452,7 @@ export class Lowering {
|
|
|
2429
2452
|
const dst = this.builder.freshTemp()
|
|
2430
2453
|
const min = args[0] ? this.exprToLiteral(args[0]) : '0'
|
|
2431
2454
|
const max = args[1] ? this.exprToLiteral(args[1]) : '100'
|
|
2432
|
-
this.builder.emitRaw(`execute store result score ${dst}
|
|
2455
|
+
this.builder.emitRaw(`execute store result score ${dst} ${LOWERING_OBJ} run random value ${min} ${max}`)
|
|
2433
2456
|
return { kind: 'var', name: dst }
|
|
2434
2457
|
}
|
|
2435
2458
|
|
|
@@ -2446,7 +2469,7 @@ export class Lowering {
|
|
|
2446
2469
|
const dst = this.builder.freshTemp()
|
|
2447
2470
|
const player = this.exprToTargetString(args[0])
|
|
2448
2471
|
const objective = this.resolveScoreboardObjective(args[0], args[1], callSpan)
|
|
2449
|
-
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}`)
|
|
2450
2473
|
return { kind: 'var', name: dst }
|
|
2451
2474
|
}
|
|
2452
2475
|
|
|
@@ -2460,7 +2483,7 @@ export class Lowering {
|
|
|
2460
2483
|
} else if (value.kind === 'var') {
|
|
2461
2484
|
// Read directly from the computed scoreboard temp. Routing through a fresh
|
|
2462
2485
|
// temp here breaks once optimization removes the apparently-dead assign.
|
|
2463
|
-
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}`)
|
|
2464
2487
|
}
|
|
2465
2488
|
return { kind: 'const', value: 0 }
|
|
2466
2489
|
}
|
|
@@ -2536,7 +2559,7 @@ export class Lowering {
|
|
|
2536
2559
|
|
|
2537
2560
|
if (name === 'bossbar_get_value') {
|
|
2538
2561
|
const dst = this.builder.freshTemp()
|
|
2539
|
-
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`)
|
|
2540
2563
|
return { kind: 'var', name: dst }
|
|
2541
2564
|
}
|
|
2542
2565
|
|
|
@@ -2583,7 +2606,7 @@ export class Lowering {
|
|
|
2583
2606
|
: this.exprToString(args[1])
|
|
2584
2607
|
const path = this.exprToString(args[2])
|
|
2585
2608
|
const scale = args[3] ? this.exprToString(args[3]) : '1'
|
|
2586
|
-
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}`)
|
|
2587
2610
|
return { kind: 'var', name: dst }
|
|
2588
2611
|
}
|
|
2589
2612
|
|
|
@@ -2593,7 +2616,7 @@ export class Lowering {
|
|
|
2593
2616
|
// array_key : e.g. "sin"
|
|
2594
2617
|
// index : integer index (const or runtime)
|
|
2595
2618
|
//
|
|
2596
|
-
// 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
|
|
2597
2620
|
// Runtime index: macro sub-function via rs:heap, mirrors readArrayElement.
|
|
2598
2621
|
if (name === 'storage_get_int') {
|
|
2599
2622
|
const storageNs = this.exprToString(args[0]) // "math:tables"
|
|
@@ -2603,7 +2626,7 @@ export class Lowering {
|
|
|
2603
2626
|
|
|
2604
2627
|
if (indexOperand.kind === 'const') {
|
|
2605
2628
|
this.builder.emitRaw(
|
|
2606
|
-
`execute store result score ${dst}
|
|
2629
|
+
`execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storageNs} ${arrayKey}[${indexOperand.value}] 1`
|
|
2607
2630
|
)
|
|
2608
2631
|
} else {
|
|
2609
2632
|
// Runtime index: store the index into rs:heap under a unique key,
|
|
@@ -2614,7 +2637,7 @@ export class Lowering {
|
|
|
2614
2637
|
? indexOperand.name
|
|
2615
2638
|
: this.operandToVar(indexOperand)
|
|
2616
2639
|
this.builder.emitRaw(
|
|
2617
|
-
`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}`
|
|
2618
2641
|
)
|
|
2619
2642
|
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
2620
2643
|
// Prefix \x01 is a sentinel for the MC macro '$' line-start marker.
|
|
@@ -2623,7 +2646,7 @@ export class Lowering {
|
|
|
2623
2646
|
// Codegen replaces \x01 → '$' when emitting the mc function file.
|
|
2624
2647
|
this.emitRawSubFunction(
|
|
2625
2648
|
subFnName,
|
|
2626
|
-
`\x01execute store result score ${dst}
|
|
2649
|
+
`\x01execute store result score ${dst} ${LOWERING_OBJ} run data get storage ${storageNs} ${arrayKey}[$(${macroKey})] 1`
|
|
2627
2650
|
)
|
|
2628
2651
|
}
|
|
2629
2652
|
return { kind: 'var', name: dst }
|
|
@@ -2650,7 +2673,7 @@ export class Lowering {
|
|
|
2650
2673
|
// value : integer value to write (const or runtime)
|
|
2651
2674
|
//
|
|
2652
2675
|
// Const index + const value:
|
|
2653
|
-
// execute store result storage <ns> <key>[N] int 1 run scoreboard players set $const_V
|
|
2676
|
+
// execute store result storage <ns> <key>[N] int 1 run scoreboard players set $const_V ${LOWERING_OBJ} V
|
|
2654
2677
|
// Runtime index or value: macro sub-function via rs:heap
|
|
2655
2678
|
if (name === 'storage_set_int') {
|
|
2656
2679
|
const storageNs = this.exprToString(args[0])
|
|
@@ -2664,7 +2687,7 @@ export class Lowering {
|
|
|
2664
2687
|
? valueOperand.name
|
|
2665
2688
|
: this.operandToVar(valueOperand)
|
|
2666
2689
|
this.builder.emitRaw(
|
|
2667
|
-
`execute store result storage ${storageNs} ${arrayKey}[${indexOperand.value}] int 1 run scoreboard players get ${valVar}
|
|
2690
|
+
`execute store result storage ${storageNs} ${arrayKey}[${indexOperand.value}] int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2668
2691
|
)
|
|
2669
2692
|
} else {
|
|
2670
2693
|
// Runtime index: we need a macro sub-function.
|
|
@@ -2680,13 +2703,13 @@ export class Lowering {
|
|
|
2680
2703
|
? valueOperand.name
|
|
2681
2704
|
: this.operandToVar(valueOperand)
|
|
2682
2705
|
this.builder.emitRaw(
|
|
2683
|
-
`execute store result storage rs:heap ${macroIdxKey} int 1 run scoreboard players get ${indexVar}
|
|
2706
|
+
`execute store result storage rs:heap ${macroIdxKey} int 1 run scoreboard players get ${indexVar} ${LOWERING_OBJ}`
|
|
2684
2707
|
)
|
|
2685
2708
|
// Pin valVar in the optimizer's read-set so the assignment is not dead-code-eliminated.
|
|
2686
2709
|
// The value is stored to rs:heap but NOT used by the macro (the macro reads the scoreboard
|
|
2687
2710
|
// slot directly to avoid the MC 'data modify set value $(n)' macro substitution bug).
|
|
2688
2711
|
this.builder.emitRaw(
|
|
2689
|
-
`execute store result storage rs:heap ${macroValKey} int 1 run scoreboard players get ${valVar}
|
|
2712
|
+
`execute store result storage rs:heap ${macroValKey} int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2690
2713
|
)
|
|
2691
2714
|
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
2692
2715
|
// Use execute store result (not 'data modify set value $(val)') to avoid MC macro
|
|
@@ -2694,7 +2717,7 @@ export class Lowering {
|
|
|
2694
2717
|
// into the macro sub-function at compile time — only the array index is macro-substituted.
|
|
2695
2718
|
this.emitRawSubFunction(
|
|
2696
2719
|
subFnName,
|
|
2697
|
-
`\x01execute store result storage ${storageNs} ${arrayKey}[$(${macroIdxKey})] int 1 run scoreboard players get ${valVar}
|
|
2720
|
+
`\x01execute store result storage ${storageNs} ${arrayKey}[$(${macroIdxKey})] int 1 run scoreboard players get ${valVar} ${LOWERING_OBJ}`
|
|
2698
2721
|
)
|
|
2699
2722
|
}
|
|
2700
2723
|
return { kind: 'const', value: 0 }
|
|
@@ -2744,7 +2767,7 @@ export class Lowering {
|
|
|
2744
2767
|
const dst = this.builder.freshTemp()
|
|
2745
2768
|
const setId = this.exprToString(args[0])
|
|
2746
2769
|
const value = this.exprToString(args[1])
|
|
2747
|
-
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}}]`)
|
|
2748
2771
|
return { kind: 'var', name: dst }
|
|
2749
2772
|
}
|
|
2750
2773
|
|
|
@@ -3061,7 +3084,7 @@ export class Lowering {
|
|
|
3061
3084
|
return
|
|
3062
3085
|
}
|
|
3063
3086
|
|
|
3064
|
-
components.push({ score: { name: this.operandToVar(operand), objective:
|
|
3087
|
+
components.push({ score: { name: this.operandToVar(operand), objective: LOWERING_OBJ } })
|
|
3065
3088
|
}
|
|
3066
3089
|
|
|
3067
3090
|
private exprToString(expr: Expr): string {
|
|
@@ -3227,12 +3250,20 @@ export class Lowering {
|
|
|
3227
3250
|
|
|
3228
3251
|
private exprToScoreboardObjective(expr: Expr, span?: Span): string {
|
|
3229
3252
|
if (expr.kind === 'mc_name') {
|
|
3230
|
-
|
|
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
|
|
3231
3256
|
}
|
|
3232
3257
|
|
|
3233
3258
|
const objective = this.exprToString(expr)
|
|
3234
3259
|
if (objective.startsWith('#') || objective.includes('.')) {
|
|
3235
|
-
|
|
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
|
|
3236
3267
|
}
|
|
3237
3268
|
|
|
3238
3269
|
return `${this.getObjectiveNamespace(span)}.${objective}`
|
|
@@ -3252,7 +3283,7 @@ export class Lowering {
|
|
|
3252
3283
|
return this.namespace
|
|
3253
3284
|
}
|
|
3254
3285
|
|
|
3255
|
-
return this.isStdlibFile(filePath) ?
|
|
3286
|
+
return this.isStdlibFile(filePath) ? LOWERING_OBJ : this.namespace
|
|
3256
3287
|
}
|
|
3257
3288
|
|
|
3258
3289
|
private tryGetStdlibInternalObjective(playerExpr: Expr | undefined, objectiveExpr: Expr, span?: Span): string | null {
|
|
@@ -3271,7 +3302,7 @@ export class Lowering {
|
|
|
3271
3302
|
}
|
|
3272
3303
|
|
|
3273
3304
|
const hash = this.shortHash(this.serializeCallSite(this.currentStdlibCallSite))
|
|
3274
|
-
return
|
|
3305
|
+
return `${LOWERING_OBJ}._${resourceBase}_${hash}`
|
|
3275
3306
|
}
|
|
3276
3307
|
|
|
3277
3308
|
private getStdlibInternalResourceBase(playerExpr: Expr | undefined): string | null {
|
|
@@ -3593,18 +3624,18 @@ export class Lowering {
|
|
|
3593
3624
|
const dst = this.builder.freshTemp()
|
|
3594
3625
|
|
|
3595
3626
|
if (index.kind === 'const') {
|
|
3596
|
-
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}]`)
|
|
3597
3628
|
return { kind: 'var', name: dst }
|
|
3598
3629
|
}
|
|
3599
3630
|
|
|
3600
3631
|
const macroKey = `__rs_index_${this.foreachCounter++}`
|
|
3601
3632
|
const subFnName = `${this.currentFn}/array_get_${this.foreachCounter++}`
|
|
3602
3633
|
const indexVar = index.kind === 'var' ? index.name : this.operandToVar(index)
|
|
3603
|
-
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}`)
|
|
3604
3635
|
this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`)
|
|
3605
3636
|
this.emitRawSubFunction(
|
|
3606
3637
|
subFnName,
|
|
3607
|
-
`\x01execute store result score ${dst}
|
|
3638
|
+
`\x01execute store result score ${dst} ${LOWERING_OBJ} run data get storage rs:heap ${arrayName}[$(${macroKey})]`
|
|
3608
3639
|
)
|
|
3609
3640
|
return { kind: 'var', name: dst }
|
|
3610
3641
|
}
|