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.
Files changed (269) hide show
  1. package/.claude/commands/build-test.md +10 -0
  2. package/.claude/commands/deploy-demo.md +12 -0
  3. package/.claude/commands/stage-status.md +13 -0
  4. package/.claude/settings.json +12 -0
  5. package/.github/workflows/ci.yml +1 -0
  6. package/CLAUDE.md +231 -0
  7. package/demo.gif +0 -0
  8. package/dist/cli.js +2 -554
  9. package/dist/compile.js +2 -266
  10. package/dist/index.js +2 -159
  11. package/dist/lowering/index.js +5 -3
  12. package/dist/src/__tests__/cli.test.d.ts +1 -0
  13. package/dist/src/__tests__/cli.test.js +104 -0
  14. package/dist/src/__tests__/codegen.test.d.ts +1 -0
  15. package/dist/src/__tests__/codegen.test.js +152 -0
  16. package/dist/src/__tests__/compile-all.test.d.ts +10 -0
  17. package/dist/src/__tests__/compile-all.test.js +108 -0
  18. package/dist/src/__tests__/dce.test.d.ts +1 -0
  19. package/dist/src/__tests__/dce.test.js +102 -0
  20. package/dist/src/__tests__/diagnostics.test.d.ts +4 -0
  21. package/dist/src/__tests__/diagnostics.test.js +177 -0
  22. package/dist/src/__tests__/e2e.test.d.ts +6 -0
  23. package/dist/src/__tests__/e2e.test.js +1789 -0
  24. package/dist/src/__tests__/entity-types.test.d.ts +1 -0
  25. package/dist/src/__tests__/entity-types.test.js +203 -0
  26. package/dist/src/__tests__/formatter.test.d.ts +1 -0
  27. package/dist/src/__tests__/formatter.test.js +40 -0
  28. package/dist/src/__tests__/lexer.test.d.ts +1 -0
  29. package/dist/src/__tests__/lexer.test.js +343 -0
  30. package/dist/src/__tests__/lowering.test.d.ts +1 -0
  31. package/dist/src/__tests__/lowering.test.js +1015 -0
  32. package/dist/src/__tests__/macro.test.d.ts +8 -0
  33. package/dist/src/__tests__/macro.test.js +306 -0
  34. package/dist/src/__tests__/mc-integration.test.d.ts +12 -0
  35. package/dist/src/__tests__/mc-integration.test.js +817 -0
  36. package/dist/src/__tests__/mc-syntax.test.d.ts +1 -0
  37. package/dist/src/__tests__/mc-syntax.test.js +124 -0
  38. package/dist/src/__tests__/nbt.test.d.ts +1 -0
  39. package/dist/src/__tests__/nbt.test.js +82 -0
  40. package/dist/src/__tests__/optimizer-advanced.test.d.ts +1 -0
  41. package/dist/src/__tests__/optimizer-advanced.test.js +124 -0
  42. package/dist/src/__tests__/optimizer.test.d.ts +1 -0
  43. package/dist/src/__tests__/optimizer.test.js +149 -0
  44. package/dist/src/__tests__/parser.test.d.ts +1 -0
  45. package/dist/src/__tests__/parser.test.js +807 -0
  46. package/dist/src/__tests__/repl.test.d.ts +1 -0
  47. package/dist/src/__tests__/repl.test.js +27 -0
  48. package/dist/src/__tests__/runtime.test.d.ts +1 -0
  49. package/dist/src/__tests__/runtime.test.js +289 -0
  50. package/dist/src/__tests__/stdlib-advanced.test.d.ts +4 -0
  51. package/dist/src/__tests__/stdlib-advanced.test.js +374 -0
  52. package/dist/src/__tests__/stdlib-bigint.test.d.ts +7 -0
  53. package/dist/src/__tests__/stdlib-bigint.test.js +426 -0
  54. package/dist/src/__tests__/stdlib-math.test.d.ts +7 -0
  55. package/dist/src/__tests__/stdlib-math.test.js +351 -0
  56. package/dist/src/__tests__/stdlib-vec.test.d.ts +4 -0
  57. package/dist/src/__tests__/stdlib-vec.test.js +263 -0
  58. package/dist/src/__tests__/structure-optimizer.test.d.ts +1 -0
  59. package/dist/src/__tests__/structure-optimizer.test.js +33 -0
  60. package/dist/src/__tests__/typechecker.test.d.ts +1 -0
  61. package/dist/src/__tests__/typechecker.test.js +552 -0
  62. package/dist/src/__tests__/var-allocator.test.d.ts +1 -0
  63. package/dist/src/__tests__/var-allocator.test.js +69 -0
  64. package/dist/src/ast/types.d.ts +515 -0
  65. package/dist/src/ast/types.js +9 -0
  66. package/dist/src/builtins/metadata.d.ts +36 -0
  67. package/dist/src/builtins/metadata.js +1014 -0
  68. package/dist/src/cli.d.ts +11 -0
  69. package/dist/src/cli.js +443 -0
  70. package/dist/src/codegen/cmdblock/index.d.ts +26 -0
  71. package/dist/src/codegen/cmdblock/index.js +45 -0
  72. package/dist/src/codegen/mcfunction/index.d.ts +40 -0
  73. package/dist/src/codegen/mcfunction/index.js +606 -0
  74. package/dist/src/codegen/structure/index.d.ts +24 -0
  75. package/dist/src/codegen/structure/index.js +279 -0
  76. package/dist/src/codegen/var-allocator.d.ts +45 -0
  77. package/dist/src/codegen/var-allocator.js +104 -0
  78. package/dist/src/compile.d.ts +37 -0
  79. package/dist/src/compile.js +165 -0
  80. package/dist/src/diagnostics/index.d.ts +44 -0
  81. package/dist/src/diagnostics/index.js +140 -0
  82. package/dist/src/events/types.d.ts +35 -0
  83. package/dist/src/events/types.js +59 -0
  84. package/dist/src/formatter/index.d.ts +1 -0
  85. package/dist/src/formatter/index.js +26 -0
  86. package/dist/src/index.d.ts +22 -0
  87. package/dist/src/index.js +45 -0
  88. package/dist/src/ir/builder.d.ts +33 -0
  89. package/dist/src/ir/builder.js +99 -0
  90. package/dist/src/ir/types.d.ts +132 -0
  91. package/dist/src/ir/types.js +15 -0
  92. package/dist/src/lexer/index.d.ts +37 -0
  93. package/dist/src/lexer/index.js +569 -0
  94. package/dist/src/lowering/index.d.ts +188 -0
  95. package/dist/src/lowering/index.js +3405 -0
  96. package/dist/src/mc-test/client.d.ts +128 -0
  97. package/dist/src/mc-test/client.js +174 -0
  98. package/dist/src/mc-test/runner.d.ts +28 -0
  99. package/dist/src/mc-test/runner.js +151 -0
  100. package/dist/src/mc-test/setup.d.ts +11 -0
  101. package/dist/src/mc-test/setup.js +98 -0
  102. package/dist/src/mc-validator/index.d.ts +17 -0
  103. package/dist/src/mc-validator/index.js +322 -0
  104. package/dist/src/nbt/index.d.ts +86 -0
  105. package/dist/src/nbt/index.js +250 -0
  106. package/dist/src/optimizer/commands.d.ts +38 -0
  107. package/dist/src/optimizer/commands.js +451 -0
  108. package/dist/src/optimizer/dce.d.ts +34 -0
  109. package/dist/src/optimizer/dce.js +639 -0
  110. package/dist/src/optimizer/passes.d.ts +34 -0
  111. package/dist/src/optimizer/passes.js +243 -0
  112. package/dist/src/optimizer/structure.d.ts +9 -0
  113. package/dist/src/optimizer/structure.js +356 -0
  114. package/dist/src/parser/index.d.ts +93 -0
  115. package/dist/src/parser/index.js +1687 -0
  116. package/dist/src/repl.d.ts +16 -0
  117. package/dist/src/repl.js +165 -0
  118. package/dist/src/runtime/index.d.ts +107 -0
  119. package/dist/src/runtime/index.js +1409 -0
  120. package/dist/src/typechecker/index.d.ts +61 -0
  121. package/dist/src/typechecker/index.js +1034 -0
  122. package/dist/src/types/entity-hierarchy.d.ts +29 -0
  123. package/dist/src/types/entity-hierarchy.js +107 -0
  124. package/dist/src2/__tests__/e2e/basic.test.d.ts +8 -0
  125. package/dist/src2/__tests__/e2e/basic.test.js +140 -0
  126. package/dist/src2/__tests__/e2e/macros.test.d.ts +9 -0
  127. package/dist/src2/__tests__/e2e/macros.test.js +182 -0
  128. package/dist/src2/__tests__/e2e/migrate.test.d.ts +13 -0
  129. package/dist/src2/__tests__/e2e/migrate.test.js +2739 -0
  130. package/dist/src2/__tests__/hir/desugar.test.d.ts +1 -0
  131. package/dist/src2/__tests__/hir/desugar.test.js +234 -0
  132. package/dist/src2/__tests__/lir/lower.test.d.ts +1 -0
  133. package/dist/src2/__tests__/lir/lower.test.js +559 -0
  134. package/dist/src2/__tests__/lir/types.test.d.ts +1 -0
  135. package/dist/src2/__tests__/lir/types.test.js +185 -0
  136. package/dist/src2/__tests__/lir/verify.test.d.ts +1 -0
  137. package/dist/src2/__tests__/lir/verify.test.js +221 -0
  138. package/dist/src2/__tests__/mir/arithmetic.test.d.ts +1 -0
  139. package/dist/src2/__tests__/mir/arithmetic.test.js +130 -0
  140. package/dist/src2/__tests__/mir/control-flow.test.d.ts +1 -0
  141. package/dist/src2/__tests__/mir/control-flow.test.js +205 -0
  142. package/dist/src2/__tests__/mir/verify.test.d.ts +1 -0
  143. package/dist/src2/__tests__/mir/verify.test.js +223 -0
  144. package/dist/src2/__tests__/optimizer/block_merge.test.d.ts +1 -0
  145. package/dist/src2/__tests__/optimizer/block_merge.test.js +78 -0
  146. package/dist/src2/__tests__/optimizer/branch_simplify.test.d.ts +1 -0
  147. package/dist/src2/__tests__/optimizer/branch_simplify.test.js +58 -0
  148. package/dist/src2/__tests__/optimizer/constant_fold.test.d.ts +1 -0
  149. package/dist/src2/__tests__/optimizer/constant_fold.test.js +131 -0
  150. package/dist/src2/__tests__/optimizer/copy_prop.test.d.ts +1 -0
  151. package/dist/src2/__tests__/optimizer/copy_prop.test.js +91 -0
  152. package/dist/src2/__tests__/optimizer/dce.test.d.ts +1 -0
  153. package/dist/src2/__tests__/optimizer/dce.test.js +76 -0
  154. package/dist/src2/__tests__/optimizer/pipeline.test.d.ts +1 -0
  155. package/dist/src2/__tests__/optimizer/pipeline.test.js +102 -0
  156. package/dist/src2/emit/compile.d.ts +19 -0
  157. package/dist/src2/emit/compile.js +80 -0
  158. package/dist/src2/emit/index.d.ts +17 -0
  159. package/dist/src2/emit/index.js +172 -0
  160. package/dist/src2/hir/lower.d.ts +15 -0
  161. package/dist/src2/hir/lower.js +378 -0
  162. package/dist/src2/hir/types.d.ts +373 -0
  163. package/dist/src2/hir/types.js +16 -0
  164. package/dist/src2/lir/lower.d.ts +15 -0
  165. package/dist/src2/lir/lower.js +453 -0
  166. package/dist/src2/lir/types.d.ts +136 -0
  167. package/dist/src2/lir/types.js +11 -0
  168. package/dist/src2/lir/verify.d.ts +14 -0
  169. package/dist/src2/lir/verify.js +113 -0
  170. package/dist/src2/mir/lower.d.ts +9 -0
  171. package/dist/src2/mir/lower.js +1030 -0
  172. package/dist/src2/mir/macro.d.ts +22 -0
  173. package/dist/src2/mir/macro.js +168 -0
  174. package/dist/src2/mir/types.d.ts +183 -0
  175. package/dist/src2/mir/types.js +11 -0
  176. package/dist/src2/mir/verify.d.ts +16 -0
  177. package/dist/src2/mir/verify.js +216 -0
  178. package/dist/src2/optimizer/block_merge.d.ts +12 -0
  179. package/dist/src2/optimizer/block_merge.js +84 -0
  180. package/dist/src2/optimizer/branch_simplify.d.ts +9 -0
  181. package/dist/src2/optimizer/branch_simplify.js +28 -0
  182. package/dist/src2/optimizer/constant_fold.d.ts +10 -0
  183. package/dist/src2/optimizer/constant_fold.js +85 -0
  184. package/dist/src2/optimizer/copy_prop.d.ts +9 -0
  185. package/dist/src2/optimizer/copy_prop.js +113 -0
  186. package/dist/src2/optimizer/dce.d.ts +8 -0
  187. package/dist/src2/optimizer/dce.js +155 -0
  188. package/dist/src2/optimizer/pipeline.d.ts +10 -0
  189. package/dist/src2/optimizer/pipeline.js +42 -0
  190. package/dist/tsconfig.tsbuildinfo +1 -0
  191. package/docs/compiler-pipeline-redesign.md +2243 -0
  192. package/docs/optimization-ideas.md +1076 -0
  193. package/editors/vscode/package-lock.json +3 -3
  194. package/editors/vscode/package.json +1 -1
  195. package/jest.config.js +1 -1
  196. package/package.json +6 -5
  197. package/scripts/postbuild.js +15 -0
  198. package/src/__tests__/cli.test.ts +8 -220
  199. package/src/__tests__/dce.test.ts +11 -56
  200. package/src/__tests__/diagnostics.test.ts +59 -38
  201. package/src/__tests__/mc-integration.test.ts +1 -2
  202. package/src/ast/types.ts +6 -1
  203. package/src/cli.ts +29 -156
  204. package/src/compile.ts +6 -162
  205. package/src/index.ts +14 -178
  206. package/src/mc-test/runner.ts +4 -3
  207. package/src/parser/index.ts +1 -1
  208. package/src/repl.ts +1 -1
  209. package/src/runtime/index.ts +1 -1
  210. package/src2/__tests__/e2e/basic.test.ts +154 -0
  211. package/src2/__tests__/e2e/macros.test.ts +199 -0
  212. package/src2/__tests__/e2e/migrate.test.ts +3008 -0
  213. package/src2/__tests__/hir/desugar.test.ts +263 -0
  214. package/src2/__tests__/lir/lower.test.ts +619 -0
  215. package/src2/__tests__/lir/types.test.ts +207 -0
  216. package/src2/__tests__/lir/verify.test.ts +249 -0
  217. package/src2/__tests__/mir/arithmetic.test.ts +156 -0
  218. package/src2/__tests__/mir/control-flow.test.ts +242 -0
  219. package/src2/__tests__/mir/verify.test.ts +254 -0
  220. package/src2/__tests__/optimizer/block_merge.test.ts +84 -0
  221. package/src2/__tests__/optimizer/branch_simplify.test.ts +64 -0
  222. package/src2/__tests__/optimizer/constant_fold.test.ts +145 -0
  223. package/src2/__tests__/optimizer/copy_prop.test.ts +99 -0
  224. package/src2/__tests__/optimizer/dce.test.ts +83 -0
  225. package/src2/__tests__/optimizer/pipeline.test.ts +116 -0
  226. package/src2/emit/compile.ts +99 -0
  227. package/src2/emit/index.ts +222 -0
  228. package/src2/hir/lower.ts +428 -0
  229. package/src2/hir/types.ts +216 -0
  230. package/src2/lir/lower.ts +556 -0
  231. package/src2/lir/types.ts +109 -0
  232. package/src2/lir/verify.ts +129 -0
  233. package/src2/mir/lower.ts +1160 -0
  234. package/src2/mir/macro.ts +167 -0
  235. package/src2/mir/types.ts +106 -0
  236. package/src2/mir/verify.ts +218 -0
  237. package/src2/optimizer/block_merge.ts +93 -0
  238. package/src2/optimizer/branch_simplify.ts +27 -0
  239. package/src2/optimizer/constant_fold.ts +88 -0
  240. package/src2/optimizer/copy_prop.ts +106 -0
  241. package/src2/optimizer/dce.ts +133 -0
  242. package/src2/optimizer/pipeline.ts +44 -0
  243. package/tsconfig.json +2 -2
  244. package/src/__tests__/codegen.test.ts +0 -161
  245. package/src/__tests__/e2e.test.ts +0 -2039
  246. package/src/__tests__/entity-types.test.ts +0 -236
  247. package/src/__tests__/lowering.test.ts +0 -1185
  248. package/src/__tests__/macro.test.ts +0 -343
  249. package/src/__tests__/nbt.test.ts +0 -58
  250. package/src/__tests__/optimizer-advanced.test.ts +0 -144
  251. package/src/__tests__/optimizer.test.ts +0 -162
  252. package/src/__tests__/runtime.test.ts +0 -305
  253. package/src/__tests__/stdlib-advanced.test.ts +0 -379
  254. package/src/__tests__/stdlib-bigint.test.ts +0 -427
  255. package/src/__tests__/stdlib-math.test.ts +0 -374
  256. package/src/__tests__/stdlib-vec.test.ts +0 -259
  257. package/src/__tests__/structure-optimizer.test.ts +0 -38
  258. package/src/__tests__/var-allocator.test.ts +0 -75
  259. package/src/codegen/cmdblock/index.ts +0 -63
  260. package/src/codegen/mcfunction/index.ts +0 -662
  261. package/src/codegen/structure/index.ts +0 -346
  262. package/src/codegen/var-allocator.ts +0 -104
  263. package/src/ir/builder.ts +0 -116
  264. package/src/ir/types.ts +0 -134
  265. package/src/lowering/index.ts +0 -3876
  266. package/src/optimizer/commands.ts +0 -534
  267. package/src/optimizer/dce.ts +0 -679
  268. package/src/optimizer/passes.ts +0 -250
  269. package/src/optimizer/structure.ts +0 -450
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * RedScript CLI
4
+ *
5
+ * Usage:
6
+ * redscript compile <file> [-o <out>] [--namespace <ns>]
7
+ * redscript check <file>
8
+ * redscript repl
9
+ * redscript version
10
+ */
11
+ export {};
@@ -0,0 +1,443 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * RedScript CLI
5
+ *
6
+ * Usage:
7
+ * redscript compile <file> [-o <out>] [--namespace <ns>]
8
+ * redscript check <file>
9
+ * redscript repl
10
+ * redscript version
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ const index_1 = require("./index");
47
+ const diagnostics_1 = require("./diagnostics");
48
+ const repl_1 = require("./repl");
49
+ const metadata_1 = require("./builtins/metadata");
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const https = __importStar(require("https"));
53
+ const child_process_1 = require("child_process");
54
+ // Parse command line arguments
55
+ const args = process.argv.slice(2);
56
+ function printUsage() {
57
+ console.log(`
58
+ RedScript Compiler v2
59
+
60
+ Usage:
61
+ redscript compile <file> [-o <out>] [--namespace <ns>]
62
+ redscript watch <dir> [-o <outdir>] [--namespace <ns>] [--hot-reload <url>]
63
+ redscript check <file>
64
+ redscript fmt <file.mcrs> [file2.mcrs ...]
65
+ redscript generate-dts [-o <file>]
66
+ redscript repl
67
+ redscript version
68
+
69
+ Commands:
70
+ compile Compile a RedScript file to a Minecraft datapack
71
+ watch Watch a directory for .mcrs file changes, recompile, and hot reload
72
+ check Check a RedScript file for errors without generating output
73
+ fmt Auto-format RedScript source files
74
+ generate-dts Generate builtin function declaration file (builtins.d.mcrs)
75
+ repl Start an interactive RedScript REPL
76
+ version Print the RedScript version
77
+ upgrade Upgrade to the latest version (npm install -g redscript-mc@latest)
78
+
79
+ Options:
80
+ -o, --output <path> Output directory or file path
81
+ --namespace <ns> Datapack namespace (default: derived from filename)
82
+ --hot-reload <url> After each successful compile, POST to <url>/reload
83
+ (use with redscript-testharness; e.g. http://localhost:25561)
84
+ -h, --help Show this help message
85
+ `);
86
+ }
87
+ function getLocalVersion() {
88
+ const packagePath = path.join(__dirname, '..', 'package.json');
89
+ try {
90
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
91
+ return pkg.version ?? '0.0.0';
92
+ }
93
+ catch {
94
+ return '0.0.0';
95
+ }
96
+ }
97
+ function printVersion() {
98
+ console.log(`RedScript v${getLocalVersion()}`);
99
+ }
100
+ /** Fetch latest version from npm registry (non-blocking, best-effort). */
101
+ function fetchLatestVersion() {
102
+ return new Promise(resolve => {
103
+ const req = https.get('https://registry.npmjs.org/redscript-mc/latest', { timeout: 3000 }, res => {
104
+ let data = '';
105
+ res.on('data', chunk => { data += chunk; });
106
+ res.on('end', () => {
107
+ try {
108
+ const json = JSON.parse(data);
109
+ resolve(json.version ?? null);
110
+ }
111
+ catch {
112
+ resolve(null);
113
+ }
114
+ });
115
+ });
116
+ req.on('error', () => resolve(null));
117
+ req.on('timeout', () => { req.destroy(); resolve(null); });
118
+ });
119
+ }
120
+ /** Compare semver strings. Returns true if b > a. */
121
+ function isNewer(current, latest) {
122
+ const parse = (v) => v.replace(/^v/, '').split('.').map(Number);
123
+ const [ca, cb, cc] = parse(current);
124
+ const [la, lb, lc] = parse(latest);
125
+ if (la !== ca)
126
+ return la > ca;
127
+ if (lb !== cb)
128
+ return lb > cb;
129
+ return lc > cc;
130
+ }
131
+ /**
132
+ * Check for a newer version and print a notice if one exists.
133
+ * Runs in background — does NOT block normal CLI operation.
134
+ */
135
+ async function checkForUpdates(silent = false) {
136
+ const current = getLocalVersion();
137
+ const latest = await fetchLatestVersion();
138
+ if (latest && isNewer(current, latest)) {
139
+ console.log(`\n💡 New version available: v${current} → v${latest}`);
140
+ console.log(` Run: redscript upgrade\n`);
141
+ }
142
+ else if (!silent && latest) {
143
+ // Only print when explicitly running 'version' or 'upgrade'
144
+ // No output for normal commands — keep startup noise-free
145
+ }
146
+ }
147
+ /** Run npm install -g to upgrade to latest. */
148
+ function upgradeCommand() {
149
+ const current = getLocalVersion();
150
+ console.log(`Current version: v${current}`);
151
+ console.log('Checking latest version...');
152
+ fetchLatestVersion().then(latest => {
153
+ if (!latest) {
154
+ console.error('Could not fetch latest version from npm.');
155
+ process.exit(1);
156
+ }
157
+ if (!isNewer(current, latest)) {
158
+ console.log(`✅ Already up to date (v${current})`);
159
+ return;
160
+ }
161
+ console.log(`Upgrading v${current} → v${latest}...`);
162
+ try {
163
+ (0, child_process_1.execSync)('npm install -g redscript-mc@latest', { stdio: 'inherit' });
164
+ console.log(`✅ Upgraded to v${latest}`);
165
+ }
166
+ catch {
167
+ console.error('Upgrade failed. Try manually: npm install -g redscript-mc@latest');
168
+ process.exit(1);
169
+ }
170
+ });
171
+ }
172
+ function parseArgs(args) {
173
+ const result = {};
174
+ let i = 0;
175
+ while (i < args.length) {
176
+ const arg = args[i];
177
+ if (arg === '-h' || arg === '--help') {
178
+ result.help = true;
179
+ i++;
180
+ }
181
+ else if (arg === '-o' || arg === '--output') {
182
+ result.output = args[++i];
183
+ i++;
184
+ }
185
+ else if (arg === '--namespace') {
186
+ result.namespace = args[++i];
187
+ i++;
188
+ }
189
+ else if (arg === '--hot-reload') {
190
+ result.hotReload = args[++i];
191
+ i++;
192
+ }
193
+ else if (!result.command) {
194
+ result.command = arg;
195
+ i++;
196
+ }
197
+ else if (!result.file) {
198
+ result.file = arg;
199
+ i++;
200
+ }
201
+ else {
202
+ i++;
203
+ }
204
+ }
205
+ return result;
206
+ }
207
+ function deriveNamespace(filePath) {
208
+ const basename = path.basename(filePath, path.extname(filePath));
209
+ // Convert to valid identifier: lowercase, replace non-alphanumeric with underscore
210
+ return basename.toLowerCase().replace(/[^a-z0-9]/g, '_');
211
+ }
212
+ function compileCommand(file, output, namespace) {
213
+ // Read source file
214
+ if (!fs.existsSync(file)) {
215
+ console.error(`Error: File not found: ${file}`);
216
+ process.exit(1);
217
+ }
218
+ const source = fs.readFileSync(file, 'utf-8');
219
+ try {
220
+ const result = (0, index_1.compile)(source, { namespace, filePath: file });
221
+ for (const w of result.warnings) {
222
+ console.error(`Warning: ${w}`);
223
+ }
224
+ // Create output directory
225
+ fs.mkdirSync(output, { recursive: true });
226
+ // Write all files
227
+ for (const dataFile of result.files) {
228
+ const filePath = path.join(output, dataFile.path);
229
+ const dir = path.dirname(filePath);
230
+ fs.mkdirSync(dir, { recursive: true });
231
+ fs.writeFileSync(filePath, dataFile.content);
232
+ }
233
+ console.log(`✓ Compiled ${file} to ${output}/`);
234
+ console.log(` Namespace: ${namespace}`);
235
+ console.log(` Files: ${result.files.length}`);
236
+ }
237
+ catch (err) {
238
+ console.error((0, diagnostics_1.formatError)(err, source));
239
+ process.exit(1);
240
+ }
241
+ }
242
+ function checkCommand(file) {
243
+ // Read source file
244
+ if (!fs.existsSync(file)) {
245
+ console.error(`Error: File not found: ${file}`);
246
+ process.exit(1);
247
+ }
248
+ const source = fs.readFileSync(file, 'utf-8');
249
+ const error = (0, index_1.check)(source, 'redscript', file);
250
+ if (error) {
251
+ console.error((0, diagnostics_1.formatError)(error, source));
252
+ process.exit(1);
253
+ }
254
+ console.log(`✓ ${file} is valid`);
255
+ }
256
+ async function hotReload(url) {
257
+ try {
258
+ const res = await fetch(`${url}/reload`, { method: 'POST' });
259
+ if (res.ok) {
260
+ console.log(`🔄 Hot reload sent → ${url}`);
261
+ }
262
+ else {
263
+ console.warn(`⚠ Hot reload failed: HTTP ${res.status}`);
264
+ }
265
+ }
266
+ catch (e) {
267
+ console.warn(`⚠ Hot reload failed (is the server running?): ${e.message}`);
268
+ }
269
+ }
270
+ function watchCommand(dir, output, namespace, hotReloadUrl) {
271
+ // Check if directory exists
272
+ if (!fs.existsSync(dir)) {
273
+ console.error(`Error: Directory not found: ${dir}`);
274
+ process.exit(1);
275
+ }
276
+ const stat = fs.statSync(dir);
277
+ if (!stat.isDirectory()) {
278
+ console.error(`Error: ${dir} is not a directory`);
279
+ process.exit(1);
280
+ }
281
+ console.log(`👁 Watching ${dir} for .mcrs file changes...`);
282
+ console.log(` Output: ${output}`);
283
+ if (hotReloadUrl)
284
+ console.log(` Hot reload: ${hotReloadUrl}`);
285
+ console.log(` Press Ctrl+C to stop\n`);
286
+ // Debounce timer
287
+ let debounceTimer = null;
288
+ // Compile all .mcrs files in directory
289
+ async function compileAll() {
290
+ const files = findRsFiles(dir);
291
+ if (files.length === 0) {
292
+ console.log(`⚠ No .mcrs files found in ${dir}`);
293
+ return;
294
+ }
295
+ let hasErrors = false;
296
+ for (const file of files) {
297
+ let source = '';
298
+ try {
299
+ source = fs.readFileSync(file, 'utf-8');
300
+ const ns = namespace ?? deriveNamespace(file);
301
+ const result = (0, index_1.compile)(source, { namespace: ns, filePath: file });
302
+ for (const w of result.warnings) {
303
+ console.error(`Warning: ${w}`);
304
+ }
305
+ // Create output directory
306
+ fs.mkdirSync(output, { recursive: true });
307
+ // Write all files
308
+ for (const dataFile of result.files) {
309
+ const filePath = path.join(output, dataFile.path);
310
+ const fileDir = path.dirname(filePath);
311
+ fs.mkdirSync(fileDir, { recursive: true });
312
+ fs.writeFileSync(filePath, dataFile.content);
313
+ }
314
+ const timestamp = new Date().toLocaleTimeString();
315
+ console.log(`✓ [${timestamp}] Compiled ${file} (${result.files.length} files)`);
316
+ }
317
+ catch (err) {
318
+ hasErrors = true;
319
+ const timestamp = new Date().toLocaleTimeString();
320
+ console.error(`✗ [${timestamp}] ${(0, diagnostics_1.formatError)(err, source)}`);
321
+ }
322
+ }
323
+ if (!hasErrors) {
324
+ if (hotReloadUrl)
325
+ await hotReload(hotReloadUrl);
326
+ console.log('');
327
+ }
328
+ }
329
+ // Find all .mcrs files recursively
330
+ function findRsFiles(directory) {
331
+ const results = [];
332
+ const entries = fs.readdirSync(directory, { withFileTypes: true });
333
+ for (const entry of entries) {
334
+ const fullPath = path.join(directory, entry.name);
335
+ if (entry.isDirectory()) {
336
+ results.push(...findRsFiles(fullPath));
337
+ }
338
+ else if (entry.isFile() && entry.name.endsWith('.mcrs')) {
339
+ results.push(fullPath);
340
+ }
341
+ }
342
+ return results;
343
+ }
344
+ // Initial compile
345
+ void compileAll();
346
+ // Watch for changes
347
+ fs.watch(dir, { recursive: true }, (eventType, filename) => {
348
+ if (filename && filename.endsWith('.mcrs')) {
349
+ // Debounce rapid changes
350
+ if (debounceTimer) {
351
+ clearTimeout(debounceTimer);
352
+ }
353
+ debounceTimer = setTimeout(() => {
354
+ console.log(`📝 Change detected: ${filename}`);
355
+ void compileAll();
356
+ }, 100);
357
+ }
358
+ });
359
+ }
360
+ // Main
361
+ const parsed = parseArgs(args);
362
+ async function main() {
363
+ if (parsed.help || !parsed.command) {
364
+ printUsage();
365
+ process.exit(parsed.help ? 0 : 1);
366
+ }
367
+ // Background update check — non-blocking, only shows notice if newer version exists
368
+ // Skip for repl/upgrade/version to avoid double-printing
369
+ const noCheckCmds = new Set(['upgrade', 'update', 'version', 'repl']);
370
+ if (!noCheckCmds.has(parsed.command ?? '')) {
371
+ checkForUpdates().catch(() => { });
372
+ }
373
+ switch (parsed.command) {
374
+ case 'compile':
375
+ if (!parsed.file) {
376
+ console.error('Error: No input file specified');
377
+ printUsage();
378
+ process.exit(1);
379
+ }
380
+ {
381
+ const namespace = parsed.namespace ?? deriveNamespace(parsed.file);
382
+ const output = parsed.output ?? './dist';
383
+ compileCommand(parsed.file, output, namespace);
384
+ }
385
+ break;
386
+ case 'watch':
387
+ if (!parsed.file) {
388
+ console.error('Error: No directory specified');
389
+ printUsage();
390
+ process.exit(1);
391
+ }
392
+ watchCommand(parsed.file, parsed.output ?? './dist', parsed.namespace, parsed.hotReload);
393
+ break;
394
+ case 'check':
395
+ if (!parsed.file) {
396
+ console.error('Error: No input file specified');
397
+ printUsage();
398
+ process.exit(1);
399
+ }
400
+ checkCommand(parsed.file);
401
+ break;
402
+ case 'fmt':
403
+ case 'format': {
404
+ const files = args.filter(a => a.endsWith('.mcrs'));
405
+ if (files.length === 0) {
406
+ console.error('Usage: redscript fmt <file.mcrs> [file2.mcrs ...]');
407
+ process.exit(1);
408
+ }
409
+ const { format } = require('./formatter');
410
+ for (const file of files) {
411
+ const content = fs.readFileSync(file, 'utf8');
412
+ const formatted = format(content);
413
+ fs.writeFileSync(file, formatted);
414
+ console.log(`Formatted: ${file}`);
415
+ }
416
+ break;
417
+ }
418
+ case 'generate-dts': {
419
+ const output = parsed.output ?? 'builtins.d.mcrs';
420
+ const dtsContent = (0, metadata_1.generateDts)();
421
+ fs.writeFileSync(output, dtsContent, 'utf-8');
422
+ console.log(`Generated ${output}`);
423
+ break;
424
+ }
425
+ case 'repl':
426
+ await (0, repl_1.startRepl)(parsed.namespace ?? 'repl');
427
+ break;
428
+ case 'version':
429
+ printVersion();
430
+ await checkForUpdates();
431
+ break;
432
+ case 'upgrade':
433
+ case 'update':
434
+ upgradeCommand();
435
+ break;
436
+ default:
437
+ console.error(`Error: Unknown command '${parsed.command}'`);
438
+ printUsage();
439
+ process.exit(1);
440
+ }
441
+ }
442
+ void main();
443
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Command Block Target
3
+ *
4
+ * Generates a JSON structure representing command blocks that can be
5
+ * placed in Minecraft to run the compiled datapack.
6
+ */
7
+ export interface CommandBlock {
8
+ type: 'repeat' | 'impulse' | 'chain';
9
+ command: string;
10
+ pos: [number, number, number];
11
+ auto?: boolean;
12
+ conditional?: boolean;
13
+ }
14
+ export interface CommandBlockStructure {
15
+ format: 'redscript-cmdblock-v1';
16
+ namespace: string;
17
+ blocks: CommandBlock[];
18
+ }
19
+ /**
20
+ * Generate a command block structure JSON for a given namespace.
21
+ *
22
+ * Creates:
23
+ * - 1 × Repeat block: function <namespace>:__tick
24
+ * - 1 × Impulse block (auto): function <namespace>:__load
25
+ */
26
+ export declare function generateCommandBlocks(namespace: string, hasTick: boolean, hasLoad: boolean): CommandBlockStructure;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Command Block Target
4
+ *
5
+ * Generates a JSON structure representing command blocks that can be
6
+ * placed in Minecraft to run the compiled datapack.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.generateCommandBlocks = generateCommandBlocks;
10
+ /**
11
+ * Generate a command block structure JSON for a given namespace.
12
+ *
13
+ * Creates:
14
+ * - 1 × Repeat block: function <namespace>:__tick
15
+ * - 1 × Impulse block (auto): function <namespace>:__load
16
+ */
17
+ function generateCommandBlocks(namespace, hasTick, hasLoad) {
18
+ const blocks = [];
19
+ let x = 0;
20
+ // Load block - impulse with auto (runs once when placed)
21
+ if (hasLoad) {
22
+ blocks.push({
23
+ type: 'impulse',
24
+ command: `function ${namespace}:__load`,
25
+ pos: [x, 0, 0],
26
+ auto: true,
27
+ });
28
+ x++;
29
+ }
30
+ // Tick block - repeat (runs every tick)
31
+ if (hasTick) {
32
+ blocks.push({
33
+ type: 'repeat',
34
+ command: `function ${namespace}:__tick`,
35
+ pos: [x, 0, 0],
36
+ });
37
+ x++;
38
+ }
39
+ return {
40
+ format: 'redscript-cmdblock-v1',
41
+ namespace,
42
+ blocks,
43
+ };
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Code generator: IR → mcfunction datapack
3
+ *
4
+ * Output structure:
5
+ * <namespace>/
6
+ * functions/
7
+ * <fn_name>.mcfunction
8
+ * <fn_name>/<block_label>.mcfunction (for control-flow continuations)
9
+ * load.mcfunction (objective setup)
10
+ *
11
+ * Variable mapping:
12
+ * scoreboard objective: "rs"
13
+ * fake player: "$<varname>"
14
+ * temporaries: "$_0", "$_1", ...
15
+ * return value: "$ret"
16
+ * parameters: "$p0", "$p1", ...
17
+ */
18
+ import type { IRModule } from '../../ir/types';
19
+ import { type OptimizationStats } from '../../optimizer/commands';
20
+ export interface DatapackFile {
21
+ path: string;
22
+ content: string;
23
+ }
24
+ export interface DatapackGenerationResult {
25
+ files: DatapackFile[];
26
+ advancements: DatapackFile[];
27
+ stats: OptimizationStats;
28
+ sourceMap?: Record<string, string>;
29
+ }
30
+ export interface DatapackGenerationOptions {
31
+ optimizeCommands?: boolean;
32
+ mangle?: boolean;
33
+ /** Scoreboard objective used for all scoreboard variables.
34
+ * Defaults to 'rs'. Override per-datapack to avoid collisions
35
+ * when multiple RedScript datapacks are loaded simultaneously. */
36
+ scoreboardObjective?: string;
37
+ }
38
+ export declare function countMcfunctionCommands(files: DatapackFile[]): number;
39
+ export declare function generateDatapackWithStats(module: IRModule, options?: DatapackGenerationOptions): DatapackGenerationResult;
40
+ export declare function generateDatapack(module: IRModule): DatapackFile[];