redscript-mc 1.1.0 → 1.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.
- package/CHANGELOG.md +59 -0
- package/README.md +53 -10
- package/README.zh.md +53 -10
- package/dist/__tests__/cli.test.js +138 -0
- package/dist/__tests__/codegen.test.js +25 -0
- package/dist/__tests__/dce.test.d.ts +1 -0
- package/dist/__tests__/dce.test.js +137 -0
- package/dist/__tests__/e2e.test.js +190 -12
- package/dist/__tests__/lexer.test.js +31 -4
- package/dist/__tests__/lowering.test.js +172 -9
- package/dist/__tests__/mc-integration.test.js +145 -51
- package/dist/__tests__/mc-syntax.test.js +12 -0
- package/dist/__tests__/optimizer-advanced.test.js +3 -3
- package/dist/__tests__/parser.test.js +90 -0
- package/dist/__tests__/runtime.test.js +21 -8
- package/dist/__tests__/typechecker.test.js +188 -0
- package/dist/ast/types.d.ts +42 -3
- package/dist/cli.js +15 -10
- package/dist/codegen/mcfunction/index.js +30 -1
- package/dist/codegen/structure/index.d.ts +4 -1
- package/dist/codegen/structure/index.js +29 -2
- package/dist/compile.d.ts +11 -0
- package/dist/compile.js +40 -6
- package/dist/events/types.d.ts +35 -0
- package/dist/events/types.js +59 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -3
- package/dist/ir/types.d.ts +4 -0
- package/dist/lexer/index.d.ts +2 -1
- package/dist/lexer/index.js +91 -1
- package/dist/lowering/index.d.ts +32 -1
- package/dist/lowering/index.js +476 -16
- package/dist/optimizer/dce.d.ts +23 -0
- package/dist/optimizer/dce.js +591 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.js +160 -26
- package/dist/typechecker/index.d.ts +19 -0
- package/dist/typechecker/index.js +392 -17
- package/docs/ARCHITECTURE.zh.md +1088 -0
- package/docs/ENTITY_TYPE_SYSTEM.md +242 -0
- package/editors/vscode/.vscodeignore +3 -0
- package/editors/vscode/CHANGELOG.md +9 -0
- package/editors/vscode/icon.png +0 -0
- package/editors/vscode/out/extension.js +1144 -72
- package/editors/vscode/package-lock.json +2 -2
- package/editors/vscode/package.json +1 -1
- package/editors/vscode/syntaxes/redscript.tmLanguage.json +6 -2
- package/examples/spiral.mcrs +79 -0
- package/logo.png +0 -0
- package/package.json +1 -1
- package/src/__tests__/cli.test.ts +166 -0
- package/src/__tests__/codegen.test.ts +27 -0
- package/src/__tests__/dce.test.ts +129 -0
- package/src/__tests__/e2e.test.ts +201 -12
- package/src/__tests__/fixtures/event-test.mcrs +13 -0
- package/src/__tests__/fixtures/impl-test.mcrs +46 -0
- package/src/__tests__/fixtures/interval-test.mcrs +11 -0
- package/src/__tests__/fixtures/is-check-test.mcrs +20 -0
- package/src/__tests__/fixtures/timeout-test.mcrs +7 -0
- package/src/__tests__/lexer.test.ts +35 -4
- package/src/__tests__/lowering.test.ts +187 -9
- package/src/__tests__/mc-integration.test.ts +166 -51
- package/src/__tests__/mc-syntax.test.ts +14 -0
- package/src/__tests__/optimizer-advanced.test.ts +3 -3
- package/src/__tests__/parser.test.ts +102 -5
- package/src/__tests__/runtime.test.ts +24 -8
- package/src/__tests__/typechecker.test.ts +204 -0
- package/src/ast/types.ts +39 -2
- package/src/cli.ts +24 -10
- package/src/codegen/mcfunction/index.ts +31 -1
- package/src/codegen/structure/index.ts +40 -2
- package/src/compile.ts +59 -7
- package/src/events/types.ts +69 -0
- package/src/index.ts +9 -4
- package/src/ir/types.ts +4 -0
- package/src/lexer/index.ts +105 -2
- package/src/lowering/index.ts +566 -18
- package/src/optimizer/dce.ts +618 -0
- package/src/parser/index.ts +187 -29
- package/src/stdlib/README.md +34 -4
- package/src/stdlib/tags.mcrs +951 -0
- package/src/stdlib/timer.mcrs +54 -33
- package/src/typechecker/index.ts +469 -18
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Entity Type System
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
RedScript v1.2 introduces a hierarchical entity type system that provides:
|
|
6
|
+
- Compile-time type checking for entity operations
|
|
7
|
+
- IDE autocompletion for entity-specific methods
|
|
8
|
+
- Type narrowing via `is` assertions
|
|
9
|
+
- Context-aware `@s` typing
|
|
10
|
+
|
|
11
|
+
## Type Hierarchy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
entity (base type)
|
|
15
|
+
├── Player ← @a, @p, @r
|
|
16
|
+
├── Mob
|
|
17
|
+
│ ├── HostileMob
|
|
18
|
+
│ │ ├── Zombie
|
|
19
|
+
│ │ ├── Skeleton
|
|
20
|
+
│ │ ├── Creeper
|
|
21
|
+
│ │ └── ...
|
|
22
|
+
│ └── PassiveMob
|
|
23
|
+
│ ├── Pig
|
|
24
|
+
│ ├── Cow
|
|
25
|
+
│ ├── Sheep
|
|
26
|
+
│ └── ...
|
|
27
|
+
├── Item
|
|
28
|
+
├── ArmorStand
|
|
29
|
+
├── Projectile
|
|
30
|
+
│ ├── Arrow
|
|
31
|
+
│ ├── Fireball
|
|
32
|
+
│ └── ...
|
|
33
|
+
└── ... (extensible)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Selector Return Types
|
|
37
|
+
|
|
38
|
+
| Selector | Return Type |
|
|
39
|
+
|----------|-------------|
|
|
40
|
+
| `@a` | `Player` |
|
|
41
|
+
| `@p` | `Player` |
|
|
42
|
+
| `@r` | `Player` |
|
|
43
|
+
| `@e` | `entity` |
|
|
44
|
+
| `@e[type=zombie]` | `Zombie` |
|
|
45
|
+
| `@e[type=pig]` | `Pig` |
|
|
46
|
+
| `@s` | Context-dependent |
|
|
47
|
+
|
|
48
|
+
## Basic Usage
|
|
49
|
+
|
|
50
|
+
### Foreach with Type Inference
|
|
51
|
+
|
|
52
|
+
```mcrs
|
|
53
|
+
// @a returns Player - player-specific methods available
|
|
54
|
+
foreach (p in @a) {
|
|
55
|
+
p.give("diamond", 1); // ✅ Player method
|
|
56
|
+
p.gamemode("creative"); // ✅ Player method
|
|
57
|
+
p.kill(); // ✅ entity method (inherited)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// @e returns entity - only base methods
|
|
61
|
+
foreach (e in @e) {
|
|
62
|
+
e.kill(); // ✅ entity method
|
|
63
|
+
e.give("diamond", 1); // ❌ Compile error: give() requires Player
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// @e[type=X] infers specific type
|
|
67
|
+
foreach (z in @e[type=zombie]) {
|
|
68
|
+
z.kill(); // ✅ entity method
|
|
69
|
+
z.setNoAI(true); // ✅ Mob method
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### @s Context Typing
|
|
74
|
+
|
|
75
|
+
`@s` type depends on the current execution context:
|
|
76
|
+
|
|
77
|
+
```mcrs
|
|
78
|
+
// Top-level: @s is entity (conservative)
|
|
79
|
+
@tick fn tick() {
|
|
80
|
+
@s.kill(); // ✅ entity method only
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Inside foreach @a: @s is Player
|
|
84
|
+
foreach (p in @a) {
|
|
85
|
+
@s.give("diamond", 1); // ✅ @s is Player
|
|
86
|
+
p.give("diamond", 1); // ✅ Same as @s
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Inside as block: @s changes
|
|
90
|
+
foreach (p in @a) {
|
|
91
|
+
// @s: Player
|
|
92
|
+
as @e[type=zombie] {
|
|
93
|
+
// @s: Zombie (context changed)
|
|
94
|
+
@s.setNoAI(true); // ✅ Mob method
|
|
95
|
+
}
|
|
96
|
+
// @s: Player (restored)
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Type Narrowing with `is`
|
|
101
|
+
|
|
102
|
+
```mcrs
|
|
103
|
+
foreach (e in @e) {
|
|
104
|
+
// e: entity
|
|
105
|
+
|
|
106
|
+
if (e is Player) {
|
|
107
|
+
// e: Player (narrowed)
|
|
108
|
+
e.give("diamond", 1); // ✅
|
|
109
|
+
e.gamemode("survival"); // ✅
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (e is Zombie) {
|
|
113
|
+
// e: Zombie (narrowed)
|
|
114
|
+
e.setNoAI(true); // ✅
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Explicit Type Assertions
|
|
120
|
+
|
|
121
|
+
```mcrs
|
|
122
|
+
// Assert type (unsafe - runtime behavior unchanged)
|
|
123
|
+
let boss = @e[tag=boss,limit=1] as Zombie;
|
|
124
|
+
boss.setNoAI(true); // Treated as Zombie
|
|
125
|
+
|
|
126
|
+
// Safe pattern: combine with type filter
|
|
127
|
+
foreach (z in @e[type=zombie,tag=boss] as Zombie) {
|
|
128
|
+
z.setNoAI(true);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Entity Methods
|
|
133
|
+
|
|
134
|
+
### Base `entity` Methods
|
|
135
|
+
|
|
136
|
+
All entities have:
|
|
137
|
+
- `kill()` - Remove entity
|
|
138
|
+
- `tp(x, y, z)` - Teleport
|
|
139
|
+
- `tag_add(tag)` / `tag_remove(tag)` - Tags
|
|
140
|
+
- `data_merge(nbt)` - NBT manipulation
|
|
141
|
+
- `effect(effect, duration, level)` - Effects
|
|
142
|
+
|
|
143
|
+
### `Player` Methods
|
|
144
|
+
|
|
145
|
+
Players additionally have:
|
|
146
|
+
- `give(item, count)` - Give items
|
|
147
|
+
- `clear(item?)` - Clear inventory
|
|
148
|
+
- `gamemode(mode)` - Set gamemode
|
|
149
|
+
- `xp(amount, type)` - XP manipulation
|
|
150
|
+
- `title(text)` / `subtitle(text)` / `actionbar(text)` - Display
|
|
151
|
+
- `playsound(sound)` - Audio
|
|
152
|
+
|
|
153
|
+
### `Mob` Methods
|
|
154
|
+
|
|
155
|
+
Mobs additionally have:
|
|
156
|
+
- `setNoAI(bool)` - Disable AI
|
|
157
|
+
- `setHealth(amount)` - Set health
|
|
158
|
+
- `setInvisible(bool)` - Visibility
|
|
159
|
+
|
|
160
|
+
## Implementation Details
|
|
161
|
+
|
|
162
|
+
### Self Type Stack
|
|
163
|
+
|
|
164
|
+
The type checker maintains a stack of self types:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
class TypeChecker {
|
|
168
|
+
private selfTypeStack: EntityType[] = [{ kind: 'entity' }];
|
|
169
|
+
|
|
170
|
+
enterContext(selector: Selector) {
|
|
171
|
+
this.selfTypeStack.push(this.inferEntityType(selector));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exitContext() {
|
|
175
|
+
this.selfTypeStack.pop();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
getSelfType(): EntityType {
|
|
179
|
+
return this.selfTypeStack[this.selfTypeStack.length - 1];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Type Inference from Selector
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
function inferEntityType(selector: Selector): EntityType {
|
|
188
|
+
switch (selector.kind) {
|
|
189
|
+
case '@a':
|
|
190
|
+
case '@p':
|
|
191
|
+
case '@r':
|
|
192
|
+
return { kind: 'Player' };
|
|
193
|
+
case '@e':
|
|
194
|
+
case '@s':
|
|
195
|
+
if (selector.filters?.type) {
|
|
196
|
+
return entityTypeFromMinecraftType(selector.filters.type);
|
|
197
|
+
}
|
|
198
|
+
return { kind: 'entity' };
|
|
199
|
+
default:
|
|
200
|
+
return { kind: 'entity' };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Method Resolution
|
|
206
|
+
|
|
207
|
+
Methods are resolved based on the entity type hierarchy:
|
|
208
|
+
|
|
209
|
+
1. Check if method exists on the specific type
|
|
210
|
+
2. Walk up the hierarchy checking parent types
|
|
211
|
+
3. Error if not found on any ancestor
|
|
212
|
+
|
|
213
|
+
## Future Extensions
|
|
214
|
+
|
|
215
|
+
### Custom Entity Types (v1.3+)
|
|
216
|
+
|
|
217
|
+
```mcrs
|
|
218
|
+
// Define custom entity type with tag
|
|
219
|
+
entity Boss extends Zombie {
|
|
220
|
+
tag: "boss";
|
|
221
|
+
|
|
222
|
+
fn enrage() {
|
|
223
|
+
effect(@s, "strength", 100, 2);
|
|
224
|
+
effect(@s, "speed", 100, 1);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Auto-narrowed when tag matches
|
|
229
|
+
foreach (b in @e[tag=boss] as Boss) {
|
|
230
|
+
b.enrage();
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Generic Selectors (v1.3+)
|
|
235
|
+
|
|
236
|
+
```mcrs
|
|
237
|
+
fn buff<T: Player>(targets: T[]) {
|
|
238
|
+
foreach (t in targets) {
|
|
239
|
+
t.effect("strength", 30, 1);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the RedScript VSCode extension will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-03-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Support for RedScript 1.2.0 language features and stdlib updates
|
|
9
|
+
- Highlighting and tooling updates for `is` checks, `impl` blocks, static method calls, timers, and `@on(Event)`
|
package/editors/vscode/icon.png
CHANGED
|
Binary file
|