@amritk/nish 0.12.0 → 0.14.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.
Files changed (42) hide show
  1. package/README.md +27 -23
  2. package/bin/launcher.js +45 -41
  3. package/bin/packaging.js +39 -33
  4. package/docs/AI.md +157 -35
  5. package/docs/INSTALL.md +13 -13
  6. package/llms.txt +1 -1
  7. package/package.json +9 -6
  8. package/runtime/nish.d.ts +85 -1
  9. package/runtime/nish.h +62 -11
  10. package/runtime/nish.mjs +38 -3
  11. package/runtime/runtime-host.c +178 -0
  12. package/runtime/{runtime_os.c → runtime-os.c} +16 -1
  13. package/runtime/{runtime_parallel.c → runtime-parallel.c} +112 -4
  14. package/runtime/{runtime_wasm.c → runtime-wasm.c} +6 -1
  15. package/runtime/runtime.c +5 -5
  16. package/runtime/shim.mjs +128 -6
  17. package/scripts/bootstrap.sh +29 -29
  18. package/scripts/build.sh +19 -13
  19. package/scripts/changelog-gen.mjs +260 -192
  20. package/scripts/ci-profile.mjs +80 -68
  21. package/scripts/codes-registry.js +25 -13
  22. package/scripts/gen-diagnostic-codes.mjs +124 -85
  23. package/scripts/nish-compiler.sh +2 -0
  24. package/scripts/platform-package.mjs +26 -26
  25. package/scripts/postinstall.mjs +46 -36
  26. package/scripts/size-report.sh +3 -3
  27. package/scripts/smoke.sh +1 -1
  28. package/std/README.md +42 -2
  29. package/std/collections.ts +194 -188
  30. package/std/crypto/base64url.ts +145 -0
  31. package/std/crypto/ct.ts +64 -0
  32. package/std/crypto/hkdf.ts +118 -0
  33. package/std/crypto/hmac.ts +155 -0
  34. package/std/crypto/sha256.ts +444 -0
  35. package/std/crypto/sha512.ts +510 -0
  36. package/std/crypto/x25519.ts +494 -0
  37. package/std/json.ts +136 -136
  38. package/std/map.ts +9 -7
  39. package/std/pair.ts +2 -2
  40. package/std/testing.ts +67 -67
  41. package/std/text.ts +54 -54
  42. package/std/threads.ts +126 -38
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Nish
4
4
 
5
+ **Native Instruction Static Host AKA Turbo Typescript. A fast subset of typescript without the encumbrance of javascript.**
6
+
5
7
  **An ahead-of-time compiler for a strictly static subset of TypeScript — LLVM IR in the middle, native binaries at the end. No interpreter, no garbage collector, nothing to ship beside the executable.**
6
8
 
7
9
  ![status](https://img.shields.io/badge/status-pre--alpha-ef4444?style=flat-square)
@@ -22,12 +24,12 @@ Nish parses source with its own lexer and parser, rejects everything dynamic
22
24
  (`any`, prototypes, `eval`, exceptions, a garbage collector), and emits
23
25
  textual LLVM IR (`.ll`). LLVM's own toolchain (`clang` / `llc`) then optimises
24
26
  and produces native binaries for x86_64, ARM64, or WebAssembly. The compiler
25
- is itself written in Nish, in `self/`, and ships as a native binary with no
27
+ is itself written in Nish, in `src/`, and ships as a native binary with no
26
28
  runtime dependency.
27
29
 
28
30
  ```
29
31
  TypeScript source ──▶ AST ──▶ validator + checker ──▶ LLVM IR (.ll) ──▶ clang/llc ──▶ native binary
30
- (self/parser.ts) (self/checker.ts) (self/emit*.ts) + runtime/runtime.c + runtime_os.c
32
+ (src/parser.ts) (src/checker.ts) (src/emit*.ts) + runtime/runtime.c + runtime-os.c
31
33
  ```
32
34
 
33
35
  If it compiles, every value has one fixed, known memory layout; binaries are
@@ -73,7 +75,7 @@ curl -fsSL https://raw.githubusercontent.com/amritk/nish/main/install.sh | sh
73
75
  > `bash scripts/fetch-seed.sh`, `npm run build`, then `build/nish ...` wherever this README says `nish`.
74
76
  > The build is a bootstrap: the previous release's `nish` (the seed, fetched
75
77
  > by `scripts/fetch-seed.sh`, or named with `NISH_BOOTSTRAP=<path>`) compiles
