Engine · 1

Parsing

The core lexes a .trl into tokens, parses them into an AST, and serializes that AST back to text — losslessly and idempotently. Every capability in this section reads the same AST, so they operate on identical structure.

Parse and serialize

The grammar (tokens and productions) defines the shape; the parser produces the nodes — declarations, tags, edges, scopes, rules. Parsing establishes structure only; it interprets no meaning.

char vale [+Grifter] [#Suspicious]
obj ledger
vale > ledger
evt the_switch [&Deceives(agent=vale, target=renn)]

The serializer is the parser's inverse: parse → serialize is a fixpoint. Re-serializing an already-canonical file changes nothing, which lets a tool rewrite a buffer safely and lets the test harness assert round-trip fidelity across the corpus.

Canonical form

Serialization is canonical: equivalent inputs collapse to one spelling, normalizing sugar and whitespace. A signature written with the ?: optional-typed sugar re-emits as its | null union — the same AST, one canonical text:

// authored            course?: concept [+Course]
// canonical           course: concept|null [+Course]

The canonical form is deterministic, so a formatter changes spelling, not meaning: it rewrites ?: to its | null union and normalizes spacing.

Interfaces

CLI
tropelang fidelity <file> and gate <file> assert the lossless, idempotent round-trip.
WASM
format(src) — the canonical serialization, returning { canonical, ok, roundtrips }; symbols(src) — the declared names and their spans.