redscript-mc 2.1.0 → 2.2.1

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 (71) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +86 -21
  3. package/README.zh.md +61 -61
  4. package/dist/src/__tests__/e2e/basic.test.js +25 -0
  5. package/dist/src/__tests__/e2e/coroutine.test.js +22 -0
  6. package/dist/src/__tests__/lsp.test.js +76 -0
  7. package/dist/src/__tests__/mc-integration.test.js +25 -13
  8. package/dist/src/__tests__/mc-syntax.test.js +1 -6
  9. package/dist/src/__tests__/schedule.test.js +105 -0
  10. package/dist/src/__tests__/stdlib-include.test.d.ts +1 -0
  11. package/dist/src/__tests__/stdlib-include.test.js +86 -0
  12. package/dist/src/__tests__/typechecker.test.js +63 -0
  13. package/dist/src/cli.js +10 -3
  14. package/dist/src/compile.d.ts +1 -0
  15. package/dist/src/compile.js +33 -10
  16. package/dist/src/emit/compile.d.ts +2 -0
  17. package/dist/src/emit/compile.js +3 -2
  18. package/dist/src/emit/index.js +3 -1
  19. package/dist/src/lir/lower.js +26 -0
  20. package/dist/src/lsp/server.js +51 -0
  21. package/dist/src/mir/lower.js +341 -12
  22. package/dist/src/mir/types.d.ts +10 -0
  23. package/dist/src/optimizer/copy_prop.js +4 -0
  24. package/dist/src/optimizer/coroutine.d.ts +2 -0
  25. package/dist/src/optimizer/coroutine.js +33 -1
  26. package/dist/src/optimizer/dce.js +7 -1
  27. package/dist/src/optimizer/lir/const_imm.js +1 -1
  28. package/dist/src/optimizer/lir/dead_slot.js +1 -1
  29. package/dist/src/typechecker/index.d.ts +2 -0
  30. package/dist/src/typechecker/index.js +29 -0
  31. package/docs/ROADMAP.md +35 -0
  32. package/editors/vscode/package-lock.json +3 -3
  33. package/editors/vscode/package.json +1 -1
  34. package/editors/vscode/syntaxes/redscript.tmLanguage.json +34 -0
  35. package/examples/coroutine-demo.mcrs +51 -0
  36. package/examples/enum-demo.mcrs +95 -0
  37. package/examples/scheduler-demo.mcrs +59 -0
  38. package/jest.config.js +19 -0
  39. package/package.json +1 -1
  40. package/src/__tests__/e2e/basic.test.ts +27 -0
  41. package/src/__tests__/e2e/coroutine.test.ts +23 -0
  42. package/src/__tests__/fixtures/array-test.mcrs +21 -22
  43. package/src/__tests__/fixtures/counter.mcrs +17 -0
  44. package/src/__tests__/fixtures/foreach-at-test.mcrs +9 -10
  45. package/src/__tests__/lsp.test.ts +89 -0
  46. package/src/__tests__/mc-integration.test.ts +25 -13
  47. package/src/__tests__/mc-syntax.test.ts +1 -7
  48. package/src/__tests__/schedule.test.ts +112 -0
  49. package/src/__tests__/stdlib-include.test.ts +61 -0
  50. package/src/__tests__/typechecker.test.ts +68 -0
  51. package/src/cli.ts +9 -1
  52. package/src/compile.ts +44 -15
  53. package/src/emit/compile.ts +5 -2
  54. package/src/emit/index.ts +3 -1
  55. package/src/lir/lower.ts +27 -0
  56. package/src/lsp/server.ts +55 -0
  57. package/src/mir/lower.ts +355 -9
  58. package/src/mir/types.ts +4 -0
  59. package/src/optimizer/copy_prop.ts +4 -0
  60. package/src/optimizer/coroutine.ts +37 -1
  61. package/src/optimizer/dce.ts +6 -1
  62. package/src/optimizer/lir/const_imm.ts +1 -1
  63. package/src/optimizer/lir/dead_slot.ts +1 -1
  64. package/src/stdlib/timer.mcrs +10 -5
  65. package/src/typechecker/index.ts +39 -0
  66. package/examples/spiral.mcrs +0 -43
  67. package/src/examples/arena.mcrs +0 -44
  68. package/src/examples/counter.mcrs +0 -12
  69. package/src/examples/new_features_demo.mcrs +0 -193
  70. package/src/examples/rpg.mcrs +0 -13
  71. package/src/examples/stdlib_demo.mcrs +0 -181