76
- > `self/`, and that compiler compiles `self/` again into `build/nish`.
78
+ > `src/`, and that compiler compiles `src/` again into `build/nish`.
77
79
 
78
80
  `hello.ts`:
79
81
 
@@ -210,7 +212,7 @@ dies with its frame, Rust refuses to compile it, Go falls back to the garbage
210
212
  collector, and Zig hands the question back to you and an allocator. Nish
211
213
  leaves the value in the arena, where it stays until `main` returns.
212
214
 
213
- So [`self/escape.ts`](self/escape.ts) and the whole-program fact
215
+ So [`src/escape.ts`](src/escape.ts) and the whole-program fact
214
216
  fixpoint are optimisations and nothing else: a refusal costs memory and never
215
217
  correctness, and no program is rejected for a lifetime reason. The compiler
216
218
  says so out loud where the cost is real: assigning an allocation to a local
@@ -304,6 +306,8 @@ nish run [options] <file.ts> [args ...]
304
306
  language spawns a thread yet)
305
307
  --no-warn-performance do not report the `performance` diagnostics (they are on by default,
306
308
  print on stderr, and never change the exit code)
309
+ --warn-portability report the `portability` diagnostics: where the program's TypeScript
310
+ reading answers differently (off by default; never changes the exit code)
307
311
  -g emit DWARF debug info (!dbg locations, variables); kept by --link
308
312
  --json print diagnostics as one JSON object per line on stdout (no excerpt)
309
313
  --emit-ast print the syntax tree of every module to stdout instead of IR
@@ -345,7 +349,7 @@ safe. `-o`, `--link`, `--target`, the `--emit-*` sidecars and
345
349
  errors there, and performance warnings are not printed, because stderr belongs
346
350
  to the program.
347
351
 
348
- Without `--link`, build the IR yourself: `clang add.ll examples/main.c runtime/runtime.c runtime/runtime_os.c -o app`
352
+ Without `--link`, build the IR yourself: `clang add.ll examples/main.c runtime/runtime.c runtime/runtime-os.c -o app`
349
353
  (the `overriding the module target triple` warning is harmless: the IR is
350
354
  target-neutral unless you pass `--target`; `-Wno-override-module` silences
351
355
  it), or step by step with `llvm-as`, `llc -O2 -filetype=obj`, and
@@ -363,7 +367,7 @@ with `--target aarch64-unknown-linux-gnu` / `wasm32-wasi` plus
363
367
  Rust-class output is the goal: no GC, no embedded engine, aliasing and
364
368
  purity facts handed to LLVM up front, and a link step that strips everything
365
369
  unused. `examples/add.ts` + `examples/main.c` + the two runtime translation units
366
- (`runtime/runtime.c` and `runtime/runtime_os.c`), x86_64 Linux, glibc
370
+ (`runtime/runtime.c` and `runtime/runtime-os.c`), x86_64 Linux, glibc
367
371
  dynamically linked (`npm run size-report`):
368
372
 
369
373
  | Profile | Bytes | What it does |
@@ -380,7 +384,7 @@ core does not grow every time the language reaches further into the operating
380
384
  system: `runtime.c` is the 3,480 bytes every program touches (one chunked bump
381
385
  arena with O(1) reset and mark/release, strings, JavaScript-exact number
382
386
  formatting, string parsing, `Math.random`, `process.argv`, array growth, the
383
- panic paths), and `runtime_os.c` the 1,190 bytes that wrap a system call (exit,
387
+ panic paths), and `runtime-os.c` the 1,190 bytes that wrap a system call (exit,
384
388
  files, directories, subprocesses, the environment, the clock) — see
