xbintsc 0.3.46 → 0.3.49
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/AGENTS.md +95 -0
- package/README.md +25 -0
- package/README.zh-CN.md +23 -0
- package/dist/src/cli/hints.d.ts +54 -0
- package/dist/src/cli/hints.js +165 -0
- package/dist/src/cli/hints.js.map +1 -0
- package/dist/src/cli/main.js +73 -9
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +26 -0
- package/dist/src/codegen/generator/tables.js +64 -12
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/diagnostics/source-text.d.ts +22 -0
- package/dist/src/diagnostics/source-text.js +76 -0
- package/dist/src/diagnostics/source-text.js.map +1 -0
- package/dist/src/driver/bundler/graph.js +2 -1
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/compiler.js +3 -2
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/lexer/scanner/strings.js +16 -3
- package/dist/src/lexer/scanner/strings.js.map +1 -1
- package/dist/tests/cli/hints.test.d.ts +9 -0
- package/dist/tests/cli/hints.test.js +143 -0
- package/dist/tests/cli/hints.test.js.map +1 -0
- package/dist/tests/cli/main.test.js +6 -4
- package/dist/tests/cli/main.test.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +17 -2
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/helpers.js +3 -2
- package/dist/tests/helpers.js.map +1 -1
- package/dist/tests/lexer/strings.test.js +14 -2
- package/dist/tests/lexer/strings.test.js.map +1 -1
- package/doc/DESIGN.md +117 -0
- package/doc/ai/README.md +63 -0
- package/doc/ai/build-recipe.md +137 -0
- package/doc/ai/cli.md +142 -0
- package/doc/ai/contributing.md +196 -0
- package/doc/ai/extensions.md +148 -0
- package/doc/ai/language-support.md +152 -0
- package/doc/ai/troubleshooting.md +163 -0
- package/doc/ai/zh-CN/README.md +56 -0
- package/doc/ai/zh-CN/build-recipe.md +132 -0
- package/doc/ai/zh-CN/cli.md +127 -0
- package/doc/ai/zh-CN/contributing.md +173 -0
- package/doc/ai/zh-CN/extensions.md +139 -0
- package/doc/ai/zh-CN/language-support.md +147 -0
- package/doc/ai/zh-CN/troubleshooting.md +150 -0
- package/doc/gui-scripts.md +350 -0
- package/doc/gui.md +646 -0
- package/doc/icon.md +265 -0
- package/doc/implemented.md +373 -0
- package/doc/node-implemented.md +588 -0
- package/doc/node-unimplemented.md +167 -0
- package/doc/post/announce.md +43 -0
- package/doc/requirements.md +145 -0
- package/doc/unimplemented.md +286 -0
- package/doc/xbintsc.config.schema.json +67 -0
- package/doc/zh-CN/DESIGN.md +104 -0
- package/doc/zh-CN/gui-scripts.md +329 -0
- package/doc/zh-CN/gui.md +588 -0
- package/doc/zh-CN/icon.md +241 -0
- package/doc/zh-CN/implemented.md +365 -0
- package/doc/zh-CN/node-implemented.md +533 -0
- package/doc/zh-CN/node-unimplemented.md +141 -0
- package/doc/zh-CN/plan-require-node-modules.md +284 -0
- package/doc/zh-CN/post/announce.md +47 -0
- package/doc/zh-CN/requirements.md +134 -0
- package/doc/zh-CN/unimplemented.md +247 -0
- package/llms.txt +45 -0
- package/package.json +4 -1
- package/runtime/ext_gui/gui.cpp +3 -1
- package/runtime/ext_gui/renderer.cpp +13 -11
- package/runtime/ext_gui/renderer_image.cpp +12 -8
- package/runtime/ext_gui/renderer_shaders.h +131 -4
- package/runtime/ext_gui/renderer_shaders_data.h +1809 -0
- package/runtime/ext_gui/renderer_text.cpp +12 -8
- package/runtime/ext_gui/shaders.hlsl +98 -0
- package/runtime/ext_gui/spirv/fill.frag +19 -0
- package/runtime/ext_gui/spirv/fill.vert +42 -0
- package/runtime/ext_gui/spirv/image.frag +16 -0
- package/runtime/ext_gui/spirv/quad.vert +30 -0
- package/runtime/ext_gui/spirv/text.frag +16 -0
- package/scripts/build-gui-shaders.mjs +204 -0
- package/scripts/build-gui.ts +35 -0
- package/scripts/check-file-length.ts +5 -1
- package/src/cli/hints.ts +194 -0
- package/src/cli/main.ts +82 -9
- package/src/codegen/generator/tables.ts +60 -14
- package/src/diagnostics/source-text.ts +78 -0
- package/src/driver/bundler/graph.ts +2 -1
- package/src/driver/compiler.ts +3 -2
- package/src/lexer/scanner/strings.ts +16 -3
package/doc/icon.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# xbintsc application icons (compile-time icon embedding)
|
|
2
|
+
|
|
3
|
+
> Language: **English** | [简体中文](./zh-CN/icon.md)
|
|
4
|
+
|
|
5
|
+
Status: **implemented** — milestones I0–I3 below have shipped. I4 (Linux
|
|
6
|
+
desktop integration) and I5 (per-window icon) remain optional follow-ups.
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
Give a compiled program a real OS-level **application / window icon** supplied
|
|
11
|
+
at *compile time* and baked into the artifact, so the binary needs no side-car
|
|
12
|
+
icon file at runtime:
|
|
13
|
+
|
|
14
|
+
- **Windows** — the icon shows in Explorer, the taskbar and Alt-Tab (PE
|
|
15
|
+
resource).
|
|
16
|
+
- **macOS** — the icon shows in Finder and the Dock (`.app` bundle with an
|
|
17
|
+
`.icns`).
|
|
18
|
+
- **Linux** — the running window/taskbar icon is set from the embedded image;
|
|
19
|
+
desktop integration (`.desktop` + themed PNG) is a follow-up.
|
|
20
|
+
|
|
21
|
+
The core compiler stays platform-agnostic: the lexer/parser/binder/codegen never
|
|
22
|
+
learn what an icon is. Icon handling is a *driver* concern (like the per-platform
|
|
23
|
+
linker flags that already live there) plus an optional *runtime* concern (the
|
|
24
|
+
`gui` extension).
|
|
25
|
+
|
|
26
|
+
## UX
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# CLI — icon is a build option
|
|
30
|
+
xbintsc build app.ts --icon assets/app.png -o app
|
|
31
|
+
xbintsc run app.ts --icon assets/app.png
|
|
32
|
+
|
|
33
|
+
# programmatic API
|
|
34
|
+
build("app.ts", { icon: "assets/app.png" });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Icon settings — and the app metadata that comes with them (name, bundle id) —
|
|
38
|
+
are normally declared once in a project build config (`xbintsc.config.json`):
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"$schema": "https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/xbintsc.config.schema.json",
|
|
43
|
+
"entry": "src/app.ts",
|
|
44
|
+
"outDir": "build",
|
|
45
|
+
"extensions": ["gui"],
|
|
46
|
+
"app": {
|
|
47
|
+
"name": "Demo",
|
|
48
|
+
"icon": "assets/app.png",
|
|
49
|
+
"bundle": true,
|
|
50
|
+
"bundleId": "com.example.demo"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
xbintsc build # reads xbintsc.config.json
|
|
57
|
+
xbintsc build --icon other.png # a flag overrides the config
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// GUI apps pick the embedded icon up automatically
|
|
62
|
+
import { createWindow, run } from "gui";
|
|
63
|
+
createWindow({ title: "Demo", width: 800, height: 600 });
|
|
64
|
+
run(); // window/taskbar/Dock icon = the one configured at build time
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Layer 0 — project build config (`xbintsc.config.json`)
|
|
68
|
+
|
|
69
|
+
Introduced by this feature (there was no project-level compile config before).
|
|
70
|
+
A single checked-in file makes a build reproducible (`xbintsc build` with no
|
|
71
|
+
arguments).
|
|
72
|
+
|
|
73
|
+
### Schema
|
|
74
|
+
|
|
75
|
+
Every field is optional:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"entry": "src/app.ts",
|
|
80
|
+
"outDir": "build",
|
|
81
|
+
"output": "build/Demo",
|
|
82
|
+
"optimize": "2",
|
|
83
|
+
"extensions": ["gui", "node"],
|
|
84
|
+
"extNative": ["native/xbintsc.manifest.json"],
|
|
85
|
+
"force": false,
|
|
86
|
+
"app": {
|
|
87
|
+
"name": "Demo",
|
|
88
|
+
"icon": "assets/app.png",
|
|
89
|
+
"bundle": true,
|
|
90
|
+
"bundleId": "com.example.demo"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Strict JSON (`JSON.parse`); unknown keys are ignored.
|
|
96
|
+
- All relative paths resolve against the **config file's directory**, not the
|
|
97
|
+
cwd.
|
|
98
|
+
- `app.bundle` is macOS-only and controls the `.app` bundle.
|
|
99
|
+
|
|
100
|
+
### Discovery & precedence
|
|
101
|
+
|
|
102
|
+
1. `--config <path>` selects a config explicitly; `--no-config` disables it.
|
|
103
|
+
2. Otherwise walk up from the positional entry's directory, then the cwd, until
|
|
104
|
+
`xbintsc.config.json` is found.
|
|
105
|
+
3. Precedence for every option: **CLI flag > config value > built-in default**.
|
|
106
|
+
4. `xbintsc build` with no positional entry falls back to `entry` in the config;
|
|
107
|
+
an error is reported if neither is present.
|
|
108
|
+
|
|
109
|
+
Implemented in `src/driver/config.ts` (`loadProjectConfig`, `parseProjectConfig`,
|
|
110
|
+
`findProjectConfig`, `resolveConfigPaths`, `ProjectConfigError`) and wired into
|
|
111
|
+
`src/cli/main.ts`.
|
|
112
|
+
|
|
113
|
+
## Layer 1 — embed & package
|
|
114
|
+
|
|
115
|
+
### `src/driver/icon.ts`
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
export type IconFormat = "png" | "ico" | "icns";
|
|
119
|
+
export interface IconInfo {
|
|
120
|
+
readonly path: string;
|
|
121
|
+
readonly format: IconFormat;
|
|
122
|
+
readonly bytes: Uint8Array;
|
|
123
|
+
readonly width: number; // 0 when unknown (e.g. .icns)
|
|
124
|
+
readonly height: number;
|
|
125
|
+
}
|
|
126
|
+
export function readIcon(path: string): IconInfo; // throws IconError
|
|
127
|
+
export function iconSource(icon: IconInfo): string; // generated C
|
|
128
|
+
export function ensureIconObject(runner, clang, cacheDir, icon): string;
|
|
129
|
+
export function pngToIco(png: Uint8Array, width, height): Uint8Array;
|
|
130
|
+
export function toIcoBytes(icon: IconInfo): Uint8Array;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`readIcon` sniffs the magic bytes (PNG/ICO/ICNS), rejects missing/empty/
|
|
134
|
+
unsupported files with an `IconError`, and reads the intrinsic size where it is
|
|
135
|
+
cheap (PNG IHDR, ICO directory entry).
|
|
136
|
+
|
|
137
|
+
### Embedded symbols
|
|
138
|
+
|
|
139
|
+
When an icon is configured — and for every GUI build even without one — the
|
|
140
|
+
driver generates a tiny C file in the cache dir (never in the user's tree),
|
|
141
|
+
compiles it with the existing `compileC`, and appends the object to the `link()`
|
|
142
|
+
input list:
|
|
143
|
+
|
|
144
|
+
```c
|
|
145
|
+
/* generated, cached by icon content hash */
|
|
146
|
+
const unsigned char xt_app_icon_data[]; /* raw icon bytes */
|
|
147
|
+
const unsigned long long xt_app_icon_size; /* 0 == no icon */
|
|
148
|
+
const char xt_app_icon_format[]; /* "png" | "ico" | "icns" */
|
|
149
|
+
const unsigned int xt_app_icon_width;
|
|
150
|
+
const unsigned int xt_app_icon_height;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The GUI extension references these symbols **unconditionally**, so the driver
|
|
154
|
+
links an empty icon object (`EMPTY_ICON`) into GUI programs even when no icon is
|
|
155
|
+
configured; `xt_app_icon_size == 0` tells the runtime to skip it. This avoids
|
|
156
|
+
fragile weak-symbol tricks (Mach-O `weak` does not resolve to null the way ELF
|
|
157
|
+
does).
|
|
158
|
+
|
|
159
|
+
### CLI & API wiring
|
|
160
|
+
|
|
161
|
+
- `src/cli/main.ts`: `--icon`, `--bundle`, `--app-name`, `--app-id`, `--config`,
|
|
162
|
+
`--no-config`; merged with the config (`mergeAppConfig`).
|
|
163
|
+
- `src/driver/compiler.ts`: `BuildOptions.icon` and `BuildOptions.app`.
|
|
164
|
+
- The icon **content hash** and the packaging options are part of the
|
|
165
|
+
executable `cacheKey`, so changing the icon rebuilds.
|
|
166
|
+
- The icon object and (on win32) the resource object are appended to the link
|
|
167
|
+
inputs.
|
|
168
|
+
- The macOS `.app` bundle is produced after linking; `BuildResult.bundlePath`
|
|
169
|
+
reports it (the executable path is unchanged, so `run` still works).
|
|
170
|
+
|
|
171
|
+
### Per-platform packaging
|
|
172
|
+
|
|
173
|
+
#### Windows (PE resource) — `src/driver/win-icon.ts`
|
|
174
|
+
|
|
175
|
+
1. A PNG input is wrapped in a minimal ICO container (`ICONDIR` +
|
|
176
|
+
`ICONDIRENTRY` pointing at the PNG payload); Vista+ accepts PNG-in-ICO.
|
|
177
|
+
2. A `.rc` (`1 ICON "icon-<hash>.ico"`) is written next to it in the cache.
|
|
178
|
+
3. `llvm-rc /fo app.res app.rc` (preferred, next to the resolved clang or on
|
|
179
|
+
`PATH`), else MinGW `windres app.rc -O coff -o app_res.o`. Override with
|
|
180
|
+
`xbintsc_RC`.
|
|
181
|
+
4. If no resource compiler exists, the build continues with the runtime icon only
|
|
182
|
+
(a cosmetic feature never hard-fails a build).
|
|
183
|
+
|
|
184
|
+
#### macOS (`MyApp.app` bundle) — `src/driver/mac-bundle.ts`
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
MyApp.app/Contents/
|
|
188
|
+
Info.plist CFBundleName/Identifier/Executable/IconFile
|
|
189
|
+
MacOS/MyApp copy of the linked executable
|
|
190
|
+
Resources/AppIcon.icns
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- `.icns` inputs are copied; `.png` inputs are converted with `sips` +
|
|
194
|
+
`iconutil`. If those tools are unavailable the PNG is shipped as
|
|
195
|
+
`AppIcon.png` and the runtime Dock icon still applies.
|
|
196
|
+
- `bundleId` supplies `CFBundleIdentifier`; the default is
|
|
197
|
+
`com.xbintsc.<binary>`.
|
|
198
|
+
- Bundling is opt-in (`app.bundle` / `--bundle`) because it changes the output
|
|
199
|
+
layout.
|
|
200
|
+
|
|
201
|
+
#### Linux
|
|
202
|
+
|
|
203
|
+
ELF has no icon convention. The only in-binary use is the runtime window icon
|
|
204
|
+
(via the embedded bytes). A follow-up may synthesize a `<name>.desktop` +
|
|
205
|
+
`hicolor` PNG and set `SDL_SetAppMetadata`/app-id hints for Wayland.
|
|
206
|
+
|
|
207
|
+
### Format policy
|
|
208
|
+
|
|
209
|
+
- **PNG is canonical** and works everywhere.
|
|
210
|
+
- `.ico` (Windows) and `.icns` (macOS) are accepted; `.ico` is best-effort as a
|
|
211
|
+
PE resource, `.icns` is copied into the mac bundle verbatim.
|
|
212
|
+
|
|
213
|
+
## Layer 2 — runtime window/Dock icon (`gui`)
|
|
214
|
+
|
|
215
|
+
`runtime/ext_gui/gui.cpp` defines `xt_gui_apply_icon(SDL_Window *)`, called from
|
|
216
|
+
`xt_gui_create_window` after the window is created:
|
|
217
|
+
|
|
218
|
+
- Reads `xt_app_icon_{data,size,format}`; skips when `size == 0`.
|
|
219
|
+
- Decodes PNG bytes with the existing `xtgui::xt_image_decode` (stb_image).
|
|
220
|
+
- Builds an `SDL_Surface` (`SDL_CreateSurfaceFrom(..., SDL_PIXELFORMAT_RGBA32,
|
|
221
|
+
pitch)`) and calls `SDL_SetWindowIcon`.
|
|
222
|
+
- Any failure is silent: an icon is cosmetic and must never stop the program.
|
|
223
|
+
|
|
224
|
+
## Caching
|
|
225
|
+
|
|
226
|
+
- The executable cache key includes the icon bytes hash, format, app name,
|
|
227
|
+
bundle flag and bundle id.
|
|
228
|
+
- The generated C object is cached on the icon content hash.
|
|
229
|
+
- The Windows `.res`/COFF object is cached on the icon+compiler hash.
|
|
230
|
+
- The `.app` bundle is part of the cached outputs, so a stale bundle is never
|
|
231
|
+
reused.
|
|
232
|
+
|
|
233
|
+
## Testing
|
|
234
|
+
|
|
235
|
+
- `tests/driver/config.test.ts` — parse/validate, discovery, path resolution.
|
|
236
|
+
- `tests/driver/icon.test.ts` — format sniffing, generated C, ICO conversion,
|
|
237
|
+
icon object caching, `llvm-rc`/`windres` command lines, mac bundle layout and
|
|
238
|
+
fallbacks, and `build()` integration (icon objects linked, missing icon ⇒
|
|
239
|
+
`DiagnosticCode.IOError`).
|
|
240
|
+
- `tests/e2e/icon.test.ts` — compiles a real GUI program with `app.icon`,
|
|
241
|
+
asserts the PNG bytes are present in the executable, runs it headless, and
|
|
242
|
+
(darwin) checks the `.app` bundle + `.icns`.
|
|
243
|
+
- The CLI suites cover `--config`/`--no-config`/`--icon`.
|
|
244
|
+
|
|
245
|
+
## Milestones
|
|
246
|
+
|
|
247
|
+
0. **I0 — project build config** ✅ (`src/driver/config.ts`, CLI wiring, tests).
|
|
248
|
+
1. **I1 — embedded icon + runtime window icon** ✅ (`--icon`,
|
|
249
|
+
`src/driver/icon.ts`, `xt_app_icon_*`, `SDL_SetWindowIcon`, cache key).
|
|
250
|
+
2. **I2 — Windows PE resource** ✅ (`src/driver/win-icon.ts`).
|
|
251
|
+
3. **I3 — macOS `.app` bundle** ✅ (`src/driver/mac-bundle.ts`).
|
|
252
|
+
4. **I4 — Linux desktop integration** (optional).
|
|
253
|
+
5. **I5 — per-window / per-asset icon** (optional).
|
|
254
|
+
|
|
255
|
+
## Decisions
|
|
256
|
+
|
|
257
|
+
- **OQ-1 UX** — icon lives in the project build config (`app.icon`) with a
|
|
258
|
+
`--icon` override. *Done.*
|
|
259
|
+
- **OQ-2 macOS bundling** — explicit `--bundle` / `app.bundle`. *Done.*
|
|
260
|
+
- **OQ-3 formats** — PNG required; ICO/ICNS best-effort. *Done.*
|
|
261
|
+
- **OQ-4 non-GUI apps** — supported everywhere (it is just a resource). *Done.*
|
|
262
|
+
- **OQ-5 default icon** — none; opt-in. *Done.*
|
|
263
|
+
- **OQ-6 config format/name** — `xbintsc.config.json`, strict JSON (`$schema`
|
|
264
|
+
allowed but ignored). *Done.*
|
|
265
|
+
- **OQ-7 config scope** — single `entry` for now. *Done.*
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# xbintsc Implemented Syntax and Features
|
|
2
|
+
|
|
3
|
+
This document was compiled by checking the source (`src/`, `runtime/`) and tests
|
|
4
|
+
(`tests/`) file by file, and lists only the syntax and features that are
|
|
5
|
+
**actually usable today**. Implementation locations are noted for traceability.
|
|
6
|
+
|
|
7
|
+
> Note: the compiler *parses* much more than it *generates code* for. Many
|
|
8
|
+
> TypeScript constructs can be parsed, and even bound, but the code generation
|
|
9
|
+
> stage reports `UnsupportedFeature`. Those are **not** listed here; see the
|
|
10
|
+
> [unimplemented document](./unimplemented.md).
|
|
11
|
+
|
|
12
|
+
> Language: **English** | [简体中文](./zh-CN/implemented.md)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Compilation pipeline (fully implemented)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
source.ts
|
|
20
|
+
│ lexer src/lexer/scanner.ts + token.ts
|
|
21
|
+
▼
|
|
22
|
+
tokens
|
|
23
|
+
│ parser src/parser/parser.ts → AST src/ast/
|
|
24
|
+
▼
|
|
25
|
+
AST
|
|
26
|
+
│ binder src/binder/binder.ts → scopes/symbols/closure capture
|
|
27
|
+
▼
|
|
28
|
+
bound AST
|
|
29
|
+
│ codegen src/codegen/llvm.ts + values.ts → LLVM IR text
|
|
30
|
+
▼
|
|
31
|
+
module.ll ── clang ──► module.o ──link──► executable
|
|
32
|
+
▲
|
|
33
|
+
runtime/*.c (C runtime, split by function)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Front end, back end, runtime and extensions are fully decoupled.
|
|
37
|
+
- The flow is orchestrated by `src/driver/compiler.ts`: `read → parse → bind → IR → object file → link`.
|
|
38
|
+
- **Self-hosting**: `xbintsc` compiles its own front end. Building `src/cli/main.ts`
|
|
39
|
+
with the compiler yields a working `xbintsc` binary, and that binary rebuilds
|
|
40
|
+
itself with byte-identical LLVM IR (source ≡ generation 1 ≡ generation 2 ≡
|
|
41
|
+
generation 3). The runtime is still hand-written C.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. Lexer (implemented)
|
|
46
|
+
|
|
47
|
+
Location: `src/lexer/scanner.ts`, `src/lexer/token.ts`
|
|
48
|
+
|
|
49
|
+
- Full token classification: identifiers, keywords, private identifiers, numbers, strings, templates, regex (scanning), all punctuation and operators.
|
|
50
|
+
- Full keyword table: `abstract any as asserts async await bigint boolean break case catch class const constructor continue debugger declare default delete do else enum export extends false finally for from function get if implements import in infer instanceof interface is keyof let module namespace never new null number object package private protected public readonly return satisfies set static string super switch symbol this throw true try type typeof undefined unique unknown var void while with yield`
|
|
51
|
+
- Numeric literals:
|
|
52
|
+
- Decimal, `0x` hex, `0o` octal, `0b` binary
|
|
53
|
+
- Underscore separators `1_000_000`
|
|
54
|
+
- Fractions, exponents `1.5e3`
|
|
55
|
+
- BigInt literals (`10n`, `0xFFn`) evaluate to arbitrary-precision integers (arithmetic, bitwise, shifts, comparisons, `toString(radix)`, `BigInt()` / `BigInt.asIntN` / `BigInt.asUintN`)
|
|
56
|
+
- BigInt literal values are parsed exactly into `bigint` (never routed through `Number`), so the token / AST value of a literal beyond 2^53 keeps full precision
|
|
57
|
+
- String literals:
|
|
58
|
+
- Single / double quotes
|
|
59
|
+
- Escapes: `\n \t \r \b \f \0 \\ \' \"`, `\xHH`, `\uHHHH`, `\u{...}`
|
|
60
|
+
- Template literals (lexer level): no-substitution templates, `TemplateHead`, `TemplateMiddle`, `TemplateTail`, with `${}` and escapes.
|
|
61
|
+
- Regex literal scanning (`/pattern/flags`), distinguishing division `/`.
|
|
62
|
+
- Private identifiers `#name`.
|
|
63
|
+
- Comments: line `//` and block `/* */` (with unterminated diagnostics).
|
|
64
|
+
- Newline and whitespace tracking (for ASI), BOM / CRLF normalization (`SourceFile`).
|
|
65
|
+
- Lexical diagnostics: unterminated string / template / comment, illegal character, illegal number, illegal escape.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 3. Parser (implemented)
|
|
70
|
+
|
|
71
|
+
Location: `src/parser/parser.ts`, `src/ast/nodes.ts`
|
|
72
|
+
|
|
73
|
+
### 3.1 Statements
|
|
74
|
+
|
|
75
|
+
- Variable declarations: `var` / `let` / `const`, with multiple declarators `const a = 1, b = 2;`
|
|
76
|
+
- Function declarations, function expressions and methods, including the `async` modifier and generators (`function*`, `yield`, `yield*`, `.next`/`.throw`/`.return`)
|
|
77
|
+
- `class` declarations / class expressions (constructor, fields, methods, `static`, `extends`)
|
|
78
|
+
- `if` / `else`
|
|
79
|
+
- `while`, `do...while`
|
|
80
|
+
- `for` (init, condition and increment may all be omitted)
|
|
81
|
+
- `for...of`, `for...in` (see the semantic limits in 3.5)
|
|
82
|
+
- `return`, `break`, `continue`, `throw` (including labeled `break label` / `continue label`)
|
|
83
|
+
- `switch` / `case` / `default` (including fall-through)
|
|
84
|
+
- `try` / `catch` / `finally` (catchable exceptions based on a runtime setjmp frame)
|
|
85
|
+
- `export var` / `export let` / `export const` (modifier parsed then erased)
|
|
86
|
+
- Block statement `{}`, empty statement `;`, `debugger;`
|
|
87
|
+
- Expression statements
|
|
88
|
+
|
|
89
|
+
### 3.2 Expressions
|
|
90
|
+
|
|
91
|
+
- All common operators with precedence / associativity (see section 5)
|
|
92
|
+
- Assignment expressions and all compound assignments (see section 5)
|
|
93
|
+
- Conditional (ternary) expressions `a ? b : c`
|
|
94
|
+
- Arrow functions `() => expr` / `() => { ... }` (including type parameters and return type annotations)
|
|
95
|
+
- Function expressions `function () {}` and named function expressions `function g() {}`
|
|
96
|
+
- Call expressions `f(...)`, member access `a.b`, element access `a[i]`
|
|
97
|
+
- Array literals `[1, 2]`, sparse array elision, spread `[...a]` (also over strings, `Map` and `Set`)
|
|
98
|
+
- Object literals `{ a: 1 }`, shorthand properties `{ a }`, method shorthand `{ m() {} }`, getter / setter shorthand `{ get x() {} }` / `{ set x(v) {} }`, computed keys `{ [expr]: 1 }`, object spread `{ ...obj }`
|
|
99
|
+
- Template literal `${}` substitutions, tagged templates (with raw strings and `String.raw`)
|
|
100
|
+
- Parenthesized expressions, `as` / `satisfies` / non-null assertion `!` (type erasure)
|
|
101
|
+
- Unary: `+ - ! ~ typeof void`, prefix / postfix `++ --`
|
|
102
|
+
- Optional chaining `?.` / `?.[]` / `?.()` (with nullish short-circuit semantics)
|
|
103
|
+
- `delete` expressions (delete an object property)
|
|
104
|
+
|
|
105
|
+
### 3.3 TypeScript type syntax (parsed only, structure preserved then erased)
|
|
106
|
+
|
|
107
|
+
- Type annotations, return type annotations, type parameters `<T>` and constraints `<T extends U>`, type parameter defaults
|
|
108
|
+
- Type references, qualified names `A.B`
|
|
109
|
+
- Unions `|`, intersections `&`, arrays `T[]`, tuples `[T, U]`, optional tuple members `T?`, rest tuple members `...T`
|
|
110
|
+
- Function types `(a: T) => U`, construct signatures `new () => T`
|
|
111
|
+
- Object type literals, property signatures, method signatures, index signatures `[k: string]: T`
|
|
112
|
+
- Conditional types `T extends U ? X : Y`, mapped types `{ [K in T]: U }`, `infer`
|
|
113
|
+
- Type operators `keyof`, `unique`, `readonly`
|
|
114
|
+
- `typeof` (type query), indexed access types `T[K]`
|
|
115
|
+
- Literal types, `this` types
|
|
116
|
+
- Type predicates `x is T` / `asserts x is T`
|
|
117
|
+
- Interfaces, type aliases, enums, namespace / module declarations
|
|
118
|
+
- The various forms of `import` / `export` (structural parsing)
|
|
119
|
+
|
|
120
|
+
### 3.4 Module syntax (structural parsing + driver bundling)
|
|
121
|
+
|
|
122
|
+
- `import default, { named } from "..."`, `import * as ns from "..."` (namespace imports of relative modules are lowered to a synthetic object literal; extension modules such as `path` are also supported), `import type`
|
|
123
|
+
- `export default`, `export { a as b }`, `export *`, `export =`
|
|
124
|
+
- Import attributes (`with` / `assert`)
|
|
125
|
+
- The **runtime semantics** of `import` / `export` are handled at the driver layer by `src/driver/modules.ts`: it recursively resolves relative dependencies *and* bare `node_modules` packages (following `exports` / `module` / `main` and package subpaths), renames top-level symbols with a per-module prefix, rewrites references, merges into a single file and rebinds. Packages may be ESM or CommonJS: a CommonJS file under `node_modules` gets a synthetic `module`/`exports` pair, its `require` calls are lowered to the bundled dependency's exports, and its statically-detected exports are exposed to ESM importers. `require()` outside `node_modules` is still rejected with a hint to use `import`. Circular dependencies error out.
|
|
126
|
+
|
|
127
|
+
### 3.5 ASI
|
|
128
|
+
|
|
129
|
+
- Automatic Semicolon Insertion, based on `precededByLineBreak` / `}` / EOF.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 4. Name binding and scopes (Binder, implemented)
|
|
134
|
+
|
|
135
|
+
Location: `src/binder/binder.ts`
|
|
136
|
+
|
|
137
|
+
- Scope kinds: module, function, block, `for`, `catch`
|
|
138
|
+
- Symbol kinds: `var` / `let` / `const` / `function` / `parameter` / `class` / `interface` / `type` / `enum` / `import` / `namespace`
|
|
139
|
+
- `var` and function declarations hoist to the function scope; `let` / `const` stay block-scoped
|
|
140
|
+
- Identifier → declaration resolution; unresolved identifier collection (`CannotFindName`)
|
|
141
|
+
- Closure capture analysis: outer variables referenced by an inner function are marked `captured` / `boxed`, and capture indices are threaded through intermediate closures
|
|
142
|
+
- Parameters are registered as local symbols; the self-name of a named function expression is registered as `const`
|
|
143
|
+
- Type-only declarations (interface / type alias) do not participate in value capture
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 5. Operators and assignment (codegen implemented)
|
|
148
|
+
|
|
149
|
+
Location: `src/codegen/llvm.ts` (`BINARY_RUNTIME`, `emitPrefix`, `emitPostfix`, `emitAssignment`)
|
|
150
|
+
|
|
151
|
+
### 5.1 Arithmetic
|
|
152
|
+
|
|
153
|
+
`+ - * / % **` (`**` is right-associative)
|
|
154
|
+
|
|
155
|
+
### 5.2 Comparison and equality
|
|
156
|
+
|
|
157
|
+
`< <= > >=`, `== !=` (loose equality), `=== !==` (strict equality)
|
|
158
|
+
|
|
159
|
+
### 5.3 Logical and short-circuit
|
|
160
|
+
|
|
161
|
+
`&& || ??` (with short-circuit evaluation), `!`
|
|
162
|
+
|
|
163
|
+
### 5.4 Bitwise
|
|
164
|
+
|
|
165
|
+
`& | ^ ~ << >> >>>`
|
|
166
|
+
|
|
167
|
+
### 5.5 Unary
|
|
168
|
+
|
|
169
|
+
`+ - ! ~`, prefix / postfix `++ --`
|
|
170
|
+
|
|
171
|
+
### 5.6 Assignment
|
|
172
|
+
|
|
173
|
+
`= += -= *= /= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??=`
|
|
174
|
+
|
|
175
|
+
### 5.7 Other expression operators
|
|
176
|
+
|
|
177
|
+
- Comma expression `,`
|
|
178
|
+
- `in` operator (`key in obj`, mapped to `xt_in`)
|
|
179
|
+
- `delete obj.key` / `delete obj[key]` (mapped to `xt_delete`)
|
|
180
|
+
- `instanceof` (mapped to `xt_instance_of`, walking the prototype chain)
|
|
181
|
+
|
|
182
|
+
> `typeof` / `void` are implemented as unary operators.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 6. Value model and calling convention (implemented)
|
|
187
|
+
|
|
188
|
+
Location: `src/codegen/values.ts`, `runtime/rt.h`
|
|
189
|
+
|
|
190
|
+
- All JS values are unified as a 64-bit `xt_value` (NaN-boxing).
|
|
191
|
+
- Doubles are not boxed; other types are tagged pointers with a 16-bit tag in the high bits and a 48-bit payload.
|
|
192
|
+
- Tags: `undefined` / `null` / `false` / `true` / `string` / `object` / `array` / `function`.
|
|
193
|
+
- Uniform function ABI:
|
|
194
|
+
|
|
195
|
+
```c
|
|
196
|
+
xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- `thisValue` is threaded as the first ABI parameter (exception-safe, supports nesting); arrow functions inherit `this` lexically from an extra environment slot.
|
|
200
|
+
- Closures thread captured variables through `env` (by reference, boxed); direct calls and closure calls share one code path.
|
|
201
|
+
- `xt_object` carries a prototype field, and property lookup walks the prototype chain; `xt_function` carries a `prototype` and a property bag (static members).
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 7. LLVM IR code generation (Codegen, implemented)
|
|
206
|
+
|
|
207
|
+
Location: `src/codegen/llvm.ts`
|
|
208
|
+
|
|
209
|
+
- Emits LLVM IR text (`.ll`); no custom register allocation (relies on `alloca` + mem2reg).
|
|
210
|
+
- Statement / block boundary values live in `alloca`; conditionals and short-circuits materialize into temporary slots instead of `phi`.
|
|
211
|
+
- Control flow: `if` / `while` / `do` / `for` / `for...of` / `for...in`, `switch`, `try/catch/finally`, `break` / `continue` / `return`.
|
|
212
|
+
- `for...of` and spread iterate arrays, strings, typed arrays, `Map`, `Set`, generators and any object exposing `[Symbol.iterator]()` through `xt_iter_open` → `xt_iter_has` / `xt_iter_value` (`Map` yields `[key, value]` pairs); a non-iterable throws `TypeError`.
|
|
213
|
+
- `switch` tests each `case` with strict equality, executes on a hit, and falls through until `break`.
|
|
214
|
+
- `try/catch/finally` is implemented with a runtime `_setjmp` frame: `xt_try_enter` pushes, `_setjmp` catches, `xt_throw` long-jumps. The IR passes the caller's frame address (`@llvm.frameaddress(0)`) as the second `_setjmp` argument, matching clang's MSVC lowering: the Windows UCRT `_setjmp` stores that frame in `_JUMP_BUFFER.Frame` and `longjmp` feeds it to `RtlUnwind`, so omitting it made `longjmp` unwind to a bogus target (`STATUS_BAD_FUNCTION_TABLE`). `_setjmp` is used rather than the exported `setjmp` symbol, whose Windows ABI is an incompatible two-argument routine. Functions containing `try` force local variables to stay in memory (inline-asm escape points) so values survive a long jump.
|
|
215
|
+
- `for...in` reuses `xt_object_keys` to enumerate keys (arrays / strings yield string indices).
|
|
216
|
+
- Expressions:
|
|
217
|
+
- Identifiers, numbers, BigInt (arbitrary precision), strings, templates, booleans, `null`, `undefined`, `arguments`
|
|
218
|
+
- Arithmetic / comparison / logical / short-circuit / conditional / bitwise / unary (including `typeof` `void`) / prefix-postfix increment-decrement / compound assignment / logical assignment
|
|
219
|
+
- Array literals (including spread `[...]`), object literals (including shorthand / methods / object spread `{...obj}`)
|
|
220
|
+
- Typed arrays (`Uint8Array`, `Int8Array`, `Uint8ClampedArray`, `Uint16Array`, `Int16Array`, `Uint32Array`, `Int32Array`, `Float32Array`, `Float64Array`): construction (`new X(n)` / `new X(iterable)` / `X.from` / `X.of`), `length` / `byteLength` / `byteOffset` / `BYTES_PER_ELEMENT`, element reads/writes with per-type coercion (`ToIntN` / `ToUintN`, `Uint8ClampedArray` rounding, `Float32` single-precision rounding) and the prototype methods `fill` / `set` / `slice` / `subarray` / `join` / `toString` / `indexOf` / `lastIndexOf` / `includes` / `forEach` / `map` / `filter` / `every` / `some` / `find` / `findIndex` / `reduce` / `reverse` / `sort` / `copyWithin` / `at` / `keys` / `values` / `entries`. See the unimplemented document for the deliberate divergences (`subarray` copies, iterator methods return arrays, no `ArrayBuffer`/`DataView`).
|
|
221
|
+
- Property access (with a `length` special case, `Math` constants), element access, calls
|
|
222
|
+
- Optional chaining `?.` / `?.[]` / `?.()`: nullish check short-circuits to `undefined`
|
|
223
|
+
- `delete`, `in`, `instanceof`
|
|
224
|
+
- `this` (saved to the function's `%saved.this`; arrow functions read from an environment slot), `super` (`super.x` / `super(...)`), `new`, `await`
|
|
225
|
+
- Closures (arrow functions / function expressions) and capture environment construction
|
|
226
|
+
- Classes: constructor closure + prototype object, stored in an LLVM global (`@class.<id>`); instance fields are initialized before the constructor body; `static` members live in the constructor's property bag; `extends` sets up the prototype chain; `super(...)` is invoked through a hidden `__ctor` on the prototype.
|
|
227
|
+
- `async`: wrapped with `xt_promise_resolve` before returning; `await` calls `xt_await` (drives the microtask queue and raises an exception on rejection).
|
|
228
|
+
- Standard library calls: `console.*`, `Math.*`, `Object.*`, array / string methods all go through `xt_call_method` / `xt_math_call` / `xt_object_*`; `JSON`/`Date`/`Map`/`Set`/`RegExp`/`Promise` statics and constructors go through their `xt_*` functions; global functions (`parseInt`, `setTimeout`, etc.) go through `xt_parse_int`, `xt_set_timeout`, etc.
|
|
229
|
+
- Global string pool (`@.str.N` private constants, UTF-8 escaped).
|
|
230
|
+
- Builtin calls: `console.log` / `info` / `warn` / `error`, `Math.*`, `Object.*`, array / string methods, global functions, extension builtins (uniform `(argc, argv)` ABI).
|
|
231
|
+
- `main` entry point (returns 0, calls the module function, and runs `xt_drain_microtasks` before returning).
|
|
232
|
+
- Unsupported nodes uniformly report `UnsupportedFeature`; they never crash.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 8. C runtime (Runtime, implemented)
|
|
237
|
+
|
|
238
|
+
Location: `runtime/xt_alloc.c`, `runtime/xt_values.c`, `runtime/xt_containers.c`,
|
|
239
|
+
`runtime/xt_stdlib.c`, `runtime/xt_stdlib2.c`, `runtime/xt_promise.c`, `runtime/xt_builtins.c`,
|
|
240
|
+
`runtime/xt_io.c`, sharing the private header `runtime/rt_internal.h`; the public ABI is in `runtime/rt.h`.
|
|
241
|
+
|
|
242
|
+
- Allocator: non-moving mark-sweep collector behind `xt_alloc` (explicit roots, subsystem root providers and a conservative C-stack scan).
|
|
243
|
+
- Value construction: `xt_undefined/xt_null/xt_bool/xt_number/xt_string_new/xt_string_from_cstr`.
|
|
244
|
+
- Strings: UTF-8 storage, concatenation, equality comparison, formatted number-to-string.
|
|
245
|
+
- Type conversion: `xt_truthy`, `xt_to_number`, `xt_to_string`, `xt_typeof`.
|
|
246
|
+
- Arithmetic: `add/sub/mul/div/mod/pow/neg/pos`.
|
|
247
|
+
- Bitwise: `and/or/xor/not/shl/shr/ushr` (including `ToInt32` semantics).
|
|
248
|
+
- Comparison: `lt/le/gt/ge`, loose / strict equality, `not`, `is_nullish`.
|
|
249
|
+
- Objects: linear property list, `object_new/get/set/has/keys/values/entries/assign/spread`.
|
|
250
|
+
- Arrays: `array_new/get/set/push/length/spread`; assigning `arr.length` truncates or extends (matching JS); `iter_length` / `iter_value` expose a uniform iteration view over arrays, strings, `Map` and `Set`.
|
|
251
|
+
- Typed arrays (`xt_typed_array.c`): typed arrays as property-bag objects with one prototype per element kind; element reads return the stored value and writes are coerced to the element type; `from` / `of` statics plus the full prototype method set; `subarray` copies.
|
|
252
|
+
- Symbols (`xt_symbol.c`): `Symbol(description)` primitives (`XT_OBJECT_KIND_SYMBOL`), the 13 well-known symbols (`Symbol.iterator`, `Symbol.asyncIterator`, `Symbol.match`, …), `Symbol.for` / `Symbol.keyFor` global registry, `symbol.description` / `toString()` / `valueOf()`; symbols are valid property keys (`Object.getOwnPropertySymbols`, symbol keyed `get`/`set`/`in`/`delete`), are skipped by `Object.keys` / `values` / `entries` / `for...in` / `JSON.stringify`, and print as `Symbol(desc)`.
|
|
253
|
+
- Generic member access: `xt_get` / `xt_set` (dispatch over arrays / objects / strings).
|
|
254
|
+
- Standard library: `xt_call_method` (uniform dispatch of array / string methods and function properties on objects), `xt_math_call` (`Math.*` and constants), global functions `xt_parse_int/parse_float/is_nan/is_finite/number_ctor/string_ctor/boolean_ctor/fetch`.
|
|
255
|
+
- Operator helpers: `xt_in` (`in`), `xt_delete` (`delete`), `xt_rest_args` (rest parameters / `arguments`).
|
|
256
|
+
- Box: `box_new/get/set` (for closure-captured variables).
|
|
257
|
+
- Functions and closures: `arg`, `closure_new/call/env/arity`.
|
|
258
|
+
- Exceptions: `xt_try_enter` / `xt_try_exception` / `xt_try_leave` maintain the `_setjmp` frame stack; `xt_throw` long-jumps to the nearest `try` when a frame exists, otherwise prints `Uncaught ...` and exits.
|
|
259
|
+
- Output: `xt_print/xt_println/xt_console_log/info/warn/error` (Node-style inspect: arrays `[ a, b ]`, objects `{ k: v }`; `info`/`log` to stdout, `warn`/`error` to stderr), plus `dir/trace/assert/count/countReset/group/groupEnd/table/time/timeEnd/timeLog`.
|
|
260
|
+
- Objects / functions: `xt_object` with a prototype chain, `xt_function` with a property bag (static members and `prototype`); `xt_new` (instantiation), `xt_instance_of` (prototype chain), `xt_object_freeze/is_frozen/from_entries`.
|
|
261
|
+
- Standard library extensions (`xt_stdlib2.c`): extended array / string / number / object methods; `Object` / `Array` / `Number` / `String` statics; `JSON.parse` / `JSON.stringify`; `Map` / `Set`; `Date` (`gmtime_r`); `RegExp` (POSIX ERE `regcomp`/`regexec` `test`/`exec`).
|
|
262
|
+
- Promise (`xt_promise.c`): synchronous microtask queue (`xt_microtasks`); `xt_promise_ctor/resolve/reject/static`, instance `then/catch/finally`; `xt_await` drives the queue until settle, and rejection raises via `xt_throw`; `xt_drain_microtasks` empties the queue at program exit.
|
|
263
|
+
- Fetch (`xt_fetch.c`): global `fetch(input, init)` is a blocking HTTP/1.1 client whose promise is already settled (the runtime has no event loop). It accepts `http://` URLs only — `https://` rejects with a `TypeError` because no TLS backend is linked — and supports `method`, `headers` (plain object or `Headers`), `body` and `redirect` (`follow` / `manual` / `error`), following up to 20 redirects and switching POST to GET on 301/302/303. The resolved `Response`-shaped object exposes `ok` / `status` / `statusText` / `url` / `headers` plus `text()` / `json()` / `arrayBuffer()` / `bytes()` / `clone()`, and `Headers` is case-insensitive with `get` / `has` / `set` / `append` / `delete` / `keys` / `values` / `entries` / `forEach` / `getSetCookie`. Invalid URLs and network failures reject with a `TypeError`.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 9. Extension mechanism (Extensions, implemented)
|
|
268
|
+
|
|
269
|
+
Location: `src/extensions/registry.ts`, `src/extensions/node/`
|
|
270
|
+
|
|
271
|
+
- An extension is a plain object: `runtimeSources()` (extra C sources), `linkerFlags()` (extra link flags), `builtins()` (global identifier → runtime symbol, uniform `(argc, argv)` ABI) and `modules()` (import specifier → named exports / namespace).
|
|
272
|
+
- `ExtensionRegistry`: register / unregister / lookup / aggregate builtins, modules, runtime sources and link flags.
|
|
273
|
+
- The built-in core extension `core`: exposes `print` (mapped to `xt_println`), always registered.
|
|
274
|
+
- The Node extension `node`:
|
|
275
|
+
- Modular organisation: `src/extensions/node/fs/` + `runtime/ext_node/fs/read_file.c`
|
|
276
|
+
- Exposes importable modules (`fs`, `fs/promises`, `path`, `os`, `process`, …) under both bare and `node:`-prefixed specifiers; `import { readFileSync } from "fs"` resolves to `xt_node_read_text_file`, and `path`/`os`/`process` map exports onto the namespace dispatchers.
|
|
277
|
+
- Adding a new module only requires a new directory plus a C implementation; the core compiler never changes.
|
|
278
|
+
- Native C++/Rust extensions (`src/extensions/native.ts`, `--ext-native`):
|
|
279
|
+
- `nativeObjects()` links pre-built objects/static archives that expose `extern "C"` symbols with the `(argc, argv)` ABI; a JSON manifest maps them onto builtins/modules (`linkerFlags` / `linkerFlagsByPlatform` cover C++/Rust runtimes).
|
|
280
|
+
- Authoring helpers live in `runtime/xt_ext.h` (C/C++) and `runtime/xt_ext.rs` (Rust); runnable projects are under `examples/extensions/`.
|
|
281
|
+
- The driver links the artifacts verbatim and the incremental cache fingerprints their contents, so a rebuilt library invalidates the cached binary.
|
|
282
|
+
- CI builds both language examples on Linux, macOS and Windows; on Windows the system clang links with the MSVC ABI (C++ `-lmsvcprt`, Rust `*-pc-windows-msvc` plus the Windows system libraries).
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 10. Driver, incremental compilation and toolchain (implemented)
|
|
287
|
+
|
|
288
|
+
Location: `src/driver/compiler.ts`, `src/driver/cache.ts`, `src/driver/toolchain.ts`, `src/driver/paths.ts`
|
|
289
|
+
|
|
290
|
+
- Compilation pipeline: read source → module bundling (`src/driver/modules.ts`, when the entry contains `import`/`export`) → parse → bind/check → IR → object file → link.
|
|
291
|
+
- Incremental cache: keyed on "compiler version + source hash + emit kind + optimization level + platform + extension fingerprint (names, linker flags, native object contents)"; if the artifacts exist and are fresh, the build is skipped.
|
|
292
|
+
- C runtime and extension sources are cached as object files by content hash and compiled only once.
|
|
293
|
+
- Toolchain wrapper: locates `clang` (overridable with `xbintsc_CLANG`), compiles IR, compiles C, links.
|
|
294
|
+
- Link flags: `-lm` is added automatically on non-Windows; extensions may append extra link flags.
|
|
295
|
+
- Project config (`src/driver/config.ts`, `xbintsc.config.json`): `entry`, `outDir`, `output`, `optimize`, `extensions`, `extNative`, `force` and `app` (`name`, `icon`, `bundle`, `bundleId`). Discovered by walking up from the entry/cwd, overridable with `--config`, disabled with `--no-config`; every path resolves against the config directory; CLI flags win over config values.
|
|
296
|
+
- Application icon (`src/driver/icon.ts`, `win-icon.ts`, `mac-bundle.ts`, `--icon`/`app.icon`): PNG/ICO/ICNS is embedded as `xt_app_icon_*` symbols, synthesized into a PE resource via `llvm-rc`/`windres` on Windows, and packaged into `Foo.app` (with `AppIcon.icns` via `sips`/`iconutil`) on macOS. The `gui` extension calls `SDL_SetWindowIcon` from the embedded bytes. `xbintsc_RC` overrides the resource compiler.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 11. CLI and programmatic API (implemented)
|
|
301
|
+
|
|
302
|
+
Location: `src/cli/main.ts`, `src/index.ts`, `bin/xbintsc.js`
|
|
303
|
+
|
|
304
|
+
### 11.1 CLI commands
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
xbintsc build <file.ts> [options] compile to a native binary
|
|
308
|
+
xbintsc run <file.ts> [-- args] compile and run
|
|
309
|
+
xbintsc emit <file.ts> print LLVM IR
|
|
310
|
+
xbintsc version print the version
|
|
311
|
+
xbintsc help help
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 11.2 CLI options
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
-o, --output <path> Output path
|
|
318
|
+
--out <dir> Output directory (default: build/)
|
|
319
|
+
--emit <kind> exe | obj | ir (default: exe)
|
|
320
|
+
-O0..-O3 Optimization level (default: -O2)
|
|
321
|
+
--ext <names> Comma separated extensions (e.g. node)
|
|
322
|
+
--ext-native <m> Register a C++/Rust extension from a JSON manifest
|
|
323
|
+
--config <path> Use a project config (default: xbintsc.config.json)
|
|
324
|
+
--no-config Do not read any project config
|
|
325
|
+
--icon <path> Embed an application icon (PNG/ICO/ICNS)
|
|
326
|
+
--bundle macOS: also produce a .app bundle
|
|
327
|
+
--app-name <name> Bundle / display name
|
|
328
|
+
--app-id <id> macOS bundle identifier (e.g. com.example.demo)
|
|
329
|
+
--force Ignore the incremental cache
|
|
330
|
+
--verbose Print progress information
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### 11.3 Programmatic API
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
import { build, compileString } from "xbintsc";
|
|
337
|
+
|
|
338
|
+
const { ir } = compileString("console.log(1 + 1);");
|
|
339
|
+
const result = build("program.ts", { emit: "exe", outDir: "build" });
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 12. Tests (implemented)
|
|
345
|
+
|
|
346
|
+
Location: `tests/` (`lexer` / `parser` / `binder` / `codegen` / `driver` / `extensions` / `cli` / `e2e`)
|
|
347
|
+
|
|
348
|
+
- Per-module unit tests; when `clang` is present, e2e really compiles and runs binaries, otherwise it is skipped automatically.
|
|
349
|
+
- e2e coverage: arithmetic and printing, recursive functions, loops / arrays / string concatenation, closures capturing by reference, JS-style printing of objects / arrays, the Node `fs` extension via `import`, `switch` fall-through, array / string methods, `Math` and global functions and all `console` levels, default / rest parameters and `arguments`, `Object` helpers and spread and `in`/`delete`, `for...in` object key enumeration, `try/catch/finally`, optional chaining, classes and `new`/`this`/`static`/`extends`/`super`/`instanceof`, `async`/`await` and `Promise`, `Map`/`Set`/`JSON` and extended standard library, `for...of` over `Map`/`Set`, array `length` assignment and iterable spread, multi-file `import`/`export` (including `.js` specifiers and plain JavaScript sources), destructuring bindings and assignments, `enum`/`const enum`, regular-expression literals and `new Error(...)`, the `Error` family and `AggregateError`, generators and `Symbol` with custom `Symbol.iterator` iterables, typed arrays (element coercion, `from`/`of`, iteration and the prototype methods), and the global `fetch` (HTTP GET/POST, headers, redirects, JSON/text/binary bodies and `TypeError` rejection).
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## 13. Implemented features quick reference
|
|
354
|
+
|
|
355
|
+
| Category | Contents |
|
|
356
|
+
| --- | --- |
|
|
357
|
+
| Declarations | `var` `let` `const`, function declarations, function expressions, arrow functions, `class` (declaration / expression), `enum` / `const enum`, interfaces / type aliases (erased) |
|
|
358
|
+
| Control flow | `if/else`, `while`, `do...while`, `for`, `for...of`, `for...in`, `switch`, `try/catch/finally`, `break`, `continue`, `return`, `throw` |
|
|
359
|
+
| Expressions | Identifiers, literals, template strings, regular-expression literals, array / object literals (with spread), destructuring bindings and assignments, calls, member / element access, optional chaining, non-null `!`, closures, `arguments`, `this`, `new`, `super`, `await` |
|
|
360
|
+
| Operators | Arithmetic, comparison, equality, logical, bitwise, shift, unary (including `typeof`/`void`), prefix/postfix increment-decrement, compound assignment, logical assignment, `in`, `delete`, `instanceof` |
|
|
361
|
+
| Functions | Default parameters, rest parameters, capturing closures, `this` binding, lexical `this` in arrow functions, `call`/`apply`/`bind`, `name`/`length` |
|
|
362
|
+
| Classes / OO | Constructors, instance fields, methods, `static`, inheritance `extends`/`super`, prototype chain, `instanceof` |
|
|
363
|
+
| Async | `async`/`await`, `Promise` (`then/catch/finally`, `resolve/reject/all/allSettled/race`), synchronous microtask queue |
|
|
364
|
+
| Modules | `import`/`export` (named / default / re-export / `export *` / `export type`), multi-file bundling over relative paths (`.js`-family specifiers resolve to their `.ts` sources, and TypeScript suffixes are preferred over JavaScript siblings when the specifier omits the extension; plain `.js` / `.jsx` / `.mjs` / `.cjs` sources are bundled directly too) and `node_modules` packages (`exports` / `module` / `main`, scoped packages and subpaths), bare specifiers resolved to extension modules; CommonJS packages under `node_modules` are lowered (`require` / `module.exports` / `exports`), while `require()` in user code is rejected with an `import` hint |
|
|
365
|
+
| Standard library | Array / string / number / object extension methods, typed arrays, `Math`, `JSON`, `Date`, `RegExp`, `Map`, `Set`, `Symbol`, `Error` family, `Object/Array/Number/String/Symbol` statics, `console.*` |
|
|
366
|
+
| Value model | 64-bit NaN-boxing, uniform function ABI (including `this`), closure environments, object prototype chains |
|
|
367
|
+
| Runtime | Strings / objects / arrays / typed arrays / closures / arithmetic / comparison / catchable exceptions / Promise / collections / symbols / generators / `fetch` / `console` |
|
|
368
|
+
| Extensions | Extension registry, `core` (print), `node` (fs / path / os / process / buffer / stream / net / dgram / http imported by specifier) |
|
|
369
|
+
| Toolchain | clang compiles IR/C, linking, incremental cache |
|
|
370
|
+
| Project config | `xbintsc.config.json` (`entry` / `outDir` / `optimize` / `extensions` / `app`), discovery + CLI precedence |
|
|
371
|
+
| Application icon | compile-time embed (PNG/ICO/ICNS), PE resource on Windows, `.app` bundle on macOS, runtime window/Dock icon via `gui` |
|
|
372
|
+
| Self-hosting | `xbintsc` compiles `src/cli/main.ts` to a native binary; the emitted IR is at a fixpoint from generation 1 |
|
|
373
|
+
| Platforms | macOS / Linux / Windows (adapted at the build level, CI in `.github/workflows`) |
|