redscript-mc 1.2.4 → 1.2.6
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/dist/codegen/structure/index.js +2 -1
- package/dist/compile.js +2 -1
- package/dist/index.js +3 -2
- package/dist/optimizer/dce.d.ts +11 -1
- package/dist/optimizer/dce.js +12 -1
- package/editors/vscode/out/extension.js +14 -3
- package/editors/vscode/package.json +1 -1
- package/editors/vscode/syntaxes/redscript.tmLanguage.json +1 -1
- package/package.json +1 -1
- package/src/codegen/structure/index.ts +2 -1
- package/src/compile.ts +2 -1
- package/src/index.ts +3 -2
- package/src/optimizer/dce.ts +20 -2
|
@@ -260,7 +260,8 @@ function compileToStructure(source, namespace, filePath, options = {}) {
|
|
|
260
260
|
const preprocessedSource = (0, compile_1.preprocessSource)(source, { filePath });
|
|
261
261
|
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
262
262
|
const parsedAst = new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
263
|
-
const
|
|
263
|
+
const dceResult = options.dce ?? true ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
|
|
264
|
+
const ast = dceResult.program;
|
|
264
265
|
const ir = new lowering_1.Lowering(namespace).lower(ast);
|
|
265
266
|
const stats = (0, commands_1.createEmptyOptimizationStats)();
|
|
266
267
|
const optimizedIRFunctions = ir.functions.map(fn => {
|
package/dist/compile.js
CHANGED
|
@@ -137,7 +137,8 @@ function compile(source, options = {}) {
|
|
|
137
137
|
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
138
138
|
// Parsing
|
|
139
139
|
const parsedAst = new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
140
|
-
const
|
|
140
|
+
const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
|
|
141
|
+
const ast = dceResult.program;
|
|
141
142
|
// Lowering
|
|
142
143
|
const ir = new lowering_1.Lowering(namespace, preprocessed.ranges).lower(ast);
|
|
143
144
|
// Optimization
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,8 @@ function compile(source, options = {}) {
|
|
|
36
36
|
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
37
37
|
// Parsing
|
|
38
38
|
const parsedAst = new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
39
|
-
const
|
|
39
|
+
const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
|
|
40
|
+
const ast = dceResult.program;
|
|
40
41
|
// Type checking (warn mode - collect errors but don't block)
|
|
41
42
|
let typeErrors;
|
|
42
43
|
if (shouldTypeCheck) {
|
|
@@ -90,7 +91,7 @@ function compile(source, options = {}) {
|
|
|
90
91
|
ast,
|
|
91
92
|
ir: optimizedIR,
|
|
92
93
|
typeErrors,
|
|
93
|
-
warnings: lowering.warnings,
|
|
94
|
+
warnings: [...dceResult.warnings, ...lowering.warnings],
|
|
94
95
|
stats: optimizationStats,
|
|
95
96
|
};
|
|
96
97
|
}
|
package/dist/optimizer/dce.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Program } from '../ast/types';
|
|
2
|
+
export interface DCEWarning {
|
|
3
|
+
message: string;
|
|
4
|
+
code: string;
|
|
5
|
+
line?: number;
|
|
6
|
+
col?: number;
|
|
7
|
+
}
|
|
2
8
|
export declare class DeadCodeEliminator {
|
|
3
9
|
private readonly functionMap;
|
|
4
10
|
private readonly reachableFunctions;
|
|
@@ -6,6 +12,7 @@ export declare class DeadCodeEliminator {
|
|
|
6
12
|
private readonly localReads;
|
|
7
13
|
private readonly localDeclIds;
|
|
8
14
|
private localIdCounter;
|
|
15
|
+
readonly warnings: DCEWarning[];
|
|
9
16
|
eliminate(program: Program): Program;
|
|
10
17
|
private findEntryPoints;
|
|
11
18
|
private markReachable;
|
|
@@ -20,4 +27,7 @@ export declare class DeadCodeEliminator {
|
|
|
20
27
|
private transformStmt;
|
|
21
28
|
private transformExpr;
|
|
22
29
|
}
|
|
23
|
-
export declare function eliminateDeadCode(program: Program):
|
|
30
|
+
export declare function eliminateDeadCode(program: Program): {
|
|
31
|
+
program: Program;
|
|
32
|
+
warnings: DCEWarning[];
|
|
33
|
+
};
|
package/dist/optimizer/dce.js
CHANGED
|
@@ -69,6 +69,7 @@ class DeadCodeEliminator {
|
|
|
69
69
|
this.localReads = new Set();
|
|
70
70
|
this.localDeclIds = new WeakMap();
|
|
71
71
|
this.localIdCounter = 0;
|
|
72
|
+
this.warnings = [];
|
|
72
73
|
}
|
|
73
74
|
eliminate(program) {
|
|
74
75
|
this.functionMap.clear();
|
|
@@ -76,6 +77,7 @@ class DeadCodeEliminator {
|
|
|
76
77
|
this.usedConstants.clear();
|
|
77
78
|
this.localReads.clear();
|
|
78
79
|
this.localIdCounter = 0;
|
|
80
|
+
this.warnings.length = 0;
|
|
79
81
|
for (const fn of program.declarations) {
|
|
80
82
|
this.functionMap.set(fn.name, fn);
|
|
81
83
|
}
|
|
@@ -402,6 +404,13 @@ class DeadCodeEliminator {
|
|
|
402
404
|
}
|
|
403
405
|
return [copySpan({ ...stmt, init }, stmt)];
|
|
404
406
|
}
|
|
407
|
+
// Unused variable - emit warning
|
|
408
|
+
this.warnings.push({
|
|
409
|
+
message: `Unused variable '${stmt.name}'`,
|
|
410
|
+
code: 'W_UNUSED_VAR',
|
|
411
|
+
line: stmt.span?.line,
|
|
412
|
+
col: stmt.span?.col,
|
|
413
|
+
});
|
|
405
414
|
if (isPureExpr(init)) {
|
|
406
415
|
return [];
|
|
407
416
|
}
|
|
@@ -587,6 +596,8 @@ class DeadCodeEliminator {
|
|
|
587
596
|
}
|
|
588
597
|
exports.DeadCodeEliminator = DeadCodeEliminator;
|
|
589
598
|
function eliminateDeadCode(program) {
|
|
590
|
-
|
|
599
|
+
const eliminator = new DeadCodeEliminator();
|
|
600
|
+
const result = eliminator.eliminate(program);
|
|
601
|
+
return { program: result, warnings: eliminator.warnings };
|
|
591
602
|
}
|
|
592
603
|
//# sourceMappingURL=dce.js.map
|
|
@@ -1163,8 +1163,17 @@ var require_parser = __commonJS({
|
|
|
1163
1163
|
this.expect("in");
|
|
1164
1164
|
const iterable = this.parseExpr();
|
|
1165
1165
|
this.expect(")");
|
|
1166
|
+
let executeContext;
|
|
1167
|
+
const execIdentKeywords = ["positioned", "rotated", "facing", "anchored", "align"];
|
|
1168
|
+
if (this.check("at") || this.check("in") || this.check("ident") && execIdentKeywords.includes(this.peek().value)) {
|
|
1169
|
+
let context = "";
|
|
1170
|
+
while (!this.check("{") && !this.check("eof")) {
|
|
1171
|
+
context += this.advance().value + " ";
|
|
1172
|
+
}
|
|
1173
|
+
executeContext = context.trim();
|
|
1174
|
+
}
|
|
1166
1175
|
const body = this.parseBlock();
|
|
1167
|
-
return this.withLoc({ kind: "foreach", binding, iterable, body }, foreachToken);
|
|
1176
|
+
return this.withLoc({ kind: "foreach", binding, iterable, body, executeContext }, foreachToken);
|
|
1168
1177
|
}
|
|
1169
1178
|
parseMatchStmt() {
|
|
1170
1179
|
const matchToken = this.expect("match");
|
|
@@ -3799,7 +3808,8 @@ var require_lowering = __commonJS({
|
|
|
3799
3808
|
}
|
|
3800
3809
|
const subFnName = `${this.currentFn}/foreach_${this.foreachCounter++}`;
|
|
3801
3810
|
const selector = this.exprToString(stmt.iterable);
|
|
3802
|
-
|
|
3811
|
+
const execContext = stmt.executeContext ? ` ${stmt.executeContext}` : "";
|
|
3812
|
+
this.builder.emitRaw(`execute as ${selector}${execContext} run function ${this.namespace}:${subFnName}`);
|
|
3803
3813
|
const savedBuilder = this.builder;
|
|
3804
3814
|
const savedVarMap = new Map(this.varMap);
|
|
3805
3815
|
const savedContext = this.currentContext;
|
|
@@ -6122,7 +6132,8 @@ var require_passes = __commonJS({
|
|
|
6122
6132
|
...block,
|
|
6123
6133
|
instrs: block.instrs.filter((instr) => {
|
|
6124
6134
|
if (instr.op === "assign" || instr.op === "binop" || instr.op === "cmp") {
|
|
6125
|
-
const
|
|
6135
|
+
const isTemp = /^\$t\d+$/.test(instr.dst) || /^\$p\d+$/.test(instr.dst) || /^\$_\d+$/.test(instr.dst);
|
|
6136
|
+
const keep = !isTemp || readVars.has(instr.dst);
|
|
6126
6137
|
if (!keep)
|
|
6127
6138
|
removed++;
|
|
6128
6139
|
return keep;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "redscript-vscode",
|
|
3
3
|
"displayName": "RedScript for Minecraft",
|
|
4
4
|
"description": "Syntax highlighting, error diagnostics, and language support for RedScript — a compiler targeting Minecraft Java Edition",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.6",
|
|
6
6
|
"publisher": "bkmashiro",
|
|
7
7
|
"icon": "icon.png",
|
|
8
8
|
"license": "MIT",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"patterns": [
|
|
134
134
|
{
|
|
135
135
|
"name": "keyword.control.redscript",
|
|
136
|
-
"match": "\\b(if|else|while|for|foreach|return|match|in|execute|as|at|unless|run|is)\\b"
|
|
136
|
+
"match": "\\b(if|else|while|for|foreach|return|match|in|execute|as|at|unless|run|is|positioned|rotated|facing|anchored|align)\\b"
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"name": "keyword.declaration.redscript",
|
package/package.json
CHANGED
|
@@ -329,7 +329,8 @@ export function compileToStructure(
|
|
|
329
329
|
const preprocessedSource = preprocessSource(source, { filePath })
|
|
330
330
|
const tokens = new Lexer(preprocessedSource, filePath).tokenize()
|
|
331
331
|
const parsedAst = new Parser(tokens, preprocessedSource, filePath).parse(namespace)
|
|
332
|
-
const
|
|
332
|
+
const dceResult = options.dce ?? true ? eliminateDeadCode(parsedAst) : { program: parsedAst, warnings: [] }
|
|
333
|
+
const ast = dceResult.program
|
|
333
334
|
const ir = new Lowering(namespace).lower(ast)
|
|
334
335
|
const stats = createEmptyOptimizationStats()
|
|
335
336
|
const optimizedIRFunctions = ir.functions.map(fn => {
|
package/src/compile.ts
CHANGED
|
@@ -175,7 +175,8 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
175
175
|
|
|
176
176
|
// Parsing
|
|
177
177
|
const parsedAst = new Parser(tokens, preprocessedSource, filePath).parse(namespace)
|
|
178
|
-
const
|
|
178
|
+
const dceResult = shouldRunDce ? eliminateDeadCode(parsedAst) : { program: parsedAst, warnings: [] }
|
|
179
|
+
const ast = dceResult.program
|
|
179
180
|
|
|
180
181
|
// Lowering
|
|
181
182
|
const ir = new Lowering(namespace, preprocessed.ranges).lower(ast)
|
package/src/index.ts
CHANGED
|
@@ -65,7 +65,8 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
65
65
|
|
|
66
66
|
// Parsing
|
|
67
67
|
const parsedAst = new Parser(tokens, preprocessedSource, filePath).parse(namespace)
|
|
68
|
-
const
|
|
68
|
+
const dceResult = shouldRunDce ? eliminateDeadCode(parsedAst) : { program: parsedAst, warnings: [] }
|
|
69
|
+
const ast = dceResult.program
|
|
69
70
|
|
|
70
71
|
// Type checking (warn mode - collect errors but don't block)
|
|
71
72
|
let typeErrors: DiagnosticError[] | undefined
|
|
@@ -129,7 +130,7 @@ export function compile(source: string, options: CompileOptions = {}): CompileRe
|
|
|
129
130
|
ast,
|
|
130
131
|
ir: optimizedIR,
|
|
131
132
|
typeErrors,
|
|
132
|
-
warnings: lowering.warnings,
|
|
133
|
+
warnings: [...dceResult.warnings, ...lowering.warnings],
|
|
133
134
|
stats: optimizationStats,
|
|
134
135
|
}
|
|
135
136
|
}
|
package/src/optimizer/dce.ts
CHANGED
|
@@ -67,6 +67,13 @@ function isPureExpr(expr: Expr): boolean {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export interface DCEWarning {
|
|
71
|
+
message: string
|
|
72
|
+
code: string
|
|
73
|
+
line?: number
|
|
74
|
+
col?: number
|
|
75
|
+
}
|
|
76
|
+
|
|
70
77
|
export class DeadCodeEliminator {
|
|
71
78
|
private readonly functionMap = new Map<string, FnDecl>()
|
|
72
79
|
private readonly reachableFunctions = new Set<string>()
|
|
@@ -74,6 +81,7 @@ export class DeadCodeEliminator {
|
|
|
74
81
|
private readonly localReads = new Set<string>()
|
|
75
82
|
private readonly localDeclIds = new WeakMap<Stmt, string>()
|
|
76
83
|
private localIdCounter = 0
|
|
84
|
+
readonly warnings: DCEWarning[] = []
|
|
77
85
|
|
|
78
86
|
eliminate(program: Program): Program {
|
|
79
87
|
this.functionMap.clear()
|
|
@@ -81,6 +89,7 @@ export class DeadCodeEliminator {
|
|
|
81
89
|
this.usedConstants.clear()
|
|
82
90
|
this.localReads.clear()
|
|
83
91
|
this.localIdCounter = 0
|
|
92
|
+
this.warnings.length = 0
|
|
84
93
|
|
|
85
94
|
for (const fn of program.declarations) {
|
|
86
95
|
this.functionMap.set(fn.name, fn)
|
|
@@ -429,6 +438,13 @@ export class DeadCodeEliminator {
|
|
|
429
438
|
}
|
|
430
439
|
return [copySpan({ ...stmt, init }, stmt)]
|
|
431
440
|
}
|
|
441
|
+
// Unused variable - emit warning
|
|
442
|
+
this.warnings.push({
|
|
443
|
+
message: `Unused variable '${stmt.name}'`,
|
|
444
|
+
code: 'W_UNUSED_VAR',
|
|
445
|
+
line: stmt.span?.line,
|
|
446
|
+
col: stmt.span?.col,
|
|
447
|
+
})
|
|
432
448
|
if (isPureExpr(init)) {
|
|
433
449
|
return []
|
|
434
450
|
}
|
|
@@ -614,6 +630,8 @@ export class DeadCodeEliminator {
|
|
|
614
630
|
}
|
|
615
631
|
}
|
|
616
632
|
|
|
617
|
-
export function eliminateDeadCode(program: Program): Program {
|
|
618
|
-
|
|
633
|
+
export function eliminateDeadCode(program: Program): { program: Program; warnings: DCEWarning[] } {
|
|
634
|
+
const eliminator = new DeadCodeEliminator()
|
|
635
|
+
const result = eliminator.eliminate(program)
|
|
636
|
+
return { program: result, warnings: eliminator.warnings }
|
|
619
637
|
}
|