redscript-mc 1.2.27 → 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.
@@ -20,8 +20,14 @@ export interface CommandFunction {
20
20
  commands: IRCommand[]
21
21
  }
22
22
 
23
- const SCOREBOARD_READ_RE =
24
- /^execute store result score (\$[A-Za-z0-9_]+) rs run scoreboard players get (\S+) (\S+)$/
23
+ // Matches scoreboard reads for LICM/CSE — objective is captured in group 2
24
+ // so the optimizer can reconstruct the command with the same objective.
25
+ let _OBJ_PATTERN = 'rs'
26
+ export function setOptimizerObjective(obj: string): void { _OBJ_PATTERN = obj }
27
+
28
+ function scoreboardReadRe(): RegExp {
29
+ return new RegExp(`^execute store result score (\\$[A-Za-z0-9_]+) ${_OBJ_PATTERN} run scoreboard players get (\\S+) (\\S+)$`)
30
+ }
25
31
  const SCOREBOARD_WRITE_RE =
26
32
  /^(?:scoreboard players (?:set|add|remove|reset)\s+(\S+)\s+(\S+)|scoreboard players operation\s+(\S+)\s+(\S+)\s+[+\-*/%]?= )/
27
33
  const EXECUTE_STORE_SCORE_RE =
@@ -130,7 +136,7 @@ function applyLICMInternal(functions: CommandFunction[]): Partial<OptimizationSt
130
136
  const scoreboardWrites = new Set<string>()
131
137
 
