# The pipeline

A program travels through four stages, and each is pushed by its caller: bytes into the parser, events into the compiler, fuel into the evaluator, buffer space into the writer.

The interactive explorer runs in a browser. What it shows, for a program you choose or write:

1. **Parser:** the source pushed in chunks of 1, 4 or 16 bytes, or whole; the events the parser sends its sink, in evaluation order (operands before their operator), each with the syntax node it belongs to and its position. The same events arrive however the source is cut.
2. **Compiler:** the compiler is the parser's sink. It shows the program's size, each function with where it begins and the shape the compiler tagged it with (`PLUCK` for `x => x.key`, `COMPARE_BY_KEY`, `COMPARE_NUMERIC`, `SUM`, ...), and the fuel the program uses with shapes and without: a shape changes fuel, never a value.
3. **Evaluator:** the evaluation run on one unit of fuel at a time, reading its frames after each unit (`sjs_vm_frame`): the program, each looping built-in (`map`, element 2 of 4) and each callback, with the source position each is at.
4. **Result:** the value as the host reads it through the value API, one value per line, each with the call that reached it (`sjs_array_at(…, 2)`, `sjs_object_at(…, 0)` and its key, `sjs_map_at(…, 0).key`) and what it holds; then the same value written as JavaScript source through a 16-byte buffer, in pieces.

An error shows at the stage that reported it: a syntax error at the parser, a name error or an unsupported construct at the compiler, a fault at the evaluator.

## A worked example

```js
[
  { name: "ada", age: 36 },
  { name: "grace", age: 85 },
  { name: "linus", age: 54 },
]
  .toSorted((a, b) => b.age - a.age)
  .map((p) => p.name)
```

**Parser.** 150 bytes become 57 events. The first 12:

| # | Event | Payload | At |
|---:|---|---|---|
| 0 | `ARRAY_BEGIN` |  | 1:1 |
| 1 | `OBJECT_BEGIN` |  | 2:3 |
| 2 | `KEY` | `name` | 2:5 |
| 3 | `STRING` | `"ada"` | 2:11 |
| 4 | `PROPERTY` |  | 2:16 |
| 5 | `KEY` | `age` | 2:18 |
| 6 | `NUMBER` | `36` | 2:23 |
| 7 | `PROPERTY` |  | 2:26 |
| 8 | `OBJECT_END` |  | 2:26 |
| 9 | `ELEMENT` |  | 1:1 |
| 10 | `OBJECT_BEGIN` |  | 3:3 |
| 11 | `KEY` | `name` | 3:5 |

**Compiler.** A program of 1354 bytes with 3 functions:

- the program, at 1:1: no shape
- function 1, at 6:23: shape `COMPARE_BY_KEY`
- function 2, at 7:15: shape `PLUCK`

It runs on 39 units of fuel with its shapes, and 57 without them, to the same value.

**Evaluator.** At step 17 of 30, its deepest, the frames are, outermost first:

1. the program, at 6:12
2. `toSorted`, at 6:12

**Writer.** Through a 16-byte buffer, in 2 pieces, it writes:

```js
["grace","linus","ada"]
```
