redscript-mc 1.2.25 → 1.2.27

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 (265) hide show
  1. package/README.md +67 -9
  2. package/README.zh.md +61 -4
  3. package/dist/__tests__/cli.test.js +1 -1
  4. package/dist/__tests__/codegen.test.js +12 -6
  5. package/dist/__tests__/e2e.test.js +6 -6
  6. package/dist/__tests__/lowering.test.js +8 -8
  7. package/dist/__tests__/optimizer.test.js +31 -0
  8. package/dist/__tests__/stdlib-advanced.test.d.ts +4 -0
  9. package/dist/__tests__/stdlib-advanced.test.js +378 -0
  10. package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
  11. package/dist/__tests__/stdlib-bigint.test.js +428 -0
  12. package/dist/__tests__/stdlib-math.test.d.ts +7 -0
  13. package/dist/__tests__/stdlib-math.test.js +352 -0
  14. package/dist/__tests__/stdlib-vec.test.d.ts +4 -0
  15. package/dist/__tests__/stdlib-vec.test.js +264 -0
  16. package/dist/ast/types.d.ts +17 -1
  17. package/dist/codegen/mcfunction/index.js +154 -18
  18. package/dist/codegen/var-allocator.d.ts +17 -0
  19. package/dist/codegen/var-allocator.js +26 -0
  20. package/dist/compile.d.ts +14 -0
  21. package/dist/compile.js +62 -5
  22. package/dist/data/arena/function/__load.mcfunction +6 -0
  23. package/dist/data/arena/function/__tick.mcfunction +2 -0
  24. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
  25. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
  26. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
  27. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
  28. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
  29. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
  30. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
  31. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
  32. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
  33. package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
  34. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
  35. package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
  36. package/dist/data/arena/function/arena_tick.mcfunction +11 -0
  37. package/dist/data/counter/function/__load.mcfunction +5 -0
  38. package/dist/data/counter/function/__tick.mcfunction +2 -0
  39. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
  40. package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
  41. package/dist/data/counter/function/counter_tick.mcfunction +11 -0
  42. package/dist/data/gcd2/function/__load.mcfunction +3 -0
  43. package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
  44. package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
  45. package/dist/data/gcd2/function/abs.mcfunction +7 -0
  46. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
  47. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
  48. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
  49. package/dist/data/gcd2/function/gcd.mcfunction +14 -0
  50. package/dist/data/gcd3/function/__load.mcfunction +3 -0
  51. package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
  52. package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
  53. package/dist/data/gcd3/function/abs.mcfunction +7 -0
  54. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
  55. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
  56. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
  57. package/dist/data/gcd3/function/gcd.mcfunction +14 -0
  58. package/dist/data/gcd3/function/test.mcfunction +7 -0
  59. package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
  60. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
  61. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
  62. package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
  63. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
  64. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
  65. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
  66. package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
  67. package/dist/data/gcd3nm/function/test.mcfunction +7 -0
  68. package/dist/data/gcd_test/function/__load.mcfunction +3 -0
  69. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
  70. package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
  71. package/dist/data/gcd_test/function/abs.mcfunction +7 -0
  72. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
  73. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
  74. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
  75. package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
  76. package/dist/data/isqrttest/function/__load.mcfunction +6 -0
  77. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
  78. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
  79. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
  80. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
  81. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
  82. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
  83. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
  84. package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
  85. package/dist/data/isqrttest/function/test.mcfunction +6 -0
  86. package/dist/data/mathtest/function/__load.mcfunction +3 -0
  87. package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
  88. package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
  89. package/dist/data/mathtest/function/abs.mcfunction +6 -0
  90. package/dist/data/mathtest/function/test.mcfunction +5 -0
  91. package/dist/data/minecraft/tags/function/load.json +5 -0
  92. package/dist/data/minecraft/tags/function/tick.json +5 -0
  93. package/dist/data/mypack/function/__load.mcfunction +13 -0
  94. package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
  95. package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
  96. package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
  97. package/dist/data/mypack/function/abs.mcfunction +6 -0
  98. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
  99. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
  100. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
  101. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
  102. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
  103. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
  104. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
  105. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
  106. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
  107. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
  108. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
  109. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
  110. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
  111. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
  112. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
  113. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
  114. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
  115. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
  116. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
  117. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
  118. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
  119. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
  120. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
  121. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
  122. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
  123. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
  124. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
  125. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
  126. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
  127. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
  128. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
  129. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
  130. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
  131. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
  132. package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
  133. package/dist/data/mypack/function/my_game.mcfunction +10 -0
  134. package/dist/data/quiz/function/__load.mcfunction +16 -0
  135. package/dist/data/quiz/function/__tick.mcfunction +6 -0
  136. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
  137. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
  138. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
  139. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
  140. package/dist/data/quiz/function/answer_a.mcfunction +4 -0
  141. package/dist/data/quiz/function/answer_b.mcfunction +4 -0
  142. package/dist/data/quiz/function/answer_c.mcfunction +4 -0
  143. package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
  144. package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
  145. package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
  146. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
  147. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
  148. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
  149. package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
  150. package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
  151. package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
  152. package/dist/data/quiz/function/ask_question.mcfunction +7 -0
  153. package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
  154. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
  155. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
  156. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
  157. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
  158. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
  159. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
  160. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
  161. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
  162. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
  163. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
  164. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
  165. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
  166. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
  167. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
  168. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
  169. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
  170. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
  171. package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
  172. package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
  173. package/dist/data/reqtest/function/__load.mcfunction +4 -0
  174. package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
  175. package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
  176. package/dist/data/reqtest/function/use_table.mcfunction +4 -0
  177. package/dist/data/reqtest2/function/__load.mcfunction +3 -0
  178. package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
  179. package/dist/data/runtime/function/__load.mcfunction +5 -0
  180. package/dist/data/runtime/function/__tick.mcfunction +2 -0
  181. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
  182. package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
  183. package/dist/data/shop/function/__load.mcfunction +7 -0
  184. package/dist/data/shop/function/__tick.mcfunction +3 -0
  185. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
  186. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
  187. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
  188. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
  189. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
  190. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
  191. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
  192. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
  193. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
  194. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
  195. package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
  196. package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
  197. package/dist/data/swap_test/function/__load.mcfunction +3 -0
  198. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
  199. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
  200. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
  201. package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
  202. package/dist/data/turret/function/__load.mcfunction +5 -0
  203. package/dist/data/turret/function/__tick.mcfunction +4 -0
  204. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
  205. package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
  206. package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
  207. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
  208. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
  209. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
  210. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
  211. package/dist/data/turret/function/turret_tick.mcfunction +5 -0
  212. package/dist/gcd2.map.json +15 -0
  213. package/dist/gcd3.map.json +17 -0
  214. package/dist/gcd_test.map.json +15 -0
  215. package/dist/index.js +20 -1
  216. package/dist/ir/types.d.ts +4 -0
  217. package/dist/isqrttest.map.json +15 -0
  218. package/dist/lexer/index.d.ts +1 -1
  219. package/dist/lexer/index.js +1 -0
  220. package/dist/lowering/index.d.ts +5 -0
  221. package/dist/lowering/index.js +154 -14
  222. package/dist/mathtest.map.json +6 -0
  223. package/dist/mypack.map.json +27 -0
  224. package/dist/optimizer/dce.js +21 -5
  225. package/dist/optimizer/passes.js +18 -6
  226. package/dist/optimizer/structure.js +7 -0
  227. package/dist/pack.mcmeta +6 -0
  228. package/dist/parser/index.d.ts +5 -0
  229. package/dist/parser/index.js +43 -2
  230. package/dist/reqtest.map.json +4 -0
  231. package/dist/reqtest2.map.json +4 -0
  232. package/dist/runtime/index.d.ts +6 -0
  233. package/dist/runtime/index.js +130 -9
  234. package/dist/runtime.map.json +7 -0
  235. package/dist/swap_test.map.json +14 -0
  236. package/editors/vscode/package-lock.json +3 -3
  237. package/editors/vscode/package.json +1 -1
  238. package/examples/showcase.mcrs +505 -0
  239. package/package.json +1 -1
  240. package/src/__tests__/cli.test.ts +1 -1
  241. package/src/__tests__/codegen.test.ts +12 -6
  242. package/src/__tests__/e2e.test.ts +6 -6
  243. package/src/__tests__/lowering.test.ts +8 -8
  244. package/src/__tests__/optimizer.test.ts +33 -0
  245. package/src/__tests__/stdlib-advanced.test.ts +379 -0
  246. package/src/__tests__/stdlib-bigint.test.ts +427 -0
  247. package/src/__tests__/stdlib-math.test.ts +374 -0
  248. package/src/__tests__/stdlib-vec.test.ts +259 -0
  249. package/src/ast/types.ts +11 -1
  250. package/src/codegen/mcfunction/index.ts +143 -19
  251. package/src/codegen/var-allocator.ts +29 -0
  252. package/src/compile.ts +72 -5
  253. package/src/index.ts +21 -1
  254. package/src/ir/types.ts +2 -0
  255. package/src/lexer/index.ts +2 -1
  256. package/src/lowering/index.ts +171 -14
  257. package/src/optimizer/dce.ts +22 -5
  258. package/src/optimizer/passes.ts +18 -5
  259. package/src/optimizer/structure.ts +6 -1
  260. package/src/parser/index.ts +47 -2
  261. package/src/runtime/index.ts +130 -10
  262. package/src/stdlib/advanced.mcrs +330 -0
  263. package/src/stdlib/bigint.mcrs +205 -0
  264. package/src/stdlib/math.mcrs +274 -21
  265. package/src/stdlib/vec.mcrs +246 -0