@@ -1,181 +0,0 @@
1
- // Stdlib pattern demo: a simple survival loop.
2
- //
3
- // This file is standalone on purpose. Since RedScript has no import system yet,
4
- // copy the helpers you need from src/stdlib/ into your project file.
5
-
6
- fn abs(x: int) -> int {
7
- if (x < 0) {
8
- return -x;
9
- } else {
10
- return x;
11
- }
12
- }
13
-
14
- fn clamp(x: int, lo: int, hi: int) -> int {
15
- if (x < lo) {
16
- return lo;
17
- } else {
18
- if (x > hi) {
19
- return hi;
20
- } else {
21
- return x;
22
- }
23
- }
24
- }
25
-
26
- fn heal(amount: int) {
27
- let health: int = scoreboard_get(@p, #health);
28
- let next: int = health + amount;
29
- scoreboard_set(@p, #health, next);
30
- }
31
-
32
- fn damage(amount: int) {
33
- let health: int = scoreboard_get(@p, #health);
34
- let next: int = health - amount;
35
-
36
- if (next < 0) {
37
- scoreboard_set(@p, #health, 0);
38
- } else {
39
- scoreboard_set(@p, #health, next);
40
- }
41
- }
42
-
43
- fn is_op() -> int {
44
- let result: int = 0;
45
-
46
- execute if entity @p[tag=op] run {
47
- result = 1;
48
- }
49
-
50
- return result;
51
- }
52
-
53
- fn timer_start(name: string, duration: int) {
54
- scoreboard_set("demo_timer_ticks", #rs, duration);
55
- scoreboard_set("demo_timer_active", #rs, 1);
56
- }
57
-
58
- fn timer_tick(name: string) -> int {
59
- let active: int = scoreboard_get("demo_timer_active", #rs);
60
- let ticks: int = scoreboard_get("demo_timer_ticks", #rs);
61
-
62
- if (active == 0) {
63
- return 0;
64
- }
65
-
66
- if (ticks > 0) {
67
- let next: int = ticks - 1;
68
- scoreboard_set("demo_timer_ticks", #rs, next);
69
-
70
- if (next == 0) {
71
- scoreboard_set("demo_timer_active", #rs, 0);
72
- }
73
-
74
- return next;
75
- }
76
-
77
- scoreboard_set("demo_timer_active", #rs, 0);
78
- return 0;
79
- }
80
-
81
- fn timer_done(name: string) -> int {
82
- let active: int = scoreboard_get("demo_timer_active", #rs);
83
- let ticks: int = scoreboard_get("demo_timer_ticks", #rs);
84
-
85
- if (active == 0) {
86
- if (ticks <= 0) {
87
- return 1;
88
- }
89
- }
90
-
91
- return 0;
92
- }
93
-
94
- fn cooldown_start(name: string, ticks: int) {
95
- scoreboard_set("demo_dash_ticks", #rs, ticks);
96
- scoreboard_set("demo_dash_active", #rs, 1);
97
- }
98
-
99
- fn cooldown_ready(name: string) -> int {
100
- let active: int = scoreboard_get("demo_dash_active", #rs);
101
- let ticks_left: int = scoreboard_get("demo_dash_ticks", #rs);
102
-
103
- if (active == 0) {
104
- return 1;
105
- }
106
-
107
- if (ticks_left <= 0) {
108
- return 1;
109
- }
110
-
111
- return 0;
112
- }
113
-
114
- fn cooldown_tick(name: string) {
115
- let active: int = scoreboard_get("demo_dash_active", #rs);
116
- let ticks_left: int = scoreboard_get("demo_dash_ticks", #rs);
117
-
118
- if (active == 0) {
119
- return;
120
- }
121
-
122
- if (ticks_left > 0) {
123
- let next: int = ticks_left - 1;
124
- scoreboard_set("demo_dash_ticks", #rs, next);
125
-
126
- if (next == 0) {
127
- scoreboard_set("demo_dash_active", #rs, 0);
128
- }
129
- } else {
130
- scoreboard_set("demo_dash_active", #rs, 0);
131
- }
132
- }
133
-
134
- @on_trigger("arena_start")
135
- fn arena_start() {
136
- scoreboard_set("arena_zone_center", #rs, 0);
137
- scoreboard_set(@p, #health, 20);
138
- timer_start("wave", 200);
139
- cooldown_start("dash", 0);
140
- title(@p, "Arena started");
141
- }
142
-
143
- @tick
144
- fn arena_tick() {
145
- let remaining: int = timer_tick("wave");
146
- cooldown_tick("dash");
147
-
148
- if (timer_done("wave") == 1) {
149
- title(@p, "Next wave");
150
- timer_start("wave", 200);
151
- }
152
-
153
- let player_x: int = data_get("entity", @p, "Pos[0]");
154
- let delta: int = player_x - scoreboard_get("arena_zone_center", #rs);
155
- let distance: int = abs(delta);
156
- let pressure: int = clamp(distance, 0, 8);
157
-
158
- if (pressure > 4) {
159
- damage(1);
160
- } else {
161
- heal(1);
162
- }
163
-
164
- if (remaining <= 40) {
165
- tell(@p, "Wave nearly over.");
166
- }
167
- }
168
-
169
- @on_trigger("dash")
170
- fn dash_trigger() {
171
- if (cooldown_ready("dash") == 1) {
172
- raw("effect give @p speed 1 3 true");
173
- cooldown_start("dash", 80);
174
- } else {
175
- tell(@p, "Dash is cooling down.");
176
- }
177
-
178
- if (is_op() == 1) {
179
- tell(@p, "Operator override available.");
180
- }
181
- }