redscript-mc 1.2.16 → 1.2.17
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/builtins.d.mcrs +42 -107
- package/dist/builtins/metadata.js +8 -16
- package/dist/lexer/index.js +9 -0
- package/dist/lowering/index.d.ts +1 -0
- package/dist/lowering/index.js +22 -0
- package/dist/parser/index.js +10 -3
- package/editors/vscode/builtins.d.mcrs +42 -107
- package/editors/vscode/package-lock.json +2 -2
- package/editors/vscode/package.json +1 -1
- package/editors/vscode/syntaxes/redscript.tmLanguage.json +1 -1
- package/package.json +1 -1
- package/src/builtins/metadata.ts +8 -13
- package/src/lexer/index.ts +9 -0
- package/src/lowering/index.ts +20 -0
- package/src/parser/index.ts +12 -3
package/package.json
CHANGED
package/src/builtins/metadata.ts
CHANGED
|
@@ -1029,16 +1029,13 @@ export const BUILTIN_METADATA: Record<string, BuiltinDef> = {
|
|
|
1029
1029
|
export function builtinToDeclaration(def: BuiltinDef): string {
|
|
1030
1030
|
const lines: string[] = []
|
|
1031
1031
|
|
|
1032
|
-
// Doc comments
|
|
1032
|
+
// Doc comments (English only)
|
|
1033
1033
|
lines.push(`/// ${def.doc}`)
|
|
1034
|
-
if (def.docZh) {
|
|
1035
|
-
lines.push(`/// ${def.docZh}`)
|
|
1036
|
-
}
|
|
1037
1034
|
|
|
1038
1035
|
// Param docs
|
|
1039
1036
|
for (const p of def.params) {
|
|
1040
|
-
const
|
|
1041
|
-
lines.push(`/// @param ${p.name}
|
|
1037
|
+
const optTag = p.required ? '' : ' (optional)'
|
|
1038
|
+
lines.push(`/// @param ${p.name} ${p.doc}${optTag}`)
|
|
1042
1039
|
}
|
|
1043
1040
|
|
|
1044
1041
|
// Returns
|
|
@@ -1051,13 +1048,9 @@ export function builtinToDeclaration(def: BuiltinDef): string {
|
|
|
1051
1048
|
lines.push(`/// @example ${ex.split('\n')[0]}`)
|
|
1052
1049
|
}
|
|
1053
1050
|
|
|
1054
|
-
// Signature
|
|
1051
|
+
// Signature - use default value syntax instead of ? for optional params
|
|
1055
1052
|
const paramStrs = def.params.map(p => {
|
|
1056
|
-
const opt = p.required ? '' : '?'
|
|
1057
1053
|
let type = p.type
|
|
1058
|
-
// Map to .d.mcrs types
|
|
1059
|
-
if (type === 'selector') type = 'selector'
|
|
1060
|
-
if (type === 'BlockPos') type = 'BlockPos'
|
|
1061
1054
|
if (type === 'effect') type = 'string'
|
|
1062
1055
|
if (type === 'sound') type = 'string'
|
|
1063
1056
|
if (type === 'block') type = 'string'
|
|
@@ -1065,8 +1058,10 @@ export function builtinToDeclaration(def: BuiltinDef): string {
|
|
|
1065
1058
|
if (type === 'entity') type = 'string'
|
|
1066
1059
|
if (type === 'dimension') type = 'string'
|
|
1067
1060
|
if (type === 'nbt') type = 'string'
|
|
1068
|
-
if (
|
|
1069
|
-
|
|
1061
|
+
if (!p.required && p.default !== undefined) {
|
|
1062
|
+
return `${p.name}: ${type} = ${p.default}`
|
|
1063
|
+
}
|
|
1064
|
+
return `${p.name}: ${type}`
|
|
1070
1065
|
})
|
|
1071
1066
|
|
|
1072
1067
|
const retType = def.returns
|
package/src/lexer/index.ts
CHANGED
|
@@ -298,6 +298,15 @@ export class Lexer {
|
|
|
298
298
|
value += this.advance()
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
+
// Check for ident (e.g. ~height → macro variable offset)
|
|
302
|
+
if (/[a-zA-Z_]/.test(this.peek())) {
|
|
303
|
+
let ident = ''
|
|
304
|
+
while (/[a-zA-Z0-9_]/.test(this.peek())) {
|
|
305
|
+
ident += this.advance()
|
|
306
|
+
}
|
|
307
|
+
// Store as rel_coord with embedded ident: ~height
|
|
308
|
+
value += ident
|
|
309
|
+
}
|
|
301
310
|
this.addToken('rel_coord', value, startLine, startCol)
|
|
302
311
|
return
|
|
303
312
|
}
|
package/src/lowering/index.ts
CHANGED
|
@@ -371,6 +371,13 @@ export class Lowering {
|
|
|
371
371
|
return expr.name
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
private tryGetMacroParamByName(name: string): string | null {
|
|
375
|
+
if (!this.currentFnParamNames.has(name)) return null
|
|
376
|
+
if (this.constValues.has(name)) return null
|
|
377
|
+
if (this.stringValues.has(name)) return null
|
|
378
|
+
return name
|
|
379
|
+
}
|
|
380
|
+
|
|
374
381
|
/**
|
|
375
382
|
* Converts an expression to a string for use as a builtin arg.
|
|
376
383
|
* If the expression is a macro param, returns `$(name)` and sets macroParam.
|
|
@@ -380,6 +387,19 @@ export class Lowering {
|
|
|
380
387
|
if (macroParam) {
|
|
381
388
|
return { str: `$(${macroParam})`, macroParam }
|
|
382
389
|
}
|
|
390
|
+
// Handle ~ident (e.g. ~height) - relative coord with variable offset
|
|
391
|
+
if (expr.kind === 'rel_coord' || expr.kind === 'local_coord') {
|
|
392
|
+
const val = expr.value // e.g. "~height" or "^depth"
|
|
393
|
+
const prefix = val[0] // ~ or ^
|
|
394
|
+
const rest = val.slice(1)
|
|
395
|
+
// If rest is an identifier (not a number), treat as macro param
|
|
396
|
+
if (rest && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(rest)) {
|
|
397
|
+
const paramName = this.tryGetMacroParamByName(rest)
|
|
398
|
+
if (paramName) {
|
|
399
|
+
return { str: `${prefix}$(${paramName})`, macroParam: paramName }
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
383
403
|
if (expr.kind === 'struct_lit' || expr.kind === 'array_lit') {
|
|
384
404
|
return { str: this.exprToSnbt(expr) }
|
|
385
405
|
}
|
package/src/parser/index.ts
CHANGED
|
@@ -260,12 +260,21 @@ export class Parser {
|
|
|
260
260
|
private parseConstDecl(): ConstDecl {
|
|
261
261
|
const constToken = this.expect('const')
|
|
262
262
|
const name = this.expect('ident').value
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
let type: TypeNode | undefined
|
|
264
|
+
if (this.match(':')) {
|
|
265
|
+
type = this.parseType()
|
|
266
|
+
}
|
|
265
267
|
this.expect('=')
|
|
266
268
|
const value = this.parseLiteralExpr()
|
|
267
269
|
this.match(';')
|
|
268
|
-
|
|
270
|
+
// Infer type from value if not provided
|
|
271
|
+
const inferredType: TypeNode = type ?? (
|
|
272
|
+
value.kind === 'str_lit' ? { kind: 'named', name: 'string' } :
|
|
273
|
+
value.kind === 'bool_lit' ? { kind: 'named', name: 'bool' } :
|
|
274
|
+
value.kind === 'float_lit' ? { kind: 'named', name: 'float' } :
|
|
275
|
+
{ kind: 'named', name: 'int' }
|
|
276
|
+
)
|
|
277
|
+
return this.withLoc({ name, type: inferredType, value }, constToken)
|
|
269
278
|
}
|
|
270
279
|
|
|
271
280
|
private parseGlobalDecl(mutable: boolean): GlobalDecl {
|