@@ -0,0 +1,505 @@
1
+ // ╔══════════════════════════════════════════════════════════════════════╗
2
+ // ║ RedScript v1.2.26 — Capability Showcase ║
3
+ // ║ ║
4
+ // ║ Demonstrates every major feature in one datapack: ║
5
+ // ║ • Math stdlib: sin/cos table, sqrt_fixed, atan2, smoothstep ║
6
+ // ║ • Vec stdlib: 2D length, normalize, rotate ║
7
+ // ║ • BigInt: arbitrary-precision Fibonacci up to F(100) ║
8
+ // ║ • Advanced: primes, Collatz, Bézier, noise, Mandelbrot ║
9
+ // ║ • Language: structs, impl blocks, enums, match, lambdas, ║
10
+ // ║ @tick/@load, foreach, f-strings, break/continue ║
11
+ // ║ • Game effects: particles, actionbar, fireworks, titles ║
12
+ // ║ ║
13
+ // ║ Usage: ║
14
+ // ║ /function showcase:start begin the showcase ║
15
+ // ║ /function showcase:stop stop everything ║
16
+ // ║ /function showcase:dump_math print math table to chat ║
17
+ // ║ /function showcase:dump_bigint print Fibonacci to chat ║
18
+ // ╚══════════════════════════════════════════════════════════════════════╝
19
+
20
+ import "../src/stdlib/math.mcrs"
21
+ import "../src/stdlib/vec.mcrs"
22
+ import "../src/stdlib/bigint.mcrs"
23
+ import "../src/stdlib/advanced.mcrs"
24
+
25
+ // ── Enums ─────────────────────────────────────────────────────────────────
26
+
27
+ enum Phase {
28
+ Idle, // 0 — waiting
29
+ Math, // 1 — trig / fixed-point showcase
30
+ BigInt, // 2 — arbitrary-precision arithmetic
31
+ Advanced, // 3 — primes, noise, fractals
32
+ Visual, // 4 — live particle ring + sin/cos actionbar
33
+ }
34
+
35
+ // ── State struct ───────────────────────────────────────────────────────────
36
+
37
+ struct ShowcaseState {
38
+ phase: int, // current Phase
39
+ tick: int, // frame counter since start
40
+ angle: int, // 0–359 degrees; advances 2°/tick during Visual phase
41
+ running: bool
42
+ }
43
+
44
+ let state: ShowcaseState = {
45
+ phase: 0,
46
+ tick: 0,
47
+ angle: 0,
48
+ running: false
49
+ };
50
+
51
+ // ── Timer (OOP demo) ───────────────────────────────────────────────────────
52
+
53
+ struct ptimer {
54
+ interval: int, // ticks between phase advances
55
+ elapsed: int
56
+ }
57
+
58
+ impl ptimer {
59
+ fn new(interval: int) -> ptimer {
60
+ return { interval: interval, elapsed: 0 };
61
+ }
62
+
63
+ fn tick(self) -> bool {
64
+ self.elapsed = self.elapsed + 1;
65
+ if (self.elapsed >= self.interval) {
66
+ self.elapsed = 0;
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+
72
+ fn reset(self) {
73
+ self.elapsed = 0;
74
+ }
75
+ }
76
+
77
+ let phase_timer: ptimer = { interval: 200, elapsed: 0 }; // advance every 10 seconds
78
+
79
+ // ── Helpers ────────────────────────────────────────────────────────────────
80
+
81
+ fn _divider() {
82
+ say("§8§m══════════════════════════════");
83
+ }
84
+
85
+ fn _section(title: string) {
86
+ _divider();
87
+ say(f"§6§l {title}");
88
+ _divider();
89
+ }
90
+
91
+ // Format a fixed-point ×1000 value as "X.XXX"
92
+ fn _fp(n: int) -> int {
93
+ // Just return raw for now; f-string handles display
94
+ return n;
95
+ }
96
+
97
+ // ── @load ─────────────────────────────────────────────────────────────────
98
+
99
+ @load
100
+ fn showcase_load() {
101
+ say("§a[Showcase] §rRedScript v1.2.26 loaded.");
102
+ say("§7 /function showcase:start §f— begin the showcase");
103
+ say("§7 /function showcase:dump_math §f— print math tables");
104
+ say("§7 /function showcase:dump_bigint §f— print big Fibonacci numbers");
105
+ }
106
+
107
+ // ── @tick ──────────────────────────────────────────────────────────────────
108
+
109
+ @tick
110
+ fn showcase_tick() {
111
+ if (!state.running) { return; }
112
+
113
+ state.tick = state.tick + 1;
114
+
115
+ // Advance phase on timer
116
+ if (phase_timer.tick()) {
117
+ _next_phase();
118
+ }
119
+
120
+ // Per-phase work
121
+ match (state.phase) {
122
+ Phase.Math => { _tick_math(); }
123
+ Phase.BigInt => { _tick_bigint_live(); }
124
+ Phase.Advanced => { _tick_advanced_live(); }
125
+ Phase.Visual => { _tick_visual(); }
126
+ }
127
+ }
128
+
129
+ fn _next_phase() {
130
+ state.phase = state.phase + 1;
131
+ if (state.phase > 4) { state.phase = 1; }
132
+
133
+ match (state.phase) {
134
+ Phase.Math => { _dump_math_phase(); }
135
+ Phase.BigInt => { _dump_bigint_phase(); }
136
+ Phase.Advanced => { _dump_advanced_phase(); }
137
+ Phase.Visual => {
138
+ _section("Live Visual FX");
139
+ say("§bOrbital ring + live sin/cos on actionbar.");
140
+ say("§7(runs for 10 seconds, then loops back to Math)");
141
+ }
142
+ }
143
+ }
144
+
145
+ // ── Phase 1: Math Stdlib ──────────────────────────────────────────────────
146
+
147
+ fn _dump_math_phase() {
148
+ _section("Math Stdlib — Fixed-Point Trigonometry");
149
+
150
+ // Sin/cos table samples
151
+ say("§eTrig (×1000 fixed-point):");
152
+ let deg: int = 0;
153
+ while (deg <= 90) {
154
+ let s: int = sin_fixed(deg);
155
+ let c: int = cos_fixed(deg);
156
+ say(f" sin({deg}°)={s} cos({deg}°)={c}");
157
+ deg = deg + 15;
158
+ }
159
+
160
+ // sqrt, pow, gcd, lcm
161
+ say("§eRoots & Powers:");
162
+ say(f" sqrt_fixed(2) = {sqrt_fixed(2)} (expect 1414)");
163
+ say(f" sqrt_fixed(3) = {sqrt_fixed(3)} (expect 1732)");
164
+ say(f" isqrt(360000000000) = {isqrt(360000000000)} (expect 600000)");
165
+ say(f" pow_int(2, 20) = {pow_int(2, 20)} (expect 1048576)");
166
+
167
+ say("§eNumber Theory:");
168
+ say(f" gcd(48, 36) = {gcd(48, 36)} (expect 12)");
169
+ say(f" lcm(4, 6) = {lcm(4, 6)} (expect 12)");
170
+ say(f" log2_int(1024) = {log2_int(1024)} (expect 10)");
171
+
172
+ say("§eInterpolation:");
173
+ say(f" lerp(0, 1000, 250) = {lerp(0, 1000, 250)} (expect 250)");
174
+ say(f" smoothstep(0,1000,0) = {smoothstep(0, 1000, 0)}");
175
+ say(f" smoothstep(0,1000,500) = {smoothstep(0, 1000, 500)} (expect ~500)");
176
+ say(f" smoothstep(0,1000,1000)= {smoothstep(0, 1000, 1000)}");
177
+ say(f" smootherstep(0,1000,500)={smootherstep(0, 1000, 500)}");
178
+
179
+ say("§eFixed-Point Multiply/Divide:");
180
+ say(f" mulfix(1414, 1414) = {mulfix(1414, 1414)} (≈ 2×1000=2000)");
181
+ say(f" divfix(1000, 3) = {divfix(1000, 3)} (≈ 333)");
182
+ }
183
+
184
+ fn _tick_math() {
185
+ // Animate: show atan2 of a rotating unit vector on actionbar
186
+ state.angle = (state.angle + 3) % 360;
187
+ let s: int = sin_fixed(state.angle);
188
+ let c: int = cos_fixed(state.angle);
189
+ let theta: int = atan2_fixed(s, c); // returns degrees directly
190
+ foreach (p in @a[limit=1]) {
191
+ actionbar(p, f"§bsin={s} §dcos={c} §eatan2={theta}°");
192
+ }
193
+ }
194
+
195
+ // ── Phase 2: BigInt ───────────────────────────────────────────────────────
196
+
197
+ fn _dump_bigint_phase() {
198
+ _section("BigInt — 32-Digit Arbitrary Precision");
199
+
200
+ say("§eFibonacci sequence (BigInt, base-10000 limbs):");
201
+
202
+ // Small Fibonacci — fits in single limb
203
+ let i: int = 0;
204
+ while (i <= 20) {
205
+ bigint_fib(i);
206
+ let v: int = bigint_get_a(0);
207
+ say(f" F({i}) = {v}");
208
+ i = i + 5;
209
+ }
210
+
211
+ // F(50) = 12,586,269,025 (3 limbs)
212
+ bigint_fib(50);
213
+ let f50_2: int = bigint_get_a(2);
214
+ let f50_1: int = bigint_get_a(1);
215
+ let f50_0: int = bigint_get_a(0);
216
+ say(f" F(50) = {f50_2}_{f50_1}_{f50_0} [= 12,586,269,025]");
217
+
218
+ // F(100) = 354,224,848,179,261,915,075 (6 limbs)
219
+ bigint_fib(100);
220
+ let f100_5: int = bigint_get_a(5);
221
+ let f100_4: int = bigint_get_a(4);
222
+ let f100_3: int = bigint_get_a(3);
223
+ let f100_2: int = bigint_get_a(2);
224
+ let f100_1: int = bigint_get_a(1);
225
+ let f100_0: int = bigint_get_a(0);
226
+ say(f" F(100)= {f100_5}_{f100_4}_{f100_3}_{f100_2}_{f100_1}_{f100_0}");
227
+ say(f" [= 354,224,848,179,261,915,075]");
228
+
229
+ // BigInt multiplication: 999999999 × 999999999
230
+ say("§eBigInt Multiply:");
231
+ bigint_init();
232
+ bigint_from_int_a(999999999);
233
+ bigint_from_int_b(999999999);
234
+ bigint_mul();
235
+ let m2: int = bigint_get_c(2);
236
+ let m1: int = bigint_get_c(1);
237
+ let m0: int = bigint_get_c(0);
238
+ say(f" 999999999² = {m2}_{m1}_{m0}");
239
+ say(f" [= 999999998_000000001]");
240
+
241
+ // BigInt subtract
242
+ say("§eBigInt Subtract:");
243
+ bigint_init();
244
+ bigint_from_int_a(1000000000);
245
+ bigint_from_int_b(1);
246
+ bigint_sub();
247
+ let s0: int = bigint_get_c(0);
248
+ let s1: int = bigint_get_c(1);
249
+ say(f" 1,000,000,000 - 1 = {s1}_{s0} [= 999999999]");
250
+ }
251
+
252
+ fn _tick_bigint_live() {
253
+ // Show incremental Fibonacci on actionbar
254
+ if (state.tick % 10 == 0) {
255
+ let n: int = (state.tick / 10) % 30;
256
+ bigint_fib(n);
257
+ let v0: int = bigint_get_a(0);
258
+ let v1: int = bigint_get_a(1);
259
+ foreach (p in @a[limit=1]) {
260
+ actionbar(p, f"§dF({n}) limb[1]={v1} limb[0]={v0}");
261
+ }
262
+ }
263
+ }
264
+
265
+ // ── Phase 3: Advanced Stdlib ──────────────────────────────────────────────
266
+
267
+ fn _dump_advanced_phase() {
268
+ _section("Advanced Stdlib — Number Theory & More");
269
+
270
+ // Primes
271
+ say("§ePrime numbers up to 50:");
272
+ let j: int = 2;
273
+ while (j <= 50) {
274
+ if (is_prime(j) == 1) {
275
+ say(f" {j}");
276
+ }
277
+ j = j + 1;
278
+ }
279
+
280
+ // Collatz conjecture
281
+ say("§eCollatz sequences:");
282
+ say(f" collatz_steps(27) = {collatz_steps(27)} (expect 111)");
283
+ say(f" collatz_steps(97) = {collatz_steps(97)}");
284
+ say(f" collatz_steps(871) = {collatz_steps(871)} (longest for n≤1000)");
285
+
286
+ // Number utilities
287
+ say("§eNumber Utilities:");
288
+ say(f" digit_sum(9999) = {digit_sum(9999)} (expect 36)");
289
+ say(f" reverse_int(12345)= {reverse_int(12345)} (expect 54321)");
290
+ say(f" digital_root(493) = {digital_root(493)} (expect 7)");
291
+
292
+ // Hash & noise
293
+ say("§eHash (splitmix32) & 1D Noise:");
294
+ say(f" hash_int(0) = {hash_int(0)}");
295
+ say(f" hash_int(1) = {hash_int(1)}");
296
+ say(f" noise1d(0,42) = {noise1d(0, 42)}");
297
+ say(f" noise1d(1,42) = {noise1d(1, 42)}");
298
+ say(f" noise1d(2,42) = {noise1d(2, 42)}");
299
+
300
+ // Modular exponentiation
301
+ say("§eModular Exponentiation:");
302
+ say(f" mod_pow(2, 10, 1000) = {mod_pow(2, 10, 1000)} (expect 24)");
303
+ say(f" mod_pow(7, 5, 13) = {mod_pow(7, 5, 13)} (expect 11) // NOTE: m<46340 to avoid INT32 overflow");
304
+
305
+ // Bézier curve
306
+ say("§eQuadratic Bézier (P0=0, P1=1000, P2=0) — shape like ∩:");
307
+ let t: int = 0;
308
+ while (t <= 1000) {
309
+ let bz: int = bezier_quad(0, 1000, 0, t);
310
+ say(f" t={t} → {bz}");
311
+ t = t + 200;
312
+ }
313
+
314
+ // Mandelbrot iteration counts at selected points
315
+ say("§eMandelbrot Iteration Counts:");
316
+ say(f" (0, 0) → {mandelbrot_iter(0, 0, 50)} iters [inside set]");
317
+ say(f" (2000, 0) → {mandelbrot_iter(2000, 0, 50)} iters [outside]");
318
+ say(f" (-1250, 0) → {mandelbrot_iter(-1250, 0, 50)} iters [boundary]");
319
+ say(f" (-750, 1000) → {mandelbrot_iter(-750, 1000, 50)} iters [boundary]");
320
+
321
+ // Vec math
322
+ say("§eVector Math (×1000 fixed-point):");
323
+ say(f" length2d_fixed(3, 4) = {length2d_fixed(3, 4)} (expect 5000)");
324
+ say(f" dot2d(1000,0, 0,1000) = {dot2d(1000, 0, 0, 1000)} (perpendicular = 0)");
325
+ say(f" dot2d(1000,0, 1000,0) = {dot2d(1000, 0, 1000, 0)} (parallel = 1e6)");
326
+ say(f" atan2_fixed(1000, 1000) = {atan2_fixed(1000, 1000)}° (expect 45)");
327
+ say(f" normalize2d_x(3, 4) = {normalize2d_x(3, 4)} (expect 600)");
328
+ say(f" normalize2d_y(3, 4) = {normalize2d_y(3, 4)} (expect 800)");
329
+ }
330
+
331
+ fn _tick_advanced_live() {
332
+ // Scan Mandelbrot x-axis in real time on actionbar
333
+ if (state.tick % 5 == 0) {
334
+ let cx: int = -2000 + (state.tick % 200) * 20; // -2000 to 2000
335
+ let iters: int = mandelbrot_iter(cx, 0, 30);
336
+ foreach (p in @a[limit=1]) {
337
+ actionbar(p, f"§aMandelbrot scan: cx={cx} iters={iters}");
338
+ }
339
+ }
340
+ }
341
+
342
+ // ── Phase 4: Visual Effects ────────────────────────────────────────────────
343
+
344
+ fn _tick_visual() {
345
+ // Advance rotation angle
346
+ state.angle = (state.angle + 2) % 360;
347
+
348
+ // Live sin/cos on actionbar
349
+ let s: int = sin_fixed(state.angle);
350
+ let c: int = cos_fixed(state.angle);
351
+ let len: int = length2d_fixed(s, c);
352
+ foreach (p in @a[limit=1]) {
353
+ actionbar(p, f"§6angle={state.angle}° §bsin={s} §dcos={c} §alen={len}");
354
+ }
355
+
356
+ // Particle ring: 8 cardinal + diagonal points pulsing in Y
357
+ // Y-offset is driven by sin (rises and falls with angle)
358
+ // Note: ~Y syntax uses a macro param; we use fixed ~1 here and
359
+ // place two rings (ground ~0 and elevated ~2) at alternating ticks
360
+ if (state.tick % 2 == 0) {
361
+ foreach (p in @a[limit=1]) at @s {
362
+ // Cardinal — end_rod (blue-white)
363
+ particle("minecraft:end_rod", ~0, ~1, ~5, 0, 0, 0, 0, 1);
364
+ particle("minecraft:end_rod", ~5, ~1, ~0, 0, 0, 0, 0, 1);
365
+ particle("minecraft:end_rod", ~0, ~1, ~-5, 0, 0, 0, 0, 1);
366
+ particle("minecraft:end_rod", ~-5, ~1, ~0, 0, 0, 0, 0, 1);
367
+ // Diagonal — flame (orange)
368
+ particle("minecraft:flame", ~3, ~1, ~3, 0, 0, 0, 0, 1);
369
+ particle("minecraft:flame", ~-3, ~1, ~3, 0, 0, 0, 0, 1);
370
+ particle("minecraft:flame", ~3, ~1, ~-3, 0, 0, 0, 0, 1);
371
+ particle("minecraft:flame", ~-3, ~1, ~-3, 0, 0, 0, 0, 1);
372
+ }
373
+ } else {
374
+ foreach (p in @a[limit=1]) at @s {
375
+ // Upper ring offset by 2 (creates helix effect alternating ticks)
376
+ particle("minecraft:end_rod", ~0, ~3, ~5, 0, 0, 0, 0, 1);
377
+ particle("minecraft:end_rod", ~5, ~3, ~0, 0, 0, 0, 0, 1);
378
+ particle("minecraft:end_rod", ~0, ~3, ~-5, 0, 0, 0, 0, 1);
379
+ particle("minecraft:end_rod", ~-5, ~3, ~0, 0, 0, 0, 0, 1);
380
+ particle("minecraft:flame", ~3, ~3, ~3, 0, 0, 0, 0, 1);
381
+ particle("minecraft:flame", ~-3, ~3, ~3, 0, 0, 0, 0, 1);
382
+ particle("minecraft:flame", ~3, ~3, ~-3, 0, 0, 0, 0, 1);
383
+ particle("minecraft:flame", ~-3, ~3, ~-3, 0, 0, 0, 0, 1);
384
+ }
385
+ }
386
+
387
+ // Firework burst at tick multiples of 100
388
+ if (state.tick % 100 == 0) {
389
+ foreach (p in @a[limit=1]) at @s {
390
+ summon("minecraft:firework_rocket", ~0, ~2, ~0);
391
+ }
392
+ }
393
+ }
394
+
395
+ // ── Public commands ────────────────────────────────────────────────────────
396
+
397
+ fn start() {
398
+ state.running = true;
399
+ state.phase = 0;
400
+ state.tick = 0;
401
+ state.angle = 0;
402
+ phase_timer.reset();
403
+
404
+ _section("RedScript v1.2.26 Showcase");
405
+ say("§aStarting capability demo — phases cycle every 10 seconds.");
406
+ say("§7Math → BigInt → Advanced → Visual FX → (repeat)");
407
+ say("§7Use §f/function showcase:dump_math §7or §f/function showcase:dump_bigint");
408
+ say("§7for the full printed output at any time.");
409
+
410
+ // Kick off phase 1 immediately
411
+ _next_phase();
412
+ }
413
+
414
+ fn stop() {
415
+ state.running = false;
416
+ foreach (p in @a[limit=1]) {
417
+ actionbar(p, "§c[Showcase stopped]");
418
+ }
419
+ say("§c[Showcase] §rStopped.");
420
+ }
421
+
422
+ // Stand-alone dump commands for reference
423
+
424
+ fn dump_math() {
425
+ _dump_math_phase();
426
+ }
427
+
428
+ fn dump_bigint() {
429
+ _dump_bigint_phase();
430
+ }
431
+
432
+ fn dump_advanced() {
433
+ _dump_advanced_phase();
434
+ }
435
+
436
+ // ── BigInt step-by-step debug ─────────────────────────────────────────────
437
+ // /function showcase:debug_bigint
438
+ fn debug_bigint() {
439
+ say("§e=== BigInt Debug ===");
440
+
441
+ // Step 0: check scoreboard objective 'rs' exists (set by __load)
442
+ // If this reads 0, __load hasn't run — do /reload first!
443
+ scoreboard_set("__dbgcheck", #rs, 9999);
444
+ let rs_check: int = scoreboard_get("__dbgcheck", #rs);
445
+ say(f"§7[0] rs-objective check={rs_check} (expect 9999; if 0 → run /reload first!)");
446
+
447
+ // Step 1: init
448
+ bigint_init();
449
+ say("§7[1] bigint_init() done");
450
+
451
+ // Step 2: from_int_a (STATIC index writes, no macro)
452
+ bigint_from_int_a(12345);
453
+ // 2a: static read (data get storage rs:bigint a[0] — NO macro)
454
+ let direct0: int = storage_get_int("rs:bigint", "a", 0);
455
+ let direct1: int = storage_get_int("rs:bigint", "a", 1);
456
+ say(f"§7[2a] static-read a[0]={direct0} a[1]={direct1} (expect 2345,1)");
457
+ // 2b: macro read (bigint_get_a uses macro sub-function)
458
+ let a0: int = bigint_get_a(0);
459
+ let a1: int = bigint_get_a(1);
460
+ say(f"§7[2b] macro-read a[0]={a0} a[1]={a1} (expect 2345,1)");
461
+
462
+ // Step 3: fib(1) = 1 (no carry, simplest case)
463
+ bigint_fib(1);
464
+ let f1: int = bigint_get_a(0);
465
+ say(f"§7[3] fib(1) → get_a(0)={f1} (expect 1)");
466
+
467
+ // Step 4: fib(5) = 5
468
+ bigint_fib(5);
469
+ let f5: int = bigint_get_a(0);
470
+ say(f"§7[4] fib(5) → get_a(0)={f5} (expect 5)");
471
+
472
+ // Step 5: fib(10) = 55
473
+ bigint_fib(10);
474
+ let f10: int = bigint_get_a(0);
475
+ say(f"§7[5] fib(10) → get_a(0)={f10} (expect 55)");
476
+
477
+ // Step 6: fib(20) = 6765
478
+ bigint_fib(20);
479
+ let f20: int = bigint_get_a(0);
480
+ say(f"§7[6] fib(20) → get_a(0)={f20} (expect 6765)");
481
+
482
+ // Step 7: manual add — bigint_add() writes via __ssi macro
483
+ bigint_init();
484
+ bigint_from_int_a(1);
485
+ bigint_from_int_b(1);
486
+ bigint_add();
487
+ let c0: int = bigint_get_c(0);
488
+ say(f"§7[7] 1+1=? get_c(0)={c0} (expect 2)");
489
+
490
+ say("§a=== Done ===");
491
+ }
492
+
493
+ // ── Lambda demo (standalone — shows higher-order functions work) ───────────
494
+
495
+ fn _apply(f: (int) -> int, x: int) -> int {
496
+ return f(x);
497
+ }
498
+
499
+ fn lambda_demo() {
500
+ let double: (int) -> int = (x: int) => x * 2;
501
+ let square: (int) -> int = (x: int) => x * x;
502
+
503
+ say(f" double(7) = {_apply(double, 7)}");
504
+ say(f" square(9) = {_apply(square, 9)}");
505
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redscript-mc",
3
- "version": "1.2.25",
3
+ "version": "1.2.27",
4
4
  "description": "A high-level programming language that compiles to Minecraft datapacks",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -173,7 +173,7 @@ describe('CLI API', () => {
173
173
  const mainFn = result.files.find(file => file.path.endsWith('/main.mcfunction'))
174
174
  expect(doneFn?.content).toContain('scoreboard players get timer_ticks rs')
175
175
  expect(doneFn?.content).toContain('return run scoreboard players get')
176
- expect(mainFn?.content).toContain('execute if score $finished rs matches 1..')
176
+ expect(mainFn?.content).toContain('execute if score $main_finished rs matches 1..')
177
177
  })
178
178
 
179
179
  it('Timer.tick increments', () => {
@@ -19,26 +19,32 @@ describe('generateDatapack', () => {
19
19
  })
20
20
 
21
21
  it('generates function file for simple add(a, b)', () => {
22
+ // IR now uses { kind: 'param', index: i } for param-copy instructions,
23
+ // matching what the lowering emits. Pass mangle:false so we can check
24
+ // readable names without worrying about sequential mangled names.
22
25
  const mod: IRModule = {
23
26
  namespace: 'mypack',
24
27
  globals: [],
25
28
  functions: [{
26
29
  name: 'add',
27
- params: ['a', 'b'],
28
- locals: ['a', 'b', 'result'],
30
+ params: ['$a', '$b'],
31
+ locals: ['$a', '$b', '$result'],
29
32
  blocks: [{
30
33
  label: 'entry',
31
34
  instrs: [
32
- { op: 'binop', dst: 'result', lhs: { kind: 'var', name: 'a' }, bop: '+', rhs: { kind: 'var', name: 'b' } },
35
+ // param-copy instructions (what the lowering now emits)
36
+ { op: 'assign', dst: '$a', src: { kind: 'param', index: 0 } },
37
+ { op: 'assign', dst: '$b', src: { kind: 'param', index: 1 } },
38
+ { op: 'binop', dst: '$result', lhs: { kind: 'var', name: '$a' }, bop: '+', rhs: { kind: 'var', name: '$b' } },
33
39
  ],
34
- term: { op: 'return', value: { kind: 'var', name: 'result' } },
40
+ term: { op: 'return', value: { kind: 'var', name: '$result' } },
35
41
  }],
36
42
  }],
37
43
  }
38
- const files = generateDatapack(mod)
44
+ const files = generateDatapackWithStats(mod, { mangle: false }).files
39
45
  const fn = files.find(f => f.path.includes('add.mcfunction'))
40
46
  expect(fn).toBeDefined()
41
- // Should have param setup
47
+ // param setup emitted from the IR
42
48
  expect(fn!.content).toContain('scoreboard players operation $a rs = $p0 rs')
43
49
  expect(fn!.content).toContain('scoreboard players operation $b rs = $p1 rs')
44
50
  // Should have add operation
@@ -124,7 +124,7 @@ fn main() {
124
124
  `)
125
125
  const mainFn = getFunction(files, 'main')
126
126
  expect(mainFn).toBeDefined()
127
- expect(mainFn).toContain('scoreboard players set $hp rs 105')
127
+ expect(mainFn).toContain('scoreboard players set $main_hp rs 105')
128
128
  expect(mainFn).toContain('Arena Battle')
129
129
  })
130
130
  })
@@ -1852,7 +1852,7 @@ describe('for-range loop', () => {
1852
1852
  const src = `fn test() { for i in 0..5 { say("hi"); } }`
1853
1853
  const files = compile(src, 'forloop')
1854
1854
  const fn = getFunction(files, 'test')
1855
- expect(fn).toContain('scoreboard players set $i rs 0')
1855
+ expect(fn).toContain('scoreboard players set $test_i rs 0')
1856
1856
  })
1857
1857
 
1858
1858
  it('generates loop sub-function with increment and condition', () => {
@@ -1861,17 +1861,17 @@ describe('for-range loop', () => {
1861
1861
  const subFn = files.find(f => f.path.includes('__for_0'))
1862
1862
  expect(subFn).toBeDefined()
1863
1863
  expect(subFn?.content).toContain('say hi')
1864
- expect(subFn?.content).toContain('scoreboard players add $i rs 1')
1865
- expect(subFn?.content).toContain('execute if score $i rs matches ..4 run function forloop:test/__for_0')
1864
+ expect(subFn?.content).toContain('scoreboard players add $test_i rs 1')
1865
+ expect(subFn?.content).toContain('execute if score $test_i rs matches ..4 run function forloop:test/__for_0')
1866
1866
  })
1867
1867
 
1868
1868
  it('supports non-zero start', () => {
1869
1869
  const src = `fn test() { for x in 3..8 { say("loop"); } }`
1870
1870
  const files = compile(src, 'forloop2')
1871
1871
  const fn = getFunction(files, 'test')
1872
- expect(fn).toContain('scoreboard players set $x rs 3')
1872
+ expect(fn).toContain('scoreboard players set $test_x rs 3')
1873
1873
  const subFn = files.find(f => f.path.includes('__for_0'))
1874
- expect(subFn?.content).toContain('execute if score $x rs matches ..7 run function forloop2:test/__for_0')
1874
+ expect(subFn?.content).toContain('execute if score $test_x rs matches ..7 run function forloop2:test/__for_0')
1875
1875
  })
1876
1876
  })
1877
1877
 
@@ -50,7 +50,7 @@ describe('Lowering', () => {
50
50
  const fn = getFunction(ir, 'foo')!
51
51
  const instrs = getInstructions(fn)
52
52
  expect(instrs.some(i =>
53
- i.op === 'assign' && i.dst === '$x' && (i.src as any).name === '$p0'
53
+ i.op === 'assign' && i.dst === '$foo_x' && (i.src as any).kind === 'param' && (i.src as any).index === 0
54
54
  )).toBe(true)
55
55
  })
56
56
 
@@ -139,7 +139,7 @@ fn foo() {
139
139
  const fn = getFunction(ir, 'foo')!
140
140
  const instrs = getInstructions(fn)
141
141
  expect(instrs.some(i =>
142
- i.op === 'assign' && i.dst === '$x' && (i.src as any).kind === 'const' && (i.src as any).value === 100
142
+ i.op === 'assign' && i.dst === '$foo_x' && (i.src as any).kind === 'const' && (i.src as any).value === 100
143
143
  )).toBe(true)
144
144
  expect(ir.globals).not.toContain('$MAX_HP')
145
145
  })
@@ -149,7 +149,7 @@ fn foo() {
149
149
  const fn = getFunction(ir, 'foo')!
150
150
  const instrs = getInstructions(fn)
151
151
  expect(instrs.some(i =>
152
- i.op === 'assign' && i.dst === '$x' && (i.src as any).value === 42
152
+ i.op === 'assign' && i.dst === '$foo_x' && (i.src as any).value === 42
153
153
  )).toBe(true)
154
154
  })
155
155
 
@@ -579,16 +579,16 @@ fn choose(dir: Direction) {
579
579
  const ir = compile('fn test() { let score: int = 7; say("You have ${score} points"); }')
580
580
  const fn = getFunction(ir, 'test')!
581
581
  const rawCmds = getRawCommands(fn)
582
- expect(rawCmds).toContain('tellraw @a ["",{"text":"You have "},{"score":{"name":"$score","objective":"rs"}},{"text":" points"}]')
582
+ expect(rawCmds).toContain('tellraw @a ["",{"text":"You have "},{"score":{"name":"$test_score","objective":"rs"}},{"text":" points"}]')
583
583
  })
584
584
 
585
585
  it('lowers f-string output builtins to tellraw/title JSON components', () => {
586
586
  const ir = compile('fn test() { let score: int = 7; say(f"Score: {score}"); tellraw(@a, f"Score: {score}"); actionbar(@s, f"Score: {score}"); title(@s, f"Score: {score}"); }')
587
587
  const fn = getFunction(ir, 'test')!
588
588
  const rawCmds = getRawCommands(fn)
589
- expect(rawCmds).toContain('tellraw @a ["",{"text":"Score: "},{"score":{"name":"$score","objective":"rs"}}]')
590
- expect(rawCmds).toContain('title @s actionbar ["",{"text":"Score: "},{"score":{"name":"$score","objective":"rs"}}]')
591
- expect(rawCmds).toContain('title @s title ["",{"text":"Score: "},{"score":{"name":"$score","objective":"rs"}}]')
589
+ expect(rawCmds).toContain('tellraw @a ["",{"text":"Score: "},{"score":{"name":"$test_score","objective":"rs"}}]')
590
+ expect(rawCmds).toContain('title @s actionbar ["",{"text":"Score: "},{"score":{"name":"$test_score","objective":"rs"}}]')
591
+ expect(rawCmds).toContain('title @s title ["",{"text":"Score: "},{"score":{"name":"$test_score","objective":"rs"}}]')
592
592
  })
593
593
 
594
594
  it('lowers summon()', () => {
@@ -1149,7 +1149,7 @@ fn count_down() {
1149
1149
  const fn = getFunction(ir, 'test')!
1150
1150
  const instrs = getInstructions(fn)
1151
1151
  expect(instrs.some(i =>
1152
- i.op === 'assign' && i.dst === '$y' && (i.src as any).kind === 'var' && (i.src as any).name === '$count'
1152
+ i.op === 'assign' && i.dst === '$test_y' && (i.src as any).kind === 'var' && (i.src as any).name === '$count'
1153
1153
  )).toBe(true)
1154
1154
  })
1155
1155