# PCB — Legacy Specification

**Artifact:** `PBC:PCB:0.0.1-SNAPSHOT` (the original standalone repository)
**Build system:** Maven, Java 21
**Status:** Archival — preserved as a *speciation point*

---

## 0. What this document is

This is the specification for the **legacy** PCB — the original, standalone form
of the Pocket / Cup / Box language, *before* it was pulled into the
`trainingGround` project and *before* the major architectural changes that
followed. It is preserved deliberately as a frozen reference: the seed from which
later flavors of the language descend.

It is **not** the current PCB. The features documented here are the foundation;
the richer behavioral systems of the modern language (inverted-mode operator
dispatch, container persistence, pocket starvation policies, seam-crossing,
flow-powered tick loops, the multi-pass knot topology analyzer, and `?box` type
inference) are **later additions and are not part of this legacy version.** Where
this document mentions a construct, it describes what the legacy code actually
contains. Section 11 lists explicitly what the legacy does *not* have, so the
boundary between this archival form and the modern language is unambiguous.

---

## 1. Design philosophy: bidirectionality

PCB is built around one idea most languages ignore: **code can run in two
directions.** Every keyword has a mirror — the character-reversed spelling — and
the forward form and its mirror are *syntactically distinct but semantically
paired*. Running a program backward is not reversing its output; it is a
structurally different traversal of the same code through the same environment.

This commitment is not cosmetic. It reaches down into the lexer (mirrored
keywords are separate token types), the parser (mirror-paired constructs), the
resolver (declarations are walked forward or in reverse depending on execution
direction), and the interpreter (a single `forward` flag selects the traversal).

---

## 2. The pipeline

A PCB program is processed in five stages:

```
source ─► Scanner ─► Grouper ─► Parser ─► Resolver ─► Interpreter
          (lexing)   (2nd-pass  (AST)     (static     (tree-walk
                      grouping)            analysis)    execution)
```

- **Scanner** — first-pass lexical analysis; produces tokens, including the
  mirrored keyword forms as distinct token types.
- **Grouper** — a second pass over the token stream that performs structural
  token grouping before parsing.
- **Parser** — builds the AST (`Expr`, `Stmt`, `Declaration` node families).
- **Resolver** — static analysis; resolves variable scope distances for
  direct-index environment lookup, walking declarations in forward or reverse
  order to match the execution direction.
- **Interpreter** — a tree-walk runtime that evaluates the AST. A `forward` flag
  selects forward or backward traversal.

The orchestrator (`Box.Box.Box`) wires these together via `runJson(...)` / `run(...)`.

---

## 3. Lexical structure & mirrored keywords

Every keyword is registered in the scanner alongside its reversed twin, and each
twin is its own `TokenType`. A representative sample:

| Forward | Mirror | Forward | Mirror |
|---|---|---|---|
| `print` | `tnirp` | `true` | `eurt` |
| `return` | `nruter` | `false` | `eslaf` |
| `read` | `daer` | `save` | `evas` |
| `move` | `evom` | `rename` | `emaner` |
| `add` | `dda` | `remove` | `evomer` |
| `clear` | `raelc` | `size` | `ezis` |
| `push` | `hsup` | `not` | `knot` |
| `and` | `dna` | `or` | `ro` |
| `fun` | `nuf` | `into` | `otni` |

The pairing `not` ↔ `knot` is load-bearing: the reversed spelling of `not` *is*
`knot`, which is why one of the container types is the **knot**. The naming is the
design.

The dynamic type tag `#HATTAG` (and its reverse `#GATTAH`) is recognized
case-insensitively, with every capitalization variant registered explicitly.

---

## 4. Primitive types

The legacy runtime (`RunTimeTypes`) defines the primitive value types and their
reversed forms:

| Type | Reversed |
|---|---|
| `Int` | `Tni` |
| `Double` | `Elbuod` |
| `Bin` | `Nib` |
| `Char` | `Rahc` |
| `String` | `Gnirts` |
| `Boolean` | `Naeloob` |

Plus the null family (`NULL`, `NILL`, `LLUN`, `LLIN`), `Any`, `Type` / `Epyt`,
and `Function`.

---

## 5. Container type system

PCB organizes values into a container hierarchy. The legacy establishes the
**eight-container vocabulary** — four forward containers and their four reverse
mirrors — in both the type enum (`RunTimeTypes`) and the runtime instance classes:

| Forward | Reverse | Runtime instance |
|---|---|---|
| `box` — pure data container | `xob` | `BoxInstance` |
| `cup` — code / execution block | `puc` | `CupInstance` |
| `pkt` / pocket — ecosystem container | `tkp` | `PocketInstance` |
| `knt` / knot — orientation / crossing | `tnk` | `TonkInstance`, `KnotInstance` |