385
389
  [docs/wp7-runtime.md](docs/wp7-runtime.md#runtime-additions-and-budget) for both
386
390
  budgets and the reasoning. `Math.*` calls are LLVM intrinsics, so pure functions
@@ -422,7 +426,7 @@ The supported direction is Node importing Nish:
422
426
 
423
427
  - `scripts/build.sh --profile wasm` produces a module `WebAssembly.instantiate`
424
428
  loads directly (`examples/node-host.mjs`); exports use the plain C ABI.
425
- Add `runtime/runtime_wasm.c` (arena + arrays, no libc) when a function
429
+ Add `runtime/runtime-wasm.c` (arena + arrays, no libc) when a function
426
430
  takes or returns an array.
427
431
  - `--emit-napi` + `scripts/build.sh --profile napi` build a `.node` addon
428
432
  with argument type checks (`examples/node-addon.mjs`).
@@ -446,11 +450,11 @@ Details: [docs/wp8-interop.md](docs/wp8-interop.md).
446
450
 
447
451
  ## The compiler in a browser
448
452
 
449
- `self/` is an Nish program, so the compiler compiles itself to
453
+ `src/` is an Nish program, so the compiler compiles itself to
450
454
  WebAssembly like any other one:
451
455
 
452
456
  ```bash
453
- nish self/compile.ts --link web/nish.wasm --profile wasi
457
+ nish src/compile.ts --link web/nish.wasm --profile wasi
454
458
  node web/compile.mjs web/nish.wasm examples/add.ts # the IR, from a Web Worker
455
459
  ```
456
460
 
@@ -464,17 +468,17 @@ refused there. [web/README.md](web/README.md) has the rest.
464
468
 
465
469
  ## Self-hosting
466
470
 
467
- `self/` is the compiler, and the only one: lexer, parser, checker and emitter,
471
+ `src/` is the compiler, and the only one: lexer, parser, checker and emitter,
468
472
  written in Nish, with no `typescript` package underneath. It compiles its own
469
473
  source to a fixed point:
470
474
 
471
475
  ```
472
- IR(stage1, self/) == IR(stage2, self/) byte for byte, and stage3 == stage2
476
+ IR(stage1, src/) == IR(stage2, src/) byte for byte, and stage3 == stage2
473
477
  ```
474
478
 
475
479
  The chain starts from a seed, the previous release's `nish` binary, the way
476
- Rust and Go build themselves: stage1 is `self/` built by the seed, stage2 is
477
- `self/` built by stage1 and is what gets installed, and stage3, built by
480
+ Rust and Go build themselves: stage1 is `src/` built by the seed, stage2 is
481
+ `src/` built by stage1 and is what gets installed, and stage3, built by
478
482
  stage2, has to reproduce stage2 file for file. `scripts/bootstrap.sh --verify`
479
483
  asserts both equalities, and `npm test` re-proves them on every run. Compiling
480
484
  the whole compiler costs it **91 ms and 86 MB**; the TypeScript compiler it
@@ -486,15 +490,15 @@ npm run build # seed -> stage1 -> stage2 = build/nish
486
490
  build/nish hello.ts --link hello # -o, --link, --profile, its own directories
487
491
  ```
488
492
 
489
- Because the seed is the last release, `self/` may only *use* in its own
490
- source what that release compiles. A new construct is implemented in `self/`
491
- and becomes usable inside `self/` from the next release on — the rolling
493
+ Because the seed is the last release, `src/` may only *use* in its own
494
+ source what that release compiles. A new construct is implemented in `src/`
495
+ and becomes usable inside `src/` from the next release on — the rolling
492
496
  freeze CI's `bootstrap` job checks. Until R6 there was a second compiler, the
493
- TypeScript one in `src/`, which seeded every bootstrap and served as the
494
- oracle each `self/` phase was compared against; it was deleted once the
497
+ TypeScript one, stage0, which seeded every bootstrap and served as the
498
+ oracle each phase of `src/` was compared against; it was deleted once the
495
499
  self-hosted compiler did everything it did
496
500
  ([wp19](docs/wp19-stage0-retirement.md)).
497
- Details, and the subset `self/` is written in, are in
501
+ Details, and the subset `src/` is written in, are in
498
502
  [docs/wp14-selfhost.md](docs/wp14-selfhost.md).
499
503
 
500
504
  ---
@@ -511,7 +515,7 @@ and the IR any of them lowers to are all still free to change.
511
515
  | M2 "Data" | classes and interfaces, arrays, runtime and intrinsics | done |
512
516
  | M3 "Rust parity" | interop, memory strategy (stack allocation, arena scopes, `T \| null`), benchmarks with `--target`/`--nsw`/PGO, differential testing against Node | done |
513
517
  | M4 "1.0" | frozen language reference, tagged release | next |
514
- | M5 "Self-hosting" | `self/`: the compiler, written in Nish, compiling itself | done |
518
+ | M5 "Self-hosting" | `src/`: the compiler, written in Nish, compiling itself | done |
515
519
 
516
520
  Not in the language yet, in the order they are likely to land: optional
517
521
  reference counting for objects that must outlive an arena reset, and dynamic
@@ -542,7 +546,7 @@ node tests/run.js locals # only cases whose name contains "locals"
542
546
  npm run test:update # write missing .ll goldens for new cases
543
547
  npm run test:diff # every whole program natively and under Node (runtime/shim.mjs), compared byte for byte
544
548
  node tests/differential/fuzz.js --stage1 --count 200 # random integer programs, the released seed's IR against HEAD's; prints the seed
545
- npm run check # tsc --noEmit: an ambient type-check of self/, std/ and tests/nish/
549
+ npm run check # tsc --noEmit: an ambient type-check of src/, std/ and tests/nish/
546
550
  npm run lint # Biome style lint (advisory, never a compile gate)
547
551
  npm run smoke # build and run every example with a main
548
552
  scripts/bootstrap.sh --verify # the whole chain, with IR(stage1) == IR(stage2) and stage3 == stage2 asserted
@@ -555,7 +559,7 @@ the add-a-construct checklist, ABI guard tests) and the conventions in
555
559
  [docs/MASTER_PLAN.md §7](docs/MASTER_PLAN.md#7-conventions-for-every-agent):
556
560
  every construct ships with a golden `.ll`, an `llvm-as` pass, a native round
557
561
  trip, a negative test, and its LANGUAGE.md and cookbook entries; no attribute
558
- without a proof; layout changes touch `self/runtime.ts` and `runtime/runtime.c` together.
562
+ without a proof; layout changes touch `src/runtime.ts` and `runtime/runtime.c` together.
559
563
  CI runs the suite on Ubuntu and macOS with LLVM 18
560
564
  ([docs/wp10-ci.md](docs/wp10-ci.md)). The documentation index is
561
565
  [docs/README.md](docs/README.md). Coding guidelines for contributors and
package/bin/launcher.js CHANGED
@@ -16,12 +16,12 @@
16
16
  *
17
17
  * **A platform with no prebuilt binary is now an error rather than a fallback,
18
18
  * and that is a decision rather than an oversight.** Until 0.6.0 this file
19
- * imported `dist/index.js` -- the TypeScript compiler built from `src/` -- so
19
+ * imported `dist/index.js` -- the TypeScript compiler built from stage0's `src/` -- so
20
20
  * musl, FreeBSD and 32-bit anything got a working compiler that happened to be
21
- * slower. `src/` was deleted in R6 (`docs/wp19-stage0-retirement.md`), so there
21
+ * slower. stage0's `src/` was deleted in R6 (`docs/wp19-stage0-retirement.md`), so there
22
22
  * is no second compiler in the package to reach for, and the honest answer is
23
23
  * the one below: name the platforms a release carries, say there is nothing to
24
- * fall back to, and exit non-zero. The alternative -- shipping `self/` and
24
+ * fall back to, and exit non-zero. The alternative -- shipping `src/` and
25
25
  * bootstrapping on the user's machine -- was priced in wp12 and turned down,
26
26
  * and quietly doing nothing was never on the table: a command that exits 0
27
27
  * having compiled nothing is worse than one that refuses.
@@ -29,14 +29,14 @@
29
29
  * `bin/` rather than the old `dist/` for the same reason: the command may not
30
30
  * be a build artifact of the compiler it installs.
31
31
  */
32
- import { spawnSync } from "node:child_process";
33
- import fs from "node:fs";
34
- import path from "node:path";
35
- import { createRequire } from "node:module";
36
- import { assetFor, noCompilerMessage, platformPackageName } from "./packaging.js";
32
+ import { spawnSync } from "node:child_process"
33
+ import fs from "node:fs"
34
+ import path from "node:path"
35
+ import { createRequire } from "node:module"
36
+ import { assetFor, noCompilerMessage, platformPackageName } from "./packaging.js"
37
37
 
38
38
  /** Package root: bin/launcher.js -> `..`, the directory `package.json` sits in. */
39
- const PKG_ROOT = path.resolve(import.meta.dirname, "..");
39
+ const PKG_ROOT = path.resolve(import.meta.dirname, "..")
40
40
 
41
41
  /**
42
42
  * Exit 3, the toolchain code.
@@ -54,17 +54,17 @@ const PKG_ROOT = path.resolve(import.meta.dirname, "..");
54
54
  * below is machine-readable. `scripts/postinstall.mjs`'s generated shim answers
55
55
  * 3 for its own version of this, so all three spell one situation the same way.
56
56
  */
57
- const NO_COMPILER = 3;
57
+ const NO_COMPILER = 3
58
58
 
59
59
  /** This package's own name, or `null` when its `package.json` cannot be read. */
60
60
  const packageName = () => {
61
61
  try {
62
- const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, "package.json"), "utf8"));
63
- return typeof pkg.name === "string" ? pkg.name : null;
62
+ const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, "package.json"), "utf8"))
63
+ return typeof pkg.name === "string" ? pkg.name : null
64
64
  } catch {
65
- return null;
65
+ return null
66
66
  }
67
- };
67
+ }
68
68
 
69
69
  /**
70
70
  * Whether this invocation asked for machine-readable output.
@@ -75,7 +75,7 @@ const packageName = () => {
75
75
  * failure the `--json` contract covers (AGENTS.md, "Machine-readable
76
76
  * surfaces").
77
77
  */
78
- const wantsJson = () => process.argv.slice(2).includes("--json");
78
+ const wantsJson = () => process.argv.slice(2).includes("--json")
79
79
 
80
80
  /**
81
81
  * Write and exit, without losing what was written.
@@ -87,9 +87,9 @@ const wantsJson = () => process.argv.slice(2).includes("--json");
87
87
  * there is nothing after it to run.
88
88
  */
89
89
  const writeAndExit = (stream, text, status) => {
90
- stream.write(text);
91
- process.exitCode = status;
92
- };
90
+ stream.write(text)
91
+ process.exitCode = status
92
+ }
93
93
 
94
94
  /**
95
95
  * Where the native compiler for this machine is, or `null` when this machine
@@ -103,26 +103,30 @@ const writeAndExit = (stream, text, status) => {
103
103
  * `build.sh`, the C runtime and the standard library one level up from itself
104
104
  * exactly as it does when unpacked by hand.
105
105
  */
106
- const nativeCompiler = (asset) => {
107
- const name = packageName();
108
- if (name === null) return null;
106
+ const nativeCompiler = (assetName) => {
107
+ const name = packageName()
108
+ if (name === null) {
109
+ return null
110
+ }
109
111
  try {
110
- const manifest = createRequire(import.meta.url).resolve(`${platformPackageName(name, asset)}/package.json`);
111
- const binary = path.join(path.dirname(manifest), "bin", "nish");
112
- return fs.existsSync(binary) ? binary : null;
112
+ const manifest = createRequire(import.meta.url).resolve(
113
+ `${platformPackageName(name, assetName)}/package.json`
114
+ )
115
+ const binary = path.join(path.dirname(manifest), "bin", "nish")
116
+ return fs.existsSync(binary) ? binary : null
113
117
  } catch {
114
118
  // Not installed. On a supported platform that is a partial install; on an
115
119
  // unsupported one npm skipped the entry on purpose. `refuse` tells the two
116
120
  // apart, because the advice differs.
117
- return null;
121
+ return null
118
122
  }
119
- };
123
+ }
120
124
 
121
125
  /**
122
126
  * Say why there is no compiler to run, and stop.
123
127
  *
124
128
  * Under `--json` that is one object on stdout and **nothing on stderr**, which
125
- * is the shape `self/compile.ts`'s own `reportToolchainFailure` uses for the
129
+ * is the shape `src/compile.ts`'s own `reportToolchainFailure` uses for the
126
130
  * same code: stdout carries objects and nothing else, so a tool reading it does
127
131
  * not have to strip a human report out of the stream. Otherwise it is the
128
132
  * report on stderr. Either way the status is the same.
@@ -137,50 +141,50 @@ const refuse = (unstartable) => {
137
141
  // none: it sends the user to install something that does not exist.
138
142
  packageName: packageName(),
139
143
  unstartable,
140
- });
144
+ })
141
145
  if (wantsJson()) {
142
146
  writeAndExit(
143
147
  process.stdout,
144
148
  `${JSON.stringify({ severity: "error", code: why.code, message: why.summary })}\n`,
145
149
  NO_COMPILER
146
- );
150
+ )
147
151
  } else {
148
- writeAndExit(process.stderr, why.report, NO_COMPILER);
152
+ writeAndExit(process.stderr, why.report, NO_COMPILER)
149
153
  }
150
- };
154
+ }
151
155
 
152
- const asset = assetFor(process.platform, process.arch);
156
+ const asset = assetFor(process.platform, process.arch)
153
157
  // No binary for this machine, and none coming: musl, FreeBSD, 32-bit anything.
154
158
  // `refuse` sets an exit code rather than exiting, so each of these returns
155
159
  // before the next line runs: the sequence below is written as a chain for that
156
160
  // reason and `process.exitCode` is what carries the status out.
157
161
  if (asset === null) {
158
- refuse(null);
162
+ refuse(null)
159
163
  } else {
160
- const binary = nativeCompiler(asset);
164
+ const binary = nativeCompiler(asset)
161
165
  if (binary === null) {
162
166
  // A binary exists for this platform and this install does not have it.
163
- refuse(null);
167
+ refuse(null)
164
168
  } else {
165
- handOver(binary);
169
+ handOver(binary)
166
170
  }
167
171
  }
168
172
 
169
173
  /** Run the native compiler and give the caller back exactly what it answered. */
170
174
  function handOver(binary) {
171
- const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
175
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" })
172
176
  if (result.error !== undefined && result.error !== null) {
173
177
  // Installed and will not start -- a broken or partial install rather than an
174
178
  // unsupported platform. There is nothing to fall back to, so this is a
175
179
  // refusal with the reason in it rather than a warning above a slower compile.
176
- refuse({ binary, reason: result.error.message });
177
- } else if (result.signal !== null) {
180
+ refuse({ binary, reason: result.error.message })
181
+ } else if (result.signal !== null) {
178
182
  // Re-raise rather than translating to an exit code, so that a crash or an
179
183
  // interrupt reaches the shell as the signal it was. `process.exitCode`
180
184
  // cannot express one, and a wrapper that turned SIGINT into exit 130 would
181
185
  // make `nish` the one command in a pipeline that did.
182
- process.kill(process.pid, result.signal);
186
+ process.kill(process.pid, result.signal)
183
187
  } else {
184
- process.exitCode = result.status ?? 0;
188
+ process.exitCode = result.status ?? 0
185
189
  }
186
190
  }
package/bin/packaging.js CHANGED
@@ -21,11 +21,11 @@
21
21
  * trusting the two lists to stay equal.
22
22
  *
23
23
  * **This is plain JavaScript under `bin/`, and that is deliberate.** It used
24
- * to be `src/packaging.ts`, compiled into `dist/` by `tsc` -- which made the
24
+ * to be stage0's `src/packaging.ts`, compiled into `dist/` by `tsc` -- which made the
25
25
  * command a build artifact of the compiler it is supposed to install. `bin/`
26
26
  * is what the tarball carries and what `bin.nish` points into, so the launcher
27
27
  * and its platform table now live where they ship, need no build step, and
28
- * survived the deletion of `src/` (`docs/wp19-stage0-retirement.md` R6). The
28
+ * survived the deletion of stage0's `src/` (`docs/wp19-stage0-retirement.md` R6). The
29
29
  * types they lose are not much of a loss for two string maps; what they gain is
30
30
  * that `npm pack` ships the same bytes this repository runs.
31
31
  */
@@ -40,7 +40,7 @@
40
40
  const ARCH_BY_CPU = {
41
41
  x64: "x86_64",
42
42
  arm64: "aarch64",
43
- };
43
+ }
44
44
 
45
45
  /**
46
46
  * The operating-system half. It is an identity map today, because node's
@@ -52,7 +52,7 @@ const ARCH_BY_CPU = {
52
52
  const OS_BY_PLATFORM = {
53
53
  linux: "linux",
54
54
  darwin: "darwin",
55
- };
55
+ }
56
56
 
57
57
  /**
58
58
  * Every asset a release actually attaches, sorted, in `seed-targets.json`'s
@@ -68,7 +68,7 @@ const OS_BY_PLATFORM = {
68
68
  * compares the two, so a literal is exactly as gated as a derivation and says
69
69
  * only what is true.
70
70
  */
71
- export const SUPPORTED_ASSETS = ["aarch64-darwin", "aarch64-linux", "x86_64-darwin", "x86_64-linux"];
71
+ export const SUPPORTED_ASSETS = ["aarch64-darwin", "aarch64-linux", "x86_64-darwin", "x86_64-linux"]
72
72
 
73
73
  /**
74
74
  * The `asset` for a node platform/arch pair, or `null` when this project
@@ -81,23 +81,29 @@ export const SUPPORTED_ASSETS = ["aarch64-darwin", "aarch64-linux", "x86_64-darw
81
81
  * exits non-zero (`docs/wp12-release.md`, "Which compiler the package ships").
82
82
  */
83
83
  export const assetFor = (platform, arch) => {
84
- const os = OS_BY_PLATFORM[platform];
85
- const cpu = ARCH_BY_CPU[arch];
86
- if (os === undefined || cpu === undefined) return null;
87
- return `${cpu}-${os}`;
88
- };
84
+ const os = OS_BY_PLATFORM[platform]
85
+ const cpu = ARCH_BY_CPU[arch]
86
+ if (os === undefined || cpu === undefined) {
87
+ return null
88
+ }
89
+ return `${cpu}-${os}`
90
+ }
89
91
 
90
92
  /** The inverse, for the generator and the tests: an `asset` back to npm's pair. */
91
93
  export const targetForAsset = (asset) => {
92
- const dash = asset.indexOf("-");
93
- if (dash < 0) return null;
94
- const arch = asset.slice(0, dash);
95
- const os = asset.slice(dash + 1);
96
- const cpu = Object.keys(ARCH_BY_CPU).find((key) => ARCH_BY_CPU[key] === arch);
97
- const platform = Object.keys(OS_BY_PLATFORM).find((key) => OS_BY_PLATFORM[key] === os);
98
- if (cpu === undefined || platform === undefined) return null;
99
- return { asset, os: platform, cpu };
100
- };
94
+ const dash = asset.indexOf("-")
95
+ if (dash < 0) {
96
+ return null
97
+ }
98
+ const arch = asset.slice(0, dash)
99
+ const os = asset.slice(dash + 1)
100
+ const cpu = Object.keys(ARCH_BY_CPU).find((key) => ARCH_BY_CPU[key] === arch)
101
+ const platform = Object.keys(OS_BY_PLATFORM).find((key) => OS_BY_PLATFORM[key] === os)
102
+ if (cpu === undefined || platform === undefined) {
103
+ return null
104
+ }
105
+ return { asset, os: platform, cpu }
106
+ }
101
107
 
102
108
  /**
103
109
  * The package holding the binary for one asset, derived from the main
@@ -108,22 +114,22 @@ export const targetForAsset = (asset) => {
108
114
  * is scoped -- docs/wp12-release.md "The npm name"), and a list of five literal
109
115
  * names would be five places to edit if it ever moves again.
110
116
  */
111
- export const platformPackageName = (packageName, asset) => `${packageName}-${asset}`;
117
+ export const platformPackageName = (packageName, asset) => `${packageName}-${asset}`
112
118
 
113
119
  /**
114
120
  * The diagnostic code every refusal here carries: `NL0002`, the toolchain code.
115
121
  *
116
- * Not a new code, and that is the point. `self/codes.ts` defines `NL0002` as
122
+ * Not a new code, and that is the point. `src/codes.ts` defines `NL0002` as
117
123
  * "the toolchain `--link` needs could not be used (exit 3)", and a prebuilt
118
124
  * compiler that is absent or will not start is the same class of failure seen
119
125
  * one step earlier: no source position, nothing wrong with the program, and the
120
126
  * thing that could not be run is a binary rather than the input. Reusing it
121
127
  * keeps the launcher out of the diagnostic registry entirely -- a code minted
122
- * here would be one `self/codes.ts` mirrors for a message the compiler can
123
- * never print, and `tests/diagnostic_coverage.js` would then want a case
128
+ * here would be one `src/codes.ts` mirrors for a message the compiler can
129
+ * never print, and `tests/diagnostic-coverage.js` would then want a case
124
130
  * provoking a rule that does not exist.
125
131
  */
126
- export const NO_COMPILER_CODE = "NL0002";
132
+ export const NO_COMPILER_CODE = "NL0002"
127
133
 
128
134
  /**
129
135
  * Why there is no compiler to run, and what to do about it: the one-line
@@ -160,13 +166,13 @@ export const NO_COMPILER_CODE = "NL0002";
160
166
  * refused wants to know whether the list is the whole list. It is.
161
167
  */
162
168
  export const noCompilerMessage = ({ platform, arch, packageName, unstartable = null }) => {
163
- const asset = assetFor(platform, arch);
164
- const published = SUPPORTED_ASSETS.join(" ");
169
+ const asset = assetFor(platform, arch)
170
+ const published = SUPPORTED_ASSETS.join(" ")
165
171
  const preamble =
166
172
  " This package installs a prebuilt native compiler. One is published for:\n" +
167
173
  ` ${published}\n\n` +
168
174
  " There is no compiler inside the package to fall back to, and nothing is\n" +
169
- " compiled on your machine on any path.\n";
175
+ " compiled on your machine on any path.\n"
170
176
  if (asset === null) {
171
177
  return {
172
178
  code: NO_COMPILER_CODE,
@@ -182,7 +188,7 @@ export const noCompilerMessage = ({ platform, arch, packageName, unstartable = n
182
188
  " NISH_BOOTSTRAP=<a released nish that runs here> scripts/bootstrap.sh\n" +
183
189
  " docs/INSTALL.md has the detail, including what to do when no released\n" +
184
190
  " binary runs on this platform at all.\n",
185
- };
191
+ }
186
192
  }
187
193
  if (unstartable !== null) {
188
194
  return {
@@ -195,14 +201,14 @@ export const noCompilerMessage = ({ platform, arch, packageName, unstartable = n
195
201
  `nish: ${unstartable.binary} could not be started (${unstartable.reason})\n\n${preamble}\n` +
196
202
  " That is a broken or partly written install rather than an unsupported\n" +
197
203
  " platform. Reinstall the package, or run `npm rebuild` if the tree moved.\n",
198
- };
204
+ }
199
205
  }
200
206
  // A `packageName` of `null` means this package's own `package.json` could not
201
207
  // be read, which is a broken install and not the moment to guess: naming the
202
208
  // wrong package sends the user to install something that does not exist, so
203
209
  // the sentence loses the name instead of inventing one.
204
- const named = packageName === null ? null : platformPackageName(packageName, asset);
205
- const pkg = named === null ? `the platform package for ${asset}` : named;
210
+ const named = packageName === null ? null : platformPackageName(packageName, asset)
211
+ const pkg = named === null ? `the platform package for ${asset}` : named
206
212
  return {
207
213
  code: NO_COMPILER_CODE,
208
214
  summary:
@@ -216,5 +222,5 @@ export const noCompilerMessage = ({ platform, arch, packageName, unstartable = n
216
222
  " `--no-optional`, a lockfile without the platform packages, or a registry that\n" +
217
223
  " does not carry them yet. Reinstall the package, or install the pair by hand as\n" +
218
224
  " docs/INSTALL.md shows.\n",
219
- };
220
- };
225
+ }
226
+ }