132
138
  for (const inner of loopFn.commands) {
133
- const readMatch = inner.cmd.match(SCOREBOARD_READ_RE)
139
+ const readMatch = inner.cmd.match(scoreboardReadRe())
134
140
  if (readMatch) {
135
141
  const [, temp, player, objective] = readMatch
136
142
  const key = `${player} ${objective}`
@@ -147,7 +153,7 @@ function applyLICMInternal(functions: CommandFunction[]): Partial<OptimizationSt
147
153
  for (const info of readInfo.values()) {
148
154
  const matches = inner.cmd.match(TEMP_RE) ?? []
149
155
  const usageCount = matches.filter(name => name === info.temp).length
150
- const isDef = inner.cmd.startsWith(`execute store result score ${info.temp} rs run scoreboard players get `)
156
+ const isDef = inner.cmd.startsWith(`execute store result score ${info.temp} ${_OBJ_PATTERN} run scoreboard players get `)
151
157
  if (!isDef) {
152
158
  info.uses += usageCount
153
159
  }
@@ -172,7 +178,7 @@ function applyLICMInternal(functions: CommandFunction[]): Partial<OptimizationSt
172
178
  const rewrittenLoopCommands: IRCommand[] = []
173
179
 
174
180
  for (const inner of loopFn.commands) {
175
- const readMatch = inner.cmd.match(SCOREBOARD_READ_RE)
181
+ const readMatch = inner.cmd.match(scoreboardReadRe())
176
182
  if (readMatch && hoistedTemps.has(readMatch[1])) {
177
183
  continue
178
184
  }
@@ -182,7 +188,7 @@ function applyLICMInternal(functions: CommandFunction[]): Partial<OptimizationSt
182
188
  loopFn.commands = rewrittenLoopCommands
183
189
  nextCommands.push(
184
190
  ...hoistable.map(item => ({
185
- cmd: `execute store result score ${item.temp} rs run scoreboard players get ${item.player} ${item.objective}`,
191
+ cmd: `execute store result score ${item.temp} ${_OBJ_PATTERN} run scoreboard players get ${item.player} ${item.objective}`,
186
192
  })),
187
193
  command
188
194
  )
@@ -198,9 +204,9 @@ function applyLICMInternal(functions: CommandFunction[]): Partial<OptimizationSt
198
204
 
199
205
  function extractArithmeticExpression(commands: IRCommand[], index: number): { key: string; dst: string } | null {
200
206
  const assign =
201
- commands[index]?.cmd.match(/^scoreboard players operation (\$[A-Za-z0-9_]+) rs = (\$[A-Za-z0-9_]+|\$const_-?\d+) rs$/) ??
202
- commands[index]?.cmd.match(/^scoreboard players set (\$[A-Za-z0-9_]+) rs (-?\d+)$/)
203
- const op = commands[index + 1]?.cmd.match(/^scoreboard players operation (\$[A-Za-z0-9_]+) rs ([+\-*/%]=) (\$[A-Za-z0-9_]+|\$const_-?\d+) rs$/)
207
+ commands[index]?.cmd.match(new RegExp(`^scoreboard players operation (\\$[A-Za-z0-9_]+) ${_OBJ_PATTERN} = (\\$[A-Za-z0-9_]+|\\$const_-?\\d+) ${_OBJ_PATTERN}$`)) ??
208
+ commands[index]?.cmd.match(new RegExp(`^scoreboard players set (\\$[A-Za-z0-9_]+) ${_OBJ_PATTERN} (-?\\d+)$`))
209
+ const op = commands[index + 1]?.cmd.match(new RegExp(`^scoreboard players operation (\\$[A-Za-z0-9_]+) ${_OBJ_PATTERN} ([+\\-*/%]=) (\\$[A-Za-z0-9_]+|\\$const_-?\\d+) ${_OBJ_PATTERN}$`))
204
210
  if (!assign || !op || assign[1] !== op[1]) {
205
211
  return null
206
212
  }
@@ -234,14 +240,14 @@ function applyCSEInternal(functions: CommandFunction[]): Partial<OptimizationSta
234
240
 
235
241
  for (let i = 0; i < commands.length; i++) {
236
242
  const command = commands[i]
237
- const readMatch = command.cmd.match(SCOREBOARD_READ_RE)
243
+ const readMatch = command.cmd.match(scoreboardReadRe())
238
244
  if (readMatch) {
239
245
  const [, dst, player, objective] = readMatch
240
246
  const key = `${player} ${objective}`
241
247
  const cached = readCache.get(key)
242
248
  if (cached) {
243
249
  stats.cseRedundantReads = (stats.cseRedundantReads ?? 0) + 1
244
- rewritten.push({ ...command, cmd: `scoreboard players operation ${dst} rs = ${cached} rs` })
250
+ rewritten.push({ ...command, cmd: `scoreboard players operation ${dst} ${_OBJ_PATTERN} = ${cached} ${_OBJ_PATTERN}` })
245
251
  } else {
246
252
  readCache.set(key, dst)
247
253
  rewritten.push(command)
@@ -255,7 +261,7 @@ function applyCSEInternal(functions: CommandFunction[]): Partial<OptimizationSta
255
261
  if (expr) {
256
262
  const cached = exprCache.get(expr.key)
257
263
  if (cached) {
258
- rewritten.push({ ...commands[i], cmd: `scoreboard players operation ${expr.dst} rs = ${cached} rs` })
264
+ rewritten.push({ ...commands[i], cmd: `scoreboard players operation ${expr.dst} ${_OBJ_PATTERN} = ${cached} ${_OBJ_PATTERN}` })
259
265
  stats.cseArithmetic = (stats.cseArithmetic ?? 0) + 1
260
266
  i += 1
261
267
  } else {
@@ -1,7 +1,11 @@
1
1
  import type { IRBlock, IRCommand, IRFunction, IRInstr, Operand, Terminator } from '../ir/types'
2
- import { createEmptyOptimizationStats, mergeOptimizationStats, optimizeCommandFunctions, type OptimizationStats } from './commands'
2
+ import { createEmptyOptimizationStats, mergeOptimizationStats, optimizeCommandFunctions, setOptimizerObjective, type OptimizationStats } from './commands'
3
3
 
4
- const OBJ = 'rs'
4
+ let OBJ = 'rs'
5
+ export function setStructureObjective(obj: string): void {
6
+ OBJ = obj
7
+ setOptimizerObjective(obj)
8
+ }
5
9
  const INLINE_THRESHOLD = 8
6
10
 
7
11
  const BOP_OP: Record<string, string> = {