redscript-mc 1.2.14 → 1.2.16
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/CHANGELOG.md +39 -0
- package/README.md +13 -6
- package/builtins.d.mcrs +559 -0
- package/dist/builtins/metadata.d.ts +36 -0
- package/dist/builtins/metadata.js +1022 -0
- package/dist/cli.js +16 -6
- package/dist/lowering/index.d.ts +11 -0
- package/dist/lowering/index.js +46 -25
- package/editors/vscode/builtins.d.mcrs +559 -0
- package/editors/vscode/out/extension.js +797 -80
- package/editors/vscode/src/symbols.ts +68 -0
- package/package.json +1 -1
- package/src/builtins/metadata.ts +1123 -0
- package/src/cli.ts +17 -6
- package/src/lowering/index.ts +50 -27
package/src/cli.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { generateCommandBlocks } from './codegen/cmdblock'
|
|
|
14
14
|
import { compileToStructure } from './codegen/structure'
|
|
15
15
|
import { formatError } from './diagnostics'
|
|
16
16
|
import { startRepl } from './repl'
|
|
17
|
+
import { generateDts } from './builtins/metadata'
|
|
17
18
|
import type { OptimizationStats } from './optimizer/commands'
|
|
18
19
|
import * as fs from 'fs'
|
|
19
20
|
import * as path from 'path'
|
|
@@ -30,16 +31,18 @@ Usage:
|
|
|
30
31
|
redscript watch <dir> [-o <outdir>] [--namespace <ns>] [--hot-reload <url>]
|
|
31
32
|
redscript check <file>
|
|
32
33
|
redscript fmt <file.mcrs> [file2.mcrs ...]
|
|
34
|
+
redscript generate-dts [-o <file>]
|
|
33
35
|
redscript repl
|
|
34
36
|
redscript version
|
|
35
37
|
|
|
36
38
|
Commands:
|
|
37
|
-
compile
|
|
38
|
-
watch
|
|
39
|
-
check
|
|
40
|
-
fmt
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
compile Compile a RedScript file to a Minecraft datapack
|
|
40
|
+
watch Watch a directory for .mcrs file changes, recompile, and hot reload
|
|
41
|
+
check Check a RedScript file for errors without generating output
|
|
42
|
+
fmt Auto-format RedScript source files
|
|
43
|
+
generate-dts Generate builtin function declaration file (builtins.d.mcrs)
|
|
44
|
+
repl Start an interactive RedScript REPL
|
|
45
|
+
version Print the RedScript version
|
|
43
46
|
|
|
44
47
|
Options:
|
|
45
48
|
-o, --output <path> Output directory or file path, depending on target
|
|
@@ -441,6 +444,14 @@ async function main(): Promise<void> {
|
|
|
441
444
|
break
|
|
442
445
|
}
|
|
443
446
|
|
|
447
|
+
case 'generate-dts': {
|
|
448
|
+
const output = parsed.output ?? 'builtins.d.mcrs'
|
|
449
|
+
const dtsContent = generateDts()
|
|
450
|
+
fs.writeFileSync(output, dtsContent, 'utf-8')
|
|
451
|
+
console.log(`Generated ${output}`)
|
|
452
|
+
break
|
|
453
|
+
}
|
|
454
|
+
|
|
444
455
|
case 'repl':
|
|
445
456
|
await startRepl(parsed.namespace ?? 'repl')
|
|
446
457
|
break
|
package/src/lowering/index.ts
CHANGED
|
@@ -25,10 +25,8 @@ import { EVENT_TYPES, getEventParamSpecs, isEventTypeName } from '../events/type
|
|
|
25
25
|
// require MC macro syntax when called with runtime variables.
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'playsound', 'tp', 'tp_to', 'effect', 'effect_clear', 'give',
|
|
31
|
-
])
|
|
28
|
+
// All builtins support macro parameters - any arg that's a function param
|
|
29
|
+
// will automatically use MC 1.20.2+ macro syntax when needed
|
|
32
30
|
|
|
33
31
|
// ---------------------------------------------------------------------------
|
|
34
32
|
// Builtin Functions
|
|
@@ -335,7 +333,7 @@ export class Lowering {
|
|
|
335
333
|
}
|
|
336
334
|
|
|
337
335
|
private preScanExpr(expr: Expr, paramNames: Set<string>, macroParams: Set<string>): void {
|
|
338
|
-
if (expr.kind === 'call' &&
|
|
336
|
+
if (expr.kind === 'call' && BUILTINS[expr.fn] !== undefined) {
|
|
339
337
|
// All ident args to macro-aware builtins that are params → macro params
|
|
340
338
|
for (const arg of expr.args) {
|
|
341
339
|
if (arg.kind === 'ident' && paramNames.has(arg.name)) {
|
|
@@ -787,6 +785,7 @@ export class Lowering {
|
|
|
787
785
|
this.lowerExecuteStmt(stmt)
|
|
788
786
|
break
|
|
789
787
|
case 'raw':
|
|
788
|
+
this.checkRawCommandInterpolation(stmt.cmd, stmt.span)
|
|
790
789
|
this.builder.emitRaw(stmt.cmd)
|
|
791
790
|
break
|
|
792
791
|
}
|
|
@@ -2528,30 +2527,16 @@ export class Lowering {
|
|
|
2528
2527
|
return { kind: 'const', value: 0 }
|
|
2529
2528
|
}
|
|
2530
2529
|
|
|
2531
|
-
//
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
if (
|
|
2536
|
-
argResults.forEach(r => { if (r.macroParam) this.currentFnMacroParams.add(r.macroParam) })
|
|
2537
|
-
}
|
|
2538
|
-
const strArgs = argResults.map(r => r.str)
|
|
2539
|
-
const cmd = BUILTINS[name]?.(strArgs)
|
|
2540
|
-
if (cmd) {
|
|
2541
|
-
this.builder.emitRaw(hasMacroArg ? `$${cmd}` : cmd)
|
|
2542
|
-
}
|
|
2543
|
-
return { kind: 'const', value: 0 }
|
|
2530
|
+
// All builtins support macro params - check if any arg is a param needing macro treatment
|
|
2531
|
+
const argResults = args.map(arg => this.exprToBuiltinArg(arg))
|
|
2532
|
+
const hasMacroArg = argResults.some(r => r.macroParam !== undefined)
|
|
2533
|
+
if (hasMacroArg) {
|
|
2534
|
+
argResults.forEach(r => { if (r.macroParam) this.currentFnMacroParams.add(r.macroParam) })
|
|
2544
2535
|
}
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
const strArgs = args.map(arg =>
|
|
2548
|
-
arg.kind === 'struct_lit' || arg.kind === 'array_lit'
|
|
2549
|
-
? this.exprToSnbt(arg)
|
|
2550
|
-
: this.exprToString(arg)
|
|
2551
|
-
)
|
|
2552
|
-
const cmd = BUILTINS[name](strArgs)
|
|
2536
|
+
const strArgs = argResults.map(r => r.str)
|
|
2537
|
+
const cmd = BUILTINS[name]?.(strArgs)
|
|
2553
2538
|
if (cmd) {
|
|
2554
|
-
this.builder.emitRaw(cmd)
|
|
2539
|
+
this.builder.emitRaw(hasMacroArg ? `$${cmd}` : cmd)
|
|
2555
2540
|
}
|
|
2556
2541
|
|
|
2557
2542
|
return { kind: 'const', value: 0 }
|
|
@@ -3269,6 +3254,44 @@ export class Lowering {
|
|
|
3269
3254
|
return undefined
|
|
3270
3255
|
}
|
|
3271
3256
|
|
|
3257
|
+
/**
|
|
3258
|
+
* Checks a raw() command string for `${...}` interpolation containing runtime variables.
|
|
3259
|
+
* - If the interpolated expression is a numeric literal → OK (MC macro syntax).
|
|
3260
|
+
* - If the interpolated name is a compile-time constant (in constValues) → OK.
|
|
3261
|
+
* - If the interpolated name is a known runtime variable (in varMap) → DiagnosticError.
|
|
3262
|
+
* - Unknown names → OK (could be MC macro params or external constants).
|
|
3263
|
+
*
|
|
3264
|
+
* This catches the common mistake of writing raw("say ${score}") expecting interpolation,
|
|
3265
|
+
* which would silently emit a literal `${score}` in the MC command.
|
|
3266
|
+
*/
|
|
3267
|
+
private checkRawCommandInterpolation(cmd: string, span?: Span): void {
|
|
3268
|
+
const interpRe = /\$\{([^}]+)\}/g
|
|
3269
|
+
let match: RegExpExecArray | null
|
|
3270
|
+
while ((match = interpRe.exec(cmd)) !== null) {
|
|
3271
|
+
const name = match[1].trim()
|
|
3272
|
+
// Numeric/boolean literals are fine (intentional MC macro syntax)
|
|
3273
|
+
if (/^\d+(\.\d+)?$/.test(name) || name === 'true' || name === 'false') {
|
|
3274
|
+
continue
|
|
3275
|
+
}
|
|
3276
|
+
// Compile-time constants are fine
|
|
3277
|
+
if (this.constValues.has(name)) {
|
|
3278
|
+
continue
|
|
3279
|
+
}
|
|
3280
|
+
// Only error if it's a known runtime variable (in varMap or function params)
|
|
3281
|
+
// Unknown identifiers are left alone (could be MC macro params the user intends)
|
|
3282
|
+
if (this.varMap.has(name) || this.currentFnParamNames.has(name)) {
|
|
3283
|
+
const loc = span ?? { line: 1, col: 1 }
|
|
3284
|
+
throw new DiagnosticError(
|
|
3285
|
+
'LoweringError',
|
|
3286
|
+
`raw() command contains runtime variable interpolation '\${${name}}'. ` +
|
|
3287
|
+
`Variables cannot be interpolated into raw commands at compile time. ` +
|
|
3288
|
+
`Use f-string messages (say/tell/announce) or MC macro syntax '$(${name})' for MC 1.20.2+ commands.`,
|
|
3289
|
+
loc
|
|
3290
|
+
)
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3272
3295
|
private resolveInstanceMethod(expr: Extract<Expr, { kind: 'call' }>): { fn: FnDecl; loweredName: string } | null {
|
|
3273
3296
|
const receiver = expr.args[0]
|
|
3274
3297
|
if (!receiver) {
|