Skip to content
ALB Wiki

Diff — ALB TypeScript backend

Comparing rev 4 → rev 5

{{infobox
| title = ALB TypeScript backend
| tool = `albw.exe` ("ALBW — AdaLogic BASIC for the Web")
| produces = TypeScript (.ts) → JavaScript + index.html + tsconfig
| runs_on = Any modern browser · Node.js
| output_dir = `web_<name>/`
| emitter_unit = `Emit_Native_TypeScript` (emit_native_typescript.adb)
| status = Full web backend — games, documents, ES/WASM libraries
}}
The **ALB TypeScript backend** — **ALBW** — compiles [[AdaLogic BASIC]] into a self-contained TypeScript program that runs in any browser or under Node.js. It is the backend that makes an ALB game a *web page*: canvas graphics, a real console, chiptune audio, files, and the full logic engine — all inside a single emitted `.ts` file.
```alb One-liner
albw game.alb --build
→ web_game/game.ts → tsc → game.js + index.html + tsconfig.json
```
# The pipeline
Unlike the streaming emitters behind [[ALB FASM backend|FASM]] and [[ALB C backend|C]], ALBW's emitter takes the **whole AST** in one call — `Compile_To_File (Root : AST_Node)` — and walks it directly: it owns a symbol table, scopes names (`Safe_JS_Name`, `Scoped_Name`), evaluates constants at emit time, and emits TypeScript source. Different architecture, same language.
| Flag | What it does |
| --- | --- |
| `-o <file>` | Output .ts path (default: derived from input name) |
| `--outdir <dir>` | Output directory |
| `--tsc` | Also run tsc — .ts → .js |
| `--target <ver>` | TypeScript target: `es5`, `es2020` (default), `esnext` |
| `--build`, `-b` | Full build: transpile + tsc + index.html shell |
| `--library`, `-l` | Shared module build — no HTML shell (for `EXPORT_ES`/`EXPORT_WASM`) |
| `--metrics`, `-m` · `--walker`, `-w` · `--quiet`, `-q` | Metrics · AST dump · silence |
A `--build` folder is a complete, openable website: the emitted `.ts`, a generated `tsconfig.json` (`strict: false`, `noCheck: true` — the generated code is already correct; the checker just gets in the way), and an `index.html` that loads the script — as a plain script or an ES module, depending on the program.
# A computer inside a file
The generated file is not a thin translation — it emits an entire **runtime machine**, expressed as typed arrays so the JIT keeps it fast:
```ts
const albKeys = new Uint8Array(512);        // keyboard state
const albMouseButtons = new Uint8Array(8);
const albVas = new Int32Array(65536);       // virtual address space
const albGcAlive = new Uint8Array(1024);    // object grid, alive flags
const albGcRefs = new Uint16Array(1024);    // refcounts
const albGcChildA … albGcChildD             // four child links per node
```
It is the same architecture as the [[ALB C backend|C]] and [[ALB FASM16 backend|FASM16]] Dumptruck — same node grid, same refcount contract — ported to the substrate JavaScript gives you: `Uint8Array` and `Int32Array` instead of structs.
- **Sized integers, emulated** — `albU8`/`albU16`/`albU32` mask; `albI8`/`albI16`/`albI32` sign-extend. ALB's sized type system behaves correctly on a language with only `number`
- **PURE, packed into one f64** — `albPurePack` encodes an exact rational (numerator+denominator, gcd-reduced, graceful shrink on overflow) into a single JavaScript number
- **Division semantics** — `albDiv`/`albMod` truncate like integer division should; divide-by-zero yields 0 rather than crashing a browser tab
- **Integer powers** — `albPowInt` does exponentiation by squaring, the way you teach it
- **A working logic engine** — `albFact*` fact store plus `albRel*` relation tables and `albRule*` **rule records with bodies** (head predicate, body length, body terms, arg modes) — Prolog, in the browser
# The console overlay
`PRINT` in a browser has nowhere to go — so ALBW builds one. The emitted runtime injects a console: a `<div>` containing a `<pre>`, monospace on `#050511`, that pins itself to the bottom 40% of the viewport when a canvas is active (fullscreen otherwise):
```ts
function albWriteText(text) { … albTextRows[row] =
  padded.slice(0, col) + ch + padded.slice(col + 1) … }
```
Underneath the div is a **character-grid text model** — `albTextRows`, an x/y cursor, `padEnd` for sparse writes — so `LOCATE`-style text behaves like a real terminal, not like `console.log`. `MODE NO CONSOLE` or the `--no-console` path disables it for programs that want only graphics.
# The frame loop — events are real
ALB's event-driven model maps directly onto the browser's:
```ts
function ALB_RunFrame(now) {
  if (!albRunning) { ALB_ProgramShutdown(); return; }
  requestAnimationFrame(ALB_RunFrame);
  if (now < albDelayUntil) return;
  if (now - albLastFrame < albFrameInterval) return;
  try { ALB_PREPARE_FRAME(); ALB_ON_TICK(); ALB_ON_PAINT(); }
  catch (err) { ALB_FATAL(err); }
}
```
`requestAnimationFrame` drives the loop; `ON TICK` and `ON PAINT` become literal emitted functions; `DELAY` is a deadline check; frame-rate throttling is a comparison. A BASIC event loop and a browser event loop turn out to be the same idea wearing different clothes.
# Graphics and sound
- **Canvas** — `HTMLCanvasElement` + `CanvasRenderingContext2D`, base framebuffer **320×200** (yes, the classic resolution), scaled to the window with correct mouse-coordinate transform, and a color LUT (palette entries evaluated at compile time)
- **Colors** — `albColorToCss` unpacks a packed RGBA `u32` into `rgba(r,g,b,a)` — the same 0xAABBGGRR value every backend understands
- **PC speaker chiptune** — `albPcSpeakerTone` drives a WebAudio **square-wave oscillator** with an attack-hold-release gain envelope: real retro beeps, polyphonic via `albActiveMusicVoices` (live `[OscillatorNode, GainNode]` pairs, reaped on `ended`)
- **Music** — `ALB_PLAY_MUSIC_FROM` fetches an ALB score file and plays it — the notation survives the journey to the web
# Files in a browser (and Node)
Browsers can't open files — so the backend emits a **virtual file table**: 64 handles (`albFileLive`, `albFileName`, `albFileBuffer`, `albFileCursor`) over a `albSaveStore` object, with real `ALB_Open`/`Read`/`Write`/`Seek`/`Close` semantics. Writes persist into the store on close.
Then the clever bit — the *same emitted file* detects Node.js:
```ts
const nodeProcess = globalThis.process;
if (nodeProcess?.versions?.node)
  buf = eval('require')('fs').readFileSync(path, 'latin1');
```
In a browser, files are virtual. Under `node game.js`, they're real — one source, two worlds, literally.
# The serious machinery
```fact Not a toy
**A capability firewall** — `albFirewallStack` with per-frame read/write allow tables on file names; **a network sniffer** — `ALB_SNIFFER_DEFINE` builds live objects with protocol, port, buffer size, and an error cell for `AST_Network_Sniffer_Decl`; **sockets** — channel keys like `ALB_NET_<proto>_<port>`; **fetch()** wired into the runtime; **`albPromptContext`** — the last 18 console lines assembled as context for AI-prompt features.
```
# It even learns
The language-level learning statements work here too: `ALB_NN_CREATE`, `ALB_NN_SEED`, `ALB_NN_INFER`, `ALB_NN_TRAIN`, `ALB_NN_ACT`, and `ALB_MARKOV_PREDICT` are emitted as TypeScript functions for `NEURAL TOPOLOGY`, `TRAIN NETWORK`, `INFER NETWORK`, `MARKOV MODEL`, and `PREDICT MARKOV`. Deterministic weight seeding means a program's net starts identically in a typed-array browser runtime as it does in the [[ALB FASM backend|x86-64 asm]] or [[ALB C backend|C]] builds — train a model on the desktop, deploy it to a page. (One learning feature stays native: `EMOTION` is FASM-only.)
# Modes and library exports
- **`MODE DOCUMENT`** in the source flips the generated `index.html` from the dark game shell to a light document shell — the same language emits *games* or *pages*
- **`EXPORT_ES` / `EXPORT_WASM`** with `--library` emit a module-aware build (no HTML shell, `module: es2020` tsconfig) — ALB programs compiled into importable web libraries; the foreign-export table is sized to match `albt`'s `Max_Foreign_Exports` so even the full-engine `libgamedeck` façade fits one weave
# Under the hood
`Emit_Native_TypeScript` is ~7,000 lines of SPARK-annotated Ada — second in size only to the [[ALB Ada backend|Ada emitter]] — driven by `albw.adb`, which handles flags, the tsconfig writer, the HTML shell writer, and the tsc/package dance. Where the native backends stream tokens into buffers, this one is an **AST interpreter that prints TypeScript**: it sees the whole program before it writes a line.
# See also
- [[AdaLogic BASIC]] — the language
- [[ALB C backend]] · [[ALB FASM backend]] · [[ALB FASM16 backend]] — the native siblings
- [[History of Programming]] — JavaScript's chapter in the arc
- [[Z3]] · [[Manchester Baby]] — the web page as a machine, then and now
# References
-
1. ALB Handbook — alb-lang.org/handbook — the language reference for all backends.
-
2. ALB Technology page — alb-lang.org/technology — the sixteen-backend matrix.
+
1. ALB Handbook — [alb-lang.org/handbook](https://alb-lang.org/handbook) — the language reference for all backends.
+
2. ALB Technology page — [alb-lang.org/technology](https://alb-lang.org/technology) — the sixteen-backend matrix.
3. ALB source — github.com/rockyoliver454/AdaLogic-BASIC-ALB-Programming-Language — the emitter sources are Apache 2.0.
[[Category:Backends]]
[[Category:AdaLogic BASIC]]