redscript-mc 1.2.30 → 2.0.0
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/.claude/commands/build-test.md +10 -0
- package/.claude/commands/deploy-demo.md +12 -0
- package/.claude/commands/stage-status.md +13 -0
- package/.claude/settings.json +12 -0
- package/.github/workflows/ci.yml +1 -0
- package/CLAUDE.md +231 -0
- package/demo.gif +0 -0
- package/dist/cli.js +2 -554
- package/dist/compile.js +2 -266
- package/dist/index.js +2 -159
- package/dist/lowering/index.js +5 -3
- package/dist/src/__tests__/cli.test.d.ts +1 -0
- package/dist/src/__tests__/cli.test.js +104 -0
- package/dist/src/__tests__/codegen.test.d.ts +1 -0
- package/dist/src/__tests__/codegen.test.js +152 -0
- package/dist/src/__tests__/compile-all.test.d.ts +10 -0
- package/dist/src/__tests__/compile-all.test.js +108 -0
- package/dist/src/__tests__/dce.test.d.ts +1 -0
- package/dist/src/__tests__/dce.test.js +102 -0
- package/dist/src/__tests__/diagnostics.test.d.ts +4 -0
- package/dist/src/__tests__/diagnostics.test.js +177 -0
- package/dist/src/__tests__/e2e.test.d.ts +6 -0
- package/dist/src/__tests__/e2e.test.js +1789 -0
- package/dist/src/__tests__/entity-types.test.d.ts +1 -0
- package/dist/src/__tests__/entity-types.test.js +203 -0
- package/dist/src/__tests__/formatter.test.d.ts +1 -0
- package/dist/src/__tests__/formatter.test.js +40 -0
- package/dist/src/__tests__/lexer.test.d.ts +1 -0
- package/dist/src/__tests__/lexer.test.js +343 -0
- package/dist/src/__tests__/lowering.test.d.ts +1 -0
- package/dist/src/__tests__/lowering.test.js +1015 -0
- package/dist/src/__tests__/macro.test.d.ts +8 -0
- package/dist/src/__tests__/macro.test.js +306 -0
- package/dist/src/__tests__/mc-integration.test.d.ts +12 -0
- package/dist/src/__tests__/mc-integration.test.js +817 -0
- package/dist/src/__tests__/mc-syntax.test.d.ts +1 -0
- package/dist/src/__tests__/mc-syntax.test.js +124 -0
- package/dist/src/__tests__/nbt.test.d.ts +1 -0
- package/dist/src/__tests__/nbt.test.js +82 -0
- package/dist/src/__tests__/optimizer-advanced.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer-advanced.test.js +124 -0
- package/dist/src/__tests__/optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer.test.js +149 -0
- package/dist/src/__tests__/parser.test.d.ts +1 -0
- package/dist/src/__tests__/parser.test.js +807 -0
- package/dist/src/__tests__/repl.test.d.ts +1 -0
- package/dist/src/__tests__/repl.test.js +27 -0
- package/dist/src/__tests__/runtime.test.d.ts +1 -0
- package/dist/src/__tests__/runtime.test.js +289 -0
- package/dist/src/__tests__/stdlib-advanced.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-advanced.test.js +374 -0
- package/dist/src/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-bigint.test.js +426 -0
- package/dist/src/__tests__/stdlib-math.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-math.test.js +351 -0
- package/dist/src/__tests__/stdlib-vec.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-vec.test.js +263 -0
- package/dist/src/__tests__/structure-optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/structure-optimizer.test.js +33 -0
- package/dist/src/__tests__/typechecker.test.d.ts +1 -0
- package/dist/src/__tests__/typechecker.test.js +552 -0
- package/dist/src/__tests__/var-allocator.test.d.ts +1 -0
- package/dist/src/__tests__/var-allocator.test.js +69 -0
- package/dist/src/ast/types.d.ts +515 -0
- package/dist/src/ast/types.js +9 -0
- package/dist/src/builtins/metadata.d.ts +36 -0
- package/dist/src/builtins/metadata.js +1014 -0
- package/dist/src/cli.d.ts +11 -0
- package/dist/src/cli.js +443 -0
- package/dist/src/codegen/cmdblock/index.d.ts +26 -0
- package/dist/src/codegen/cmdblock/index.js +45 -0
- package/dist/src/codegen/mcfunction/index.d.ts +40 -0
- package/dist/src/codegen/mcfunction/index.js +606 -0
- package/dist/src/codegen/structure/index.d.ts +24 -0
- package/dist/src/codegen/structure/index.js +279 -0
- package/dist/src/codegen/var-allocator.d.ts +45 -0
- package/dist/src/codegen/var-allocator.js +104 -0
- package/dist/src/compile.d.ts +37 -0
- package/dist/src/compile.js +165 -0
- package/dist/src/diagnostics/index.d.ts +44 -0
- package/dist/src/diagnostics/index.js +140 -0
- package/dist/src/events/types.d.ts +35 -0
- package/dist/src/events/types.js +59 -0
- package/dist/src/formatter/index.d.ts +1 -0
- package/dist/src/formatter/index.js +26 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.js +45 -0
- package/dist/src/ir/builder.d.ts +33 -0
- package/dist/src/ir/builder.js +99 -0
- package/dist/src/ir/types.d.ts +132 -0
- package/dist/src/ir/types.js +15 -0
- package/dist/src/lexer/index.d.ts +37 -0
- package/dist/src/lexer/index.js +569 -0
- package/dist/src/lowering/index.d.ts +188 -0
- package/dist/src/lowering/index.js +3405 -0
- package/dist/src/mc-test/client.d.ts +128 -0
- package/dist/src/mc-test/client.js +174 -0
- package/dist/src/mc-test/runner.d.ts +28 -0
- package/dist/src/mc-test/runner.js +151 -0
- package/dist/src/mc-test/setup.d.ts +11 -0
- package/dist/src/mc-test/setup.js +98 -0
- package/dist/src/mc-validator/index.d.ts +17 -0
- package/dist/src/mc-validator/index.js +322 -0
- package/dist/src/nbt/index.d.ts +86 -0
- package/dist/src/nbt/index.js +250 -0
- package/dist/src/optimizer/commands.d.ts +38 -0
- package/dist/src/optimizer/commands.js +451 -0
- package/dist/src/optimizer/dce.d.ts +34 -0
- package/dist/src/optimizer/dce.js +639 -0
- package/dist/src/optimizer/passes.d.ts +34 -0
- package/dist/src/optimizer/passes.js +243 -0
- package/dist/src/optimizer/structure.d.ts +9 -0
- package/dist/src/optimizer/structure.js +356 -0
- package/dist/src/parser/index.d.ts +93 -0
- package/dist/src/parser/index.js +1687 -0
- package/dist/src/repl.d.ts +16 -0
- package/dist/src/repl.js +165 -0
- package/dist/src/runtime/index.d.ts +107 -0
- package/dist/src/runtime/index.js +1409 -0
- package/dist/src/typechecker/index.d.ts +61 -0
- package/dist/src/typechecker/index.js +1034 -0
- package/dist/src/types/entity-hierarchy.d.ts +29 -0
- package/dist/src/types/entity-hierarchy.js +107 -0
- package/dist/src2/__tests__/e2e/basic.test.d.ts +8 -0
- package/dist/src2/__tests__/e2e/basic.test.js +140 -0
- package/dist/src2/__tests__/e2e/macros.test.d.ts +9 -0
- package/dist/src2/__tests__/e2e/macros.test.js +182 -0
- package/dist/src2/__tests__/e2e/migrate.test.d.ts +13 -0
- package/dist/src2/__tests__/e2e/migrate.test.js +2739 -0
- package/dist/src2/__tests__/hir/desugar.test.d.ts +1 -0
- package/dist/src2/__tests__/hir/desugar.test.js +234 -0
- package/dist/src2/__tests__/lir/lower.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/lower.test.js +559 -0
- package/dist/src2/__tests__/lir/types.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/types.test.js +185 -0
- package/dist/src2/__tests__/lir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/verify.test.js +221 -0
- package/dist/src2/__tests__/mir/arithmetic.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/arithmetic.test.js +130 -0
- package/dist/src2/__tests__/mir/control-flow.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/control-flow.test.js +205 -0
- package/dist/src2/__tests__/mir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/verify.test.js +223 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.js +78 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.js +58 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.js +131 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.js +91 -0
- package/dist/src2/__tests__/optimizer/dce.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/dce.test.js +76 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.js +102 -0
- package/dist/src2/emit/compile.d.ts +19 -0
- package/dist/src2/emit/compile.js +80 -0
- package/dist/src2/emit/index.d.ts +17 -0
- package/dist/src2/emit/index.js +172 -0
- package/dist/src2/hir/lower.d.ts +15 -0
- package/dist/src2/hir/lower.js +378 -0
- package/dist/src2/hir/types.d.ts +373 -0
- package/dist/src2/hir/types.js +16 -0
- package/dist/src2/lir/lower.d.ts +15 -0
- package/dist/src2/lir/lower.js +453 -0
- package/dist/src2/lir/types.d.ts +136 -0
- package/dist/src2/lir/types.js +11 -0
- package/dist/src2/lir/verify.d.ts +14 -0
- package/dist/src2/lir/verify.js +113 -0
- package/dist/src2/mir/lower.d.ts +9 -0
- package/dist/src2/mir/lower.js +1030 -0
- package/dist/src2/mir/macro.d.ts +22 -0
- package/dist/src2/mir/macro.js +168 -0
- package/dist/src2/mir/types.d.ts +183 -0
- package/dist/src2/mir/types.js +11 -0
- package/dist/src2/mir/verify.d.ts +16 -0
- package/dist/src2/mir/verify.js +216 -0
- package/dist/src2/optimizer/block_merge.d.ts +12 -0
- package/dist/src2/optimizer/block_merge.js +84 -0
- package/dist/src2/optimizer/branch_simplify.d.ts +9 -0
- package/dist/src2/optimizer/branch_simplify.js +28 -0
- package/dist/src2/optimizer/constant_fold.d.ts +10 -0
- package/dist/src2/optimizer/constant_fold.js +85 -0
- package/dist/src2/optimizer/copy_prop.d.ts +9 -0
- package/dist/src2/optimizer/copy_prop.js +113 -0
- package/dist/src2/optimizer/dce.d.ts +8 -0
- package/dist/src2/optimizer/dce.js +155 -0
- package/dist/src2/optimizer/pipeline.d.ts +10 -0
- package/dist/src2/optimizer/pipeline.js +42 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/compiler-pipeline-redesign.md +2243 -0
- package/docs/optimization-ideas.md +1076 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/jest.config.js +1 -1
- package/package.json +6 -5
- package/scripts/postbuild.js +15 -0
- package/src/__tests__/cli.test.ts +8 -220
- package/src/__tests__/dce.test.ts +11 -56
- package/src/__tests__/diagnostics.test.ts +59 -38
- package/src/__tests__/mc-integration.test.ts +1 -2
- package/src/ast/types.ts +6 -1
- package/src/cli.ts +29 -156
- package/src/compile.ts +6 -162
- package/src/index.ts +14 -178
- package/src/mc-test/runner.ts +4 -3
- package/src/parser/index.ts +1 -1
- package/src/repl.ts +1 -1
- package/src/runtime/index.ts +1 -1
- package/src2/__tests__/e2e/basic.test.ts +154 -0
- package/src2/__tests__/e2e/macros.test.ts +199 -0
- package/src2/__tests__/e2e/migrate.test.ts +3008 -0
- package/src2/__tests__/hir/desugar.test.ts +263 -0
- package/src2/__tests__/lir/lower.test.ts +619 -0
- package/src2/__tests__/lir/types.test.ts +207 -0
- package/src2/__tests__/lir/verify.test.ts +249 -0
- package/src2/__tests__/mir/arithmetic.test.ts +156 -0
- package/src2/__tests__/mir/control-flow.test.ts +242 -0
- package/src2/__tests__/mir/verify.test.ts +254 -0
- package/src2/__tests__/optimizer/block_merge.test.ts +84 -0
- package/src2/__tests__/optimizer/branch_simplify.test.ts +64 -0
- package/src2/__tests__/optimizer/constant_fold.test.ts +145 -0
- package/src2/__tests__/optimizer/copy_prop.test.ts +99 -0
- package/src2/__tests__/optimizer/dce.test.ts +83 -0
- package/src2/__tests__/optimizer/pipeline.test.ts +116 -0
- package/src2/emit/compile.ts +99 -0
- package/src2/emit/index.ts +222 -0
- package/src2/hir/lower.ts +428 -0
- package/src2/hir/types.ts +216 -0
- package/src2/lir/lower.ts +556 -0
- package/src2/lir/types.ts +109 -0
- package/src2/lir/verify.ts +129 -0
- package/src2/mir/lower.ts +1160 -0
- package/src2/mir/macro.ts +167 -0
- package/src2/mir/types.ts +106 -0
- package/src2/mir/verify.ts +218 -0
- package/src2/optimizer/block_merge.ts +93 -0
- package/src2/optimizer/branch_simplify.ts +27 -0
- package/src2/optimizer/constant_fold.ts +88 -0
- package/src2/optimizer/copy_prop.ts +106 -0
- package/src2/optimizer/dce.ts +133 -0
- package/src2/optimizer/pipeline.ts +44 -0
- package/tsconfig.json +2 -2
- package/src/__tests__/codegen.test.ts +0 -161
- package/src/__tests__/e2e.test.ts +0 -2039
- package/src/__tests__/entity-types.test.ts +0 -236
- package/src/__tests__/lowering.test.ts +0 -1185
- package/src/__tests__/macro.test.ts +0 -343
- package/src/__tests__/nbt.test.ts +0 -58
- package/src/__tests__/optimizer-advanced.test.ts +0 -144
- package/src/__tests__/optimizer.test.ts +0 -162
- package/src/__tests__/runtime.test.ts +0 -305
- package/src/__tests__/stdlib-advanced.test.ts +0 -379
- package/src/__tests__/stdlib-bigint.test.ts +0 -427
- package/src/__tests__/stdlib-math.test.ts +0 -374
- package/src/__tests__/stdlib-vec.test.ts +0 -259
- package/src/__tests__/structure-optimizer.test.ts +0 -38
- package/src/__tests__/var-allocator.test.ts +0 -75
- package/src/codegen/cmdblock/index.ts +0 -63
- package/src/codegen/mcfunction/index.ts +0 -662
- package/src/codegen/structure/index.ts +0 -346
- package/src/codegen/var-allocator.ts +0 -104
- package/src/ir/builder.ts +0 -116
- package/src/ir/types.ts +0 -134
- package/src/lowering/index.ts +0 -3876
- package/src/optimizer/commands.ts +0 -534
- package/src/optimizer/dce.ts +0 -679
- package/src/optimizer/passes.ts +0 -250
- package/src/optimizer/structure.ts +0 -450
package/dist/compile.js
CHANGED
|
@@ -1,266 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* RedScript Compile API
|
|
4
|
-
*
|
|
5
|
-
* Main compile function with proper error handling and diagnostics.
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.resolveSourceLine = resolveSourceLine;
|
|
42
|
-
exports.preprocessSourceWithMetadata = preprocessSourceWithMetadata;
|
|
43
|
-
exports.preprocessSource = preprocessSource;
|
|
44
|
-
exports.compile = compile;
|
|
45
|
-
exports.formatCompileError = formatCompileError;
|
|
46
|
-
const fs = __importStar(require("fs"));
|
|
47
|
-
const path = __importStar(require("path"));
|
|
48
|
-
const lexer_1 = require("./lexer");
|
|
49
|
-
const parser_1 = require("./parser");
|
|
50
|
-
const lowering_1 = require("./lowering");
|
|
51
|
-
const passes_1 = require("./optimizer/passes");
|
|
52
|
-
const dce_1 = require("./optimizer/dce");
|
|
53
|
-
const mcfunction_1 = require("./codegen/mcfunction");
|
|
54
|
-
const diagnostics_1 = require("./diagnostics");
|
|
55
|
-
/**
|
|
56
|
-
* Resolve a combined-source line number back to the original file and line.
|
|
57
|
-
* Returns { filePath, line } if a mapping is found, otherwise returns the input unchanged.
|
|
58
|
-
*/
|
|
59
|
-
function resolveSourceLine(combinedLine, ranges, fallbackFile) {
|
|
60
|
-
for (const range of ranges) {
|
|
61
|
-
if (combinedLine >= range.startLine && combinedLine <= range.endLine) {
|
|
62
|
-
const localLine = combinedLine - range.startLine + 1;
|
|
63
|
-
return { filePath: range.filePath, line: localLine };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return { filePath: fallbackFile, line: combinedLine };
|
|
67
|
-
}
|
|
68
|
-
const IMPORT_RE = /^\s*import\s+"([^"]+)"\s*;?\s*$/;
|
|
69
|
-
/** Returns true if the source file declares `module library;` at its top
|
|
70
|
-
* (before any non-comment/non-blank lines). */
|
|
71
|
-
function isLibrarySource(source) {
|
|
72
|
-
for (const line of source.split('\n')) {
|
|
73
|
-
const trimmed = line.trim();
|
|
74
|
-
if (!trimmed || trimmed.startsWith('//'))
|
|
75
|
-
continue;
|
|
76
|
-
return /^module\s+library\s*;/.test(trimmed);
|
|
77
|
-
}
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
function countLines(source) {
|
|
81
|
-
return source === '' ? 0 : source.split('\n').length;
|
|
82
|
-
}
|
|
83
|
-
function offsetRanges(ranges, lineOffset) {
|
|
84
|
-
return ranges.map(range => ({
|
|
85
|
-
startLine: range.startLine + lineOffset,
|
|
86
|
-
endLine: range.endLine + lineOffset,
|
|
87
|
-
filePath: range.filePath,
|
|
88
|
-
}));
|
|
89
|
-
}
|
|
90
|
-
function preprocessSourceWithMetadata(source, options = {}) {
|
|
91
|
-
const { filePath } = options;
|
|
92
|
-
const seen = options.seen ?? new Set();
|
|
93
|
-
if (filePath) {
|
|
94
|
-
seen.add(path.resolve(filePath));
|
|
95
|
-
}
|
|
96
|
-
const lines = source.split('\n');
|
|
97
|
-
const imports = [];
|
|
98
|
-
/** Library imports: `module library;` files routed here instead of concatenated. */
|
|
99
|
-
const libraryImports = [];
|
|
100
|
-
const bodyLines = [];
|
|
101
|
-
let parsingHeader = true;
|
|
102
|
-
for (let i = 0; i < lines.length; i++) {
|
|
103
|
-
const line = lines[i];
|
|
104
|
-
const trimmed = line.trim();
|
|
105
|
-
const match = line.match(IMPORT_RE);
|
|
106
|
-
if (parsingHeader && match) {
|
|
107
|
-
if (!filePath) {
|
|
108
|
-
throw new diagnostics_1.DiagnosticError('ParseError', 'Import statements require a file path', { line: i + 1, col: 1 }, lines);
|
|
109
|
-
}
|
|
110
|
-
const importPath = path.resolve(path.dirname(filePath), match[1]);
|
|
111
|
-
if (!seen.has(importPath)) {
|
|
112
|
-
seen.add(importPath);
|
|
113
|
-
let importedSource;
|
|
114
|
-
try {
|
|
115
|
-
importedSource = fs.readFileSync(importPath, 'utf-8');
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
throw new diagnostics_1.DiagnosticError('ParseError', `Cannot import '${match[1]}'`, { file: filePath, line: i + 1, col: 1 }, lines);
|
|
119
|
-
}
|
|
120
|
-
if (isLibrarySource(importedSource)) {
|
|
121
|
-
// Library file: parse separately so its functions are DCE-eligible.
|
|
122
|
-
// Also collect any transitive library imports inside it.
|
|
123
|
-
const nested = preprocessSourceWithMetadata(importedSource, { filePath: importPath, seen });
|
|
124
|
-
libraryImports.push({ source: importedSource, filePath: importPath });
|
|
125
|
-
// Propagate transitive library imports (e.g. math.mcrs imports vec.mcrs)
|
|
126
|
-
if (nested.libraryImports)
|
|
127
|
-
libraryImports.push(...nested.libraryImports);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
imports.push(preprocessSourceWithMetadata(importedSource, { filePath: importPath, seen }));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
if (parsingHeader && (trimmed === '' || trimmed.startsWith('//'))) {
|
|
136
|
-
bodyLines.push(line);
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
parsingHeader = false;
|
|
140
|
-
bodyLines.push(line);
|
|
141
|
-
}
|
|
142
|
-
const body = bodyLines.join('\n');
|
|
143
|
-
const parts = [...imports.map(entry => entry.source), body].filter(Boolean);
|
|
144
|
-
const combined = parts.join('\n');
|
|
145
|
-
const ranges = [];
|
|
146
|
-
let lineOffset = 0;
|
|
147
|
-
for (const entry of imports) {
|
|
148
|
-
ranges.push(...offsetRanges(entry.ranges, lineOffset));
|
|
149
|
-
lineOffset += countLines(entry.source);
|
|
150
|
-
}
|
|
151
|
-
if (filePath && body) {
|
|
152
|
-
ranges.push({
|
|
153
|
-
startLine: lineOffset + 1,
|
|
154
|
-
endLine: lineOffset + countLines(body),
|
|
155
|
-
filePath: path.resolve(filePath),
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
source: combined,
|
|
160
|
-
ranges,
|
|
161
|
-
libraryImports: libraryImports.length > 0 ? libraryImports : undefined,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function preprocessSource(source, options = {}) {
|
|
165
|
-
return preprocessSourceWithMetadata(source, options).source;
|
|
166
|
-
}
|
|
167
|
-
// ---------------------------------------------------------------------------
|
|
168
|
-
// Main Compile Function
|
|
169
|
-
// ---------------------------------------------------------------------------
|
|
170
|
-
function compile(source, options = {}) {
|
|
171
|
-
const { namespace = 'redscript', filePath, optimize: shouldOptimize = true } = options;
|
|
172
|
-
const shouldRunDce = options.dce ?? shouldOptimize;
|
|
173
|
-
let sourceLines = source.split('\n');
|
|
174
|
-
try {
|
|
175
|
-
const preprocessed = preprocessSourceWithMetadata(source, { filePath });
|
|
176
|
-
const preprocessedSource = preprocessed.source;
|
|
177
|
-
sourceLines = preprocessedSource.split('\n');
|
|
178
|
-
// Lexing
|
|
179
|
-
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
180
|
-
// Parsing — user source
|
|
181
|
-
const parsedAst = new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
182
|
-
// Collect all library sources: explicit `librarySources` option +
|
|
183
|
-
// auto-detected imports (files with `module library;` pulled out by the
|
|
184
|
-
// preprocessor rather than concatenated).
|
|
185
|
-
const allLibrarySources = [];
|
|
186
|
-
for (const libSrc of options.librarySources ?? []) {
|
|
187
|
-
allLibrarySources.push({ src: libSrc });
|
|
188
|
-
}
|
|
189
|
-
for (const li of preprocessed.libraryImports ?? []) {
|
|
190
|
-
allLibrarySources.push({ src: li.source, fp: li.filePath });
|
|
191
|
-
}
|
|
192
|
-
// Parse library sources independently (fresh Parser per source) so that
|
|
193
|
-
// `inLibraryMode` never bleeds into user code. All resulting functions get
|
|
194
|
-
// isLibraryFn=true (either via `module library;` in the source, or forced below).
|
|
195
|
-
for (const { src, fp } of allLibrarySources) {
|
|
196
|
-
const libPreprocessed = preprocessSourceWithMetadata(src, fp ? { filePath: fp } : {});
|
|
197
|
-
const libTokens = new lexer_1.Lexer(libPreprocessed.source, fp).tokenize();
|
|
198
|
-
const libAst = new parser_1.Parser(libTokens, libPreprocessed.source, fp).parse(namespace);
|
|
199
|
-
// Force all functions to library mode (even if source lacks `module library;`)
|
|
200
|
-
for (const fn of libAst.declarations)
|
|
201
|
-
fn.isLibraryFn = true;
|
|
202
|
-
// Merge into main AST
|
|
203
|
-
parsedAst.declarations.push(...libAst.declarations);
|
|
204
|
-
parsedAst.structs.push(...libAst.structs);
|
|
205
|
-
parsedAst.implBlocks.push(...libAst.implBlocks);
|
|
206
|
-
parsedAst.enums.push(...libAst.enums);
|
|
207
|
-
parsedAst.consts.push(...libAst.consts);
|
|
208
|
-
parsedAst.globals.push(...libAst.globals);
|
|
209
|
-
}
|
|
210
|
-
const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
|
|
211
|
-
const ast = dceResult.program;
|
|
212
|
-
// Configure scoreboard objective for this compilation.
|
|
213
|
-
// Default: use the datapack namespace so each datapack gets its own objective
|
|
214
|
-
// automatically, preventing variable collisions when multiple datapacks coexist.
|
|
215
|
-
const scoreboardObj = options.scoreboardObjective ?? `__${namespace}`;
|
|
216
|
-
(0, lowering_1.setScoreboardObjective)(scoreboardObj);
|
|
217
|
-
// Lowering
|
|
218
|
-
const ir = new lowering_1.Lowering(namespace, preprocessed.ranges).lower(ast);
|
|
219
|
-
// Optimization
|
|
220
|
-
const optimized = shouldOptimize
|
|
221
|
-
? { ...ir, functions: ir.functions.map(fn => (0, passes_1.optimize)(fn)) }
|
|
222
|
-
: ir;
|
|
223
|
-
// Code generation — mangle=true by default to prevent cross-function
|
|
224
|
-
// scoreboard variable collisions in the global MC scoreboard namespace.
|
|
225
|
-
const generated = (0, mcfunction_1.generateDatapackWithStats)(optimized, {
|
|
226
|
-
mangle: options.mangle ?? true,
|
|
227
|
-
scoreboardObjective: scoreboardObj,
|
|
228
|
-
});
|
|
229
|
-
return {
|
|
230
|
-
success: true,
|
|
231
|
-
files: [...generated.files, ...generated.advancements],
|
|
232
|
-
advancements: generated.advancements,
|
|
233
|
-
ast,
|
|
234
|
-
ir: optimized,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
catch (err) {
|
|
238
|
-
// Already a DiagnosticError
|
|
239
|
-
if (err instanceof diagnostics_1.DiagnosticError) {
|
|
240
|
-
return { success: false, error: err };
|
|
241
|
-
}
|
|
242
|
-
// Try to parse the error message for line/col info
|
|
243
|
-
if (err instanceof Error) {
|
|
244
|
-
const diagnostic = (0, diagnostics_1.parseErrorMessage)('ParseError', err.message, sourceLines, filePath);
|
|
245
|
-
return { success: false, error: diagnostic };
|
|
246
|
-
}
|
|
247
|
-
// Unknown error
|
|
248
|
-
return {
|
|
249
|
-
success: false,
|
|
250
|
-
error: new diagnostics_1.DiagnosticError('ParseError', String(err), { file: filePath, line: 1, col: 1 }, sourceLines)
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
// ---------------------------------------------------------------------------
|
|
255
|
-
// Format Compile Error
|
|
256
|
-
// ---------------------------------------------------------------------------
|
|
257
|
-
function formatCompileError(result) {
|
|
258
|
-
if (result.success) {
|
|
259
|
-
return 'Compilation successful';
|
|
260
|
-
}
|
|
261
|
-
if (result.error) {
|
|
262
|
-
return (0, diagnostics_1.formatError)(result.error, result.error.sourceLines?.join('\n'));
|
|
263
|
-
}
|
|
264
|
-
return 'Unknown error';
|
|
265
|
-
}
|
|
266
|
-
//# sourceMappingURL=compile.js.map
|
|
1
|
+
// shim — delegates to dist/src/
|
|
2
|
+
module.exports = require('./src/compile');
|
package/dist/index.js
CHANGED
|
@@ -1,159 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* RedScript Compiler
|
|
4
|
-
*
|
|
5
|
-
* Main entry point for programmatic usage.
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.MCCommandValidator = exports.generateDatapack = exports.optimize = exports.Lowering = exports.TypeChecker = exports.Parser = exports.Lexer = exports.version = void 0;
|
|
9
|
-
exports.compile = compile;
|
|
10
|
-
exports.check = check;
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
-
exports.version = '1.2.11';
|
|
13
|
-
const lexer_1 = require("./lexer");
|
|
14
|
-
const parser_1 = require("./parser");
|
|
15
|
-
const typechecker_1 = require("./typechecker");
|
|
16
|
-
const lowering_1 = require("./lowering");
|
|
17
|
-
const passes_1 = require("./optimizer/passes");
|
|
18
|
-
const dce_1 = require("./optimizer/dce");
|
|
19
|
-
const mcfunction_1 = require("./codegen/mcfunction");
|
|
20
|
-
const compile_1 = require("./compile");
|
|
21
|
-
const commands_1 = require("./optimizer/commands");
|
|
22
|
-
/**
|
|
23
|
-
* Compile RedScript source code to a Minecraft datapack.
|
|
24
|
-
*
|
|
25
|
-
* @param source - The RedScript source code
|
|
26
|
-
* @param options - Compilation options
|
|
27
|
-
* @returns Compiled datapack files
|
|
28
|
-
*/
|
|
29
|
-
function compile(source, options = {}) {
|
|
30
|
-
const namespace = options.namespace ?? 'redscript';
|
|
31
|
-
const shouldOptimize = options.optimize ?? true;
|
|
32
|
-
const shouldTypeCheck = options.typeCheck ?? true;
|
|
33
|
-
const shouldRunDce = options.dce ?? shouldOptimize;
|
|
34
|
-
const mangle = options.mangle ?? false;
|
|
35
|
-
const filePath = options.filePath;
|
|
36
|
-
const preprocessed = (0, compile_1.preprocessSourceWithMetadata)(source, { filePath });
|
|
37
|
-
const preprocessedSource = preprocessed.source;
|
|
38
|
-
// Lexing
|
|
39
|
-
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
40
|
-
// Parsing — user source
|
|
41
|
-
const parsedAst = new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
42
|
-
// Library imports: files that declared `module library;` are parsed independently
|
|
43
|
-
// (fresh Parser per file) so their functions are DCE-eligible but never bleed into user code.
|
|
44
|
-
const allLibrarySources = [];
|
|
45
|
-
for (const li of preprocessed.libraryImports ?? []) {
|
|
46
|
-
allLibrarySources.push({ src: li.source, fp: li.filePath });
|
|
47
|
-
}
|
|
48
|
-
for (const { src, fp } of allLibrarySources) {
|
|
49
|
-
const libPreprocessed = (0, compile_1.preprocessSourceWithMetadata)(src, fp ? { filePath: fp } : {});
|
|
50
|
-
const libTokens = new lexer_1.Lexer(libPreprocessed.source, fp).tokenize();
|
|
51
|
-
const libAst = new parser_1.Parser(libTokens, libPreprocessed.source, fp).parse(namespace);
|
|
52
|
-
for (const fn of libAst.declarations)
|
|
53
|
-
fn.isLibraryFn = true;
|
|
54
|
-
parsedAst.declarations.push(...libAst.declarations);
|
|
55
|
-
parsedAst.structs.push(...libAst.structs);
|
|
56
|
-
parsedAst.implBlocks.push(...libAst.implBlocks);
|
|
57
|
-
parsedAst.enums.push(...libAst.enums);
|
|
58
|
-
parsedAst.consts.push(...libAst.consts);
|
|
59
|
-
parsedAst.globals.push(...libAst.globals);
|
|
60
|
-
}
|
|
61
|
-
const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst, preprocessed.ranges) : { program: parsedAst, warnings: [] };
|
|
62
|
-
const ast = dceResult.program;
|
|
63
|
-
// Type checking (warn mode - collect errors but don't block)
|
|
64
|
-
let typeErrors;
|
|
65
|
-
if (shouldTypeCheck) {
|
|
66
|
-
const checker = new typechecker_1.TypeChecker(preprocessedSource, filePath);
|
|
67
|
-
typeErrors = checker.check(ast);
|
|
68
|
-
}
|
|
69
|
-
// Configure scoreboard objective for this compilation.
|
|
70
|
-
// Default: use the datapack namespace so each datapack gets its own objective
|
|
71
|
-
// automatically, preventing variable collisions when multiple datapacks coexist.
|
|
72
|
-
const scoreboardObj = options.scoreboardObjective ?? `__${namespace}`;
|
|
73
|
-
(0, lowering_1.setScoreboardObjective)(scoreboardObj);
|
|
74
|
-
// Lowering to IR
|
|
75
|
-
const lowering = new lowering_1.Lowering(namespace, preprocessed.ranges);
|
|
76
|
-
const ir = lowering.lower(ast);
|
|
77
|
-
let optimizedIR = ir;
|
|
78
|
-
let generated = (0, mcfunction_1.generateDatapackWithStats)(ir, { optimizeCommands: shouldOptimize, mangle, scoreboardObjective: scoreboardObj });
|
|
79
|
-
let optimizationStats;
|
|
80
|
-
if (shouldOptimize) {
|
|
81
|
-
const stats = (0, commands_1.createEmptyOptimizationStats)();
|
|
82
|
-
const copyPropagatedFunctions = [];
|
|
83
|
-
const deadCodeEliminatedFunctions = [];
|
|
84
|
-
for (const fn of ir.functions) {
|
|
85
|
-
const folded = (0, passes_1.constantFoldingWithStats)(fn);
|
|
86
|
-
stats.constantFolds += folded.stats.constantFolds ?? 0;
|
|
87
|
-
const propagated = (0, passes_1.copyPropagation)(folded.fn);
|
|
88
|
-
copyPropagatedFunctions.push(propagated);
|
|
89
|
-
const dce = (0, passes_1.deadCodeEliminationWithStats)(propagated);
|
|
90
|
-
deadCodeEliminatedFunctions.push(dce.fn);
|
|
91
|
-
}
|
|
92
|
-
const copyPropagatedIR = { ...ir, functions: copyPropagatedFunctions };
|
|
93
|
-
optimizedIR = { ...ir, functions: deadCodeEliminatedFunctions };
|
|
94
|
-
const baselineGenerated = (0, mcfunction_1.generateDatapackWithStats)(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj });
|
|
95
|
-
const beforeDceGenerated = (0, mcfunction_1.generateDatapackWithStats)(copyPropagatedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj });
|
|
96
|
-
const afterDceGenerated = (0, mcfunction_1.generateDatapackWithStats)(optimizedIR, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj });
|
|
97
|
-
generated = (0, mcfunction_1.generateDatapackWithStats)(optimizedIR, { optimizeCommands: true, mangle, scoreboardObjective: scoreboardObj });
|
|
98
|
-
stats.deadCodeRemoved =
|
|
99
|
-
(0, mcfunction_1.countMcfunctionCommands)(beforeDceGenerated.files) - (0, mcfunction_1.countMcfunctionCommands)(afterDceGenerated.files);
|
|
100
|
-
stats.licmHoists = generated.stats.licmHoists;
|
|
101
|
-
stats.licmLoopBodies = generated.stats.licmLoopBodies;
|
|
102
|
-
stats.cseRedundantReads = generated.stats.cseRedundantReads;
|
|
103
|
-
stats.cseArithmetic = generated.stats.cseArithmetic;
|
|
104
|
-
stats.setblockMergedCommands = generated.stats.setblockMergedCommands;
|
|
105
|
-
stats.setblockFillCommands = generated.stats.setblockFillCommands;
|
|
106
|
-
stats.setblockSavedCommands = generated.stats.setblockSavedCommands;
|
|
107
|
-
stats.totalCommandsBefore = (0, mcfunction_1.countMcfunctionCommands)(baselineGenerated.files);
|
|
108
|
-
stats.totalCommandsAfter = (0, mcfunction_1.countMcfunctionCommands)(generated.files);
|
|
109
|
-
optimizationStats = stats;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
optimizedIR = ir;
|
|
113
|
-
generated = (0, mcfunction_1.generateDatapackWithStats)(ir, { optimizeCommands: false, mangle, scoreboardObjective: scoreboardObj });
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
files: [...generated.files, ...generated.advancements],
|
|
117
|
-
advancements: generated.advancements,
|
|
118
|
-
ast,
|
|
119
|
-
ir: optimizedIR,
|
|
120
|
-
typeErrors,
|
|
121
|
-
warnings: [...dceResult.warnings, ...lowering.warnings],
|
|
122
|
-
stats: optimizationStats,
|
|
123
|
-
sourceMap: generated.sourceMap,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Check RedScript source code for errors without generating output.
|
|
128
|
-
*
|
|
129
|
-
* @param source - The RedScript source code
|
|
130
|
-
* @param namespace - Optional namespace
|
|
131
|
-
* @returns null if no errors, or an error object
|
|
132
|
-
*/
|
|
133
|
-
function check(source, namespace = 'redscript', filePath) {
|
|
134
|
-
try {
|
|
135
|
-
const preprocessedSource = (0, compile_1.preprocessSource)(source, { filePath });
|
|
136
|
-
const tokens = new lexer_1.Lexer(preprocessedSource, filePath).tokenize();
|
|
137
|
-
new parser_1.Parser(tokens, preprocessedSource, filePath).parse(namespace);
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
catch (err) {
|
|
141
|
-
return err;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// Re-export types and classes for advanced usage
|
|
145
|
-
var lexer_2 = require("./lexer");
|
|
146
|
-
Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return lexer_2.Lexer; } });
|
|
147
|
-
var parser_2 = require("./parser");
|
|
148
|
-
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return parser_2.Parser; } });
|
|
149
|
-
var typechecker_2 = require("./typechecker");
|
|
150
|
-
Object.defineProperty(exports, "TypeChecker", { enumerable: true, get: function () { return typechecker_2.TypeChecker; } });
|
|
151
|
-
var lowering_2 = require("./lowering");
|
|
152
|
-
Object.defineProperty(exports, "Lowering", { enumerable: true, get: function () { return lowering_2.Lowering; } });
|
|
153
|
-
var passes_2 = require("./optimizer/passes");
|
|
154
|
-
Object.defineProperty(exports, "optimize", { enumerable: true, get: function () { return passes_2.optimize; } });
|
|
155
|
-
var mcfunction_2 = require("./codegen/mcfunction");
|
|
156
|
-
Object.defineProperty(exports, "generateDatapack", { enumerable: true, get: function () { return mcfunction_2.generateDatapack; } });
|
|
157
|
-
var mc_validator_1 = require("./mc-validator");
|
|
158
|
-
Object.defineProperty(exports, "MCCommandValidator", { enumerable: true, get: function () { return mc_validator_1.MCCommandValidator; } });
|
|
159
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
// shim — delegates to dist/src/
|
|
2
|
+
module.exports = require('./src/index');
|
package/dist/lowering/index.js
CHANGED
|
@@ -2483,7 +2483,9 @@ class Lowering {
|
|
|
2483
2483
|
const strArgs = argResults.map(r => r.str);
|
|
2484
2484
|
const cmd = BUILTINS[name]?.(strArgs);
|
|
2485
2485
|
if (cmd) {
|
|
2486
|
-
|
|
2486
|
+
// Use \x01 sentinel (not literal '$') so resolveRaw doesn't treat the
|
|
2487
|
+
// MC macro prefix as a variable reference and allocate a fresh temp for it.
|
|
2488
|
+
this.builder.emitRaw(hasMacroArg ? `\x01${cmd}` : cmd);
|
|
2487
2489
|
}
|
|
2488
2490
|
return { kind: 'const', value: 0 };
|
|
2489
2491
|
}
|
|
@@ -3012,10 +3014,10 @@ class Lowering {
|
|
|
3012
3014
|
this.currentFnMacroParams.add(r.macroParam); });
|
|
3013
3015
|
const strs = argResults.map(r => r.str);
|
|
3014
3016
|
if (args.length === 2) {
|
|
3015
|
-
return { cmd:
|
|
3017
|
+
return { cmd: `\x01tp ${strs[0]} ${strs[1]}` };
|
|
3016
3018
|
}
|
|
3017
3019
|
if (args.length === 4) {
|
|
3018
|
-
return { cmd:
|
|
3020
|
+
return { cmd: `\x01tp ${strs[0]} ${strs[1]} ${strs[2]} ${strs[3]}` };
|
|
3019
3021
|
}
|
|
3020
3022
|
}
|
|
3021
3023
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const index_1 = require("../index");
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
// Note: watch command is tested manually as it's an interactive long-running process
|
|
41
|
+
describe('CLI API', () => {
|
|
42
|
+
describe('imports', () => {
|
|
43
|
+
it('compiles a file with imported helpers', () => {
|
|
44
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-imports-'));
|
|
45
|
+
const libPath = path.join(tempDir, 'lib.mcrs');
|
|
46
|
+
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
47
|
+
fs.writeFileSync(libPath, 'fn double(x: int) -> int { return x + x; }\n');
|
|
48
|
+
fs.writeFileSync(mainPath, 'import "./lib.mcrs"\n\nfn main() { let value: int = double(2); }\n');
|
|
49
|
+
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
50
|
+
const result = (0, index_1.compile)(source, { namespace: 'imports', filePath: mainPath });
|
|
51
|
+
expect(result.files.length).toBeGreaterThan(0);
|
|
52
|
+
// Verify both functions are compiled by checking output files
|
|
53
|
+
expect(result.files.some(f => f.path.includes('/double.mcfunction'))).toBe(true);
|
|
54
|
+
expect(result.files.some(f => f.path.includes('/main.mcfunction'))).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
it('deduplicates circular imports', () => {
|
|
57
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'redscript-circular-'));
|
|
58
|
+
const aPath = path.join(tempDir, 'a.mcrs');
|
|
59
|
+
const bPath = path.join(tempDir, 'b.mcrs');
|
|
60
|
+
const mainPath = path.join(tempDir, 'main.mcrs');
|
|
61
|
+
fs.writeFileSync(aPath, 'import "./b.mcrs"\n\nfn from_a() -> int { return 1; }\n');
|
|
62
|
+
fs.writeFileSync(bPath, 'import "./a.mcrs"\n\nfn from_b() -> int { return from_a(); }\n');
|
|
63
|
+
fs.writeFileSync(mainPath, 'import "./a.mcrs"\n\nfn main() { let value: int = from_b(); }\n');
|
|
64
|
+
const source = fs.readFileSync(mainPath, 'utf-8');
|
|
65
|
+
const result = (0, index_1.compile)(source, { namespace: 'circular', filePath: mainPath });
|
|
66
|
+
// Verify each function appears exactly once in output
|
|
67
|
+
expect(result.files.filter(f => f.path.endsWith('/from_a.mcfunction'))).toHaveLength(1);
|
|
68
|
+
expect(result.files.filter(f => f.path.endsWith('/from_b.mcfunction'))).toHaveLength(1);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('compile()', () => {
|
|
72
|
+
it('compiles simple source', () => {
|
|
73
|
+
const source = 'fn test() { say("hello"); }';
|
|
74
|
+
const result = (0, index_1.compile)(source, { namespace: 'mypack' });
|
|
75
|
+
expect(result.files.length).toBeGreaterThan(0);
|
|
76
|
+
});
|
|
77
|
+
it('generates correct file structure', () => {
|
|
78
|
+
const source = 'fn test() { say("hello"); }';
|
|
79
|
+
const result = (0, index_1.compile)(source, { namespace: 'game' });
|
|
80
|
+
const paths = result.files.map(f => f.path);
|
|
81
|
+
expect(paths).toContain('pack.mcmeta');
|
|
82
|
+
expect(paths).toContain('data/game/function/load.mcfunction');
|
|
83
|
+
expect(paths.some(p => p.includes('test.mcfunction'))).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe('check()', () => {
|
|
87
|
+
it('returns null for valid source', () => {
|
|
88
|
+
const source = 'fn test() { say("hello"); }';
|
|
89
|
+
const error = (0, index_1.check)(source);
|
|
90
|
+
expect(error).toBeNull();
|
|
91
|
+
});
|
|
92
|
+
it('returns error for invalid source', () => {
|
|
93
|
+
const source = 'fn test( { say("hello"); }'; // Missing )
|
|
94
|
+
const error = (0, index_1.check)(source);
|
|
95
|
+
expect(error).toBeInstanceOf(Error);
|
|
96
|
+
});
|
|
97
|
+
it('returns error for syntax errors', () => {
|
|
98
|
+
const source = 'fn test() { let x = ; }'; // Missing value
|
|
99
|
+
const error = (0, index_1.check)(source);
|
|
100
|
+
expect(error).toBeInstanceOf(Error);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|