@amritk/nish-aarch64-darwin 0.10.0
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/INSTALL.md +468 -0
- package/LICENSE +21 -0
- package/bin/nish +0 -0
- package/package.json +31 -0
- package/runtime/nish.d.ts +290 -0
- package/runtime/nish.h +340 -0
- package/runtime/nish.mjs +143 -0
- package/runtime/runtime.c +1184 -0
- package/runtime/runtime_os.c +351 -0
- package/runtime/runtime_parallel.c +156 -0
- package/runtime/runtime_wasm.c +99 -0
- package/runtime/shim.mjs +672 -0
- package/scripts/build.sh +279 -0
- package/std/README.md +185 -0
- package/std/json.ts +402 -0
- package/std/pair.ts +28 -0
- package/std/testing.ts +347 -0
- package/std/text.ts +193 -0
package/INSTALL.md
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
# Installing nish
|
|
2
|
+
|
|
3
|
+
`nish` compiles a static subset of TypeScript to LLVM IR and, with
|
|
4
|
+
`--link`, to a native binary. The compiler is itself a native binary, written
|
|
5
|
+
in Nish (`self/`), and needs nothing to run; the `--link` step (and anything
|
|
6
|
+
else that turns `.ll` into machine code) needs an LLVM toolchain.
|
|
7
|
+
|
|
8
|
+
## 1. Prerequisites
|
|
9
|
+
|
|
10
|
+
- **Node.js 22.18 or newer** (22 is what CI uses), for the npm route and for
|
|
11
|
+
building from a checkout — the launcher, the postinstall step and the test
|
|
12
|
+
harness are Node scripts. It is the version where Node strips TypeScript
|
|
13
|
+
types without a flag, which `docs/RUN_UNDER_NODE.md` relies on. The
|
|
14
|
+
`install.sh` route below needs no Node at all.
|
|
15
|
+
- **clang** (LLVM 18 recommended) and **lld**, for `--link`. Without them
|
|
16
|
+
`nish` still writes the `.ll` files and exits 3 with the install
|
|
17
|
+
command for your platform when you ask for `--link`.
|
|
18
|
+
|
|
19
|
+
### Ubuntu / Debian
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
sudo apt-get update
|
|
23
|
+
sudo apt-get install -y clang-18 lld-18 llvm-18
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Debian ships versioned binaries (`clang-18`, `ld.lld-18`, ...). Either point
|
|
27
|
+
`nish` at the versioned compiler with `CC=clang-18`, or expose the plain
|
|
28
|
+
names on `PATH`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
mkdir -p ~/.local/llvm-bin
|
|
32
|
+
for t in clang clang++ llc llvm-as opt ld.lld wasm-ld; do
|
|
33
|
+
ln -sf "/usr/bin/$t-18" ~/.local/llvm-bin/$t
|
|
34
|
+
done
|
|
35
|
+
export PATH=~/.local/llvm-bin:$PATH # add to your shell profile
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
(`sudo apt-get install -y clang lld llvm` also works if your release's default
|
|
39
|
+
LLVM is 15 or newer.)
|
|
40
|
+
|
|
41
|
+
### Fedora
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
sudo dnf install clang lld llvm
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### macOS
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
brew install llvm@18
|
|
51
|
+
export PATH="$(brew --prefix llvm@18)/bin:$PATH" # add to your shell profile
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Xcode's `clang` (`xcode-select --install`) also works for native binaries;
|
|
55
|
+
the Homebrew LLVM is needed for the `wasm` and `wasi` profiles (`wasm-ld`).
|
|
56
|
+
|
|
57
|
+
### WASI (optional, for `--profile wasi`)
|
|
58
|
+
|
|
59
|
+
The `wasi` profile links the runtime against wasi-libc so that whole programs
|
|
60
|
+
(strings, `console.log`, files, `process.argv`) run under any WASI host. It
|
|
61
|
+
needs a WASI sysroot and compiler-rt's wasm32 builtins next to your clang:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Ubuntu / Debian: the packaged sysroot lands in /usr/lib/wasi-sysroot
|
|
65
|
+
sudo apt-get install -y wasi-libc libclang-rt-18-dev-wasm32
|
|
66
|
+
|
|
67
|
+
# Any platform: wasi-sdk's sysroot and builtins tarballs (versions that match your clang)
|
|
68
|
+
curl -L -o - https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sysroot-24.0.tar.gz | tar -xz -C /opt
|
|
69
|
+
curl -L -o - https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/libclang_rt.builtins-wasm32-wasi-24.0.tar.gz | tar -xz -C /opt
|
|
70
|
+
export WASI_SYSROOT=/opt/wasi-sysroot-24.0 # add to your shell profile
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`scripts/build.sh` looks for the sysroot in `WASI_SYSROOT`,
|
|
74
|
+
`/usr/lib/wasi-sysroot`, `/opt/wasi-sdk/share/wasi-sysroot` and
|
|
75
|
+
`/usr/share/wasi-sysroot`, and for `libclang_rt.builtins-wasm32.a` in clang's
|
|
76
|
+
resource directory, next to the sysroot (as the tarball above unpacks it),
|
|
77
|
+
in `<sysroot>/lib/wasm32-wasi/`, or at `WASI_BUILTINS=<file>`. Then:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
nish examples/argv.ts --link build/argv.wasm --profile wasi
|
|
81
|
+
node examples/wasi-host.mjs build/argv.wasm 3 4 five # or: wasmtime build/argv.wasm 3 4 five
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Node's built-in `node:wasi` runs the module (argv, stdout, exit code and the
|
|
85
|
+
working directory behave as natively); `npm test` prints
|
|
86
|
+
`skipped: no WASI sysroot` and moves on when none is installed.
|
|
87
|
+
|
|
88
|
+
### Windows
|
|
89
|
+
|
|
90
|
+
Windows is not supported natively yet: `scripts/build.sh` is a bash script
|
|
91
|
+
and the runtime is built with clang on a POSIX toolchain. Use
|
|
92
|
+
[WSL](https://learn.microsoft.com/windows/wsl/install) with Ubuntu and follow
|
|
93
|
+
the Ubuntu steps inside it.
|
|
94
|
+
|
|
95
|
+
## 2. Install the compiler
|
|
96
|
+
|
|
97
|
+
**Two ways in, and they install the same compiler.** Neither compiles anything
|
|
98
|
+
on your machine: the binary was built, `--verify`d and smoke-tested on hardware
|
|
99
|
+
of its own architecture by the release workflow before the release existed, and
|
|
100
|
+
installing is a download and an unpack.
|
|
101
|
+
|
|
102
|
+
Through npm, which is also how an Nish *program* resolves its dependencies
|
|
103
|
+
([wp21-packages.md](wp21-packages.md)), so this is the one to pick if you want
|
|
104
|
+
the compiler pinned per project in a `package.json`:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm install -g @amritk/nish
|
|
108
|
+
nish --version
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or without npm and without node at all:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
curl -fsSL https://raw.githubusercontent.com/amritk/nish/main/install.sh | sh
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
That unpacks into `~/.nish` and prints the one line to add to your shell
|
|
118
|
+
profile. On a platform it has no binary for it says so and names the four it
|
|
119
|
+
does build — the npm route covers exactly the same four and no more, because
|
|
120
|
+
since 0.6.0 there is no compiler inside that package to fall back to either.
|
|
121
|
+
|
|
122
|
+
**Upgrading is running it again.** There is no separate command: it installs
|
|
123
|
+
over an existing install, says `upgrading nish 0.3.0 to 0.4.0`, and says
|
|
124
|
+
`nothing to do` when the version already matches.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
curl -fsSL https://raw.githubusercontent.com/amritk/nish/main/install.sh | sh # latest
|
|
128
|
+
curl -fsSL https://raw.githubusercontent.com/amritk/nish/main/install.sh | sh -s 0.4.0 # a version
|
|
129
|
+
sh install.sh --dir /opt/nish # somewhere other than ~/.nish (or NISH_INSTALL)
|
|
130
|
+
sh install.sh --force # reinstall the version already there
|
|
131
|
+
sh install.sh --uninstall # remove it
|
|
132
|
+
sh install.sh --help # all of the above
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
An upgrade cannot leave you without a compiler. The new one is unpacked beside
|
|
136
|
+
the old, checked that it runs *and* that it reports the version that was asked
|
|
137
|
+
for — which catches a truncated download, a tarball built for another
|
|
138
|
+
architecture, and an asset whose name does not match what is inside it — and
|
|
139
|
+
only then swapped in. If any of that fails the install you had is untouched.
|
|
140
|
+
|
|
141
|
+
The npm route installs the **native** compiler, and it is a download rather than a
|
|
142
|
+
build: nothing is compiled on your machine. The package declares one
|
|
143
|
+
`nish-<os>-<arch>` package per supported platform as an `optionalDependencies`
|
|
144
|
+
entry with `os` and `cpu` set, so npm fetches exactly the one that matches and
|
|
145
|
+
skips the rest. Each of those carries the self-hosted compiler — `self/`
|
|
146
|
+
compiled by itself — already built, `--verify`d and smoke-tested on a machine
|
|
147
|
+
of its own architecture by the release workflow.
|
|
148
|
+
|
|
149
|
+
A postinstall step then puts that binary on your PATH directly, so `nish` is
|
|
150
|
+
the compiler rather than a node script that starts it — 3.2 ms per invocation
|
|
151
|
+
instead of 94 ms, measured. If you install with `npm ci --ignore-scripts`, or
|
|
152
|
+
in a sandbox that disables scripts, the step does not run and `nish` is a small
|
|
153
|
+
node launcher that spawns the same binary: the same compiler and the same
|
|
154
|
+
answers, about 91 ms slower to start. Nothing else changes, and the install
|
|
155
|
+
never fails over it.
|
|
156
|
+
|
|
157
|
+
> [!IMPORTANT]
|
|
158
|
+
> **Unpacking a release tarball onto your `PATH` is not an install.** The
|
|
159
|
+
> compiler resolves `scripts/build.sh` and `runtime/` from `argv[0]`'s
|
|
160
|
+
> directory, and a bare `nish` found on `PATH` has no directory in it — so it
|
|
161
|
+
> looks in `./..` and every `--link` fails against whatever your working
|
|
162
|
+
> directory happens to be, while `--version` and `-o` keep working. Both
|
|
163
|
+
> installers above handle it by running the binary through a one-line `exec` of
|
|
164
|
+
> an absolute path. If you unpack a tarball by hand, invoke it by path
|
|
165
|
+
> (`nish-<version>-<asset>/bin/nish`) or write that wrapper yourself. The
|
|
166
|
+
> underlying defect is [wp19 §5a](wp19-stage0-retirement.md#5a-what-r6-is-waiting-on)
|
|
167
|
+
> item 4.
|
|
168
|
+
|
|
169
|
+
**Do not install `nish`.** That name on the public registry has belonged to
|
|
170
|
+
`stdarg`'s "A Node.js Interactive shell" since February 2014 — versions 0.0.0
|
|
171
|
+
and 0.0.1, both deprecated by their author, nothing published since. **This
|
|
172
|
+
compiler is `@amritk/nish`** (decided 2026-09-19,
|
|
173
|
+
[docs/wp12-release.md](wp12-release.md#the-npm-name)), and the command it
|
|
174
|
+
installs is still `nish` — the package name and the command are two different
|
|
175
|
+
strings, and that is the one thing the scope costs.
|
|
176
|
+
|
|
177
|
+
**On a platform this project attaches no binary for, `npm install` gets you a
|
|
178
|
+
command that refuses.** The table below is the whole list, so musl, FreeBSD and
|
|
179
|
+
32-bit anything are outside it, and outside it `nish` prints what happened,
|
|
180
|
+
names the four platforms that do have a binary, and exits 3:
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
$ nish --version
|
|
184
|
+
nish: no prebuilt compiler for freebsd/x64
|
|
185
|
+
|
|
186
|
+
This package installs a prebuilt native compiler. One is published for:
|
|
187
|
+
aarch64-darwin aarch64-linux x86_64-darwin x86_64-linux
|
|
188
|
+
|
|
189
|
+
There is no compiler inside the package to fall back to, and nothing is
|
|
190
|
+
compiled on your machine on any path.
|
|
191
|
+
|
|
192
|
+
To get a compiler for this machine, build one from a released `nish` in a
|
|
193
|
+
checkout of the repository:
|
|
194
|
+
NISH_BOOTSTRAP=<a released nish that runs here> scripts/bootstrap.sh
|
|
195
|
+
docs/INSTALL.md has the detail, including what to do when no released
|
|
196
|
+
binary runs on this platform at all.
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Until 0.6.0 it ran the TypeScript compiler that shipped in the same package
|
|
200
|
+
instead — the same compiler by every test here, about eight times slower, and
|
|
201
|
+
no C toolchain needed. That compiler was `src/`, which was deleted in R6
|
|
202
|
+
([wp19](wp19-stage0-retirement.md)), so there is nothing left in the package to
|
|
203
|
+
fall back to. The cost is stated where the rest of that deletion's costs are,
|
|
204
|
+
in [wp19 §6](wp19-stage0-retirement.md#6-what-retirement-costs-stated-plainly),
|
|
205
|
+
and it is a real one: **musl, FreeBSD and 32-bit platforms have no `npm
|
|
206
|
+
install` route to a compiler any more.**
|
|
207
|
+
|
|
208
|
+
What is left for those platforms is the bootstrap, and it needs one thing this
|
|
209
|
+
page cannot hand you: a compiler that already runs on the machine. The seed does
|
|
210
|
+
not have to be *for* the machine — it has to run *on* it — so the practical
|
|
211
|
+
routes are
|
|
212
|
+
|
|
213
|
+
- a glibc container or host to build in, when the target is musl. Build
|
|
214
|
+
`build/nish` there with `NISH_BOOTSTRAP=<released nish> scripts/bootstrap.sh`,
|
|
215
|
+
and then **emit the IR in the container and link it on the musl host**:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# in the glibc container, where build/nish runs
|
|
219
|
+
build/nish app.ts -o app.ll
|
|
220
|
+
# on the musl host, with its own clang and the runtime from this repository
|
|
221
|
+
clang app.ll runtime/runtime.c runtime/runtime_os.c -lm -o app
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`--link`ing inside the container is the mistake to avoid: it shells out to the
|
|
225
|
+
container's `clang` and hands you a glibc binary, which is the one thing the
|
|
226
|
+
musl host cannot run. The split works because the compiler's output is
|
|
227
|
+
target-neutral text — the C toolchain that compiles `runtime.c` and links is
|
|
228
|
+
what decides the libc, not the compiler that wrote the IR;
|
|
229
|
+
- `--profile wasi`, which compiles the compiler itself into a single WASI module
|
|
230
|
+
that runs anywhere Node does (`web/compile.mjs` drives one). This is not a
|
|
231
|
+
shipped artefact and there is no supported install path for it;
|
|
232
|
+
- a target this project does build, if one will do.
|
|
233
|
+
|
|
234
|
+
If you need one of these to be a first-class install, that is the conversation
|
|
235
|
+
to have on the issue tracker rather than a workaround to discover here.
|
|
236
|
+
|
|
237
|
+
**Nothing is published to the registry yet.** The installer is built and
|
|
238
|
+
tested, and what is left is a person publishing a release under it, which
|
|
239
|
+
[docs/wp12-release.md](wp12-release.md#release-procedure) step 4 is about.
|
|
240
|
+
Until that happens, install from a release.
|
|
241
|
+
|
|
242
|
+
From a release tarball on GitHub — the same package `npm publish` would upload,
|
|
243
|
+
carried by the release instead of the registry. The `Release` workflow attaches
|
|
244
|
+
the npm tarball to the release it builds for a `v*` tag. `npm pack` names it
|
|
245
|
+
after `package.json#name`, so it is `amritk-nish-<version>.tgz` from 0.4.0 on
|
|
246
|
+
and `nish-<version>.tgz` for the releases cut before the scope was taken — the
|
|
247
|
+
example below is one of those:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
curl -LO https://github.com/amritk/nish/releases/download/v0.2.0/nish-0.2.0.tgz
|
|
251
|
+
npm install -g ./nish-0.2.0.tgz
|
|
252
|
+
nish --version
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Installed on its own like that, the package finds no platform package next to
|
|
256
|
+
it and refuses — the same refusal as above, but for the other reason: the binary
|
|
257
|
+
was never fetched rather than none existing for your machine. The message says
|
|
258
|
+
which of the two it is, because the remedy differs. **So install the pair**: a
|
|
259
|
+
release from 0.4.0 on attaches the platform packages beside the npm tarball,
|
|
260
|
+
under the name `npm pack` gave them.
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
base=https://github.com/amritk/nish/releases/download/v0.4.0
|
|
264
|
+
curl -LO $base/amritk-nish-0.4.0.tgz
|
|
265
|
+
curl -LO $base/amritk-nish-x86_64-linux-0.4.0.tgz # the row matching your machine
|
|
266
|
+
npm install -g ./amritk-nish-0.4.0.tgz ./amritk-nish-x86_64-linux-0.4.0.tgz
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
As a native compiler, which needs no Node at all. A release also attaches the
|
|
270
|
+
self-hosted compiler — the binary `self/` produces by compiling itself — one
|
|
271
|
+
per supported platform, from the version named in the last column:
|
|
272
|
+
|
|
273
|
+
| Asset | For | Attached from |
|
|
274
|
+
| --- | --- | --- |
|
|
275
|
+
| `nish-<version>-x86_64-linux.tar.gz` | Linux on Intel or AMD | v0.1.1 |
|
|
276
|
+
| `nish-<version>-aarch64-linux.tar.gz` | Linux on ARM | v0.4.0 |
|
|
277
|
+
| `nish-<version>-x86_64-darwin.tar.gz` | macOS on Intel | v0.4.0 |
|
|
278
|
+
| `nish-<version>-aarch64-darwin.tar.gz` | macOS on Apple Silicon | v0.4.0 |
|
|
279
|
+
|
|
280
|
+
Each is built and smoke-tested on a machine of its own architecture rather than
|
|
281
|
+
cross-compiled, so the one you take has compiled and run two programs before it
|
|
282
|
+
reached you — a one-module one and a two-module one, from a directory unrelated
|
|
283
|
+
to the machine that built it.
|
|
284
|
+
|
|
285
|
+
The last column is there because a release is a past event and a workflow is
|
|
286
|
+
not. `release.yml` builds all four, but a release already published cannot grow
|
|
287
|
+
an asset: **v0.2.0, the current release, attaches `x86_64-linux` only**. Those
|
|
288
|
+
versions are not prose — they are `attachedSince` in
|
|
289
|
+
[`.github/seed-targets.json`](https://github.com/amritk/nish/blob/main/.github/seed-targets.json),
|
|
290
|
+
the same file the release workflow builds its matrix from, so this table and
|
|
291
|
+
the assets cannot drift apart without a test failing.
|
|
292
|
+
|
|
293
|
+
**The three new rows say v0.4.0 rather than v0.3.0 on purpose.** The workflow
|
|
294
|
+
builds all four now, but nothing in this repository has ever run on macOS or on
|
|
295
|
+
ARM Linux, and a row that has never run is not something to put in front of a
|
|
296
|
+
release: `release` needs the whole matrix, so one red row blocks the publish.
|
|
297
|
+
They wait for a release after the run that exercises them. The two macOS rows
|
|
298
|
+
wait on a second thing as well — the bootstrap's `stage3 == stage2` check does
|
|
299
|
+
not hold as a raw byte comparison under `ld64`, and which bytes actually differ
|
|
300
|
+
has not been measured on real hardware, so a darwin row may turn up work rather
|
|
301
|
+
than a green tick. `scripts/verify-binaries.sh`'s header is the long version.
|
|
302
|
+
|
|
303
|
+
Check [the releases page](https://github.com/amritk/nish/releases/latest) for
|
|
304
|
+
what a given version actually carries; on a platform whose row has not shipped
|
|
305
|
+
yet, take the npm package above, or build from source below.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# pick the row above that matches `uname -s` and `uname -m`
|
|
309
|
+
curl -LO https://github.com/amritk/nish/releases/download/v0.2.0/nish-0.2.0-x86_64-linux.tar.gz
|
|
310
|
+
tar -xzf nish-0.2.0-x86_64-linux.tar.gz
|
|
311
|
+
nish-0.2.0-x86_64-linux/bin/nish --version
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Both URLs name the version rather than using GitHub's version-neutral
|
|
315
|
+
`/releases/latest/download/` form, because that form needs the asset's exact
|
|
316
|
+
file name and every asset name carries the version in it. **v0.2.0 is the
|
|
317
|
+
current release**; v0.1.1 before it was the first one with a binary attached.
|
|
318
|
+
The `v0.1.0` tag exists but has no release behind it and no assets, so every
|
|
319
|
+
`v0.1.0` download URL is a 404 — the tag was pushed by a workflow, and GitHub
|
|
320
|
+
raises no event for that, so nothing ever built it
|
|
321
|
+
([docs/wp12-release.md](wp12-release.md#release-procedure) step 2). When a newer
|
|
322
|
+
release exists, take its version from
|
|
323
|
+
[the releases page](https://github.com/amritk/nish/releases/latest).
|
|
324
|
+
|
|
325
|
+
Unpack it and run `bin/nish` from wherever you like; put that on `PATH` if you
|
|
326
|
+
want it there. Keep the directory intact rather than moving the binary out of
|
|
327
|
+
it: `--link` runs `scripts/build.sh` and compiles the C runtime
|
|
328
|
+
(`runtime/runtime.c` and `runtime/runtime_os.c`, the system-call half), and the
|
|
329
|
+
compiler finds all of them relative to its own location — `bin/nish` alone in a
|
|
330
|
+
directory can still emit IR with `-o`, but `--link` will tell you it cannot
|
|
331
|
+
find `scripts/build.sh`.
|
|
332
|
+
|
|
333
|
+
It still needs `clang` and `lld` on `PATH` for `--link` (§1), because linking
|
|
334
|
+
is the C toolchain's job, not the compiler's; what it does not need is Node.
|
|
335
|
+
x86_64 Linux is the only platform built today — on anything else, take the
|
|
336
|
+
`.tgz` above or build from a checkout.
|
|
337
|
+
|
|
338
|
+
From a checkout:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
git clone https://github.com/amritk/nish.git
|
|
342
|
+
cd nish
|
|
343
|
+
npm ci
|
|
344
|
+
bash scripts/fetch-seed.sh # the last release, into build/seed/
|
|
345
|
+
npm run build # seed -> stage1 -> stage2 = build/nish
|
|
346
|
+
build/nish hello.ts --link hello
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
The build is a bootstrap, the way Rust and Go build themselves: the compiler
|
|
350
|
+
is written in Nish, so something has to compile it first, and that is the
|
|
351
|
+
previous release's `nish` binary — the seed. `scripts/fetch-seed.sh` downloads
|
|
352
|
+
it into `build/seed/`; `NISH_BOOTSTRAP=<path>` names one you already have and
|
|
353
|
+
skips the download. §2a has what the build does with it.
|
|
354
|
+
|
|
355
|
+
The published package ships `bin/` (the `nish` command, which is a launcher),
|
|
356
|
+
`runtime/` (the C runtime — two translation units and their header),
|
|
357
|
+
`scripts/build.sh` (the link pipeline) and `std/` (the standard library). The
|
|
358
|
+
compiler itself is not in it: it arrives as one prebuilt
|
|
359
|
+
`@amritk/nish-<asset>` package per platform, and `bin/nish` hands over to
|
|
360
|
+
whichever one npm installed. `nish` locates the runtime, the script and `std/`
|
|
361
|
+
relative to its own install directory, so a global install works from any
|
|
362
|
+
working directory — and the binary runs from inside its own platform package
|
|
363
|
+
for exactly that reason.
|
|
364
|
+
|
|
365
|
+
Building the IR yourself rather than through `--link` means naming the runtime
|
|
366
|
+
on the `clang` line, and it is two files:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
clang app.ll runtime/runtime.c runtime/runtime_os.c -lm -o app
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
`runtime.c` is the half every program touches — the arena, strings, arrays,
|
|
373
|
+
number formatting, the panics — and `runtime_os.c` is the half that wraps the
|
|
374
|
+
system calls: files, directories, subprocesses, `getenv`, the monotonic clock.
|
|
375
|
+
They are separate so that each carries its own measured size ceiling
|
|
376
|
+
([docs/wp7-runtime.md](wp7-runtime.md)); nothing in the core calls into the
|
|
377
|
+
system-call half, so an older line that names `runtime.c` alone still links a
|
|
378
|
+
program that reads no files and spawns nothing. `scripts/build.sh` compiles
|
|
379
|
+
`runtime_os.c` beside any `runtime.c` it is handed, so a build that goes
|
|
380
|
+
through it — every `--link`, and every `--profile` recipe in these documents —
|
|
381
|
+
needs to name only the one.
|
|
382
|
+
|
|
383
|
+
## 2a. What `npm run build` does
|
|
384
|
+
|
|
385
|
+
`self/` is the compiler, written in Nish, and it compiles itself
|
|
386
|
+
([docs/wp14-selfhost.md](wp14-selfhost.md)). From a checkout, with clang on
|
|
387
|
+
`PATH`, `npm run build` runs `scripts/bootstrap.sh` with the seed from §2:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
npm run build # build/nish
|
|
391
|
+
NISH_BOOTSTRAP=~/.nish/bin/nish npm run build # the same, seeded by an installed nish
|
|
392
|
+
scripts/bootstrap.sh --verify # and assert the fixed point
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
The seed builds stage1, stage1 builds stage2, and stage2 is installed as
|
|
396
|
+
`build/nish`. `--verify` also builds stage3 and asserts
|
|
397
|
+
`IR(stage1) == IR(stage2)` and `stage3 == stage2` byte for byte; the seed's
|
|
398
|
+
own IR is only reported beside them, because a codegen change since the
|
|
399
|
+
release is expected to move it. `--stages 1` stops one link sooner.
|
|
400
|
+
|
|
401
|
+
`build/nish` is then the compiler you run: it takes the same `-o`, `--link`
|
|
402
|
+
and `--profile` spellings as an installed `nish`, because it is the same
|
|
403
|
+
program, and makes every directory in the way of the IR, a sidecar or the
|
|
404
|
+
binary itself. It looks for `scripts/build.sh` and the two `runtime/*.c` files
|
|
405
|
+
one level up from wherever it was invoked, then in the working directory, so
|
|
406
|
+
it wants a checkout or an installed package around it the way `nish` does.
|
|
407
|
+
|
|
408
|
+
Because the seed is the last release, `self/` may only *use* in its own
|
|
409
|
+
source the constructs that release compiles. A new construct is implemented
|
|
410
|
+
in `self/` and becomes usable inside `self/` from the next release on; CI's
|
|
411
|
+
`bootstrap` job is what checks that the released seed still builds stage1.
|
|
412
|
+
Until R6 the seed was a TypeScript compiler in `src/`, run under Node; it was
|
|
413
|
+
deleted once the native one answered every flag it did
|
|
414
|
+
([wp19](wp19-stage0-retirement.md)).
|
|
415
|
+
|
|
416
|
+
## 3. Hello world
|
|
417
|
+
|
|
418
|
+
Create `hello.ts`:
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
export const main = (): number => {
|
|
422
|
+
console.log("hello from Nish");
|
|
423
|
+
return 0;
|
|
424
|
+
};
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
`export const main` is the process entry; its return value is the exit code
|
|
428
|
+
(`main(): void` exits 0). Compile and link it:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
nish hello.ts --link hello
|
|
432
|
+
# wrote hello.ll
|
|
433
|
+
# linked hello: 5104 bytes (speed)
|
|
434
|
+
./hello
|
|
435
|
+
# hello from Nish
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
`hello.ll` is the LLVM IR, kept next to the binary. To only get the IR:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
nish hello.ts -o hello.ll
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Other build profiles: `--profile size` (smallest binary), `--profile debug`
|
|
445
|
+
(no optimisation, symbols kept). Run `nish --help` for every flag, and
|
|
446
|
+
see the [README](../README.md) for the language subset.
|
|
447
|
+
|
|
448
|
+
## 4. Exit codes
|
|
449
|
+
|
|
450
|
+
| Code | Meaning |
|
|
451
|
+
| ---: | --- |
|
|
452
|
+
| 0 | success |
|
|
453
|
+
| 1 | the program was rejected: compile error (`file:line:col: error: ...`), missing input file, or an `-o` layout that does not fit the module count |
|
|
454
|
+
| 2 | usage error: unknown flag, missing argument, no input files |
|
|
455
|
+
| 3 | toolchain error: `--link` found no `clang` (`CC` overrides), or `scripts/build.sh` failed (its output is shown; the `.ll` files are still written) — or the `nish` command found no prebuilt compiler for this platform, or one that would not start. Under `--json` all of these are one `NL0002` object |
|
|
456
|
+
| 70 | internal compiler error: an unexpected exception. Please report it at <https://github.com/amritk/nish/issues> with the input and command line; `NISH_DEBUG=1` prints the stack trace |
|
|
457
|
+
|
|
458
|
+
## Troubleshooting
|
|
459
|
+
|
|
460
|
+
- `--link: no usable C compiler found` -- install clang as above, or set
|
|
461
|
+
`CC=/path/to/clang` (for example `CC=clang-18` on Debian).
|
|
462
|
+
- `warning: overriding the module target triple` from clang -- harmless: the
|
|
463
|
+
IR is target-neutral and clang fills in the host triple.
|
|
464
|
+
- `the wasm profile needs wasm-ld` -- install `lld` (`lld-18` on Debian,
|
|
465
|
+
bundled with Homebrew `llvm@18`).
|
|
466
|
+
- `the wasi profile needs a WASI sysroot` / `needs compiler-rt's wasm32
|
|
467
|
+
builtins` -- install them as in the WASI section above, or point
|
|
468
|
+
`WASI_SYSROOT` (a directory) and `WASI_BUILTINS` (the `.a` file) at them.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nish contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/bin/nish
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amritk/nish-aarch64-darwin",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "The @amritk/nish native compiler for macOS on ARM64",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"os": [
|
|
7
|
+
"darwin"
|
|
8
|
+
],
|
|
9
|
+
"cpu": [
|
|
10
|
+
"arm64"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"runtime",
|
|
18
|
+
"scripts",
|
|
19
|
+
"std",
|
|
20
|
+
"LICENSE",
|
|
21
|
+
"INSTALL.md"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/amritk/nish.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/amritk/nish/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/amritk/nish#readme"
|
|
31
|
+
}
|