ic10r-node 1.0.0 → 1.0.2
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 +5 -5
- package/README.md +400 -400
- package/README.zh.md +400 -400
- package/package.json +1 -1
- package/types/context.d.ts +5 -2
- package/types/engine.d.ts +2 -0
- package/types/index.d.ts +1 -0
- package/types/memory.d.ts +3 -2
- package/types/value.d.ts +22 -0
package/README.md
CHANGED
|
@@ -1,400 +1,400 @@
|
|
|
1
|
-
# ic10r-node
|
|
2
|
-
|
|
3
|
-
[](https://badge.fury.io/js/ic10r_node)
|
|
4
|
-
[](https://nodejs.org/)
|
|
5
|
-
[](https://isocpp.org/)
|
|
6
|
-
[](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
|
7
|
-
|
|
8
|
-
[中文](./README.zh.md)
|
|
9
|
-
|
|
10
|
-
## Overview
|
|
11
|
-
|
|
12
|
-
`ic10r-node` is the Node.js native binding module for the **IC10 Runtime**, providing a complete execution engine for IC10 programs.
|
|
13
|
-
|
|
14
|
-
IC10 is an assembly-style programming language used in the game [Stationeers](https://store.steampowered.com/app/544550/Stationeers/) to control computers and devices in the game. This module takes the compiled AST and symbol table (produced by [`ic10c-node`](https://www.npmjs.com/package/ic10c-node)) and executes the program tick-by-tick, simulating the IC10 processor's behavior.
|
|
15
|
-
|
|
16
|
-
## Features
|
|
17
|
-
|
|
18
|
-
- **Execution Engine** – runs IC10 programs tick-by-tick (`runTick`) or to completion (`runFull`)
|
|
19
|
-
- **Register File & Stack** – full 16-register file (`r0`–`r15`) and stack memory (`push`/`pop`/`peek`/`poke`)
|
|
20
|
-
- **Device Manager** – register external devices and the chip device, query by type/name hash
|
|
21
|
-
- **Device I/O** – read/write logic properties, device stacks, slots, and reagent modes
|
|
22
|
-
- **Execution Control** – `halt`/`sleep` support, instruction limit, tick duration configuration
|
|
23
|
-
- **Cross‑Platform** – builds on Linux (GCC/Clang) and Windows (MSVC)
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
### Prerequisites
|
|
28
|
-
|
|
29
|
-
- Node.js >= 16.0.0 (Node.js 26.x recommended)
|
|
30
|
-
- C++ compiler (GCC 13+ / Clang 16+ / MSVC 2022)
|
|
31
|
-
- CMake >= 3.28.1
|
|
32
|
-
- [`ic10c-node`](https://www.npmjs.com/package/ic10c-node) (peer dependency for compilation)
|
|
33
|
-
|
|
34
|
-
### Install from npm
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npm install ic10r-node ic10c-node
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Build from Source
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# Clone repository
|
|
44
|
-
git clone https://github.com/edoCsItahW/Stationeers.git
|
|
45
|
-
cd Stationeers/code/IC10/backend/runtime
|
|
46
|
-
|
|
47
|
-
# Install dependencies
|
|
48
|
-
npm install
|
|
49
|
-
|
|
50
|
-
# Download Node.js headers
|
|
51
|
-
npx node-gyp install
|
|
52
|
-
|
|
53
|
-
# Build native module
|
|
54
|
-
npm run build
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Quick Start
|
|
58
|
-
|
|
59
|
-
### Basic Usage
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import * as ic10c from 'ic10c-node';
|
|
63
|
-
import * as ic10r from 'ic10r-node';
|
|
64
|
-
|
|
65
|
-
// IC10 source code
|
|
66
|
-
const source = `
|
|
67
|
-
main:
|
|
68
|
-
move r0 42
|
|
69
|
-
add r1 r0 10
|
|
70
|
-
hcf
|
|
71
|
-
`;
|
|
72
|
-
|
|
73
|
-
// 1. Compile (using ic10c-node)
|
|
74
|
-
const tokens = ic10c.Lexer.tokenize(source);
|
|
75
|
-
const program = new ic10c.Parser(tokens).parse();
|
|
76
|
-
const analyser = new ic10c.Analyser();
|
|
77
|
-
await analyser.visit(program);
|
|
78
|
-
|
|
79
|
-
// 2. Create engine (using ic10r-node)
|
|
80
|
-
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
81
|
-
|
|
82
|
-
// 3. Execute
|
|
83
|
-
engine.runFull();
|
|
84
|
-
|
|
85
|
-
// 4. Inspect results
|
|
86
|
-
const r0 = engine.context.memory.getReg('r0'); // 42
|
|
87
|
-
const r1 = engine.context.memory.getReg('r1'); // 52
|
|
88
|
-
console.log(`r0 = ${r0}, r1 = ${r1}`);
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Tick-by-Tick Execution
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
import * as ic10c from 'ic10c-node';
|
|
95
|
-
import * as ic10r from 'ic10r-node';
|
|
96
|
-
|
|
97
|
-
const source = `
|
|
98
|
-
loop:
|
|
99
|
-
move r0 1
|
|
100
|
-
yield
|
|
101
|
-
jal loop
|
|
102
|
-
`;
|
|
103
|
-
|
|
104
|
-
const tokens = ic10c.Lexer.tokenize(source);
|
|
105
|
-
const program = new ic10c.Parser(tokens).parse();
|
|
106
|
-
const analyser = new ic10c.Analyser();
|
|
107
|
-
await analyser.visit(program);
|
|
108
|
-
|
|
109
|
-
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
110
|
-
|
|
111
|
-
// Run one tick at a time
|
|
112
|
-
engine.runTick(); // executes one tick
|
|
113
|
-
engine.runTick(); // executes next tick
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Device Interaction
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
import * as ic10c from 'ic10c-node';
|
|
120
|
-
import * as ic10r from 'ic10r-node';
|
|
121
|
-
|
|
122
|
-
const source = `
|
|
123
|
-
alias led d0
|
|
124
|
-
main:
|
|
125
|
-
s led Setting 1
|
|
126
|
-
hcf
|
|
127
|
-
`;
|
|
128
|
-
|
|
129
|
-
const tokens = ic10c.Lexer.tokenize(source);
|
|
130
|
-
const program = new ic10c.Parser(tokens).parse();
|
|
131
|
-
const analyser = new ic10c.Analyser();
|
|
132
|
-
await analyser.visit(program);
|
|
133
|
-
|
|
134
|
-
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
135
|
-
|
|
136
|
-
// Register an external device
|
|
137
|
-
const device = engine.context.manager.getDevice('d0');
|
|
138
|
-
engine.context.manager.setExternalDevice('d0', device);
|
|
139
|
-
|
|
140
|
-
engine.runFull();
|
|
141
|
-
|
|
142
|
-
// Read device logic after execution
|
|
143
|
-
console.log(device.readLogic('Setting')); // 1
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## API Reference
|
|
147
|
-
|
|
148
|
-
### Classes
|
|
149
|
-
|
|
150
|
-
| Class | Description |
|
|
151
|
-
|:------|:------------|
|
|
152
|
-
| `Engine` | IC10 program execution engine |
|
|
153
|
-
| `Context` | Execution context (PC, memory, manager) |
|
|
154
|
-
| `Memory` | Register file and stack memory |
|
|
155
|
-
| `Manager` | Device manager |
|
|
156
|
-
| `Device` | Device I/O interface (logic, slots, reagents) |
|
|
157
|
-
|
|
158
|
-
### Config
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
import type { Config } from 'ic10r-node';
|
|
162
|
-
|
|
163
|
-
const config: Config = {
|
|
164
|
-
tickDuration: 0.5, // seconds per tick
|
|
165
|
-
maxInstructions: 128, // max instructions per tick
|
|
166
|
-
maxStackSize: 512 // max stack size
|
|
167
|
-
};
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Engine
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
import { Engine } from 'ic10r-node';
|
|
174
|
-
import type { Program, SymbolTable } from 'ic10c-node';
|
|
175
|
-
|
|
176
|
-
// Create engine with optional config
|
|
177
|
-
const engine = new Engine(program, symbolTable, {
|
|
178
|
-
tickDuration: 0.5,
|
|
179
|
-
maxInstructions: 128
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Execute
|
|
183
|
-
engine.runTick(); // one tick
|
|
184
|
-
engine.runFull(); // until halt
|
|
185
|
-
|
|
186
|
-
// Access context
|
|
187
|
-
const ctx = engine.context;
|
|
188
|
-
console.log(ctx.pc); // program counter
|
|
189
|
-
console.log(ctx.halted); // halted flag
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Context
|
|
193
|
-
|
|
194
|
-
```typescript
|
|
195
|
-
const ctx = engine.context;
|
|
196
|
-
|
|
197
|
-
// Program counter
|
|
198
|
-
ctx.pc = 0;
|
|
199
|
-
|
|
200
|
-
// Memory access
|
|
201
|
-
const memory = ctx.memory;
|
|
202
|
-
|
|
203
|
-
// Device manager
|
|
204
|
-
const manager = ctx.manager;
|
|
205
|
-
|
|
206
|
-
// Execution control
|
|
207
|
-
ctx.halt(); // halt execution
|
|
208
|
-
ctx.sleep(1.0); // sleep for 1 second
|
|
209
|
-
console.log(ctx.isSleeping);
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Memory
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
const mem = engine.context.memory;
|
|
216
|
-
|
|
217
|
-
// Register access
|
|
218
|
-
mem.setReg('r0', 42);
|
|
219
|
-
const r0 = mem.getReg('r0'); // 42
|
|
220
|
-
|
|
221
|
-
// Stack operations
|
|
222
|
-
mem.push(100);
|
|
223
|
-
mem.push(200);
|
|
224
|
-
const top = mem.peek(); // 200
|
|
225
|
-
const val = mem.pop(); // 200
|
|
226
|
-
|
|
227
|
-
// Direct stack access
|
|
228
|
-
mem.setStack(0, 999);
|
|
229
|
-
const s0 = mem.getStack(0); // 999
|
|
230
|
-
|
|
231
|
-
// Serialize
|
|
232
|
-
const json = mem.toJSON();
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Manager
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
const mgr = engine.context.manager;
|
|
239
|
-
|
|
240
|
-
// Device registration
|
|
241
|
-
mgr.setExternalDevice('d0', device);
|
|
242
|
-
mgr.setChipDevice(chipDevice);
|
|
243
|
-
|
|
244
|
-
// Device lookup
|
|
245
|
-
const dev = mgr.getDevice('d0');
|
|
246
|
-
const found = mgr.findDeviceByType(typeHash);
|
|
247
|
-
const all = mgr.findDevicesByType(typeHash);
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Device
|
|
251
|
-
|
|
252
|
-
```typescript
|
|
253
|
-
const dev = mgr.getDevice('d0');
|
|
254
|
-
|
|
255
|
-
// Logic properties
|
|
256
|
-
dev.writeLogic('Setting', 1);
|
|
257
|
-
const val = dev.readLogic('Setting');
|
|
258
|
-
|
|
259
|
-
// Device stack
|
|
260
|
-
dev.writeStack(0, 42);
|
|
261
|
-
const s0 = dev.readStack(0);
|
|
262
|
-
|
|
263
|
-
// Slots
|
|
264
|
-
dev.writeSlot(0, 'Occupied', 1);
|
|
265
|
-
const occ = dev.readSlot(0, 'Occupied');
|
|
266
|
-
|
|
267
|
-
// Reagents
|
|
268
|
-
const mode = dev.readReagent(0);
|
|
269
|
-
const amount = dev.queryReagentAmount(reagentHash);
|
|
270
|
-
|
|
271
|
-
// Metadata
|
|
272
|
-
const typeHash = dev.getTypeHash();
|
|
273
|
-
const nameHash = dev.getNameHash();
|
|
274
|
-
|
|
275
|
-
// Lifecycle
|
|
276
|
-
dev.tick();
|
|
277
|
-
dev.clearStack();
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## IC10 Instruction Examples
|
|
281
|
-
|
|
282
|
-
### Arithmetic
|
|
283
|
-
|
|
284
|
-
```ic10
|
|
285
|
-
move r0 10
|
|
286
|
-
move r1 20
|
|
287
|
-
add r2 r0 r1 # r2 = 30
|
|
288
|
-
sub r3 r2 5 # r3 = 25
|
|
289
|
-
mul r4 r3 2 # r4 = 50
|
|
290
|
-
div r5 r4 5 # r5 = 10
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### Control Flow
|
|
294
|
-
|
|
295
|
-
```ic10
|
|
296
|
-
loop:
|
|
297
|
-
move r0 1
|
|
298
|
-
yield
|
|
299
|
-
jal loop
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
### Device I/O
|
|
303
|
-
|
|
304
|
-
```ic10
|
|
305
|
-
alias led d0
|
|
306
|
-
s led Setting 1
|
|
307
|
-
r r0 led Setting
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
## TypeScript
|
|
311
|
-
|
|
312
|
-
This module includes complete TypeScript type definitions.
|
|
313
|
-
|
|
314
|
-
```typescript
|
|
315
|
-
import { Engine, Context, Memory, Manager, Device } from 'ic10r-node';
|
|
316
|
-
import type { Config } from 'ic10r-node';
|
|
317
|
-
|
|
318
|
-
const config: Config = {
|
|
319
|
-
tickDuration: 0.5,
|
|
320
|
-
maxInstructions: 128,
|
|
321
|
-
maxStackSize: 512
|
|
322
|
-
};
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
## Build Instructions
|
|
326
|
-
|
|
327
|
-
### Requirements
|
|
328
|
-
|
|
329
|
-
- **Node.js**: 16.0.0+
|
|
330
|
-
- **CMake**: 3.28.1+
|
|
331
|
-
- **C++ Compiler**:
|
|
332
|
-
- Linux: GCC 13+ or Clang 16+
|
|
333
|
-
- Windows: MSVC 2022
|
|
334
|
-
|
|
335
|
-
### Build Steps
|
|
336
|
-
|
|
337
|
-
```bash
|
|
338
|
-
# 1. Install Node.js dependencies
|
|
339
|
-
npm install
|
|
340
|
-
|
|
341
|
-
# 2. Download Node.js headers
|
|
342
|
-
npx node-gyp install
|
|
343
|
-
|
|
344
|
-
# 3. Configure CMake
|
|
345
|
-
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
|
|
346
|
-
|
|
347
|
-
# 4. Build
|
|
348
|
-
cmake --build build --parallel 4
|
|
349
|
-
|
|
350
|
-
# 5. Copy generated .node file
|
|
351
|
-
cp build/ic10r-node.node src/
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Project Structure
|
|
355
|
-
|
|
356
|
-
```
|
|
357
|
-
ic10r-node/
|
|
358
|
-
├── src/
|
|
359
|
-
│ └── ic10r-node.node # Native module (built)
|
|
360
|
-
├── types/
|
|
361
|
-
│ ├── index.d.ts # TypeScript type definitions (entry)
|
|
362
|
-
│ ├── config.d.ts # Config interface
|
|
363
|
-
│ ├── context.d.ts # Context class
|
|
364
|
-
│ ├── device.d.ts # Device class
|
|
365
|
-
│ ├── engine.d.ts # Engine class
|
|
366
|
-
│ ├── manager.d.ts # Manager class
|
|
367
|
-
│ └── memory.d.ts # Memory class
|
|
368
|
-
├── tsconfig.json
|
|
369
|
-
├── package.json
|
|
370
|
-
└── README.md
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
## License
|
|
374
|
-
|
|
375
|
-
This project is licensed under **CC BY-NC-SA 4.0** (Creative Commons Attribution-NonCommercial-ShareAlike 4.0).
|
|
376
|
-
|
|
377
|
-
[](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
|
378
|
-
|
|
379
|
-
## Contributing
|
|
380
|
-
|
|
381
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
382
|
-
|
|
383
|
-
1. Fork the repository
|
|
384
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
385
|
-
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
386
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
387
|
-
5. Open a Pull Request
|
|
388
|
-
|
|
389
|
-
## Contact
|
|
390
|
-
|
|
391
|
-
- **Author**: edocsitahw
|
|
392
|
-
- **Email**: edocsitahw@qq.com
|
|
393
|
-
- **Repository**: [https://github.com/edoCsItahW/Stationeers](https://github.com/edoCsItahW/Stationeers)
|
|
394
|
-
|
|
395
|
-
## Related Links
|
|
396
|
-
|
|
397
|
-
- [ic10c-node – IC10 Compiler Node.js Bindings](https://www.npmjs.com/package/ic10c-node)
|
|
398
|
-
- [Stationeers Official Website](https://store.steampowered.com/app/544550/Stationeers/)
|
|
399
|
-
- [Node.js N-API Documentation](https://nodejs.org/api/n-api.html)
|
|
400
|
-
- [node-addon-api Documentation](https://github.com/nodejs/node-addon-api)
|
|
1
|
+
# ic10r-node
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/ic10r_node)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](https://isocpp.org/)
|
|
6
|
+
[](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
|
7
|
+
|
|
8
|
+
[中文](./README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
`ic10r-node` is the Node.js native binding module for the **IC10 Runtime**, providing a complete execution engine for IC10 programs.
|
|
13
|
+
|
|
14
|
+
IC10 is an assembly-style programming language used in the game [Stationeers](https://store.steampowered.com/app/544550/Stationeers/) to control computers and devices in the game. This module takes the compiled AST and symbol table (produced by [`ic10c-node`](https://www.npmjs.com/package/ic10c-node)) and executes the program tick-by-tick, simulating the IC10 processor's behavior.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Execution Engine** – runs IC10 programs tick-by-tick (`runTick`) or to completion (`runFull`)
|
|
19
|
+
- **Register File & Stack** – full 16-register file (`r0`–`r15`) and stack memory (`push`/`pop`/`peek`/`poke`)
|
|
20
|
+
- **Device Manager** – register external devices and the chip device, query by type/name hash
|
|
21
|
+
- **Device I/O** – read/write logic properties, device stacks, slots, and reagent modes
|
|
22
|
+
- **Execution Control** – `halt`/`sleep` support, instruction limit, tick duration configuration
|
|
23
|
+
- **Cross‑Platform** – builds on Linux (GCC/Clang) and Windows (MSVC)
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### Prerequisites
|
|
28
|
+
|
|
29
|
+
- Node.js >= 16.0.0 (Node.js 26.x recommended)
|
|
30
|
+
- C++ compiler (GCC 13+ / Clang 16+ / MSVC 2022)
|
|
31
|
+
- CMake >= 3.28.1
|
|
32
|
+
- [`ic10c-node`](https://www.npmjs.com/package/ic10c-node) (peer dependency for compilation)
|
|
33
|
+
|
|
34
|
+
### Install from npm
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install ic10r-node ic10c-node
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Build from Source
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Clone repository
|
|
44
|
+
git clone https://github.com/edoCsItahW/Stationeers.git
|
|
45
|
+
cd Stationeers/code/IC10/backend/runtime
|
|
46
|
+
|
|
47
|
+
# Install dependencies
|
|
48
|
+
npm install
|
|
49
|
+
|
|
50
|
+
# Download Node.js headers
|
|
51
|
+
npx node-gyp install
|
|
52
|
+
|
|
53
|
+
# Build native module
|
|
54
|
+
npm run build
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
### Basic Usage
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import * as ic10c from 'ic10c-node';
|
|
63
|
+
import * as ic10r from 'ic10r-node';
|
|
64
|
+
|
|
65
|
+
// IC10 source code
|
|
66
|
+
const source = `
|
|
67
|
+
main:
|
|
68
|
+
move r0 42
|
|
69
|
+
add r1 r0 10
|
|
70
|
+
hcf
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
// 1. Compile (using ic10c-node)
|
|
74
|
+
const tokens = ic10c.Lexer.tokenize(source);
|
|
75
|
+
const program = new ic10c.Parser(tokens).parse();
|
|
76
|
+
const analyser = new ic10c.Analyser();
|
|
77
|
+
await analyser.visit(program);
|
|
78
|
+
|
|
79
|
+
// 2. Create engine (using ic10r-node)
|
|
80
|
+
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
81
|
+
|
|
82
|
+
// 3. Execute
|
|
83
|
+
engine.runFull();
|
|
84
|
+
|
|
85
|
+
// 4. Inspect results
|
|
86
|
+
const r0 = engine.context.memory.getReg('r0'); // 42
|
|
87
|
+
const r1 = engine.context.memory.getReg('r1'); // 52
|
|
88
|
+
console.log(`r0 = ${r0}, r1 = ${r1}`);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Tick-by-Tick Execution
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import * as ic10c from 'ic10c-node';
|
|
95
|
+
import * as ic10r from 'ic10r-node';
|
|
96
|
+
|
|
97
|
+
const source = `
|
|
98
|
+
loop:
|
|
99
|
+
move r0 1
|
|
100
|
+
yield
|
|
101
|
+
jal loop
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
const tokens = ic10c.Lexer.tokenize(source);
|
|
105
|
+
const program = new ic10c.Parser(tokens).parse();
|
|
106
|
+
const analyser = new ic10c.Analyser();
|
|
107
|
+
await analyser.visit(program);
|
|
108
|
+
|
|
109
|
+
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
110
|
+
|
|
111
|
+
// Run one tick at a time
|
|
112
|
+
engine.runTick(); // executes one tick
|
|
113
|
+
engine.runTick(); // executes next tick
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Device Interaction
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import * as ic10c from 'ic10c-node';
|
|
120
|
+
import * as ic10r from 'ic10r-node';
|
|
121
|
+
|
|
122
|
+
const source = `
|
|
123
|
+
alias led d0
|
|
124
|
+
main:
|
|
125
|
+
s led Setting 1
|
|
126
|
+
hcf
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
const tokens = ic10c.Lexer.tokenize(source);
|
|
130
|
+
const program = new ic10c.Parser(tokens).parse();
|
|
131
|
+
const analyser = new ic10c.Analyser();
|
|
132
|
+
await analyser.visit(program);
|
|
133
|
+
|
|
134
|
+
const engine = new ic10r.Engine(program, analyser.symbolTable);
|
|
135
|
+
|
|
136
|
+
// Register an external device
|
|
137
|
+
const device = engine.context.manager.getDevice('d0');
|
|
138
|
+
engine.context.manager.setExternalDevice('d0', device);
|
|
139
|
+
|
|
140
|
+
engine.runFull();
|
|
141
|
+
|
|
142
|
+
// Read device logic after execution
|
|
143
|
+
console.log(device.readLogic('Setting')); // 1
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## API Reference
|
|
147
|
+
|
|
148
|
+
### Classes
|
|
149
|
+
|
|
150
|
+
| Class | Description |
|
|
151
|
+
|:------|:------------|
|
|
152
|
+
| `Engine` | IC10 program execution engine |
|
|
153
|
+
| `Context` | Execution context (PC, memory, manager) |
|
|
154
|
+
| `Memory` | Register file and stack memory |
|
|
155
|
+
| `Manager` | Device manager |
|
|
156
|
+
| `Device` | Device I/O interface (logic, slots, reagents) |
|
|
157
|
+
|
|
158
|
+
### Config
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import type { Config } from 'ic10r-node';
|
|
162
|
+
|
|
163
|
+
const config: Config = {
|
|
164
|
+
tickDuration: 0.5, // seconds per tick
|
|
165
|
+
maxInstructions: 128, // max instructions per tick
|
|
166
|
+
maxStackSize: 512 // max stack size
|
|
167
|
+
};
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Engine
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { Engine } from 'ic10r-node';
|
|
174
|
+
import type { Program, SymbolTable } from 'ic10c-node';
|
|
175
|
+
|
|
176
|
+
// Create engine with optional config
|
|
177
|
+
const engine = new Engine(program, symbolTable, {
|
|
178
|
+
tickDuration: 0.5,
|
|
179
|
+
maxInstructions: 128
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Execute
|
|
183
|
+
engine.runTick(); // one tick
|
|
184
|
+
engine.runFull(); // until halt
|
|
185
|
+
|
|
186
|
+
// Access context
|
|
187
|
+
const ctx = engine.context;
|
|
188
|
+
console.log(ctx.pc); // program counter
|
|
189
|
+
console.log(ctx.halted); // halted flag
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Context
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const ctx = engine.context;
|
|
196
|
+
|
|
197
|
+
// Program counter
|
|
198
|
+
ctx.pc = 0;
|
|
199
|
+
|
|
200
|
+
// Memory access
|
|
201
|
+
const memory = ctx.memory;
|
|
202
|
+
|
|
203
|
+
// Device manager
|
|
204
|
+
const manager = ctx.manager;
|
|
205
|
+
|
|
206
|
+
// Execution control
|
|
207
|
+
ctx.halt(); // halt execution
|
|
208
|
+
ctx.sleep(1.0); // sleep for 1 second
|
|
209
|
+
console.log(ctx.isSleeping);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Memory
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const mem = engine.context.memory;
|
|
216
|
+
|
|
217
|
+
// Register access
|
|
218
|
+
mem.setReg('r0', 42);
|
|
219
|
+
const r0 = mem.getReg('r0'); // 42
|
|
220
|
+
|
|
221
|
+
// Stack operations
|
|
222
|
+
mem.push(100);
|
|
223
|
+
mem.push(200);
|
|
224
|
+
const top = mem.peek(); // 200
|
|
225
|
+
const val = mem.pop(); // 200
|
|
226
|
+
|
|
227
|
+
// Direct stack access
|
|
228
|
+
mem.setStack(0, 999);
|
|
229
|
+
const s0 = mem.getStack(0); // 999
|
|
230
|
+
|
|
231
|
+
// Serialize
|
|
232
|
+
const json = mem.toJSON();
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Manager
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const mgr = engine.context.manager;
|
|
239
|
+
|
|
240
|
+
// Device registration
|
|
241
|
+
mgr.setExternalDevice('d0', device);
|
|
242
|
+
mgr.setChipDevice(chipDevice);
|
|
243
|
+
|
|
244
|
+
// Device lookup
|
|
245
|
+
const dev = mgr.getDevice('d0');
|
|
246
|
+
const found = mgr.findDeviceByType(typeHash);
|
|
247
|
+
const all = mgr.findDevicesByType(typeHash);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Device
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const dev = mgr.getDevice('d0');
|
|
254
|
+
|
|
255
|
+
// Logic properties
|
|
256
|
+
dev.writeLogic('Setting', 1);
|
|
257
|
+
const val = dev.readLogic('Setting');
|
|
258
|
+
|
|
259
|
+
// Device stack
|
|
260
|
+
dev.writeStack(0, 42);
|
|
261
|
+
const s0 = dev.readStack(0);
|
|
262
|
+
|
|
263
|
+
// Slots
|
|
264
|
+
dev.writeSlot(0, 'Occupied', 1);
|
|
265
|
+
const occ = dev.readSlot(0, 'Occupied');
|
|
266
|
+
|
|
267
|
+
// Reagents
|
|
268
|
+
const mode = dev.readReagent(0);
|
|
269
|
+
const amount = dev.queryReagentAmount(reagentHash);
|
|
270
|
+
|
|
271
|
+
// Metadata
|
|
272
|
+
const typeHash = dev.getTypeHash();
|
|
273
|
+
const nameHash = dev.getNameHash();
|
|
274
|
+
|
|
275
|
+
// Lifecycle
|
|
276
|
+
dev.tick();
|
|
277
|
+
dev.clearStack();
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## IC10 Instruction Examples
|
|
281
|
+
|
|
282
|
+
### Arithmetic
|
|
283
|
+
|
|
284
|
+
```ic10
|
|
285
|
+
move r0 10
|
|
286
|
+
move r1 20
|
|
287
|
+
add r2 r0 r1 # r2 = 30
|
|
288
|
+
sub r3 r2 5 # r3 = 25
|
|
289
|
+
mul r4 r3 2 # r4 = 50
|
|
290
|
+
div r5 r4 5 # r5 = 10
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Control Flow
|
|
294
|
+
|
|
295
|
+
```ic10
|
|
296
|
+
loop:
|
|
297
|
+
move r0 1
|
|
298
|
+
yield
|
|
299
|
+
jal loop
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Device I/O
|
|
303
|
+
|
|
304
|
+
```ic10
|
|
305
|
+
alias led d0
|
|
306
|
+
s led Setting 1
|
|
307
|
+
r r0 led Setting
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## TypeScript
|
|
311
|
+
|
|
312
|
+
This module includes complete TypeScript type definitions.
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { Engine, Context, Memory, Manager, Device } from 'ic10r-node';
|
|
316
|
+
import type { Config } from 'ic10r-node';
|
|
317
|
+
|
|
318
|
+
const config: Config = {
|
|
319
|
+
tickDuration: 0.5,
|
|
320
|
+
maxInstructions: 128,
|
|
321
|
+
maxStackSize: 512
|
|
322
|
+
};
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Build Instructions
|
|
326
|
+
|
|
327
|
+
### Requirements
|
|
328
|
+
|
|
329
|
+
- **Node.js**: 16.0.0+
|
|
330
|
+
- **CMake**: 3.28.1+
|
|
331
|
+
- **C++ Compiler**:
|
|
332
|
+
- Linux: GCC 13+ or Clang 16+
|
|
333
|
+
- Windows: MSVC 2022
|
|
334
|
+
|
|
335
|
+
### Build Steps
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# 1. Install Node.js dependencies
|
|
339
|
+
npm install
|
|
340
|
+
|
|
341
|
+
# 2. Download Node.js headers
|
|
342
|
+
npx node-gyp install
|
|
343
|
+
|
|
344
|
+
# 3. Configure CMake
|
|
345
|
+
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
|
|
346
|
+
|
|
347
|
+
# 4. Build
|
|
348
|
+
cmake --build build --parallel 4
|
|
349
|
+
|
|
350
|
+
# 5. Copy generated .node file
|
|
351
|
+
cp build/ic10r-node.node src/
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Project Structure
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
ic10r-node/
|
|
358
|
+
├── src/
|
|
359
|
+
│ └── ic10r-node.node # Native module (built)
|
|
360
|
+
├── types/
|
|
361
|
+
│ ├── index.d.ts # TypeScript type definitions (entry)
|
|
362
|
+
│ ├── config.d.ts # Config interface
|
|
363
|
+
│ ├── context.d.ts # Context class
|
|
364
|
+
│ ├── device.d.ts # Device class
|
|
365
|
+
│ ├── engine.d.ts # Engine class
|
|
366
|
+
│ ├── manager.d.ts # Manager class
|
|
367
|
+
│ └── memory.d.ts # Memory class
|
|
368
|
+
├── tsconfig.json
|
|
369
|
+
├── package.json
|
|
370
|
+
└── README.md
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## License
|
|
374
|
+
|
|
375
|
+
This project is licensed under **CC BY-NC-SA 4.0** (Creative Commons Attribution-NonCommercial-ShareAlike 4.0).
|
|
376
|
+
|
|
377
|
+
[](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
|
378
|
+
|
|
379
|
+
## Contributing
|
|
380
|
+
|
|
381
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
382
|
+
|
|
383
|
+
1. Fork the repository
|
|
384
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
385
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
386
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
387
|
+
5. Open a Pull Request
|
|
388
|
+
|
|
389
|
+
## Contact
|
|
390
|
+
|
|
391
|
+
- **Author**: edocsitahw
|
|
392
|
+
- **Email**: edocsitahw@qq.com
|
|
393
|
+
- **Repository**: [https://github.com/edoCsItahW/Stationeers](https://github.com/edoCsItahW/Stationeers)
|
|
394
|
+
|
|
395
|
+
## Related Links
|
|
396
|
+
|
|
397
|
+
- [ic10c-node – IC10 Compiler Node.js Bindings](https://www.npmjs.com/package/ic10c-node)
|
|
398
|
+
- [Stationeers Official Website](https://store.steampowered.com/app/544550/Stationeers/)
|
|
399
|
+
- [Node.js N-API Documentation](https://nodejs.org/api/n-api.html)
|
|
400
|
+
- [node-addon-api Documentation](https://github.com/nodejs/node-addon-api)
|