All runtime instances descend from a common `Instance` base. In the legacy form,
these containers establish the *type vocabulary and runtime representation* that
the modern language later elaborates with richer behavioral contracts (see §11).

---

## 6. Forward / backward execution model

Bidirectionality is enforced at the **environment** level, not merely
syntactically:

- When any value is defined — a variable, a function, or a type — it is bound
  under **both** its forward name and its mirrored name as separate bindings.
- A **function** declaration carries both a forward identifier and a
  `backwardIdentifier`, so it is reachable from either direction of execution.
- The **resolver** walks all declarations in forward order when execution is set
  to run forward, and in reverse order when set to run backward, computing the
  scope distances used for direct-index lookup at runtime.
- The **interpreter** holds a single `forward` flag (`setForward(...)`). Flipping
  it traverses the same AST in the opposite direction through the same
  environment.

A program authored entirely in forward PCB can therefore be executed backward by
flipping one flag.

---

## 7. The HATTAG dynamic type system

PCB carries a dynamic type tag, `#HATTAG` (mirror: `#GATTAH`), recognized
case-insensitively across all capitalization variants. It is the legacy basis for
runtime-typed values — the foundation the modern type system later builds on.

---

## 8. The math sub-language

PCB embeds a **second, self-contained language for mathematics** under
`Box/math/`, with its own scanner, parser, interpreter, syntax, and token set:

- `MathScanner` — lexer for math expressions
- `MathParser` — math AST
- `MathInterpreter` — evaluation
- `MathDeriver` — a `Term.Visitor` that computes **symbolic derivatives**

It is a language within the language — present in the legacy form and one of its
most complete subsystems.

---

## 9. FL\* world-reach commands (host-agnostic)

PCB includes first-class commands for creating, moving, and destroying named
entities: `FLCreate`, `FLMove`, `FLDestroy`, and the `FLE`/`FLsetValue` variants.
In the legacy form these are **fully decoupled from any external host** — they
operate on a self-contained, in-interpreter entity registry
(`Map<String, FlEntity>`), with a read-only `getFlEntities()` view. The language
keeps its "reach into a world" capability as a pluggable principle while standing
entirely on its own.

---

## 10. Running the legacy

The orchestrator `Box.Box.Box` drives the pipeline. Because this is archival
research code, the entry points are best treated as **study material rather than a
turnkey launcher** — e.g. `Box.main` reads a test script through the standard
pipeline (scan → group → parse → resolve → interpret) and can serialize the
resulting AST to JSON for inspection.

```
mvn clean compile      # Java 21; jackson-databind (AST JSON) + mockito (tests)
```

The build is **standalone** — no game-engine or external host dependency.

---

## 11. What the legacy does NOT have

To keep the boundary with the modern language explicit, the following constructs
described on the current PCB page are **trainingGround-era additions and are not
part of this legacy version**:

- **Inverted-mode operator dispatch** (`puc` flipping the arithmetic/comparison
  dispatch table) — *not present.*
- **Container persistence** (serializing system-container state across JVM
  sessions) — *not present.*
- **Pocket starvation policies** and **seam-crossing** between pockets and `tkp` —
  *not present.*
- **Flow-powered tick loops** (the `"(."` / `".)"` flow connector as the power
  source for autonomous pocket execution, heat death) — *not present.*
- **The multi-pass knot topology analyzer** (SETUP / ENTRY / UNWIND region
  resolution over interleaved bracket topology) — *not present.*
- **`?box` user-defined type inference** with slot-pattern matching — *not
  present.*

These grew later. The legacy is the foundation they grew from.

---

## 12. Status

| Component | Legacy size |
|---|---|
| Interpreter (tree-walk) | ~9,400 lines · Java 21 |
| Scanner | ~890 lines |
| Parser | `Expr` ~2,800 ln · `Stmt` ~1,500 ln |
| Grouper | ~800 lines |
| Resolver | ~1,140 lines |
| Container instances | box / xob · cup / puc · pkt / tkp · knt / tnk |
| Math sub-language | scanner · parser · interpreter · symbolic deriver |
| Build | standalone · Java 21 · Maven · no external host |

---

*PCB · Pocket / Cup / Box · legacy / archival lineage.
Source: [github.com/brackishbert-coder/PCB](https://github.com/brackishbert-coder/PCB).
Current language: [github.com/brackishbert-coder/trainingGround](https://github.com/brackishbert-coder/trainingGround).*
