redscript-mc 1.2.29 → 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 (274) 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/README.md +29 -28
  8. package/README.zh.md +28 -28
  9. package/demo.gif +0 -0
  10. package/dist/cli.js +2 -554
  11. package/dist/compile.js +2 -266
  12. package/dist/index.js +2 -159
  13. package/dist/lexer/index.js +9 -1
  14. package/dist/lowering/index.js +22 -5
  15. package/dist/src/__tests__/cli.test.d.ts +1 -0
  16. package/dist/src/__tests__/cli.test.js +104 -0
  17. package/dist/src/__tests__/codegen.test.d.ts +1 -0
  18. package/dist/src/__tests__/codegen.test.js +152 -0
  19. package/dist/src/__tests__/compile-all.test.d.ts +10 -0
  20. package/dist/src/__tests__/compile-all.test.js +108 -0
  21. package/dist/src/__tests__/dce.test.d.ts +1 -0
  22. package/dist/src/__tests__/dce.test.js +102 -0
  23. package/dist/src/__tests__/diagnostics.test.d.ts +4 -0
  24. package/dist/src/__tests__/diagnostics.test.js +177 -0
  25. package/dist/src/__tests__/e2e.test.d.ts +6 -0
  26. package/dist/src/__tests__/e2e.test.js +1789 -0
  27. package/dist/src/__tests__/entity-types.test.d.ts +1 -0
  28. package/dist/src/__tests__/entity-types.test.js +203 -0
  29. package/dist/src/__tests__/formatter.test.d.ts +1 -0
  30. package/dist/src/__tests__/formatter.test.js +40 -0
  31. package/dist/src/__tests__/lexer.test.d.ts +1 -0
  32. package/dist/src/__tests__/lexer.test.js +343 -0
  33. package/dist/src/__tests__/lowering.test.d.ts +1 -0
  34. package/dist/src/__tests__/lowering.test.js +1015 -0
  35. package/dist/src/__tests__/macro.test.d.ts +8 -0
  36. package/dist/src/__tests__/macro.test.js +306 -0
  37. package/dist/src/__tests__/mc-integration.test.d.ts +12 -0
  38. package/dist/src/__tests__/mc-integration.test.js +817 -0
  39. package/dist/src/__tests__/mc-syntax.test.d.ts +1 -0
  40. package/dist/src/__tests__/mc-syntax.test.js +124 -0
  41. package/dist/src/__tests__/nbt.test.d.ts +1 -0
  42. package/dist/src/__tests__/nbt.test.js +82 -0
  43. package/dist/src/__tests__/optimizer-advanced.test.d.ts +1 -0
  44. package/dist/src/__tests__/optimizer-advanced.test.js +124 -0
  45. package/dist/src/__tests__/optimizer.test.d.ts +1 -0
  46. package/dist/src/__tests__/optimizer.test.js +149 -0
  47. package/dist/src/__tests__/parser.test.d.ts +1 -0
  48. package/dist/src/__tests__/parser.test.js +807 -0
  49. package/dist/src/__tests__/repl.test.d.ts +1 -0
  50. package/dist/src/__tests__/repl.test.js +27 -0
  51. package/dist/src/__tests__/runtime.test.d.ts +1 -0
  52. package/dist/src/__tests__/runtime.test.js +289 -0
  53. package/dist/src/__tests__/stdlib-advanced.test.d.ts +4 -0
  54. package/dist/src/__tests__/stdlib-advanced.test.js +374 -0
  55. package/dist/src/__tests__/stdlib-bigint.test.d.ts +7 -0
  56. package/dist/src/__tests__/stdlib-bigint.test.js +426 -0
  57. package/dist/src/__tests__/stdlib-math.test.d.ts +7 -0
  58. package/dist/src/__tests__/stdlib-math.test.js +351 -0
  59. package/dist/src/__tests__/stdlib-vec.test.d.ts +4 -0
  60. package/dist/src/__tests__/stdlib-vec.test.js +263 -0
  61. package/dist/src/__tests__/structure-optimizer.test.d.ts +1 -0
  62. package/dist/src/__tests__/structure-optimizer.test.js +33 -0
  63. package/dist/src/__tests__/typechecker.test.d.ts +1 -0
  64. package/dist/src/__tests__/typechecker.test.js +552 -0
  65. package/dist/src/__tests__/var-allocator.test.d.ts +1 -0
  66. package/dist/src/__tests__/var-allocator.test.js +69 -0
  67. package/dist/src/ast/types.d.ts +515 -0
  68. package/dist/src/ast/types.js +9 -0
  69. package/dist/src/builtins/metadata.d.ts +36 -0
  70. package/dist/src/builtins/metadata.js +1014 -0
  71. package/dist/src/cli.d.ts +11 -0
  72. package/dist/src/cli.js +443 -0
  73. package/dist/src/codegen/cmdblock/index.d.ts +26 -0
  74. package/dist/src/codegen/cmdblock/index.js +45 -0
  75. package/dist/src/codegen/mcfunction/index.d.ts +40 -0
  76. package/dist/src/codegen/mcfunction/index.js +606 -0
  77. package/dist/src/codegen/structure/index.d.ts +24 -0
  78. package/dist/src/codegen/structure/index.js +279 -0
  79. package/dist/src/codegen/var-allocator.d.ts +45 -0
  80. package/dist/src/codegen/var-allocator.js +104 -0
  81. package/dist/src/compile.d.ts +37 -0
  82. package/dist/src/compile.js +165 -0
  83. package/dist/src/diagnostics/index.d.ts +44 -0
  84. package/dist/src/diagnostics/index.js +140 -0
  85. package/dist/src/events/types.d.ts +35 -0
  86. package/dist/src/events/types.js +59 -0
  87. package/dist/src/formatter/index.d.ts +1 -0
  88. package/dist/src/formatter/index.js +26 -0
  89. package/dist/src/index.d.ts +22 -0
  90. package/dist/src/index.js +45 -0
  91. package/dist/src/ir/builder.d.ts +33 -0
  92. package/dist/src/ir/builder.js +99 -0
  93. package/dist/src/ir/types.d.ts +132 -0
  94. package/dist/src/ir/types.js +15 -0
  95. package/dist/src/lexer/index.d.ts +37 -0
  96. package/dist/src/lexer/index.js +569 -0
  97. package/dist/src/lowering/index.d.ts +188 -0
  98. package/dist/src/lowering/index.js +3405 -0
  99. package/dist/src/mc-test/client.d.ts +128 -0
  100. package/dist/src/mc-test/client.js +174 -0
  101. package/dist/src/mc-test/runner.d.ts +28 -0
  102. package/dist/src/mc-test/runner.js +151 -0
  103. package/dist/src/mc-test/setup.d.ts +11 -0
  104. package/dist/src/mc-test/setup.js +98 -0
  105. package/dist/src/mc-validator/index.d.ts +17 -0
  106. package/dist/src/mc-validator/index.js +322 -0
  107. package/dist/src/nbt/index.d.ts +86 -0
  108. package/dist/src/nbt/index.js +250 -0
  109. package/dist/src/optimizer/commands.d.ts +38 -0
  110. package/dist/src/optimizer/commands.js +451 -0
  111. package/dist/src/optimizer/dce.d.ts +34 -0
  112. package/dist/src/optimizer/dce.js +639 -0
  113. package/dist/src/optimizer/passes.d.ts +34 -0
  114. package/dist/src/optimizer/passes.js +243 -0
  115. package/dist/src/optimizer/structure.d.ts +9 -0
  116. package/dist/src/optimizer/structure.js +356 -0
  117. package/dist/src/parser/index.d.ts +93 -0
  118. package/dist/src/parser/index.js +1687 -0
  119. package/dist/src/repl.d.ts +16 -0
  120. package/dist/src/repl.js +165 -0
  121. package/dist/src/runtime/index.d.ts +107 -0
  122. package/dist/src/runtime/index.js +1409 -0
  123. package/dist/src/typechecker/index.d.ts +61 -0
  124. package/dist/src/typechecker/index.js +1034 -0
  125. package/dist/src/types/entity-hierarchy.d.ts +29 -0
  126. package/dist/src/types/entity-hierarchy.js +107 -0
  127. package/dist/src2/__tests__/e2e/basic.test.d.ts +8 -0
  128. package/dist/src2/__tests__/e2e/basic.test.js +140 -0
  129. package/dist/src2/__tests__/e2e/macros.test.d.ts +9 -0
  130. package/dist/src2/__tests__/e2e/macros.test.js +182 -0
  131. package/dist/src2/__tests__/e2e/migrate.test.d.ts +13 -0
  132. package/dist/src2/__tests__/e2e/migrate.test.js +2739 -0
  133. package/dist/src2/__tests__/hir/desugar.test.d.ts +1 -0
  134. package/dist/src2/__tests__/hir/desugar.test.js +234 -0
  135. package/dist/src2/__tests__/lir/lower.test.d.ts +1 -0
  136. package/dist/src2/__tests__/lir/lower.test.js +559 -0
  137. package/dist/src2/__tests__/lir/types.test.d.ts +1 -0
  138. package/dist/src2/__tests__/lir/types.test.js +185 -0
  139. package/dist/src2/__tests__/lir/verify.test.d.ts +1 -0
  140. package/dist/src2/__tests__/lir/verify.test.js +221 -0
  141. package/dist/src2/__tests__/mir/arithmetic.test.d.ts +1 -0
  142. package/dist/src2/__tests__/mir/arithmetic.test.js +130 -0
  143. package/dist/src2/__tests__/mir/control-flow.test.d.ts +1 -0
  144. package/dist/src2/__tests__/mir/control-flow.test.js +205 -0
  145. package/dist/src2/__tests__/mir/verify.test.d.ts +1 -0
  146. package/dist/src2/__tests__/mir/verify.test.js +223 -0
  147. package/dist/src2/__tests__/optimizer/block_merge.test.d.ts +1 -0
  148. package/dist/src2/__tests__/optimizer/block_merge.test.js +78 -0
  149. package/dist/src2/__tests__/optimizer/branch_simplify.test.d.ts +1 -0
  150. package/dist/src2/__tests__/optimizer/branch_simplify.test.js +58 -0
  151. package/dist/src2/__tests__/optimizer/constant_fold.test.d.ts +1 -0
  152. package/dist/src2/__tests__/optimizer/constant_fold.test.js +131 -0
  153. package/dist/src2/__tests__/optimizer/copy_prop.test.d.ts +1 -0
  154. package/dist/src2/__tests__/optimizer/copy_prop.test.js +91 -0
  155. package/dist/src2/__tests__/optimizer/dce.test.d.ts +1 -0
  156. package/dist/src2/__tests__/optimizer/dce.test.js +76 -0
  157. package/dist/src2/__tests__/optimizer/pipeline.test.d.ts +1 -0
  158. package/dist/src2/__tests__/optimizer/pipeline.test.js +102 -0
  159. package/dist/src2/emit/compile.d.ts +19 -0
  160. package/dist/src2/emit/compile.js +80 -0
  161. package/dist/src2/emit/index.d.ts +17 -0
  162. package/dist/src2/emit/index.js +172 -0
  163. package/dist/src2/hir/lower.d.ts +15 -0
  164. package/dist/src2/hir/lower.js +378 -0
  165. package/dist/src2/hir/types.d.ts +373 -0
  166. package/dist/src2/hir/types.js +16 -0
  167. package/dist/src2/lir/lower.d.ts +15 -0
  168. package/dist/src2/lir/lower.js +453 -0
  169. package/dist/src2/lir/types.d.ts +136 -0
  170. package/dist/src2/lir/types.js +11 -0
  171. package/dist/src2/lir/verify.d.ts +14 -0
  172. package/dist/src2/lir/verify.js +113 -0
  173. package/dist/src2/mir/lower.d.ts +9 -0
  174. package/dist/src2/mir/lower.js +1030 -0
  175. package/dist/src2/mir/macro.d.ts +22 -0
  176. package/dist/src2/mir/macro.js +168 -0
  177. package/dist/src2/mir/types.d.ts +183 -0
  178. package/dist/src2/mir/types.js +11 -0
  179. package/dist/src2/mir/verify.d.ts +16 -0
  180. package/dist/src2/mir/verify.js +216 -0
  181. package/dist/src2/optimizer/block_merge.d.ts +12 -0
  182. package/dist/src2/optimizer/block_merge.js +84 -0
  183. package/dist/src2/optimizer/branch_simplify.d.ts +9 -0
  184. package/dist/src2/optimizer/branch_simplify.js +28 -0
  185. package/dist/src2/optimizer/constant_fold.d.ts +10 -0
  186. package/dist/src2/optimizer/constant_fold.js +85 -0
  187. package/dist/src2/optimizer/copy_prop.d.ts +9 -0
  188. package/dist/src2/optimizer/copy_prop.js +113 -0
  189. package/dist/src2/optimizer/dce.d.ts +8 -0
  190. package/dist/src2/optimizer/dce.js +155 -0
  191. package/dist/src2/optimizer/pipeline.d.ts +10 -0
  192. package/dist/src2/optimizer/pipeline.js +42 -0
  193. package/dist/tsconfig.tsbuildinfo +1 -0
  194. package/docs/compiler-pipeline-redesign.md +2243 -0
  195. package/docs/optimization-ideas.md +1076 -0
  196. package/editors/vscode/package-lock.json +3 -3
  197. package/editors/vscode/package.json +1 -1
  198. package/examples/readme-demo.mcrs +44 -66
  199. package/jest.config.js +1 -1
  200. package/package.json +6 -5
  201. package/scripts/postbuild.js +15 -0
  202. package/src/__tests__/cli.test.ts +8 -220
  203. package/src/__tests__/dce.test.ts +11 -56
  204. package/src/__tests__/diagnostics.test.ts +59 -38
  205. package/src/__tests__/mc-integration.test.ts +1 -2
  206. package/src/ast/types.ts +6 -1
  207. package/src/cli.ts +29 -156
  208. package/src/compile.ts +6 -162
  209. package/src/index.ts +14 -178
  210. package/src/lexer/index.ts +9 -1
  211. package/src/mc-test/runner.ts +4 -3
  212. package/src/parser/index.ts +1 -1
  213. package/src/repl.ts +1 -1
  214. package/src/runtime/index.ts +1 -1
  215. package/src2/__tests__/e2e/basic.test.ts +154 -0
  216. package/src2/__tests__/e2e/macros.test.ts +199 -0
  217. package/src2/__tests__/e2e/migrate.test.ts +3008 -0
  218. package/src2/__tests__/hir/desugar.test.ts +263 -0
  219. package/src2/__tests__/lir/lower.test.ts +619 -0
  220. package/src2/__tests__/lir/types.test.ts +207 -0
  221. package/src2/__tests__/lir/verify.test.ts +249 -0
  222. package/src2/__tests__/mir/arithmetic.test.ts +156 -0
  223. package/src2/__tests__/mir/control-flow.test.ts +242 -0
  224. package/src2/__tests__/mir/verify.test.ts +254 -0
  225. package/src2/__tests__/optimizer/block_merge.test.ts +84 -0
  226. package/src2/__tests__/optimizer/branch_simplify.test.ts +64 -0
  227. package/src2/__tests__/optimizer/constant_fold.test.ts +145 -0
  228. package/src2/__tests__/optimizer/copy_prop.test.ts +99 -0
  229. package/src2/__tests__/optimizer/dce.test.ts +83 -0
  230. package/src2/__tests__/optimizer/pipeline.test.ts +116 -0
  231. package/src2/emit/compile.ts +99 -0
  232. package/src2/emit/index.ts +222 -0
  233. package/src2/hir/lower.ts +428 -0
  234. package/src2/hir/types.ts +216 -0
  235. package/src2/lir/lower.ts +556 -0
  236. package/src2/lir/types.ts +109 -0
  237. package/src2/lir/verify.ts +129 -0
  238. package/src2/mir/lower.ts +1160 -0
  239. package/src2/mir/macro.ts +167 -0
  240. package/src2/mir/types.ts +106 -0
  241. package/src2/mir/verify.ts +218 -0
  242. package/src2/optimizer/block_merge.ts +93 -0
  243. package/src2/optimizer/branch_simplify.ts +27 -0
  244. package/src2/optimizer/constant_fold.ts +88 -0
  245. package/src2/optimizer/copy_prop.ts +106 -0
  246. package/src2/optimizer/dce.ts +133 -0
  247. package/src2/optimizer/pipeline.ts +44 -0
  248. package/tsconfig.json +2 -2
  249. package/src/__tests__/codegen.test.ts +0 -161
  250. package/src/__tests__/e2e.test.ts +0 -2039
  251. package/src/__tests__/entity-types.test.ts +0 -236
  252. package/src/__tests__/lowering.test.ts +0 -1185
  253. package/src/__tests__/macro.test.ts +0 -343
  254. package/src/__tests__/nbt.test.ts +0 -58
  255. package/src/__tests__/optimizer-advanced.test.ts +0 -144
  256. package/src/__tests__/optimizer.test.ts +0 -162
  257. package/src/__tests__/runtime.test.ts +0 -305
  258. package/src/__tests__/stdlib-advanced.test.ts +0 -379
  259. package/src/__tests__/stdlib-bigint.test.ts +0 -427
  260. package/src/__tests__/stdlib-math.test.ts +0 -374
  261. package/src/__tests__/stdlib-vec.test.ts +0 -259
  262. package/src/__tests__/structure-optimizer.test.ts +0 -38
  263. package/src/__tests__/var-allocator.test.ts +0 -75
  264. package/src/codegen/cmdblock/index.ts +0 -63
  265. package/src/codegen/mcfunction/index.ts +0 -662
  266. package/src/codegen/structure/index.ts +0 -346
  267. package/src/codegen/var-allocator.ts +0 -104
  268. package/src/ir/builder.ts +0 -116
  269. package/src/ir/types.ts +0 -134
  270. package/src/lowering/index.ts +0 -3860
  271. package/src/optimizer/commands.ts +0 -534
  272. package/src/optimizer/dce.ts +0 -679
  273. package/src/optimizer/passes.ts +0 -250
  274. package/src/optimizer/structure.ts +0 -450
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lexer_1 = require("../../../src/lexer");
4
+ const parser_1 = require("../../../src/parser");
5
+ const lower_1 = require("../../hir/lower");
6
+ function parse(source) {
7
+ const tokens = new lexer_1.Lexer(source).tokenize();
8
+ const ast = new parser_1.Parser(tokens).parse('test');
9
+ return (0, lower_1.lowerToHIR)(ast);
10
+ }
11
+ function getBody(source) {
12
+ const mod = parse(source);
13
+ return mod.functions[0].body;
14
+ }
15
+ describe('HIR lowering — for loop desugaring', () => {
16
+ test('for(init;cond;step) → let + while with step in separate block', () => {
17
+ const body = getBody('fn f() { for (let i: int = 0; i < 10; i = i + 1) { let x: int = i; } }');
18
+ // Should produce: let i = 0; while(i < 10) { body } step { i = i + 1 }
19
+ expect(body).toHaveLength(2);
20
+ expect(body[0].kind).toBe('let');
21
+ const letStmt = body[0];
22
+ expect(letStmt.name).toBe('i');
23
+ expect(body[1].kind).toBe('while');
24
+ const whileStmt = body[1];
25
+ expect(whileStmt.cond.kind).toBe('binary');
26
+ // while body: only the original body (step is separate)
27
+ expect(whileStmt.body).toHaveLength(1);
28
+ expect(whileStmt.body[0].kind).toBe('let'); // let x = i
29
+ // step block: i = i + 1 (separate so continue still increments)
30
+ expect(whileStmt.step).toBeDefined();
31
+ expect(whileStmt.step).toHaveLength(1);
32
+ expect(whileStmt.step[0].kind).toBe('expr'); // i = i + 1
33
+ });
34
+ test('for loop without init', () => {
35
+ const body = getBody('fn f() { let i: int = 0; for (; i < 5; i = i + 1) {} }');
36
+ // let i = 0; while(i < 5) { i = i + 1 }
37
+ expect(body).toHaveLength(2);
38
+ expect(body[0].kind).toBe('let');
39
+ expect(body[1].kind).toBe('while');
40
+ });
41
+ });
42
+ describe('HIR lowering — for_range desugaring', () => {
43
+ test('for i in 0..10 → let + while with step block', () => {
44
+ const body = getBody('fn f() { for i in 0..10 { let x: int = i; } }');
45
+ expect(body).toHaveLength(2);
46
+ const letStmt = body[0];
47
+ expect(letStmt.kind).toBe('let');
48
+ expect(letStmt.name).toBe('i');
49
+ expect(letStmt.init.kind).toBe('int_lit');
50
+ const whileStmt = body[1];
51
+ expect(whileStmt.kind).toBe('while');
52
+ // cond: i < 10
53
+ expect(whileStmt.cond.kind).toBe('binary');
54
+ const cond = whileStmt.cond;
55
+ expect(cond.op).toBe('<');
56
+ // body: only user body (step is separate)
57
+ expect(whileStmt.body).toHaveLength(1);
58
+ expect(whileStmt.body[0].kind).toBe('let');
59
+ // step: i = i + 1 (in separate block so continue still increments)
60
+ expect(whileStmt.step).toBeDefined();
61
+ expect(whileStmt.step).toHaveLength(1);
62
+ expect(whileStmt.step[0].kind).toBe('expr');
63
+ });
64
+ });
65
+ describe('HIR lowering — compound assignment desugaring', () => {
66
+ test('x += 1 → x = x + 1', () => {
67
+ const body = getBody('fn f() { let x: int = 0; x += 1; }');
68
+ const exprStmt = body[1];
69
+ expect(exprStmt.kind).toBe('expr');
70
+ const assign = exprStmt.expr;
71
+ expect(assign.kind).toBe('assign');
72
+ expect(assign.target).toBe('x');
73
+ // value should be x + 1
74
+ const binExpr = assign.value;
75
+ expect(binExpr.kind).toBe('binary');
76
+ expect(binExpr.op).toBe('+');
77
+ expect(binExpr.left.name).toBe('x');
78
+ expect(binExpr.right.value).toBe(1);
79
+ });
80
+ test('x -= 5 → x = x - 5', () => {
81
+ const body = getBody('fn f() { let x: int = 10; x -= 5; }');
82
+ const exprStmt = body[1];
83
+ const assign = exprStmt.expr;
84
+ expect(assign.kind).toBe('assign');
85
+ const bin = assign.value;
86
+ expect(bin.op).toBe('-');
87
+ });
88
+ test('x *= 2 → x = x * 2', () => {
89
+ const body = getBody('fn f() { let x: int = 1; x *= 2; }');
90
+ const exprStmt = body[1];
91
+ const assign = exprStmt.expr;
92
+ const bin = assign.value;
93
+ expect(bin.op).toBe('*');
94
+ });
95
+ test('x /= 3 → x = x / 3', () => {
96
+ const body = getBody('fn f() { let x: int = 9; x /= 3; }');
97
+ const exprStmt = body[1];
98
+ const assign = exprStmt.expr;
99
+ const bin = assign.value;
100
+ expect(bin.op).toBe('/');
101
+ });
102
+ test('x %= 3 → x = x % 3', () => {
103
+ const body = getBody('fn f() { let x: int = 10; x %= 3; }');
104
+ const exprStmt = body[1];
105
+ const assign = exprStmt.expr;
106
+ const bin = assign.value;
107
+ expect(bin.op).toBe('%');
108
+ });
109
+ });
110
+ describe('HIR lowering — execute block unification', () => {
111
+ test('as_block → execute [as]', () => {
112
+ const body = getBody('fn f() { as @e[tag=foo] { } }');
113
+ expect(body).toHaveLength(1);
114
+ const exec = body[0];
115
+ expect(exec.kind).toBe('execute');
116
+ expect(exec.subcommands).toHaveLength(1);
117
+ expect(exec.subcommands[0].kind).toBe('as');
118
+ });
119
+ test('foreach with at context preserved', () => {
120
+ const body = getBody('fn f() { foreach (p in @a) at @s { } }');
121
+ expect(body).toHaveLength(1);
122
+ expect(body[0].kind).toBe('foreach');
123
+ const fe = body[0];
124
+ expect(fe.executeContext).toBe('at @s');
125
+ });
126
+ });
127
+ describe('HIR lowering — && and || preservation', () => {
128
+ test('&& preserved as binary op', () => {
129
+ const body = getBody('fn f() { let x: bool = true && false; }');
130
+ const letStmt = body[0];
131
+ const bin = letStmt.init;
132
+ expect(bin.kind).toBe('binary');
133
+ expect(bin.op).toBe('&&');
134
+ });
135
+ test('|| preserved as binary op', () => {
136
+ const body = getBody('fn f() { let x: bool = true || false; }');
137
+ const letStmt = body[0];
138
+ const bin = letStmt.init;
139
+ expect(bin.kind).toBe('binary');
140
+ expect(bin.op).toBe('||');
141
+ });
142
+ });
143
+ describe('HIR lowering — pass-through constructs', () => {
144
+ test('while loop passes through', () => {
145
+ const body = getBody('fn f() { while (true) { } }');
146
+ expect(body).toHaveLength(1);
147
+ expect(body[0].kind).toBe('while');
148
+ });
149
+ test('if/else passes through', () => {
150
+ const body = getBody('fn f() { if (true) { } else { } }');
151
+ expect(body).toHaveLength(1);
152
+ expect(body[0].kind).toBe('if');
153
+ const ifStmt = body[0];
154
+ expect(ifStmt.then).toBeDefined();
155
+ expect(ifStmt.else_).toBeDefined();
156
+ });
157
+ test('return passes through', () => {
158
+ const body = getBody('fn f(): int { return 42; }');
159
+ expect(body).toHaveLength(1);
160
+ expect(body[0].kind).toBe('return');
161
+ const ret = body[0];
162
+ expect(ret.value).toBeDefined();
163
+ expect(ret.value.value).toBe(42);
164
+ });
165
+ test('function call passes through', () => {
166
+ const body = getBody('fn f() { foo(1, 2); }');
167
+ expect(body).toHaveLength(1);
168
+ const exprStmt = body[0];
169
+ const call = exprStmt.expr;
170
+ expect(call.kind).toBe('call');
171
+ expect(call.fn).toBe('foo');
172
+ expect(call.args).toHaveLength(2);
173
+ });
174
+ test('break and continue pass through', () => {
175
+ const body = getBody('fn f() { while (true) { break; continue; } }');
176
+ const whileStmt = body[0];
177
+ expect(whileStmt.body[0].kind).toBe('break');
178
+ expect(whileStmt.body[1].kind).toBe('continue');
179
+ });
180
+ test('raw command passes through', () => {
181
+ const body = getBody('fn f() { raw("say hello"); }');
182
+ expect(body).toHaveLength(1);
183
+ expect(body[0].kind).toBe('raw');
184
+ });
185
+ });
186
+ describe('HIR lowering — module structure', () => {
187
+ test('struct declarations preserved', () => {
188
+ const mod = parse('struct Vec2 { x: int, y: int }');
189
+ expect(mod.structs).toHaveLength(1);
190
+ expect(mod.structs[0].name).toBe('Vec2');
191
+ expect(mod.structs[0].fields).toHaveLength(2);
192
+ });
193
+ test('const declarations preserved', () => {
194
+ const mod = parse('const MAX: int = 100;');
195
+ expect(mod.consts).toHaveLength(1);
196
+ expect(mod.consts[0].name).toBe('MAX');
197
+ });
198
+ test('namespace preserved', () => {
199
+ const mod = parse('fn f() {}');
200
+ expect(mod.namespace).toBe('test');
201
+ });
202
+ test('decorators preserved on functions', () => {
203
+ const mod = parse('@tick fn tick_fn() {}');
204
+ expect(mod.functions).toHaveLength(1);
205
+ expect(mod.functions[0].decorators).toHaveLength(1);
206
+ expect(mod.functions[0].decorators[0].name).toBe('tick');
207
+ });
208
+ });
209
+ describe('HIR lowering — member compound assignment', () => {
210
+ test('obj.field += 1 → obj.field = obj.field + 1', () => {
211
+ const mod = parse('struct S { x: int } fn f() { let s: S = { x: 0 }; s.x += 1; }');
212
+ const body = mod.functions[0].body;
213
+ const exprStmt = body[1];
214
+ const assign = exprStmt.expr;
215
+ expect(assign.kind).toBe('member_assign');
216
+ expect(assign.field).toBe('x');
217
+ const bin = assign.value;
218
+ expect(bin.kind).toBe('binary');
219
+ expect(bin.op).toBe('+');
220
+ expect(bin.left.kind).toBe('member');
221
+ expect(bin.left.field).toBe('x');
222
+ });
223
+ });
224
+ describe('HIR lowering — plain assignment passes through', () => {
225
+ test('x = 5 stays as x = 5', () => {
226
+ const body = getBody('fn f() { let x: int = 0; x = 5; }');
227
+ const exprStmt = body[1];
228
+ const assign = exprStmt.expr;
229
+ expect(assign.kind).toBe('assign');
230
+ expect(assign.target).toBe('x');
231
+ expect(assign.value.value).toBe(5);
232
+ });
233
+ });
234
+ //# sourceMappingURL=desugar.test.js.map
@@ -0,0 +1 @@
1
+ export {};