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,172 @@
1
+ "use strict";
2
+ /**
3
+ * Stage 7 — LIR → .mcfunction Emission
4
+ *
5
+ * Converts a LIRModule into DatapackFile[] representing a Minecraft datapack.
6
+ * Each LIRFunction becomes a .mcfunction file under data/<ns>/function/.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.emit = emit;
10
+ // ---------------------------------------------------------------------------
11
+ // Public API
12
+ // ---------------------------------------------------------------------------
13
+ function emit(module, options) {
14
+ const { namespace } = options;
15
+ const tickFns = options.tickFunctions ?? [];
16
+ const loadFns = options.loadFunctions ?? [];
17
+ const objective = module.objective;
18
+ const files = [];
19
+ // pack.mcmeta
20
+ files.push({
21
+ path: 'pack.mcmeta',
22
+ content: JSON.stringify({
23
+ pack: { pack_format: 26, description: `RedScript datapack: ${namespace}` },
24
+ }, null, 2) + '\n',
25
+ });
26
+ // load.mcfunction — creates the scoreboard objective
27
+ const loadCmds = [`scoreboard objectives add ${objective} dummy`];
28
+ files.push({
29
+ path: `data/${namespace}/function/load.mcfunction`,
30
+ content: loadCmds.join('\n') + '\n',
31
+ });
32
+ // Each LIR function → .mcfunction file
33
+ for (const fn of module.functions) {
34
+ const lines = emitFunction(fn, namespace, objective);
35
+ const fnPath = fnNameToPath(fn.name, namespace);
36
+ files.push({ path: fnPath, content: lines.join('\n') + '\n' });
37
+ }
38
+ // Tag files for tick/load
39
+ if (loadFns.length > 0 || true) {
40
+ // Always include load.json — it must reference the load.mcfunction
41
+ const loadValues = [`${namespace}:load`, ...loadFns.map(fn => `${namespace}:${fn}`)];
42
+ files.push({
43
+ path: 'data/minecraft/tags/function/load.json',
44
+ content: JSON.stringify({ values: loadValues }, null, 2) + '\n',
45
+ });
46
+ }
47
+ if (tickFns.length > 0) {
48
+ const tickValues = tickFns.map(fn => `${namespace}:${fn}`);
49
+ files.push({
50
+ path: 'data/minecraft/tags/function/tick.json',
51
+ content: JSON.stringify({ values: tickValues }, null, 2) + '\n',
52
+ });
53
+ }
54
+ return files;
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Function emission
58
+ // ---------------------------------------------------------------------------
59
+ function emitFunction(fn, namespace, objective) {
60
+ const lines = [];
61
+ for (const instr of fn.instructions) {
62
+ lines.push(emitInstr(instr, namespace, objective));
63
+ }
64
+ return lines;
65
+ }
66
+ function fnNameToPath(name, namespace) {
67
+ // LIR function names may contain :: for methods — convert to /
68
+ const mcName = name.replace(/::/g, '/').toLowerCase();
69
+ return `data/${namespace}/function/${mcName}.mcfunction`;
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Instruction emission
73
+ // ---------------------------------------------------------------------------
74
+ function emitInstr(instr, ns, obj) {
75
+ switch (instr.kind) {
76
+ case 'score_set':
77
+ return `scoreboard players set ${slot(instr.dst)} ${instr.value}`;
78
+ case 'score_copy':
79
+ return `scoreboard players operation ${slot(instr.dst)} = ${slot(instr.src)}`;
80
+ case 'score_add':
81
+ return `scoreboard players operation ${slot(instr.dst)} += ${slot(instr.src)}`;
82
+ case 'score_sub':
83
+ return `scoreboard players operation ${slot(instr.dst)} -= ${slot(instr.src)}`;
84
+ case 'score_mul':
85
+ return `scoreboard players operation ${slot(instr.dst)} *= ${slot(instr.src)}`;
86
+ case 'score_div':
87
+ return `scoreboard players operation ${slot(instr.dst)} /= ${slot(instr.src)}`;
88
+ case 'score_mod':
89
+ return `scoreboard players operation ${slot(instr.dst)} %= ${slot(instr.src)}`;
90
+ case 'score_min':
91
+ return `scoreboard players operation ${slot(instr.dst)} < ${slot(instr.src)}`;
92
+ case 'score_max':
93
+ return `scoreboard players operation ${slot(instr.dst)} > ${slot(instr.src)}`;
94
+ case 'score_swap':
95
+ return `scoreboard players operation ${slot(instr.a)} >< ${slot(instr.b)}`;
96
+ case 'store_cmd_to_score':
97
+ return `execute store result score ${slot(instr.dst)} run ${emitInstr(instr.cmd, ns, obj)}`;
98
+ case 'store_score_to_nbt':
99
+ return `execute store result storage ${instr.ns} ${instr.path} ${instr.type} ${instr.scale} run scoreboard players get ${slot(instr.src)}`;
100
+ case 'store_nbt_to_score':
101
+ return `execute store result score ${slot(instr.dst)} run data get storage ${instr.ns} ${instr.path} ${instr.scale}`;
102
+ case 'nbt_set_literal':
103
+ return `data modify storage ${instr.ns} ${instr.path} set value ${instr.value}`;
104
+ case 'nbt_copy':
105
+ return `data modify storage ${instr.dstNs} ${instr.dstPath} set from storage ${instr.srcNs} ${instr.srcPath}`;
106
+ case 'call':
107
+ return `function ${instr.fn}`;
108
+ case 'call_macro':
109
+ return `function ${instr.fn} with storage ${instr.storage}`;
110
+ case 'call_if_matches':
111
+ return `execute if score ${slot(instr.slot)} matches ${instr.range} run function ${instr.fn}`;
112
+ case 'call_unless_matches':
113
+ return `execute unless score ${slot(instr.slot)} matches ${instr.range} run function ${instr.fn}`;
114
+ case 'call_if_score':
115
+ return `execute if score ${slot(instr.a)} ${cmpToMC(instr.op)} ${slot(instr.b)} run function ${instr.fn}`;
116
+ case 'call_unless_score':
117
+ return `execute unless score ${slot(instr.a)} ${cmpToMC(instr.op)} ${slot(instr.b)} run function ${instr.fn}`;
118
+ case 'call_context': {
119
+ const subcmds = instr.subcommands.map(emitSubcmd).join(' ');
120
+ return `execute ${subcmds} run function ${instr.fn}`;
121
+ }
122
+ case 'return_value':
123
+ return `scoreboard players operation $ret ${instr.slot.obj} = ${slot(instr.slot)}`;
124
+ case 'macro_line':
125
+ return `$${instr.template}`;
126
+ case 'raw':
127
+ return instr.cmd;
128
+ }
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ // Helpers
132
+ // ---------------------------------------------------------------------------
133
+ function slot(s) {
134
+ return `${s.player} ${s.obj}`;
135
+ }
136
+ function cmpToMC(op) {
137
+ switch (op) {
138
+ case 'eq': return '=';
139
+ case 'ne': return '='; // ne uses "unless" form, but when used in if score context
140
+ case 'lt': return '<';
141
+ case 'le': return '<=';
142
+ case 'gt': return '>';
143
+ case 'ge': return '>=';
144
+ }
145
+ }
146
+ function emitSubcmd(sub) {
147
+ switch (sub.kind) {
148
+ case 'as':
149
+ return `as ${sub.selector}`;
150
+ case 'at':
151
+ return `at ${sub.selector}`;
152
+ case 'at_self':
153
+ return 'at @s';
154
+ case 'positioned':
155
+ return `positioned ${sub.x} ${sub.y} ${sub.z}`;
156
+ case 'rotated':
157
+ return `rotated ${sub.yaw} ${sub.pitch}`;
158
+ case 'in':
159
+ return `in ${sub.dimension}`;
160
+ case 'anchored':
161
+ return `anchored ${sub.anchor}`;
162
+ case 'if_score':
163
+ return `if score ${sub.a} ${cmpToMC(sub.op)} ${sub.b}`;
164
+ case 'unless_score':
165
+ return `unless score ${sub.a} ${cmpToMC(sub.op)} ${sub.b}`;
166
+ case 'if_matches':
167
+ return `if score ${sub.score} matches ${sub.range}`;
168
+ case 'unless_matches':
169
+ return `unless score ${sub.score} matches ${sub.range}`;
170
+ }
171
+ }
172
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * AST → HIR Lowering — Stage 2 of the RedScript compiler pipeline.
3
+ *
4
+ * Desugaring transforms:
5
+ * - for(init;cond;step) → block { init; while(cond) { body; step } }
6
+ * - for_range(v,start,end) → block { let v = start; while(v < end) { body; v = v + 1 } }
7
+ * - a += b / -= / *= / /= / %= → a = a OP b
8
+ * - a && b → if(a) { b } else { false }
9
+ * - a || b → if(a) { true } else { b }
10
+ * - as_block / at_block / as_at → unified execute with subcommands
11
+ * - All other nodes pass through with field-wise recursion
12
+ */
13
+ import type { Program } from '../../src/ast/types';
14
+ import type { HIRModule } from './types';
15
+ export declare function lowerToHIR(program: Program): HIRModule;
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ /**
3
+ * AST → HIR Lowering — Stage 2 of the RedScript compiler pipeline.
4
+ *
5
+ * Desugaring transforms:
6
+ * - for(init;cond;step) → block { init; while(cond) { body; step } }
7
+ * - for_range(v,start,end) → block { let v = start; while(v < end) { body; v = v + 1 } }
8
+ * - a += b / -= / *= / /= / %= → a = a OP b
9
+ * - a && b → if(a) { b } else { false }
10
+ * - a || b → if(a) { true } else { b }
11
+ * - as_block / at_block / as_at → unified execute with subcommands
12
+ * - All other nodes pass through with field-wise recursion
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.lowerToHIR = lowerToHIR;
16
+ // ---------------------------------------------------------------------------
17
+ // Public API
18
+ // ---------------------------------------------------------------------------
19
+ function lowerToHIR(program) {
20
+ return {
21
+ namespace: program.namespace,
22
+ globals: program.globals.map(lowerGlobal),
23
+ functions: program.declarations.map(lowerFunction),
24
+ structs: program.structs.map((s) => ({
25
+ name: s.name,
26
+ fields: s.fields.map(f => ({ name: f.name, type: f.type })),
27
+ span: s.span,
28
+ })),
29
+ implBlocks: program.implBlocks.map((ib) => ({
30
+ typeName: ib.typeName,
31
+ methods: ib.methods.map(lowerFunction),
32
+ span: ib.span,
33
+ })),
34
+ enums: program.enums.map((e) => ({
35
+ name: e.name,
36
+ variants: e.variants.map(v => ({ name: v.name, value: v.value })),
37
+ span: e.span,
38
+ })),
39
+ consts: program.consts.map((c) => ({
40
+ name: c.name,
41
+ type: c.type,
42
+ value: lowerExpr(c.value),
43
+ span: c.span,
44
+ })),
45
+ isLibrary: program.isLibrary,
46
+ };
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Functions & globals
50
+ // ---------------------------------------------------------------------------
51
+ function lowerGlobal(g) {
52
+ return {
53
+ name: g.name,
54
+ type: g.type,
55
+ init: lowerExpr(g.init),
56
+ mutable: g.mutable,
57
+ span: g.span,
58
+ };
59
+ }
60
+ function lowerFunction(fn) {
61
+ return {
62
+ name: fn.name,
63
+ params: fn.params.map(lowerParam),
64
+ returnType: fn.returnType,
65
+ decorators: fn.decorators,
66
+ body: lowerBlock(fn.body),
67
+ isLibraryFn: fn.isLibraryFn,
68
+ span: fn.span,
69
+ };
70
+ }
71
+ function lowerParam(p) {
72
+ return {
73
+ name: p.name,
74
+ type: p.type,
75
+ default: p.default ? lowerExpr(p.default) : undefined,
76
+ };
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Blocks & statements
80
+ // ---------------------------------------------------------------------------
81
+ function lowerBlock(block) {
82
+ const result = [];
83
+ for (const stmt of block) {
84
+ const lowered = lowerStmt(stmt);
85
+ // lowerStmt may return an array (e.g. for → [init, while])
86
+ if (Array.isArray(lowered)) {
87
+ result.push(...lowered);
88
+ }
89
+ else {
90
+ result.push(lowered);
91
+ }
92
+ }
93
+ return result;
94
+ }
95
+ function lowerStmt(stmt) {
96
+ switch (stmt.kind) {
97
+ case 'let':
98
+ return { kind: 'let', name: stmt.name, type: stmt.type, init: lowerExpr(stmt.init), span: stmt.span };
99
+ case 'expr':
100
+ return { kind: 'expr', expr: lowerExpr(stmt.expr), span: stmt.span };
101
+ case 'return':
102
+ return { kind: 'return', value: stmt.value ? lowerExpr(stmt.value) : undefined, span: stmt.span };
103
+ case 'break':
104
+ return { kind: 'break', span: stmt.span };
105
+ case 'continue':
106
+ return { kind: 'continue', span: stmt.span };
107
+ case 'if':
108
+ return {
109
+ kind: 'if',
110
+ cond: lowerExpr(stmt.cond),
111
+ then: lowerBlock(stmt.then),
112
+ else_: stmt.else_ ? lowerBlock(stmt.else_) : undefined,
113
+ span: stmt.span,
114
+ };
115
+ case 'while':
116
+ return { kind: 'while', cond: lowerExpr(stmt.cond), body: lowerBlock(stmt.body), span: stmt.span };
117
+ // --- Desugaring: for → while ---
118
+ case 'for': {
119
+ const stmts = [];
120
+ // Init
121
+ if (stmt.init) {
122
+ const init = lowerStmt(stmt.init);
123
+ if (Array.isArray(init))
124
+ stmts.push(...init);
125
+ else
126
+ stmts.push(init);
127
+ }
128
+ // while(cond) { body } step { step_expr }
129
+ const body = lowerBlock(stmt.body);
130
+ const step = [{ kind: 'expr', expr: lowerExpr(stmt.step), span: stmt.span }];
131
+ stmts.push({ kind: 'while', cond: lowerExpr(stmt.cond), body, step, span: stmt.span });
132
+ return stmts;
133
+ }
134
+ // --- Desugaring: for_range → let + while(cond) { body } step { v++ } ---
135
+ case 'for_range': {
136
+ const varName = stmt.varName;
137
+ const initStmt = {
138
+ kind: 'let',
139
+ name: varName,
140
+ type: { kind: 'named', name: 'int' },
141
+ init: lowerExpr(stmt.start),
142
+ span: stmt.span,
143
+ };
144
+ const body = lowerBlock(stmt.body);
145
+ // step: v = v + 1 (in separate step block so continue still increments)
146
+ const step = [{
147
+ kind: 'expr',
148
+ expr: {
149
+ kind: 'assign',
150
+ target: varName,
151
+ value: {
152
+ kind: 'binary',
153
+ op: '+',
154
+ left: { kind: 'ident', name: varName },
155
+ right: { kind: 'int_lit', value: 1 },
156
+ },
157
+ },
158
+ }];
159
+ const whileStmt = {
160
+ kind: 'while',
161
+ cond: {
162
+ kind: 'binary',
163
+ op: '<',
164
+ left: { kind: 'ident', name: varName },
165
+ right: lowerExpr(stmt.end),
166
+ },
167
+ body,
168
+ step,
169
+ span: stmt.span,
170
+ };
171
+ return [initStmt, whileStmt];
172
+ }
173
+ case 'foreach':
174
+ return {
175
+ kind: 'foreach',
176
+ binding: stmt.binding,
177
+ iterable: lowerExpr(stmt.iterable),
178
+ body: lowerBlock(stmt.body),
179
+ executeContext: stmt.executeContext,
180
+ span: stmt.span,
181
+ };
182
+ case 'match':
183
+ return {
184
+ kind: 'match',
185
+ expr: lowerExpr(stmt.expr),
186
+ arms: stmt.arms.map(arm => ({
187
+ pattern: arm.pattern ? lowerExpr(arm.pattern) : null,
188
+ body: lowerBlock(arm.body),
189
+ })),
190
+ span: stmt.span,
191
+ };
192
+ // --- Desugaring: as_block → execute [as] ---
193
+ case 'as_block':
194
+ return {
195
+ kind: 'execute',
196
+ subcommands: [{ kind: 'as', selector: stmt.selector }],
197
+ body: lowerBlock(stmt.body),
198
+ span: stmt.span,
199
+ };
200
+ // --- Desugaring: at_block → execute [at] ---
201
+ case 'at_block':
202
+ return {
203
+ kind: 'execute',
204
+ subcommands: [{ kind: 'at', selector: stmt.selector }],
205
+ body: lowerBlock(stmt.body),
206
+ span: stmt.span,
207
+ };
208
+ // --- Desugaring: as_at → execute [as, at] ---
209
+ case 'as_at':
210
+ return {
211
+ kind: 'execute',
212
+ subcommands: [
213
+ { kind: 'as', selector: stmt.as_sel },
214
+ { kind: 'at', selector: stmt.at_sel },
215
+ ],
216
+ body: lowerBlock(stmt.body),
217
+ span: stmt.span,
218
+ };
219
+ case 'execute':
220
+ return {
221
+ kind: 'execute',
222
+ subcommands: stmt.subcommands.map(lowerExecuteSubcommand),
223
+ body: lowerBlock(stmt.body),
224
+ span: stmt.span,
225
+ };
226
+ case 'raw':
227
+ return { kind: 'raw', cmd: stmt.cmd, span: stmt.span };
228
+ default: {
229
+ const _exhaustive = stmt;
230
+ throw new Error(`Unknown statement kind: ${_exhaustive.kind}`);
231
+ }
232
+ }
233
+ }
234
+ // ---------------------------------------------------------------------------
235
+ // Execute subcommands (pass-through — same shape)
236
+ // ---------------------------------------------------------------------------
237
+ function lowerExecuteSubcommand(sub) {
238
+ // All subcommand types share the same shape between AST and HIR
239
+ return sub;
240
+ }
241
+ // ---------------------------------------------------------------------------
242
+ // Expressions
243
+ // ---------------------------------------------------------------------------
244
+ /** Map compound assignment operator to its base binary op */
245
+ const COMPOUND_TO_BINOP = {
246
+ '+=': '+',
247
+ '-=': '-',
248
+ '*=': '*',
249
+ '/=': '/',
250
+ '%=': '%',
251
+ };
252
+ function lowerExpr(expr) {
253
+ switch (expr.kind) {
254
+ // --- Pass-through literals ---
255
+ case 'int_lit':
256
+ case 'float_lit':
257
+ case 'byte_lit':
258
+ case 'short_lit':
259
+ case 'long_lit':
260
+ case 'double_lit':
261
+ case 'bool_lit':
262
+ case 'str_lit':
263
+ case 'range_lit':
264
+ case 'rel_coord':
265
+ case 'local_coord':
266
+ case 'mc_name':
267
+ case 'blockpos':
268
+ return expr;
269
+ case 'ident':
270
+ return { kind: 'ident', name: expr.name, span: expr.span };
271
+ case 'selector':
272
+ return { kind: 'selector', raw: expr.raw, isSingle: expr.isSingle, sel: expr.sel, span: expr.span };
273
+ case 'array_lit':
274
+ return { kind: 'array_lit', elements: expr.elements.map(lowerExpr), span: expr.span };
275
+ case 'struct_lit':
276
+ return {
277
+ kind: 'struct_lit',
278
+ fields: expr.fields.map(f => ({ name: f.name, value: lowerExpr(f.value) })),
279
+ span: expr.span,
280
+ };
281
+ case 'str_interp':
282
+ return {
283
+ kind: 'str_interp',
284
+ parts: expr.parts.map(p => typeof p === 'string' ? p : lowerExpr(p)),
285
+ span: expr.span,
286
+ };
287
+ case 'f_string':
288
+ return { kind: 'f_string', parts: expr.parts, span: expr.span };
289
+ // Binary ops — && and || preserved as-is (short-circuit → control flow in MIR)
290
+ case 'binary':
291
+ return {
292
+ kind: 'binary',
293
+ op: expr.op,
294
+ left: lowerExpr(expr.left),
295
+ right: lowerExpr(expr.right),
296
+ span: expr.span,
297
+ };
298
+ case 'unary':
299
+ return { kind: 'unary', op: expr.op, operand: lowerExpr(expr.operand), span: expr.span };
300
+ case 'is_check':
301
+ return { kind: 'is_check', expr: lowerExpr(expr.expr), entityType: expr.entityType, span: expr.span };
302
+ // --- Desugaring: compound assignment → plain assign ---
303
+ case 'assign':
304
+ if (expr.op !== '=') {
305
+ const binOp = COMPOUND_TO_BINOP[expr.op];
306
+ return {
307
+ kind: 'assign',
308
+ target: expr.target,
309
+ value: {
310
+ kind: 'binary',
311
+ op: binOp,
312
+ left: { kind: 'ident', name: expr.target },
313
+ right: lowerExpr(expr.value),
314
+ span: expr.span,
315
+ },
316
+ span: expr.span,
317
+ };
318
+ }
319
+ return { kind: 'assign', target: expr.target, value: lowerExpr(expr.value), span: expr.span };
320
+ // --- Desugaring: compound member_assign → plain member_assign ---
321
+ case 'member_assign':
322
+ if (expr.op !== '=') {
323
+ const binOp = COMPOUND_TO_BINOP[expr.op];
324
+ const obj = lowerExpr(expr.obj);
325
+ return {
326
+ kind: 'member_assign',
327
+ obj,
328
+ field: expr.field,
329
+ value: {
330
+ kind: 'binary',
331
+ op: binOp,
332
+ left: { kind: 'member', obj, field: expr.field },
333
+ right: lowerExpr(expr.value),
334
+ span: expr.span,
335
+ },
336
+ span: expr.span,
337
+ };
338
+ }
339
+ return {
340
+ kind: 'member_assign',
341
+ obj: lowerExpr(expr.obj),
342
+ field: expr.field,
343
+ value: lowerExpr(expr.value),
344
+ span: expr.span,
345
+ };
346
+ case 'member':
347
+ return { kind: 'member', obj: lowerExpr(expr.obj), field: expr.field, span: expr.span };
348
+ case 'index':
349
+ return { kind: 'index', obj: lowerExpr(expr.obj), index: lowerExpr(expr.index), span: expr.span };
350
+ case 'call':
351
+ return { kind: 'call', fn: expr.fn, args: expr.args.map(lowerExpr), span: expr.span };
352
+ case 'invoke':
353
+ return { kind: 'invoke', callee: lowerExpr(expr.callee), args: expr.args.map(lowerExpr), span: expr.span };
354
+ case 'static_call':
355
+ return {
356
+ kind: 'static_call',
357
+ type: expr.type,
358
+ method: expr.method,
359
+ args: expr.args.map(lowerExpr),
360
+ span: expr.span,
361
+ };
362
+ case 'lambda': {
363
+ const body = Array.isArray(expr.body) ? lowerBlock(expr.body) : lowerExpr(expr.body);
364
+ return {
365
+ kind: 'lambda',
366
+ params: expr.params,
367
+ returnType: expr.returnType,
368
+ body,
369
+ span: expr.span,
370
+ };
371
+ }
372
+ default: {
373
+ const _exhaustive = expr;
374
+ throw new Error(`Unknown expression kind: ${_exhaustive.kind}`);
375
+ }
376
+ }
377
+ }
378
+ //# sourceMappingURL=lower.js.map