Expand description
Node — the canonical AST, and an ordinary value.
docs/02-syntax.md §2.2 fixes the shape:
model Node:
head: Sym | Lit
args: list[Node]
meta: MetaEverything else is derived. Both surfaces — the Python one and the S-expression one — read to
identical Node trees; beck fmt prints either. That is the whole trick: “significant
whitespace is only hard if your macros do string concatenation. Ours cannot.”
One representational decision the doc leaves implicit: head is a symbol or a literal, so an
application whose callee is itself an expression has nowhere to put the callee. Those use the
reserved head sym::CALL — (call (. f g) x) — which keeps the common case, and therefore
the original sketch’s notation, literal: (update_at todos id ...) is a symbol head with three
arguments, exactly as written.
Modules§
- sym
- The reserved heads. Named constants rather than string literals scattered through the compiler:
a typo in
"paramss"would otherwise be a silently-unmatched form.
Structs§
- Meta
- Everything a
Nodeknows about itself beyond its shape. - Node
- Scope
- A hygiene scope. Fresh scopes are minted by the macro expander; the set a symbol carries is
what decides which binding it refers to (
crate::Symbol). - Scope
Set - A set of hygiene scopes, kept sorted and deduplicated so that subset tests are a merge.
- Symbol
- An identifier, with the hygiene scopes it was written (or introduced) in.