on master help sign in
Implement the parser

+parse-tokens builds the syntax tree from the layout pass's tokens by recursive descent, following section 3 of jibb.hoon. Every node carries its span. +check-spans checks that each node's span follows section 1's rules, and golden reports any node that breaks them, so every golden case checks spans too. All 14 Jibb code blocks in the doc parse. Every case whose about.txt expects a parse parses, and every expected error comes at the expected line and column. tests/golden/*/tree.txt holds the trees. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRcThHuWjFX8MWUDBeWfyn

commit3c5f50ae3f371f6cf21dec5f7727ab5d4e7eaf55 authorClaude <noreply@anthropic.com> dateThu 29 Oct 2026, 23:16 (3 days ago) parent15a5545
228 files changed+3223−26
jibb-dev/lib/jibb.hoon+1377−26 tests/golden/doc-core-02-update/tree.txt+77 tests/golden/doc-grammar-01-imports/tree.txt+4 tests/golden/doc-grammar-02-buttons/tree.txt+21 tests/golden/doc-grammar-03-view-day/tree.txt+20 tests/golden/doc-grammar-04-step/tree.txt+38 tests/golden/doc-grammar-06-cart-store/tree.txt+39 tests/golden/doc-grammar-07-basket/tree.txt+103 tests/golden/doc-overview-01-cmd-sub/tree.txt+42 tests/golden/doc-overview-02-theme/tree.txt+32 tests/golden/doc-overview-04-todo-api/tree.txt+16 tests/golden/doc-overview-08-about/tree.txt+24 tests/golden/doc-overview-09-blog-index/tree.txt+23 tests/golden/doc-overview-10-todo-list/tree.txt+168 tests/golden/doc-overview-11-index/tree.txt+23 tests/golden/inline-base32/tree.txt+2 tests/golden/inline-call/tree.txt+3 tests/golden/inline-cell/tree.txt+7 tests/golden/inline-change-done/tree.txt+4 tests/golden/inline-change-draft/tree.txt+5 tests/golden/inline-crash/tree.txt+3 tests/golden/inline-ctor-typed/tree.txt+10 tests/golden/inline-date/tree.txt+3 tests/golden/inline-decimal/tree.txt+2 tests/golden/inline-duration/tree.txt+3 tests/golden/inline-fold-mold/tree.txt+7 tests/golden/inline-gate-mold/tree.txt+3 tests/golden/inline-gate-samples/tree.txt+13 tests/golden/inline-gate-wide/tree.txt+7 tests/golden/inline-generic-mold/tree.txt+3 tests/golden/inline-hex/tree.txt+2 tests/golden/inline-import-mark-face-bad/tree.txt+3 tests/golden/inline-imports-after-definition/tree.txt+3 tests/golden/inline-island/tree.txt+3 tests/golden/inline-kinds/tree.txt+18 tests/golden/inline-knot/tree.txt+2 tests/golden/inline-leftout-barcab/tree.txt+3 tests/golden/inline-leftout-barcen/tree.txt+3 tests/golden/inline-leftout-barhep/tree.txt+3 tests/golden/inline-leftout-bartar/tree.txt+3 tests/golden/inline-leftout-buc-paren/tree.txt+3 tests/golden/inline-leftout-buccen/tree.txt+3 tests/golden/inline-leftout-cencol/tree.txt+3 tests/golden/inline-leftout-centis/tree.txt+3 tests/golden/inline-leftout-colon-wing/tree.txt+3 tests/golden/inline-leftout-colsig/tree.txt+3 tests/golden/inline-leftout-coltar/tree.txt+3 tests/golden/inline-leftout-dottar/tree.txt+3 tests/golden/inline-leftout-dottis/tree.txt+3 tests/golden/inline-leftout-faslus/tree.txt+3 tests/golden/inline-leftout-hephep/tree.txt+3 tests/golden/inline-leftout-kethep-wide/tree.txt+3 tests/golden/inline-leftout-kettar/tree.txt+3 tests/golden/inline-leftout-sail/tree.txt+3 tests/golden/inline-leftout-sigbar/tree.txt+3 tests/golden/inline-leftout-signed-float-auras/tree.txt+3 tests/golden/inline-leftout-tis-paren/tree.txt+3 tests/golden/inline-leftout-tisfas/tree.txt+3 tests/golden/inline-leftout-tisgal/tree.txt+3 tests/golden/inline-leftout-tisgar/tree.txt+3 tests/golden/inline-leftout-tistis/tree.txt+3 tests/golden/inline-leftout-wutcol/tree.txt+3 tests/golden/inline-leftout-wuthep-wide/tree.txt+3 tests/golden/inline-leftout-wutlus/tree.txt+3 tests/golden/inline-leftout-wutzap/tree.txt+3 tests/golden/inline-leftout-zap-not/tree.txt+3 tests/golden/inline-leftout-zapgar/tree.txt+3 tests/golden/inline-list-parens/tree.txt+7 tests/golden/inline-list/tree.txt+5 tests/golden/inline-literal-defaults/tree.txt+6 tests/golden/inline-load-slug/tree.txt+7 tests/golden/inline-local-names/tree.txt+15 tests/golden/inline-loobean/tree.txt+3 tests/golden/inline-mark-digit/tree.txt+2 tests/golden/inline-module-definitions/tree.txt+3 tests/golden/inline-mold-add/tree.txt+8 tests/golden/inline-mold-any-empty/tree.txt+3 tests/golden/inline-mold-atoms/tree.txt+9 tests/golden/inline-mold-constants/tree.txt+5 tests/golden/inline-mold-containers/tree.txt+17 tests/golden/inline-mold-gate/tree.txt+3 tests/golden/inline-mold-generic/tree.txt+10 tests/golden/inline-mold-opaque/tree.txt+4 tests/golden/inline-mold-paths/tree.txt+4 tests/golden/inline-mold-records/tree.txt+15 tests/golden/inline-namespaces/tree.txt+5 tests/golden/inline-no-operators/tree.txt+7 tests/golden/inline-no-subs/tree.txt+3 tests/golden/inline-null/tree.txt+2 tests/golden/inline-pair/tree.txt+3 tests/golden/inline-pairs-two-items/tree.txt+5 tests/golden/inline-path/tree.txt+2 tests/golden/inline-pattern-any/tree.txt+8 tests/golden/inline-pattern-cell/tree.txt+11 tests/golden/inline-pattern-crash-arm/tree.txt+10 tests/golden/inline-pattern-date-bad/tree.txt+3 tests/golden/inline-pattern-eq/tree.txt+12 tests/golden/inline-pattern-head-tag/tree.txt+11 tests/golden/inline-pattern-interpolated-bad/tree.txt+3 tests/golden/inline-pattern-list-bad/tree.txt+3 tests/golden/inline-pattern-literals/tree.txt+11 tests/golden/inline-pattern-loobean/tree.txt+9 tests/golden/inline-pattern-move-any/tree.txt+11 tests/golden/inline-pattern-name/tree.txt+8 tests/golden/inline-pattern-null/tree.txt+10 tests/golden/inline-pattern-pair-bad/tree.txt+3 tests/golden/inline-pattern-tail-tag/tree.txt+11 tests/golden/inline-pattern-term/tree.txt+9 tests/golden/inline-pattern-two-tags/tree.txt+11 tests/golden/inline-pattern-unit/tree.txt+12 tests/golden/inline-qath/tree.txt+4 tests/golden/inline-requests/tree.txt+12 tests/golden/inline-scry-case/tree.txt+8 tests/golden/inline-self-reference/tree.txt+4 tests/golden/inline-ship/tree.txt+3 tests/golden/inline-static-image/tree.txt+4 tests/golden/inline-string/tree.txt+4 tests/golden/inline-tag-shape/tree.txt+3 tests/golden/inline-term/tree.txt+2 tests/golden/inline-text-items/tree.txt+6 tests/golden/inline-union-wide/tree.txt+3 tests/golden/inline-unit/tree.txt+3 tests/golden/inline-wide-form-rune-bad/tree.txt+3 tests/golden/inline-wide-forms/tree.txt+7 tests/golden/inline-wide-union-call/tree.txt+3 tests/golden/inline-wings/tree.txt+5 tests/golden/lex-base32-bad-1/tree.txt+3 tests/golden/lex-base32-ok-1/tree.txt+5 tests/golden/lex-call-open-bad-1/tree.txt+7 tests/golden/lex-call-open-bad-2/tree.txt+3 tests/golden/lex-call-open-bad-3/tree.txt+4 tests/golden/lex-call-open-ok-1/tree.txt+14 tests/golden/lex-cell-bad-1/tree.txt+3 tests/golden/lex-cell-ok-1/tree.txt+15 tests/golden/lex-comment-bad-1/tree.txt+3 tests/golden/lex-comment-ok-1/tree.txt+6 tests/golden/lex-comment-ok-2/tree.txt+2 tests/golden/lex-comment-ok-3/tree.txt+1 tests/golden/lex-date-bad-1/tree.txt+3 tests/golden/lex-date-bad-2/tree.txt+3 tests/golden/lex-date-ok-1/tree.txt+5 tests/golden/lex-decimal-bad-1/tree.txt+3 tests/golden/lex-decimal-bad-2/tree.txt+3 tests/golden/lex-decimal-ok-1/tree.txt+5 tests/golden/lex-duration-bad-1/tree.txt+3 tests/golden/lex-duration-ok-1/tree.txt+5 tests/golden/lex-hex-bad-1/tree.txt+3 tests/golden/lex-hex-ok-1/tree.txt+5 tests/golden/lex-indent-bad-1/tree.txt+3 tests/golden/lex-indent-bad-2/tree.txt+3 tests/golden/lex-indent-bad-3/tree.txt+3 tests/golden/lex-indent-ok-1/tree.txt+21 tests/golden/lex-indent-ok-2/tree.txt+17 tests/golden/lex-indent-ok-3/tree.txt+11 tests/golden/lex-interp-bad-1/tree.txt+3 tests/golden/lex-interp-bad-2/tree.txt+3 tests/golden/lex-interp-bad-3/tree.txt+3 tests/golden/lex-interp-bad-4/tree.txt+2 tests/golden/lex-interp-ok-1/tree.txt+22 tests/golden/lex-interp-ok-2/tree.txt+17 tests/golden/lex-knot-bad-1/tree.txt+3 tests/golden/lex-knot-ok-1/tree.txt+4 tests/golden/lex-layout-bad-1/tree.txt+3 tests/golden/lex-layout-bad-2/tree.txt+3 tests/golden/lex-layout-bad-3/tree.txt+3 tests/golden/lex-layout-bad-4/tree.txt+3 tests/golden/lex-layout-ok-1/tree.txt+20 tests/golden/lex-list-bad-1/tree.txt+3 tests/golden/lex-list-ok-1/tree.txt+11 tests/golden/lex-loobean-bad-1/tree.txt+3 tests/golden/lex-loobean-ok-1/tree.txt+3 tests/golden/lex-name-bad-1/tree.txt+3 tests/golden/lex-name-bad-2/tree.txt+3 tests/golden/lex-name-bad-3/tree.txt+3 tests/golden/lex-name-bad-4/tree.txt+3 tests/golden/lex-name-ok-1/tree.txt+11 tests/golden/lex-null-bad-1/tree.txt+3 tests/golden/lex-null-ok-1/tree.txt+19 tests/golden/lex-open-bracket-bad-1/tree.txt+3 tests/golden/lex-open-bracket-bad-2/tree.txt+3 tests/golden/lex-open-bracket-bad-3/tree.txt+3 tests/golden/lex-open-bracket-bad-4/tree.txt+3 tests/golden/lex-open-bracket-ok-1/tree.txt+21 tests/golden/lex-open-bracket-ok-2/tree.txt+9 tests/golden/lex-pair-binding-bad-1/tree.txt+9 tests/golden/lex-pair-binding-ok-1/tree.txt+11 tests/golden/lex-path-bad-1/tree.txt+3 tests/golden/lex-path-ok-1/tree.txt+5 tests/golden/lex-rune-layout-bad-1/tree.txt+3 tests/golden/lex-rune-layout-bad-2/tree.txt+3 tests/golden/lex-rune-layout-bad-3/tree.txt+3 tests/golden/lex-rune-layout-bad-4/tree.txt+3 tests/golden/lex-rune-layout-ok-1/tree.txt+42 tests/golden/lex-ship-bad-1/tree.txt+3 tests/golden/lex-ship-ok-1/tree.txt+4 tests/golden/lex-spacing-bad-1/tree.txt+3 tests/golden/lex-spacing-bad-2/tree.txt+3 tests/golden/lex-spacing-bad-3/tree.txt+3 tests/golden/lex-spacing-bad-4/tree.txt+5 tests/golden/lex-spacing-ok-1/tree.txt+17 tests/golden/lex-string-bad-1/tree.txt+3 tests/golden/lex-string-bad-2/tree.txt+3 tests/golden/lex-string-ok-1/tree.txt+4 tests/golden/lex-term-bad-1/tree.txt+3 tests/golden/lex-term-bad-2/tree.txt+3 tests/golden/lex-term-bad-3/tree.txt+3 tests/golden/lex-term-ok-1/tree.txt+7 tests/golden/lex-tight-change-bad-1/tree.txt+6 tests/golden/lex-tight-change-bad-2/tree.txt+3 tests/golden/lex-tight-change-ok-1/tree.txt+14 tests/golden/lex-tight-ctor-bad-1/tree.txt+3 tests/golden/lex-tight-ctor-bad-2/tree.txt+5 tests/golden/lex-tight-ctor-ok-1/tree.txt+7 tests/golden/lex-tight-opener-bad-1/tree.txt+5 tests/golden/lex-tight-opener-bad-2/tree.txt+3 tests/golden/lex-tight-opener-bad-3/tree.txt+3 tests/golden/lex-tight-opener-bad-4/tree.txt+3 tests/golden/lex-tight-opener-ok-1/tree.txt+12 tests/golden/lex-tight-pair-bad-1/tree.txt+3 tests/golden/lex-tight-pair-ok-1/tree.txt+18 tests/golden/lex-tight-qath-bad-1/tree.txt+3 tests/golden/lex-tight-qath-bad-2/tree.txt+3 tests/golden/lex-tight-qath-bad-3/tree.txt+3 tests/golden/lex-tight-qath-ok-1/tree.txt+9 tests/golden/lex-tight-unit-bad-1/tree.txt+3 tests/golden/lex-tight-unit-ok-1/tree.txt+13 tests/golden/lex-tight-wing-bad-1/tree.txt+3 tests/golden/lex-tight-wing-ok-1/tree.txt+8
jibb-dev/lib/jibb.hoon+1377−26
@@ -19,9 +19,9 @@
1919:: fails: an error it finds is its last token (2.0), and +layout-error
2020:: takes it out.
2121::
22−:: Status: the types, the printers, +golden and the layout pass
23−:: (+layout, +lexer) work. +parse-tokens is a stub that returns an
24−:: error; it is implemented next, against the design below. Choices the
22+:: Status: the types, the printers, +golden, the layout pass (+layout,
23+:: +lexer) and the parser (+parse-tokens, +parser) work, and +golden
24+:: checks every tree's spans (+check-spans, section 1). Choices the
2525:: doc leaves open are marked "(doc question)": they follow the most
2626:: likely reading and are listed, with the doc's words, for the doc's
2727:: author to settle. The golden corpus's "expect:" lines give each
@@ -50,8 +50,9 @@
5050:: code, not at the line that closes them. Every node's span holds its
5151:: children's spans, in source order. The printed tree shows starts
5252:: only, and milestone 1's errors use starts only, so ends are first
53−:: tested by milestone 2's excerpts; the parser's own tests should check
54−:: the two rules above on every golden tree.
53+:: used by milestone 2's excerpts. Until then +check-spans tests the two
54+:: rules above on every tree +golden prints, and a tree that breaks one
55+:: ends with a line "SPAN ERROR: (<kind> <start> to <end>) <why>".
5556::
5657:: ===================================================================
5758:: 2. The layout pass (+layout)
@@ -313,14 +314,15 @@
313314:: 3. The parser (+parse-tokens)
314315:: ===================================================================
315316::
316−:: Hand-written recursive descent over the token list: one arm per EBNF
317−:: rule, each taking the remaining tokens and returning (pare node): the
318−:: node and the tokens after it, or an error. Steps chain with ;< and
319−:: +then, so an error stops the parse:
317+:: Hand-written recursive descent over the token list (+parser): one
318+:: arm per EBNF rule, each taking the remaining tokens and returning
319+:: (pare node): the node and the tokens after it, or an error. Steps
320+:: chain with ;< and +then, so an error stops the parse (+read-cast):
320321::
321−:: ;< [s=shape ts=(list token)] then (mold ts)
322−:: ;< [e=expr ts=(list token)] then (expr-or-body ts)
323−:: [%& [%cast [beg.at.rune end:(span-of e)] s e] ts]
322+:: ;< [s=shape after=(list token)] then (read-mold ts)
323+:: ;< [e=expr more=(list token)] then
324+:: (read-expr-or-body "the mold" after)
325+:: [%& [%cast [beg.at.ket end:(span-of e)] s e] more]
324326::
325327:: Why: after the layout pass the grammar is LL(2). Each choice is made by
326328:: the next token, at most with the one after it and whether it is tight:
@@ -341,10 +343,13 @@
341343:: An operand that isn't where an expression starts (a call's argument,
342344:: an item, a pair's or unit's operand, the wide gate's body) can't be a
343345:: rune, so there |= is a constructor and needs its term at once:
344−:: (state.cart |= %got) is an error at the space after |=, 1:20. Loops
345−:: over many items (definitions, arms, lines, items) may recurse: vere's
346−:: stack takes ten million plain frames, so no Jibb file nests or runs
347−:: long enough to overflow it.
346+:: (state.cart |= %got) is an error at the space after |=, 1:20. A loop
347+:: over many items (definitions, arms, lines, items) is a trap whose
348+:: every step, through +then, is a tail call, so a long module grows no
349+:: stack. Nesting does, by a few frames a level: 100.000 nested
350+:: parentheses parse, and so does a 20.000-line module. +golden's tree
351+:: is another matter: its indent grows with depth, so 7.000 nested
352+:: parentheses print as 49 MB and 10.000 run out of memory.
348353::
349354:: The EBNF and its nodes (see the types below):
350355:: module { import NEWLINE } { definition NEWLINE }, then the end
@@ -462,7 +467,8 @@
462467:: out: eq is a gate", = followed tight by / is "=/ is left out: ++
463468:: defines values", and * is "*mold is left out: no defaults"; ^- or ?-
464469:: followed tight by ( is "the wide form ^-(…) is left out: indentation
465−:: covers it". Examples:
470+:: covers it". The messages quote that code in backticks (2.0), as in
471+:: "`=(a b)` is left out: eq is a gate". Examples:
466472:: expected `]` or an item on a deeper line, found a line at the same
467473:: depth
468474:: expected the end of the line, found a deeper line; only a bracket
@@ -816,22 +822,21 @@
816822:: +parse-tokens: tokens to tree (design: section 3)
817823::
818824:: It accepts no error token, so it fails at the first of its own
819−:: error and the layout pass's (2.0). The stub reports an error token
820−:: that comes first, as the parser will, and fails otherwise.
825+:: error and the layout pass's (2.0). +parser does the work.
821826::
822827++ parse-tokens
823828 |= [file=path toks=(list token)]
824829 ^- (each module error)
825− ?: ?=([[* * [%error *]] *] toks)
826− (fail file toks "a module")
827− =/ at=loc ?~(toks [1 1] (where i.toks))
828− [%| file line.at col.at "parser not implemented"]
830+ (~(read-module parser file) toks)
829831::
830832:: +golden: both stages printed, or the rendered error
831833::
832834:: tokens: the layout pass's tokens, or its error if it found one
833835:: tree: the parser's tree, or the first error of either stage, which
834−:: the parser reports since it accepts no error token (2.0)
836+:: the parser reports since it accepts no error token (2.0). A tree
837+:: whose spans break section 1's rules (+check-spans) gets a last
838+:: line saying how, "SPAN ERROR: …", so every golden case checks
839+:: them.
835840::
836841++ golden
837842 |= [file=path src=@t]
@@ -843,8 +848,13 @@
843848 =/ par (parse-tokens file toks)
844849 ?: ?=(%| -.par) (show-error src p.par)
845850 :: a parser that accepted an error token would be wrong; say so
846− ?^ bad (show-error src u.bad)
847− (show-module p.par)
851+ ?^ bad
852+ %^ cat 3 (show-error src u.bad)
853+ '\0aPARSER ERROR: the parser accepted an error token'
854+ =/ tree=@t (show-module p.par)
855+ =/ why=(unit tape) (check-spans p.par toks)
856+ ?~ why tree
857+ (cat 3 tree (crip "\0aSPAN ERROR: {u.why}"))
848858::
849859+| %lexer
850860::
@@ -1595,6 +1605,7 @@
15951605 %indent "a deeper line"
15961606 %dedent "a shallower line"
15971607 %newline "a line at the same depth"
1608+ %'`' "`` ` ``"
15981609 ==
15991610 ?- -.x
16001611 %name "`{(trip p.x)}`"
@@ -1947,4 +1958,1344 @@
19471958 :+ %| file
19481959 :+ line.end.at.prev col.end.at.prev
19491960 "expected {want} right after {(show-found prev)}, found a space"
1961+::
1962+:: +fail-why: +fail with a hint after its message, "; <why>"
1963+::
1964+:: The layout pass's error, at an error token, stays as it is (2.0).
1965+::
1966+++ fail-why
1967+ |= [file=path toks=(list token) want=tape why=tape]
1968+ ^- [%| p=error]
1969+ =/ e=[%| p=error] (fail file toks want)
1970+ ?: &(?=(^ toks) ?=([%error *] lex.i.toks)) e
1971+ e(msg.p (weld msg.p.e "; {why}"))
1972+::
1973+:: Token tests for the parser
1974+::
1975+:: +is-layout: INDENT, DEDENT or NEWLINE
1976+::
1977+++ is-layout
1978+ |= t=token
1979+ ^- ?
1980+ ?=(?(%indent %dedent %newline) lex.t)
1981+::
1982+:: +is-closer: ) or ], or the } that ends an interpolation
1983+::
1984+++ is-closer
1985+ |= t=token
1986+ ^- ?
1987+ ?| =(%')' lex.t)
1988+ =(%']' lex.t)
1989+ ?=([?(%str-mid %str-tail) *] lex.t)
1990+ ==
1991+::
1992+:: +ends-call: a token that ends a call, or the operands on a group's
1993+:: first line, without an error of their own: a layout token, a
1994+:: closer, or the layout pass's error
1995+::
1996+++ ends-call
1997+ |= t=token
1998+ ^- ?
1999+ ?| (is-layout t)
2000+ (is-closer t)
2001+ ?=([%error *] lex.t)
2002+ ==
2003+::
2004+:: +is-operand-start: a token an operand starts with; where an operand
2005+:: goes, |= is the constructor's (section 3)
2006+::
2007+++ is-operand-start
2008+ |= t=token
2009+ ^- ?
2010+ ?| ?=(?(%'%/' %'/' %'`' %'(' %'~[' %'[' %'|=(' %'|=') lex.t)
2011+ ?=([?(%lit %str %str-head %name %wing) *] lex.t)
2012+ ==
2013+::
2014+:: +is-rune: a rune that is never an operand: ^- ~& ?- !!
2015+::
2016+++ is-rune
2017+ |= t=token
2018+ ^- ?
2019+ ?=(?(%'^-' %'~&' %'?-' %'!!') lex.t)
2020+::
2021+:: +is-ctor: |= with a term tight after it, a case's constructor
2022+::
2023+++ is-ctor
2024+ |= ts=(list token)
2025+ ^- ?
2026+ ?=([[* * %'|='] [* %& [%lit %term *]] *] ts)
2027+::
2028+:: +is-rune-start: a rune where an expression starts; |= is a rune
2029+:: there unless it is the constructor
2030+::
2031+++ is-rune-start
2032+ |= ts=(list token)
2033+ ^- ?
2034+ ?~ ts |
2035+ ?| (is-rune i.ts)
2036+ &(=(%'|=' lex.i.ts) !(is-ctor ts))
2037+ ==
2038+::
2039+:: +text-piece: a string's text as its pieces: none when it is empty
2040+::
2041+++ text-piece
2042+ |= txt=@t
2043+ ^- (list piece)
2044+ ?:(=('' txt) ~ ~[[%text txt]])
2045+::
2046+:: +names-of: a name's or a wing's names
2047+::
2048+++ names-of
2049+ |= x=lexeme
2050+ ^- (list term)
2051+ ?+ x ~
2052+ [%name *] ~[p.x]
2053+ [%wing *] p.x
2054+ ==
2055+::
2056+:: +call-of: a call's elements as one expression: one alone is itself
2057+::
2058+++ call-of
2059+ |= els=(list expr)
2060+ ^- expr
2061+ ?~ els [%crash *span ~]
2062+ ?~ t.els i.els
2063+ [%call [beg:(span-of i.els) end:(span-of (rear t.els))] i.els t.els]
2064+::
2065+:: +bracket-node: a tuple, list or change from its items, ending at fin
2066+::
2067+++ bracket-node
2068+ |= $: kind=?(%tuple %list %change)
2069+ op=token
2070+ target=(unit [t=token names=(list term)])
2071+ its=(list item)
2072+ fin=loc
2073+ ==
2074+ ^- expr
2075+ ?- kind
2076+ %tuple [%tuple [beg.at.op fin] its]
2077+ %list [%list [beg.at.op fin] (turn its |=(i=item val.i))]
2078+ ::
2079+ %change
2080+ =/ beg=loc ?~(target beg.at.op beg.at.t.u.target)
2081+ :^ %change [beg fin] ?~(target ~ names.u.target)
2082+ (turn its |=(i=item ^-(edit [at.i ?~(face.i %$ u.face.i) val.i])))
2083+ ==
2084+::
2085++| %parser
2086+::
2087+:: +parser: section 3's recursive descent over one file's tokens
2088+::
2089+:: Each +read- arm reads one rule of the EBNF from the head of the
2090+:: tokens it is given and returns (pare node): the node and the
2091+:: tokens after it, or the first error. It decides by the next token,
2092+:: at most with the one after it and whether that one is tight
2093+:: (section 3), so it never backtracks. A loop over items is a trap
2094+:: whose every step, through +then, is a tail call, so a long module
2095+:: grows no stack; only nesting does, and a line's nesting is bounded
2096+:: by its length.
2097+::
2098+++ parser
2099+ |_ file=path
2100+ ::
2101+ :: +bad: "expected <want>, found <the next token>" (+fail)
2102+ ::
2103+ ++ bad
2104+ |= [ts=(list token) want=tape]
2105+ ^- [%| p=error]
2106+ (fail file ts want)
2107+ ::
2108+ :: +bad-why: +bad with a hint (+fail-why)
2109+ ::
2110+ ++ bad-why
2111+ |= [ts=(list token) want=tape why=tape]
2112+ ^- [%| p=error]
2113+ (fail-why file ts want why)
2114+ ::
2115+ :: +bad-space: a tight form that found a space after prev
2116+ :: (+fail-space)
2117+ ::
2118+ ++ bad-space
2119+ |= [prev=token ts=(list token) want=tape]
2120+ ^- [%| p=error]
2121+ (fail-space file prev ts want)
2122+ ::
2123+ :: +bad-at: an error inside a token (section 3, Errors)
2124+ ::
2125+ ++ bad-at
2126+ |= [at=loc msg=tape]
2127+ ^- [%| p=error]
2128+ [%| file line.at col.at msg]
2129+ ::
2130+ :: +bad-end: a line that should end and goes on
2131+ ::
2132+ ++ bad-end
2133+ |= ts=(list token)
2134+ ^- [%| p=error]
2135+ ?. ?=([[* * %indent] *] ts) (bad ts "the end of the line")
2136+ %^ bad-why ts "the end of the line"
2137+ %+ weld "only a bracket open at the end of a line, "
2138+ "or a rune's body, takes deeper lines"
2139+ ::
2140+ :: +no-space: a token tight after an item, where a space goes
2141+ ::
2142+ ++ no-space
2143+ |= ts=(list token)
2144+ ^- [%| p=error]
2145+ ?. ?=([[* * %'='] *] ts) (bad ts "a space between items")
2146+ %^ bad-why ts "a space between items"
2147+ "`name=value` goes in a cell, as [a=1], or a change, as m(a=1)"
2148+ ::
2149+ :: +no-operand: a token where an operand goes that starts none, with
2150+ :: a hint for the left-out forms the lexer can't see (2.6)
2151+ ::
2152+ ++ no-operand
2153+ |= ts=(list token)
2154+ ^- [%| p=error]
2155+ =/ want=tape "an expression"
2156+ ?: ?=([[* * %'='] [* %& %'('] *] ts)
2157+ (bad-why ts want "`=(a b)` is left out: eq is a gate")
2158+ ?: ?=([[* * %'='] [* %& %'/'] *] ts)
2159+ (bad-why ts want "`=/` is left out: `++` defines values")
2160+ ?: ?=([[* * %'*'] *] ts)
2161+ (bad-why ts want "`*mold` is left out: no defaults")
2162+ ?: ?=([[* * %'+'] *] ts)
2163+ (bad-why ts want "a pair takes no spaces, as gap+%s2")
2164+ ?: &(?=(^ ts) (is-rune i.ts))
2165+ (bad-why ts want "a rune here goes in parentheses")
2166+ (bad ts want)
2167+ ::
2168+ :: +unclosed: where the closer of the bracket op opened should be
2169+ ::
2170+ ++ unclosed
2171+ |= [op=token close=tape ts=(list token)]
2172+ ^- [%| p=error]
2173+ =/ want=tape
2174+ "`{close}` to close the {(show-found op)} at {(show-loc beg.at.op)}"
2175+ ?. ?=([[* * %indent] *] ts) (bad ts want)
2176+ (bad-why ts want "this bracket closes on its line")
2177+ ::
2178+ :: +unclosed-open: a bracket that may be left open, whose line ends
2179+ :: with neither its closer nor deeper lines; last is its last item's
2180+ :: span, and noun names its items
2181+ ::
2182+ ++ unclosed-open
2183+ |= [op=token close=tape noun=tape last=(unit span) ts=(list token)]
2184+ ^- [%| p=error]
2185+ ?. ?=([[* * ?(%newline %dedent)] *] ts) (unclosed op close ts)
2186+ :: its last item ends on a later line: an item left open took them
2187+ ?: &(?=(^ last) (gth line.end.u.last line.beg.at.op))
2188+ %^ bad-why ts
2189+ "`{close}` to close the {(show-found op)} at {(show-loc beg.at.op)}"
2190+ "only the last bracket open at the end of a line takes the deeper lines"
2191+ (bad ts "`{close}` or {noun} on a deeper line")
2192+ ::
2193+ :: +wide-rune: a rune followed tight; txt( is a left-out wide form
2194+ ::
2195+ ++ wide-rune
2196+ |= [txt=tape ts=(list token)]
2197+ ^- [%| p=error]
2198+ =/ want=tape "a space after `{txt}`"
2199+ ?. ?=([[* * %'('] *] ts) (bad ts want)
2200+ %^ bad-why ts want
2201+ "the wide form `{txt}(…)` is left out: indentation covers it"
2202+ ::
2203+ :: +unnamed: a change's item or line without its name=
2204+ ::
2205+ ++ unnamed
2206+ |= ts=(list token)
2207+ ^- [%| p=error]
2208+ %^ bad-why ts "a named item"
2209+ "a change's items are named, as in m(done=%.y)"
2210+ ::
2211+ :: +read-module: { import NEWLINE } { definition NEWLINE }, then the
2212+ :: end of the tokens
2213+ ::
2214+ ++ read-module
2215+ |= ts=(list token)
2216+ ^- (each module error)
2217+ =| ims=(list import)
2218+ |- ^- (each module error)
2219+ ?: ?=([[* * ?(%'/-' %'/%' %'/=')] *] ts)
2220+ ;< [im=import after=(list token)] then (read-import ts)
2221+ ?. ?=([[* * %newline] *] after) (bad-end after)
2222+ $(ims [im ims], ts t.after)
2223+ =| defs=(list def)
2224+ |- ^- (each module error)
2225+ ?~ ts [%& (flop ims) (flop defs)]
2226+ ?: ?=([[* * ?(%'/-' %'/%' %'/=')] *] ts)
2227+ (bad-why ts "a definition" "imports come first")
2228+ ;< [d=def after=(list token)] then (read-def ts)
2229+ ?. ?=([[* * %newline] *] after) (bad-end after)
2230+ $(defs [d defs], ts t.after)
2231+ ::
2232+ :: +read-import: /- name, /% term, or /= name pathlit
2233+ ::
2234+ ++ read-import
2235+ |= ts=(list token)
2236+ ^- (pare import)
2237+ ?~ ts (bad ts "an import")
2238+ =* g i.ts
2239+ =/ rest=(list token) t.ts
2240+ ?: &(?=(^ rest) tight.i.rest)
2241+ (bad rest "a space after {(show-found g)}")
2242+ ?: =(%'/%' lex.g)
2243+ ?: ?=([[* * [%lit %term %tas *]] *] rest)
2244+ [%& [%mark [beg.at.g end.at.i.rest] val.p.lex.i.rest] t.rest]
2245+ =/ want=tape "a mark's term, as `%todo-action`"
2246+ ?. ?=([[* * [%name *]] *] rest) (bad rest want)
2247+ (bad-why rest want "`/%` takes no face: it names the type after its mark")
2248+ ?. ?=([[* * [%name *]] *] rest) (bad rest "a name")
2249+ =* nam i.rest
2250+ ?. =(%'/=' lex.g)
2251+ [%& [%sur [beg.at.g end.at.nam] p.lex.nam] t.rest]
2252+ =/ more=(list token) t.rest
2253+ ?: &(?=(^ more) tight.i.more) (bad more "a space after the name")
2254+ ?. ?=([[* * %'/'] *] more)
2255+ (bad more "a module's path, as /ui/components/card")
2256+ ;< [[sp=span segs=(list @ta)] after=(list token)] then
2257+ (read-pathlit i.more t.more)
2258+ [%& [%jibb [beg.at.g end.sp] p.lex.nam segs] after]
2259+ ::
2260+ :: +read-pathlit: after a path's /, its knots, each after a tight /
2261+ :: and tight itself; / alone is the empty path
2262+ ::
2263+ ++ read-pathlit
2264+ |= [sl=token ts=(list token)]
2265+ ^- (pare [span (list @ta)])
2266+ ?. ?=([[* %& [%knot *]] *] ts)
2267+ ?: &(?=(^ ts) tight.i.ts !(is-closer i.ts))
2268+ (bad ts "a path segment")
2269+ [%& [at.sl ~] ts]
2270+ =/ segs=(list @ta) ~[p.lex.i.ts]
2271+ =/ fin=loc end.at.i.ts
2272+ =/ rest=(list token) t.ts
2273+ |- ^- (pare [span (list @ta)])
2274+ ?. ?=([[* %& %'/'] *] rest)
2275+ [%& [[beg.at.sl fin] (flop segs)] rest]
2276+ =/ nex=(list token) t.rest
2277+ ?: ?=([[* %& [%knot *]] *] nex)
2278+ $(segs [p.lex.i.nex segs], fin end.at.i.nex, rest t.nex)
2279+ ?: &(?=(^ nex) tight.i.nex) (bad nex "a path segment")
2280+ (bad-space i.rest nex "a path segment")
2281+ ::
2282+ :: +read-def: ++ name, then an expression or a body; +$ name, then a
2283+ :: mold on its line or alone on a deeper one
2284+ ::
2285+ ++ read-def
2286+ |= ts=(list token)
2287+ ^- (pare def)
2288+ ?~ ts (bad ts "a definition")
2289+ =* rune i.ts
2290+ ?: =(%'++' lex.rune)
2291+ ;< [nam=term after=(list token)] then (read-def-name rune t.ts)
2292+ ;< [e=expr more=(list token)] then
2293+ (read-expr-or-body "the name" after)
2294+ [%& [%value [beg.at.rune end:(span-of e)] nam e] more]
2295+ ?: (is-closer rune)
2296+ %^ bad-why ts "a definition"
2297+ "this closes no bracket, as one open at the end of its line needs none"
2298+ ?. =(%'+$' lex.rune) (bad ts "a definition")
2299+ ;< [nam=term after=(list token)] then (read-def-name rune t.ts)
2300+ ?: ?=([[* * %indent] *] after)
2301+ ;< [s=shape more=(list token)] then (read-mold t.after)
2302+ ?: ?=([[* * %dedent] *] more)
2303+ [%& [%mold [beg.at.rune end:(span-of s)] nam s] t.more]
2304+ ?. ?=([[* * %newline] *] more) (bad-end more)
2305+ %^ bad-why more "the end of the mold"
2306+ "a `+$` takes one mold; a union is `$?` with its cases below"
2307+ ?: ?=([[* * ?(%newline %dedent)] *] after)
2308+ (bad after "a mold, on its line or a deeper one")
2309+ ?: &(?=(^ after) tight.i.after) (bad after "a space after the name")
2310+ ;< [s=shape more=(list token)] then (read-mold after)
2311+ [%& [%mold [beg.at.rune end:(span-of s)] nam s] more]
2312+ ::
2313+ :: +read-def-name: after ++ or +$, a space and a name
2314+ ::
2315+ ++ read-def-name
2316+ |= [rune=token ts=(list token)]
2317+ ^- (pare term)
2318+ ?: &(?=(^ ts) tight.i.ts)
2319+ (bad ts "a space after {(show-found rune)}")
2320+ ?. ?=([[* * [%name *]] *] ts) (bad ts "a name")
2321+ [%& p.lex.i.ts t.ts]
2322+ ::
2323+ :: +read-expr-or-body: a space and an expression on the line, or a
2324+ :: body on deeper lines; what names what comes before, for errors
2325+ ::
2326+ ++ read-expr-or-body
2327+ |= [what=tape ts=(list token)]
2328+ ^- (pare expr)
2329+ ?: ?=([[* * %indent] *] ts) (read-body t.ts)
2330+ ?: ?=([[* * ?(%newline %dedent)] *] ts)
2331+ (bad ts "an expression, or a body on deeper lines")
2332+ ?: &(?=(^ ts) tight.i.ts) (bad ts "a space after {what}")
2333+ (read-expr ts)
2334+ ::
2335+ :: +read-body: after its INDENT, { definition NEWLINE } expr DEDENT
2336+ ::
2337+ ++ read-body
2338+ |= ts=(list token)
2339+ ^- (pare expr)
2340+ =| defs=(list def)
2341+ |- ^- (pare expr)
2342+ ?: ?=([[* * ?(%'++' %'+$')] *] ts)
2343+ ;< [d=def after=(list token)] then (read-def ts)
2344+ ?: ?=([[* * %newline] *] after) $(defs [d defs], ts t.after)
2345+ ?. ?=([[* * %dedent] *] after) (bad-end after)
2346+ (bad after "the body's final expression, after its definitions")
2347+ ;< [e=expr after=(list token)] then (read-expr ts)
2348+ ?: ?=([[* * %dedent] *] after)
2349+ =/ ds=(list def) (flop defs)
2350+ =/ beg=loc ?~(ds beg:(span-of e) beg:(span-of i.ds))
2351+ [%& [%body [beg end:(span-of e)] ds e] t.after]
2352+ ?. ?=([[* * %newline] *] after) (bad-end after)
2353+ %^ bad-why after "the end of the body"
2354+ "a body's final expression is its last line"
2355+ ::
2356+ :: +read-expr: a rune, or a call
2357+ ::
2358+ ++ read-expr
2359+ |= ts=(list token)
2360+ ^- (pare expr)
2361+ ?~ ts (bad ts "an expression")
2362+ =* t i.ts
2363+ ?+ lex.t (read-call ts)
2364+ %'|=' ?:((is-ctor ts) (read-call ts) (read-gate t t.ts))
2365+ %'^-' (read-cast t t.ts)
2366+ %'~&' (read-trace t t.ts)
2367+ %'?-' (read-branch t t.ts)
2368+ %'!!' [%& [%crash at.t ~] t.ts]
2369+ ==
2370+ ::
2371+ :: +read-call: operand { operand }; one operand alone is itself
2372+ ::
2373+ ++ read-call
2374+ |= ts=(list token)
2375+ ^- (pare expr)
2376+ ;< [els=(list expr) after=(list token)] then (read-operands ts)
2377+ ?~ els (no-operand ts)
2378+ [%& (call-of els) after]
2379+ ::
2380+ :: +read-operands: a call's operands, or those on a group's first
2381+ :: line, to the end of the call; each after the first follows a space
2382+ ::
2383+ ++ read-operands
2384+ |= ts=(list token)
2385+ ^- (pare (list expr))
2386+ =| els=(list expr)
2387+ |- ^- (pare (list expr))
2388+ ?~ ts [%& (flop els) ts]
2389+ =* t i.ts
2390+ ?: (ends-call t) [%& (flop els) ts]
2391+ ?: &(tight.t ?=(^ els)) (no-space ts)
2392+ ?: (is-operand-start t)
2393+ ;< [e=expr more=(list token)] then (read-operand ts)
2394+ $(els [e els], ts more)
2395+ ?: &(?=(^ els) (is-rune t))
2396+ %^ bad-why ts "an expression"
2397+ "inside a call, a rune goes in parentheses"
2398+ (no-operand ts)
2399+ ::
2400+ :: +read-operand: one operand, told by its first token and, after a
2401+ :: name or a wing, by a tight ( or +
2402+ ::
2403+ ++ read-operand
2404+ |= ts=(list token)
2405+ ^- (pare expr)
2406+ ?~ ts (bad ts "an expression")
2407+ =* t i.ts
2408+ ?+ lex.t (no-operand ts)
2409+ [%lit *] [%& [%lit at.t p.lex.t] t.ts]
2410+ [%str *] [%& [%str at.t (text-piece p.lex.t)] t.ts]
2411+ [%str-head *] (read-string t t.ts)
2412+ [%name *] (read-ref t t.ts)
2413+ [%wing *] (read-ref t t.ts)
2414+ %'%/' (read-qath t t.ts)
2415+ %'/' (read-path t t.ts)
2416+ %'`' (read-unit t t.ts)
2417+ %'(' (read-group t t.ts)
2418+ %'~[' (read-bracket %list t ~ t.ts)
2419+ %'[' (read-bracket %tuple t ~ t.ts)
2420+ %'|=(' (read-gate-wide t t.ts)
2421+ %'|=' (read-ctor t t.ts)
2422+ ==
2423+ ::
2424+ :: +read-ref: after a name or wing, a tight ( makes a change, and
2425+ :: after a name a tight + a pair; else it is a wing
2426+ ::
2427+ ++ read-ref
2428+ |= [t=token ts=(list token)]
2429+ ^- (pare expr)
2430+ =/ names=(list term) (names-of lex.t)
2431+ ?: ?=([[* %& %'('] *] ts)
2432+ (read-bracket %change i.ts `[t names] t.ts)
2433+ ?: &(?=([[* %& %'+'] *] ts) ?=([%name *] lex.t))
2434+ (read-pair t p.lex.t i.ts t.ts)
2435+ [%& [%wing at.t names] ts]
2436+ ::
2437+ :: +read-pair: name+operand, with no spaces
2438+ ::
2439+ ++ read-pair
2440+ |= [t=token tag=term lus=token ts=(list token)]
2441+ ^- (pare expr)
2442+ ?: |(?=(~ ts) !tight.i.ts) (bad-space lus ts "an operand")
2443+ ;< [v=expr after=(list token)] then (read-operand ts)
2444+ [%& [%pair [beg.at.t end:(span-of v)] tag v] after]
2445+ ::
2446+ :: +read-unit: ` and an operand, with no space
2447+ ::
2448+ ++ read-unit
2449+ |= [tic=token ts=(list token)]
2450+ ^- (pare expr)
2451+ ?: |(?=(~ ts) !tight.i.ts) (bad-space tic ts "an operand")
2452+ ;< [v=expr after=(list token)] then (read-operand ts)
2453+ [%& [%unit [beg.at.tic end:(span-of v)] v] after]
2454+ ::
2455+ :: +read-ctor: |= and a term, with no space: a case's constructor
2456+ ::
2457+ ++ read-ctor
2458+ |= [bar=token ts=(list token)]
2459+ ^- (pare expr)
2460+ ?: |(?=(~ ts) !tight.i.ts) (bad-space bar ts "a term")
2461+ ?. ?=([[* * [%lit %term *]] *] ts) (bad ts "a term")
2462+ [%& [%ctor [beg.at.bar end.at.i.ts] p.lex.i.ts] t.ts]
2463+ ::
2464+ :: +read-path: a path literal, as /posts/~zod (doc question)
2465+ ::
2466+ ++ read-path
2467+ |= [sl=token ts=(list token)]
2468+ ^- (pare expr)
2469+ ;< [[sp=span segs=(list @ta)] after=(list token)] then
2470+ (read-pathlit sl ts)
2471+ [%& [%path sp segs] after]
2472+ ::
2473+ :: +read-qath: %/, then its segments, knots or (expr), each after a
2474+ :: tight / and tight itself; %/ alone is the root
2475+ ::
2476+ ++ read-qath
2477+ |= [cen=token ts=(list token)]
2478+ ^- (pare expr)
2479+ ?. ?=([[* %& ?([%knot *] %'(')] *] ts)
2480+ ?: &(?=(^ ts) tight.i.ts !(is-closer i.ts))
2481+ (bad ts "a path segment")
2482+ [%& [%qath at.cen ~] ts]
2483+ =| segs=(list qseg)
2484+ |- ^- (pare expr)
2485+ ;< [[s=qseg fin=loc] after=(list token)] then (read-qseg ts)
2486+ ?. ?=([[* %& %'/'] *] after)
2487+ [%& [%qath [beg.at.cen fin] (flop [s segs])] after]
2488+ =/ nex=(list token) t.after
2489+ ?: ?=([[* %& ?([%knot *] %'(')] *] nex)
2490+ $(segs [s segs], ts nex)
2491+ ?: &(?=(^ nex) tight.i.nex) (bad nex "a path segment")
2492+ (bad-space i.after nex "a path segment")
2493+ ::
2494+ :: +read-qseg: an application path's segment, a knot or (expr), and
2495+ :: where it ends
2496+ ::
2497+ ++ read-qseg
2498+ |= ts=(list token)
2499+ ^- (pare [qseg loc])
2500+ ?: ?=([[* * [%knot *]] *] ts)
2501+ [%& [[%knot p.lex.i.ts] end.at.i.ts] t.ts]
2502+ ?. ?=([[* * %'('] *] ts) (bad ts "a path segment")
2503+ =* par i.ts
2504+ ;< [e=expr after=(list token)] then (read-expr t.ts)
2505+ ?. ?=([[* * %')'] *] after) (unclosed par ")" after)
2506+ [%& [[%expr e] end.at.i.after] t.after]
2507+ ::
2508+ :: +read-string: after its str-head, a string's interpolations and
2509+ :: text: expr { str-mid expr } str-tail
2510+ ::
2511+ ++ read-string
2512+ |= [head=token ts=(list token)]
2513+ ^- (pare expr)
2514+ =/ ps=(list piece)
2515+ ?.(?=([%str-head *] lex.head) ~ (text-piece p.lex.head))
2516+ =/ op=token head
2517+ |- ^- (pare expr)
2518+ ;< [e=expr after=(list token)] then (read-expr ts)
2519+ =. ps [[%expr e] ps]
2520+ ?: ?=([[* * [%str-mid *]] *] after)
2521+ $(ps (weld (text-piece p.lex.i.after) ps), op i.after, ts t.after)
2522+ ?. ?=([[* * [%str-tail *]] *] after)
2523+ =/ brace=loc [line.end.at.op (dec (max 2 col.end.at.op))]
2524+ (bad after "`}` to close the `\{` at {(show-loc brace)}")
2525+ =. ps (weld (text-piece p.lex.i.after) ps)
2526+ [%& [%str [beg.at.head end.at.i.after] (flop ps)] t.after]
2527+ ::
2528+ :: +read-group: ( expr ), or ( { operand } and its lines below, left
2529+ :: open
2530+ ::
2531+ :: A ( followed by a rune is the closed form. Else the group holds
2532+ :: its first line's operands and then its lines as one call, or the
2533+ :: one element alone.
2534+ ::
2535+ ++ read-group
2536+ |= [par=token ts=(list token)]
2537+ ^- (pare expr)
2538+ ?: (is-rune-start ts)
2539+ ;< [e=expr after=(list token)] then (read-expr ts)
2540+ ?. ?=([[* * %')'] *] after) (unclosed par ")" after)
2541+ [%& [%group [beg.at.par end.at.i.after] e] t.after]
2542+ ;< [els=(list expr) after=(list token)] then (read-operands ts)
2543+ ?: ?=([[* * %')'] *] after)
2544+ ?~ els (bad after "an expression")
2545+ [%& [%group [beg.at.par end.at.i.after] (call-of els)] t.after]
2546+ ?. ?=([[* * %indent] *] after)
2547+ =/ last=(unit span) ?~(els ~ `(span-of (rear els)))
2548+ (unclosed-open par ")" "an argument" last after)
2549+ ;< [ls=(list item) more=(list token)] then
2550+ (read-lines %group t.after)
2551+ =/ inner=expr (call-of (weld els (turn ls |=(i=item val.i))))
2552+ [%& [%group [beg.at.par end:(span-of inner)] inner] more]
2553+ ::
2554+ :: +read-bracket: a tuple's, list's or change's items, to its closer
2555+ :: on the line, or to the end of its lines below when left open
2556+ ::
2557+ ++ read-bracket
2558+ |= $: kind=?(%tuple %list %change)
2559+ op=token
2560+ target=(unit [t=token names=(list term)])
2561+ ts=(list token)
2562+ ==
2563+ ^- (pare expr)
2564+ =/ close=?(%')' %']') ?:(?=(%change kind) %')' %']')
2565+ =| its=(list item)
2566+ |- ^- (pare expr)
2567+ ?~ ts (bad ts "an item")
2568+ =* t i.ts
2569+ ?: =(close lex.t)
2570+ [%& (bracket-node kind op target (flop its) end.at.t) t.ts]
2571+ ?: (is-closer t) (unclosed op (trip close) ts)
2572+ ?: ?=(%indent lex.t)
2573+ ;< [ls=(list item) more=(list token)] then (read-lines kind t.ts)
2574+ =/ all=(list item) (weld (flop its) ls)
2575+ =/ fin=loc ?~(all end.at.op end.at:(rear all))
2576+ [%& (bracket-node kind op target all fin) more]
2577+ ?: ?=(?(%newline %dedent) lex.t)
2578+ =/ last=(unit span) ?~(its ~ `at.i.its)
2579+ (unclosed-open op (trip close) "an item" last ts)
2580+ ?: &(tight.t ?=(^ its)) (no-space ts)
2581+ ;< [i=item more=(list token)] then (read-item kind ts)
2582+ $(its [i its], ts more)
2583+ ::
2584+ :: +read-item: [ name= ] operand; a tuple's item may be named, a
2585+ :: change's must be, a list's is not
2586+ ::
2587+ ++ read-item
2588+ |= [kind=?(%tuple %list %change) ts=(list token)]
2589+ ^- (pare item)
2590+ ?: &(!?=(%list kind) ?=([[* * [%name *]] [* %& %'='] *] ts))
2591+ =* nam i.ts
2592+ =/ rest=(list token) t.t.ts
2593+ ?: |(?=(~ rest) !tight.i.rest) (bad-space i.t.ts rest "a value")
2594+ ;< [v=expr after=(list token)] then (read-operand rest)
2595+ [%& [[beg.at.nam end:(span-of v)] `p.lex.nam v] after]
2596+ ?: ?=(%change kind) (unnamed ts)
2597+ ?: &(?=(^ ts) (is-rune i.ts))
2598+ %^ bad-why ts "an expression"
2599+ "inside brackets, a rune goes in parentheses"
2600+ ;< [v=expr after=(list token)] then (read-operand ts)
2601+ [%& [(span-of v) ~ v] after]
2602+ ::
2603+ :: +read-lines: after an open bracket's INDENT, its lines, an item
2604+ :: each, to its DEDENT
2605+ ::
2606+ ++ read-lines
2607+ |= [kind=?(%tuple %list %change %group) ts=(list token)]
2608+ ^- (pare (list item))
2609+ =| ls=(list item)
2610+ |- ^- (pare (list item))
2611+ ;< [l=item after=(list token)] then (read-line kind ts)
2612+ ?: ?=([[* * %newline] *] after) $(ls [l ls], ts t.after)
2613+ ?: ?=([[* * %dedent] *] after) [%& (flop [l ls]) t.after]
2614+ ?. ?=([[* * ?(%')' %']')] *] after) (bad-end after)
2615+ %^ bad-why after "the end of the line"
2616+ "a bracket open at the end of its line takes no closer"
2617+ ::
2618+ :: +read-line: an open bracket's line, [ name= ] expr; a tuple's may
2619+ :: be named, a change's must be, a list's and a group's are not
2620+ :: (doc question)
2621+ ::
2622+ ++ read-line
2623+ |= [kind=?(%tuple %list %change %group) ts=(list token)]
2624+ ^- (pare item)
2625+ ?: ?& ?=(?(%tuple %change) kind)
2626+ ?=([[* * [%name *]] [* %& %'='] *] ts)
2627+ ==
2628+ =* nam i.ts
2629+ =/ rest=(list token) t.t.ts
2630+ ?: |(?=(~ rest) !tight.i.rest) (bad-space i.t.ts rest "a value")
2631+ ;< [v=expr after=(list token)] then (read-expr rest)
2632+ [%& [[beg.at.nam end:(span-of v)] `p.lex.nam v] after]
2633+ ?: ?=(%change kind) (unnamed ts)
2634+ ;< [v=expr after=(list token)] then (read-expr ts)
2635+ [%& [(span-of v) ~ v] after]
2636+ ::
2637+ :: +read-gate-wide: |=( sample operand ), the one wide expression
2638+ ::
2639+ ++ read-gate-wide
2640+ |= [op=token ts=(list token)]
2641+ ^- (pare expr)
2642+ ;< [s=sample after=(list token)] then (read-sample ts)
2643+ ?: ?=([[* * %')'] *] after) (bad after "the gate's body")
2644+ ?: &(?=(^ after) tight.i.after) (bad after "a space after the sample")
2645+ ?: &(?=(^ after) (is-rune i.after))
2646+ %^ bad-why after "an expression"
2647+ "the wide gate's body is an operand, so a rune goes in parentheses"
2648+ ;< [b=expr more=(list token)] then (read-operand after)
2649+ ?: ?=([[* * %')'] *] more)
2650+ [%& [%gate-wide [beg.at.op end.at.i.more] s b] t.more]
2651+ ?. &(?=(^ more) !tight.i.more (is-operand-start i.more))
2652+ (unclosed op ")" more)
2653+ %^ bad-why more
2654+ "`)` to close the `|=(` at {(show-loc beg.at.op)}"
2655+ "the wide gate's body is one operand, so a call goes in parentheses"
2656+ ::
2657+ :: +read-gate: |= sample, then an expression or a body
2658+ ::
2659+ ++ read-gate
2660+ |= [bar=token ts=(list token)]
2661+ ^- (pare expr)
2662+ ?: &(?=(^ ts) tight.i.ts) (bad ts "a space after `|=`")
2663+ ;< [s=sample after=(list token)] then (read-sample ts)
2664+ ;< [e=expr more=(list token)] then
2665+ (read-expr-or-body "the sample" after)
2666+ [%& [%gate [beg.at.bar end:(span-of e)] s e] more]
2667+ ::
2668+ :: +read-cast: ^- mold, then an expression or a body
2669+ ::
2670+ ++ read-cast
2671+ |= [ket=token ts=(list token)]
2672+ ^- (pare expr)
2673+ ?: &(?=(^ ts) tight.i.ts) (wide-rune "^-" ts)
2674+ ;< [s=shape after=(list token)] then (read-mold ts)
2675+ ;< [e=expr more=(list token)] then
2676+ (read-expr-or-body "the mold" after)
2677+ [%& [%cast [beg.at.ket end:(span-of e)] s e] more]
2678+ ::
2679+ :: +read-trace: ~& expr, then its body below
2680+ ::
2681+ ++ read-trace
2682+ |= [sig=token ts=(list token)]
2683+ ^- (pare expr)
2684+ ?: &(?=(^ ts) tight.i.ts) (bad ts "a space after `~&`")
2685+ ;< [v=expr after=(list token)] then (read-expr ts)
2686+ ?. ?=([[* * %indent] *] after)
2687+ (bad after "`~&`'s body on deeper lines")
2688+ ;< [b=expr more=(list token)] then (read-body t.after)
2689+ [%& [%trace [beg.at.sig end:(span-of b)] v b] more]
2690+ ::
2691+ :: +read-branch: ?- expr, then its arms below, one per line
2692+ ::
2693+ ++ read-branch
2694+ |= [wut=token ts=(list token)]
2695+ ^- (pare expr)
2696+ ?: &(?=(^ ts) tight.i.ts) (wide-rune "?-" ts)
2697+ ;< [s=expr after=(list token)] then (read-expr ts)
2698+ ?. ?=([[* * %indent] *] after)
2699+ (bad after "`?-`'s arms on deeper lines")
2700+ =| arms=(list arm)
2701+ =/ rest=(list token) t.after
2702+ |- ^- (pare expr)
2703+ ;< [a=arm more=(list token)] then (read-arm rest)
2704+ ?: ?=([[* * %newline] *] more) $(arms [a arms], rest t.more)
2705+ ?. ?=([[* * %dedent] *] more) (bad-end more)
2706+ [%& [%branch [beg.at.wut end.at.a] s (flop [a arms])] t.more]
2707+ ::
2708+ :: +read-arm: a pattern, then an expression or a body
2709+ ::
2710+ ++ read-arm
2711+ |= ts=(list token)
2712+ ^- (pare arm)
2713+ ;< [p=pattern after=(list token)] then (read-pattern ts)
2714+ ?: ?=([[* %& %'+'] *] after)
2715+ %^ bad-why after "a space after the pattern"
2716+ "patterns take no pairs: write a cell, as [%gap %s2]"
2717+ ;< [e=expr more=(list token)] then
2718+ (read-expr-or-body "the pattern" after)
2719+ [%& [[beg:(span-of p) end:(span-of e)] p e] more]
2720+ ::
2721+ :: +read-pattern: a term, number, string, ship, loobean, ~, * or name,
2722+ :: or a cell of patterns
2723+ ::
2724+ :: A date, duration or knot fails at its second character, since ~
2725+ :: alone is null and no ship goes on so; ~[ at its [; and a string
2726+ :: with {…} at its { (section 3, Errors).
2727+ ::
2728+ ++ read-pattern
2729+ |= ts=(list token)
2730+ ^- (pare pattern)
2731+ ?~ ts (bad ts "a pattern")
2732+ =* t i.ts
2733+ =/ next=loc [line.beg.at.t +(col.beg.at.t)]
2734+ ?+ lex.t (bad ts "a pattern")
2735+ [%lit *]
2736+ =* l p.lex.t
2737+ ?: ?=(?(%number %ship %term %loobean %null) form.l)
2738+ [%& [%lit at.t l] t.ts]
2739+ =/ what=tape
2740+ ?- form.l
2741+ %date "dates"
2742+ %duration "durations"
2743+ %knot "knots"
2744+ ==
2745+ %+ bad-at next
2746+ ;: weld
2747+ "expected a pattern, found {(show-found t)}; patterns take no "
2748+ what
2749+ ": compare values with ?- (eq a b)"
2750+ ==
2751+ ::
2752+ [%str *] [%& [%str at.t p.lex.t] t.ts]
2753+ %'*' [%& [%any at.t ~] t.ts]
2754+ [%name *] [%& [%bind at.t p.lex.t] t.ts]
2755+ %'[' (read-cell-pattern t t.ts)
2756+ %'`' (bad-why ts "a pattern" "patterns take no units: write [~ x]")
2757+ ::
2758+ [%str-head *]
2759+ %+ bad-at [line.end.at.t (dec (max 2 col.end.at.t))]
2760+ %+ weld "expected a pattern, found a string with `\{…}`; "
2761+ "patterns take strings without `\{…}`"
2762+ ::
2763+ %'~['
2764+ %+ bad-at next
2765+ "expected a pattern, found `~[`; patterns take no lists"
2766+ ==
2767+ ::
2768+ :: +read-cell-pattern: [ pattern { pattern } ], closed on its line
2769+ ::
2770+ ++ read-cell-pattern
2771+ |= [op=token ts=(list token)]
2772+ ^- (pare pattern)
2773+ =| ps=(list pattern)
2774+ |- ^- (pare pattern)
2775+ ?: ?=([[* * %']'] *] ts)
2776+ ?~ ps (bad ts "a pattern")
2777+ [%& [%cell [beg.at.op end.at.i.ts] (flop ps)] t.ts]
2778+ ?: &(?=(^ ts) |((is-closer i.ts) (is-layout i.ts)))
2779+ (unclosed op "]" ts)
2780+ ?: &(?=(^ ps) ?=(^ ts) tight.i.ts) (no-space ts)
2781+ ;< [p=pattern after=(list token)] then (read-pattern ts)
2782+ $(ps [p ps], ts after)
2783+ ::
2784+ :: +read-sample: a gate's sample, a field, except that a bare name
2785+ :: binds, alone or in a cell sample at any depth (section 3)
2786+ ::
2787+ ++ read-sample
2788+ |= ts=(list token)
2789+ ^- (pare sample)
2790+ ?: ?=([[* * [%name *]] [* %& %'='] *] ts) (read-face ts)
2791+ ?: ?=([[* * [%name *]] *] ts) [%& [%bind at.i.ts p.lex.i.ts] t.ts]
2792+ ?: ?=([[* * %'='] *] ts) (read-pun i.ts t.ts)
2793+ ?: &(?=(^ ts) (is-layout i.ts)) (bad ts "a sample")
2794+ ?. ?=([[* * %'['] *] ts)
2795+ ;< [s=shape after=(list token)] then (read-mold ts)
2796+ [%& [%bare (span-of s) s] after]
2797+ =* op i.ts
2798+ =| ss=(list sample)
2799+ =/ rest=(list token) t.ts
2800+ |- ^- (pare sample)
2801+ ?: ?=([[* * %']'] *] rest)
2802+ ?~ ss (bad rest "a sample")
2803+ [%& [%cell [beg.at.op end.at.i.rest] (flop ss)] t.rest]
2804+ ?: &(?=(^ rest) |((is-closer i.rest) (is-layout i.rest)))
2805+ (unclosed op "]" rest)
2806+ ?: &(?=(^ ss) ?=(^ rest) tight.i.rest) (no-space rest)
2807+ ;< [s=sample after=(list token)] then (read-sample rest)
2808+ $(ss [s ss], rest after)
2809+ ::
2810+ :: +read-field: a cell mold's field: name=mold, =name, or a mold
2811+ ::
2812+ ++ read-field
2813+ |= ts=(list token)
2814+ ^- (pare field)
2815+ ?: ?=([[* * [%name *]] [* %& %'='] *] ts) (read-face ts)
2816+ ?: ?=([[* * %'='] *] ts) (read-pun i.ts t.ts)
2817+ ;< [s=shape after=(list token)] then (read-mold ts)
2818+ [%& [%bare (span-of s) s] after]
2819+ ::
2820+ :: +read-face: name=mold, with no spaces
2821+ ::
2822+ ++ read-face
2823+ |= ts=(list token)
2824+ ^- (pare field)
2825+ ?. ?=([[* * [%name *]] [* * %'='] *] ts) (bad ts "a name")
2826+ =* nam i.ts
2827+ =/ rest=(list token) t.t.ts
2828+ ?: |(?=(~ rest) !tight.i.rest) (bad-space i.t.ts rest "a mold")
2829+ ;< [s=shape after=(list token)] then (read-mold rest)
2830+ [%& [%face [beg.at.nam end:(span-of s)] p.lex.nam s] after]
2831+ ::
2832+ :: +read-pun: =name, with no space, for name=name
2833+ ::
2834+ ++ read-pun
2835+ |= [tis=token ts=(list token)]
2836+ ^- (pare field)
2837+ ?: |(?=(~ ts) !tight.i.ts) (bad-space tis ts "a name")
2838+ ?. ?=([[* * [%name *]] *] ts) (bad ts "a name")
2839+ [%& [%pun [beg.at.tis end.at.i.ts] p.lex.i.ts] t.ts]
2840+ ::
2841+ :: +read-mold: one mold
2842+ ::
2843+ ++ read-mold
2844+ |= ts=(list token)
2845+ ^- (pare shape)
2846+ ?~ ts (bad ts "a mold")
2847+ =* t i.ts
2848+ ?+ lex.t (bad ts "a mold")
2849+ [%aura *] [%& [%aura at.t p.lex.t] t.ts]
2850+ %'*' [%& [%noun at.t ~] t.ts]
2851+ %'!!' [%& [%void at.t ~] t.ts]
2852+ %'?' [%& [%flag at.t ~] t.ts]
2853+ [%name *] [%& [%ref at.t ~[p.lex.t]] t.ts]
2854+ [%wing *] [%& [%ref at.t p.lex.t] t.ts]
2855+ [%tvar *] [%& [%tvar at.t p.lex.t] t.ts]
2856+ %'/' (read-pathmold t t.ts)
2857+ %'(' (read-apply t t.ts)
2858+ %'[' (read-cell-mold t t.ts)
2859+ %'$?' (read-union t t.ts)
2860+ %'$?(' (read-union-wide t t.ts)
2861+ %'$-(' (read-fn t t.ts)
2862+ %'|$' (read-generic t t.ts)
2863+ ::
2864+ [%lit *]
2865+ ?. ?=(?(%null %term %loobean) form.p.lex.t) (bad ts "a mold")
2866+ [%& [%const at.t p.lex.t] t.ts]
2867+ ==
2868+ ::
2869+ :: +read-molds: molds to the ) of the bracket op opened: after a
2870+ :: space each, or but the first if not spaced; at least one
2871+ ::
2872+ ++ read-molds
2873+ |= [op=token spaced=? ts=(list token)]
2874+ ^- (pare [(list shape) loc])
2875+ =| ms=(list shape)
2876+ |- ^- (pare [(list shape) loc])
2877+ ?: ?=([[* * %')'] *] ts)
2878+ ?~ ms (bad ts "a mold")
2879+ [%& [(flop ms) end.at.i.ts] t.ts]
2880+ ?: &(?=(^ ts) |((is-closer i.ts) (is-layout i.ts)))
2881+ (unclosed op ")" ts)
2882+ ?: &(?=(^ ts) tight.i.ts |(spaced ?=(^ ms))) (no-space ts)
2883+ ;< [m=shape after=(list token)] then (read-mold ts)
2884+ $(ms [m ms], ts after)
2885+ ::
2886+ :: +read-apply: ( ref mold { mold } )
2887+ ::
2888+ ++ read-apply
2889+ |= [op=token ts=(list token)]
2890+ ^- (pare shape)
2891+ ?. ?=([[* * ?([%name *] [%wing *])] *] ts)
2892+ (bad ts "a mold's name, as in (list @t)")
2893+ ;< [[ms=(list shape) fin=loc] after=(list token)] then
2894+ (read-molds op & t.ts)
2895+ [%& [%apply [beg.at.op fin] (names-of lex.i.ts) ms] after]
2896+ ::
2897+ :: +read-union-wide: $?( mold { mold } )
2898+ ::
2899+ ++ read-union-wide
2900+ |= [op=token ts=(list token)]
2901+ ^- (pare shape)
2902+ ;< [[ms=(list shape) fin=loc] after=(list token)] then
2903+ (read-molds op | ts)
2904+ [%& [%union [beg.at.op fin] ms] after]
2905+ ::
2906+ :: +read-fn: $-( mold mold )
2907+ ::
2908+ ++ read-fn
2909+ |= [op=token ts=(list token)]
2910+ ^- (pare shape)
2911+ ;< [a=shape after=(list token)] then (read-mold ts)
2912+ ?: ?=([[* * %')'] *] after) (bad after "a mold, the product")
2913+ ?: &(?=(^ after) |((is-closer i.after) (is-layout i.after)))
2914+ (unclosed op ")" after)
2915+ ?: &(?=(^ after) tight.i.after) (no-space after)
2916+ ;< [b=shape more=(list token)] then (read-mold after)
2917+ ?. ?=([[* * %')'] *] more) (unclosed op ")" more)
2918+ [%& [%fn [beg.at.op end.at.i.more] a b] t.more]
2919+ ::
2920+ :: +read-cell-mold: [ field { field } ]
2921+ ::
2922+ ++ read-cell-mold
2923+ |= [op=token ts=(list token)]
2924+ ^- (pare shape)
2925+ =| fs=(list field)
2926+ |- ^- (pare shape)
2927+ ?: ?=([[* * %']'] *] ts)
2928+ ?~ fs (bad ts "a mold")
2929+ [%& [%cell [beg.at.op end.at.i.ts] (flop fs)] t.ts]
2930+ ?: &(?=(^ ts) |((is-closer i.ts) (is-layout i.ts)))
2931+ (unclosed op "]" ts)
2932+ ?: &(?=(^ fs) ?=(^ ts) tight.i.ts) (no-space ts)
2933+ ;< [f=field after=(list token)] then (read-field ts)
2934+ $(fs [f fs], ts after)
2935+ ::
2936+ :: +read-union: $?, then its cases below, one mold per line
2937+ ::
2938+ ++ read-union
2939+ |= [buc=token ts=(list token)]
2940+ ^- (pare shape)
2941+ ?. ?=([[* * %indent] *] ts)
2942+ ?: ?=([[* * ?(%newline %dedent)] *] ts)
2943+ (bad ts "`$?`'s cases on deeper lines")
2944+ %^ bad-why ts "the end of the line"
2945+ "`$?` takes its cases on deeper lines, one per line, or write $?(%a %b)"
2946+ =| cs=(list shape)
2947+ =/ rest=(list token) t.ts
2948+ |- ^- (pare shape)
2949+ ;< [c=shape after=(list token)] then (read-mold rest)
2950+ ?: ?=([[* * %newline] *] after) $(cs [c cs], rest t.after)
2951+ ?: ?=([[* * %dedent] *] after)
2952+ [%& [%union [beg.at.buc end:(span-of c)] (flop [c cs])] t.after]
2953+ ?: ?=([[* * %indent] *] after) (bad-end after)
2954+ (bad-why after "the end of the line" "a union takes one case per line")
2955+ ::
2956+ :: +read-generic: |$ [ typevar { typevar } ] mold
2957+ ::
2958+ ++ read-generic
2959+ |= [bar=token ts=(list token)]
2960+ ^- (pare shape)
2961+ ?: &(?=(^ ts) tight.i.ts) (bad ts "a space after `|$`")
2962+ ?. ?=([[* * %'['] *] ts)
2963+ (bad ts "`[` and its type variables, as in |$ [M]")
2964+ =* op i.ts
2965+ =| vs=(list @t)
2966+ =/ rest=(list token) t.ts
2967+ |- ^- (pare shape)
2968+ ?: ?=([[* * %']'] *] rest)
2969+ ?~ vs (bad rest "a type variable")
2970+ =/ more=(list token) t.rest
2971+ ?: &(?=(^ more) tight.i.more) (bad more "a space after `]`")
2972+ ;< [b=shape after=(list token)] then (read-mold more)
2973+ [%& [%generic [beg.at.bar end:(span-of b)] (flop vs) b] after]
2974+ ?: &(?=(^ rest) |((is-closer i.rest) (is-layout i.rest)))
2975+ (unclosed op "]" rest)
2976+ ?: &(?=(^ vs) ?=(^ rest) tight.i.rest) (no-space rest)
2977+ ?. ?=([[* * [%tvar *]] *] rest) (bad rest "a type variable")
2978+ $(vs [p.lex.i.rest vs], rest t.rest)
2979+ ::
2980+ :: +read-pathmold: / [ segment { / segment } ], each / and segment
2981+ :: tight; / alone is the empty path
2982+ ::
2983+ ++ read-pathmold
2984+ |= [sl=token ts=(list token)]
2985+ ^- (pare shape)
2986+ ?. ?=([[* %& ?([%knot *] %'[')] *] ts)
2987+ ?: &(?=(^ ts) tight.i.ts !(is-closer i.ts))
2988+ (bad ts "a path segment")
2989+ [%& [%path at.sl ~] ts]
2990+ =| segs=(list pseg)
2991+ |- ^- (pare shape)
2992+ ;< [[s=pseg fin=loc] after=(list token)] then (read-pseg ts)
2993+ ?. ?=([[* %& %'/'] *] after)
2994+ [%& [%path [beg.at.sl fin] (flop [s segs])] after]
2995+ =/ nex=(list token) t.after
2996+ ?: ?=([[* %& ?([%knot *] %'[')] *] nex)
2997+ $(segs [s segs], ts nex)
2998+ ?: &(?=(^ nex) tight.i.nex) (bad nex "a path segment")
2999+ (bad-space i.after nex "a path segment")
3000+ ::
3001+ :: +read-pseg: a path mold's segment, a knot or [name=aura] with no
3002+ :: spaces, and where it ends
3003+ ::
3004+ ++ read-pseg
3005+ |= ts=(list token)
3006+ ^- (pare [pseg loc])
3007+ ?: ?=([[* * [%knot *]] *] ts)
3008+ [%& [[%knot p.lex.i.ts] end.at.i.ts] t.ts]
3009+ ?. ?=([[* * %'['] *] ts) (bad ts "a path segment")
3010+ =* op i.ts
3011+ =/ r1=(list token) t.ts
3012+ ?: |(?=(~ r1) !tight.i.r1) (bad-space op r1 "a name")
3013+ ?. ?=([[* * [%name *]] *] r1) (bad r1 "a name")
3014+ =/ r2=(list token) t.r1
3015+ ?: |(?=(~ r2) !tight.i.r2) (bad-space i.r1 r2 "`=`")
3016+ ?. ?=([[* * %'='] *] r2) (bad r2 "`=`")
3017+ =/ r3=(list token) t.r2
3018+ ?: |(?=(~ r3) !tight.i.r3) (bad-space i.r2 r3 "an aura")
3019+ ?. ?=([[* * [%aura *]] *] r3) (bad r3 "an aura")
3020+ =/ r4=(list token) t.r3
3021+ ?: |(?=(~ r4) !tight.i.r4) (bad-space i.r3 r4 "`]`")
3022+ ?. ?=([[* * %']'] *] r4) (bad r4 "`]`")
3023+ =/ at=span [beg.at.op end.at.i.r4]
3024+ [%& [[%typed at p.lex.i.r1 p.lex.i.r3] end.at.i.r4] t.r4]
3025+ --
3026+::
3027++| %span-check
3028+::
3029+:: +outline: a node as +check-spans sees it
3030+::
3031+:: lead lists the kinds (+kind-of) of token the node may start with,
3032+:: or is ~ when it starts with its first child; last likewise for its
3033+:: end, and open lets a bracket that may be left open end with its
3034+:: last child instead.
3035+::
3036++$ outline
3037+ $~ [%$ *span ~ ~ | ~]
3038+ $: kind=@tas
3039+ at=span
3040+ lead=(list @)
3041+ last=(list @)
3042+ open=?
3043+ kids=(list outline)
3044+ ==
3045+::
3046+:: +check-spans: whether a module's spans follow section 1's rules
3047+::
3048+:: A node starts at its first token and ends where its last token
3049+:: ends, never at a layout token: at its own token where it has one
3050+:: there (a rune, a name, an opener or a closer), else where its
3051+:: first or last child does. Its children's spans lie inside its own
3052+:: in source order, and so do the module's imports and definitions.
3053+:: Gives the first node that breaks a rule, and how, or ~.
3054+::
3055+++ check-spans
3056+ |= [mod=module toks=(list token)]
3057+ ^- (unit tape)
3058+ =/ real=(list token) (skip toks is-layout)
3059+ =/ begs=(map loc @) (malt (turn real |=(t=token [beg.at.t (kind-of t)])))
3060+ =/ ends=(map loc @) (malt (turn real |=(t=token [end.at.t (kind-of t)])))
3061+ %^ check-kids [begs ends] ~
3062+ (weld (turn imports.mod outline-import) (turn defs.mod outline-def))
3063+::
3064+:: +kind-of: a token's kind: a glyph, or its lexeme's tag
3065+::
3066+++ kind-of
3067+ |= t=token
3068+ ^- @
3069+ ?@(lex.t lex.t -.lex.t)
3070+::
3071+:: +check-kids: nodes in source order, inside the span in, each checked
3072+::
3073+++ check-kids
3074+ |= [maps=[begs=(map loc @) ends=(map loc @)] in=(unit span) os=(list outline)]
3075+ ^- (unit tape)
3076+ =| prev=(unit span)
3077+ |- ^- (unit tape)
3078+ ?~ os ~
3079+ =* o i.os
3080+ ?: &(?=(^ in) (loc-lth beg.at.o beg.u.in))
3081+ `(span-bad o "starts before its parent")
3082+ ?: &(?=(^ in) (loc-lth end.u.in end.at.o))
3083+ `(span-bad o "ends after its parent")
3084+ ?: &(?=(^ prev) (loc-lth beg.at.o end.u.prev))
3085+ `(span-bad o "starts before the node before it ends")
3086+ =/ bad=(unit tape) (check-outline maps o)
3087+ ?^ bad bad
3088+ $(prev `at.o, os t.os)
3089+::
3090+:: +check-outline: one node's start and end, then its children
3091+::
3092+++ check-outline
3093+ |= [maps=[begs=(map loc @) ends=(map loc @)] o=outline]
3094+ ^- (unit tape)
3095+ =* ks kids.o
3096+ =/ head=(unit span) ?~(ks ~ `at.i.ks)
3097+ =/ tail=(unit span) ?~(ks ~ `at:(rear ks))
3098+ ?. (loc-lth beg.at.o end.at.o) `(span-bad o "is empty")
3099+ :: the start: its own token, or its first child's
3100+ =/ start=(unit tape)
3101+ ?~ lead.o
3102+ ?~ head `"has no token or child to start with"
3103+ ?: =(beg.at.o beg.u.head) ~
3104+ `"should start where its first child does, at {(show-loc beg.u.head)}"
3105+ =/ k=(unit @) (~(get by begs.maps) beg.at.o)
3106+ ?~ k `"starts where no token does"
3107+ ?. (lien `(list @)`lead.o |=(a=@ =(a u.k)))
3108+ `"starts at a token of a kind it can't start with"
3109+ ?: &(?=(^ head) !(loc-lth beg.at.o beg.u.head))
3110+ `"should start with its own token, before its first child"
3111+ ~
3112+ ?^ start `(span-bad o u.start)
3113+ :: the end: its own token, or its last child's
3114+ =/ stop=(unit tape)
3115+ ?: &(|(?=(~ last.o) open.o) ?=(^ tail) =(end.at.o end.u.tail)) ~
3116+ ?~ last.o
3117+ ?~ tail `"has no token or child to end with"
3118+ `"should end where its last child does, at {(show-loc end.u.tail)}"
3119+ =/ k=(unit @) (~(get by ends.maps) end.at.o)
3120+ ?~ k `"ends where no token does"
3121+ ?. (lien `(list @)`last.o |=(a=@ =(a u.k)))
3122+ `"ends at a token of a kind it can't end with"
3123+ ?: &(?=(^ tail) !(loc-lth end.u.tail end.at.o))
3124+ `"should end with its own token, after its last child"
3125+ ~
3126+ ?^ stop `(span-bad o u.stop)
3127+ (check-kids maps `at.o ks)
3128+::
3129+:: +span-bad: a span check's error, naming the node by kind and span
3130+::
3131+++ span-bad
3132+ |= [o=outline why=tape]
3133+ ^- tape
3134+ "({(trip kind.o)} {(show-loc beg.at.o)} to {(show-loc end.at.o)}) {why}"
3135+::
3136+:: +loc-lth: whether a comes before b
3137+::
3138+++ loc-lth
3139+ |= [a=loc b=loc]
3140+ ^- ?
3141+ ?| (lth line.a line.b)
3142+ &(=(line.a line.b) (lth col.a col.b))
3143+ ==
3144+::
3145+++ outline-import
3146+ |= i=import
3147+ ^- outline
3148+ ?- -.i
3149+ %sur [%sur at.i ~[%'/-'] ~[%name] | ~]
3150+ %mark [%mark at.i ~[%'/%'] ~[%lit] | ~]
3151+ %jibb [%jibb at.i ~[%'/='] ~[%'/' %knot] | ~]
3152+ ==
3153+::
3154+++ outline-def
3155+ |= d=def
3156+ ^- outline
3157+ ?- -.d
3158+ %mold [%mold at.d ~[%'+$'] ~ | ~[(outline-shape shape.d)]]
3159+ %value [%value at.d ~[%'++'] ~ | ~[(outline-expr val.d)]]
3160+ ==
3161+::
3162+++ outline-expr
3163+ |= e=expr
3164+ ^- outline
3165+ ?- -.e
3166+ %lit [%lit at.e ~[%lit] ~[%lit] | ~]
3167+ %str (outline-str at.e pieces.e)
3168+ %path [%path at.e ~[%'/'] ~[%'/' %knot] | ~]
3169+ %wing [%wing at.e ~[%name %wing] ~[%name %wing] | ~]
3170+ %pair [%pair at.e ~[%name] ~ | ~[(outline-expr val.e)]]
3171+ %unit [%unit at.e ~[%'`'] ~ | ~[(outline-expr val.e)]]
3172+ %group [%group at.e ~[%'('] ~[%')'] & ~[(outline-expr inner.e)]]
3173+ %list [%list at.e ~[%'~['] ~[%']'] & (turn items.e outline-expr)]
3174+ %tuple [%tuple at.e ~[%'['] ~[%']'] & (turn items.e outline-item)]
3175+ %ctor [%ctor at.e ~[%'|='] ~[%lit] | ~]
3176+ %crash [%crash at.e ~[%'!!'] ~[%'!!'] | ~]
3177+ ::
3178+ %qath
3179+ =/ ks=(list outline)
3180+ %+ murn segs.e
3181+ |=(s=qseg ?.(?=(%expr -.s) ~ `(outline-expr p.s)))
3182+ [%qath at.e ~[%'%/'] ~[%'%/' %knot %')'] | ks]
3183+ ::
3184+ %change
3185+ =/ ks=(list outline) (turn edits.e outline-edit)
3186+ [%change at.e ~[%name %wing] ~[%')'] & ks]
3187+ ::
3188+ %gate-wide
3189+ =/ ks=(list outline)
3190+ ~[(outline-sample sample.e) (outline-expr body.e)]
3191+ [%gate-wide at.e ~[%'|=('] ~[%')'] | ks]
3192+ ::
3193+ %call
3194+ [%call at.e ~ ~ | [(outline-expr head.e) (turn args.e outline-expr)]]
3195+ ::
3196+ %gate
3197+ =/ ks=(list outline)
3198+ ~[(outline-sample sample.e) (outline-expr body.e)]
3199+ [%gate at.e ~[%'|='] ~ | ks]
3200+ ::
3201+ %cast
3202+ =/ ks=(list outline) ~[(outline-shape shape.e) (outline-expr val.e)]
3203+ [%cast at.e ~[%'^-'] ~ | ks]
3204+ ::
3205+ %trace
3206+ =/ ks=(list outline) ~[(outline-expr val.e) (outline-expr then.e)]
3207+ [%trace at.e ~[%'~&'] ~ | ks]
3208+ ::
3209+ %branch
3210+ =/ ks=(list outline)
3211+ [(outline-expr subject.e) (turn arms.e outline-arm)]
3212+ [%branch at.e ~[%'?-'] ~ | ks]
3213+ ::
3214+ %body
3215+ =/ ks=(list outline)
3216+ (snoc (turn defs.e outline-def) (outline-expr final.e))
3217+ [%body at.e ~ ~ | ks]
3218+ ==
3219+::
3220+++ outline-str
3221+ |= [at=span ps=(list piece)]
3222+ ^- outline
3223+ =/ ks=(list outline)
3224+ (murn ps |=(p=piece ?.(?=(%expr -.p) ~ `(outline-expr p.p))))
3225+ ?~ ks [%str at ~[%str] ~[%str] | ~]
3226+ [%str at ~[%str-head] ~[%str-tail] | ks]
3227+::
3228+++ outline-item
3229+ |= i=item
3230+ ^- outline
3231+ ?~ face.i [%item at.i ~ ~ | ~[(outline-expr val.i)]]
3232+ [%face at.i ~[%name] ~ | ~[(outline-expr val.i)]]
3233+::
3234+++ outline-edit
3235+ |= e=edit
3236+ ^- outline
3237+ [%edit at.e ~[%name] ~ | ~[(outline-expr val.e)]]
3238+::
3239+++ outline-arm
3240+ |= a=arm
3241+ ^- outline
3242+ [%arm at.a ~ ~ | ~[(outline-pattern pat.a) (outline-expr val.a)]]
3243+::
3244+++ outline-sample
3245+ |= s=sample
3246+ ^- outline
3247+ ?- -.s
3248+ %bind [%bind at.s ~[%name] ~[%name] | ~]
3249+ %face [%face at.s ~[%name] ~ | ~[(outline-shape shape.s)]]
3250+ %pun [%pun at.s ~[%'='] ~[%name] | ~]
3251+ %cell [%cell at.s ~[%'['] ~[%']'] | (turn items.s outline-sample)]
3252+ %bare [%bare at.s ~ ~ | ~[(outline-shape shape.s)]]
3253+ ==
3254+::
3255+++ outline-pattern
3256+ |= p=pattern
3257+ ^- outline
3258+ ?- -.p
3259+ %lit [%lit at.p ~[%lit] ~[%lit] | ~]
3260+ %str [%str at.p ~[%str] ~[%str] | ~]
3261+ %any [%any at.p ~[%'*'] ~[%'*'] | ~]
3262+ %bind [%bind at.p ~[%name] ~[%name] | ~]
3263+ %cell [%cell at.p ~[%'['] ~[%']'] | (turn items.p outline-pattern)]
3264+ ==
3265+::
3266+++ outline-shape
3267+ |= s=shape
3268+ ^- outline
3269+ ?- -.s
3270+ %aura [%aura at.s ~[%aura] ~[%aura] | ~]
3271+ %noun [%noun at.s ~[%'*'] ~[%'*'] | ~]
3272+ %void [%void at.s ~[%'!!'] ~[%'!!'] | ~]
3273+ %flag [%flag at.s ~[%'?'] ~[%'?'] | ~]
3274+ %const [%const at.s ~[%lit] ~[%lit] | ~]
3275+ %ref [%ref at.s ~[%name %wing] ~[%name %wing] | ~]
3276+ %tvar [%tvar at.s ~[%tvar] ~[%tvar] | ~]
3277+ %apply [%apply at.s ~[%'('] ~[%')'] | (turn args.s outline-shape)]
3278+ %cell [%cell at.s ~[%'['] ~[%']'] | (turn fields.s outline-sample)]
3279+ ::
3280+ %path
3281+ =/ ks=(list outline)
3282+ %+ murn segs.s
3283+ |= g=pseg
3284+ ^- (unit outline)
3285+ ?. ?=(%typed -.g) ~
3286+ `[%typed at.g ~[%'['] ~[%']'] | ~]
3287+ [%path at.s ~[%'/'] ~[%'/' %knot %']'] & ks]
3288+ ::
3289+ %union
3290+ =/ ks=(list outline) (turn cases.s outline-shape)
3291+ [%union at.s ~[%'$?' %'$?('] ~[%')'] & ks]
3292+ ::
3293+ %fn
3294+ =/ ks=(list outline)
3295+ ~[(outline-shape sample.s) (outline-shape product.s)]
3296+ [%fn at.s ~[%'$-('] ~[%')'] | ks]
3297+ ::
3298+ %generic
3299+ [%generic at.s ~[%'|$'] ~ | ~[(outline-shape body.s)]]
3300+ ==
19503301--
tests/golden/doc-core-02-update/tree.txtnew file+77
@@ -0,0 +1,77 @@
1+(module
2+ (value 1:1 update
3+ (gate 1:11
4+ (cell 1:14
5+ (pun 1:15 msg)
6+ (face 1:20 m (ref 1:22 model)))
7+ (body 2:3
8+ (branch 2:3
9+ (wing 2:6 msg)
10+ (arm 3:5
11+ (cell 3:5 (lit 3:6 %typed) (bind 3:13 t))
12+ (body 4:7
13+ (branch 4:7
14+ (group 4:10
15+ (call 4:11
16+ (wing 4:11 gth)
17+ (group 4:15
18+ (call 4:16
19+ (wing 4:16 lent)
20+ (group 4:21
21+ (call 4:22
22+ (wing 4:22 tuba)
23+ (group 4:27
24+ (call 4:28 (wing 4:28 trip) (wing 4:33 t)))))))
25+ (lit 4:38 80)))
26+ (arm 5:9
27+ (lit 5:9 %.y)
28+ (tuple 5:14
29+ (change 5:15 m
30+ (edit 5:17 draft (wing 5:23 t))
31+ (edit 5:25 error
32+ (unit 5:31 (str 5:32 "Too long"))))
33+ (lit 5:44 ~)))
34+ (arm 6:9
35+ (lit 6:9 %.n)
36+ (tuple 6:14
37+ (change 6:15 m
38+ (edit 6:17 draft (wing 6:23 t))
39+ (edit 6:25 error (lit 6:31 ~)))
40+ (lit 6:34 ~))))))
41+ (arm 7:5
42+ (lit 7:5 %submit)
43+ (tuple 7:20
44+ (change 7:21 m
45+ (edit 7:23 draft (str 7:29 "")))
46+ (list 7:33
47+ (tuple 7:35
48+ (lit 7:36 %poke)
49+ (group 7:42
50+ (call 7:43
51+ (wing 7:43 todo-action.todo)
52+ (tuple 7:60 (lit 7:61 %add) (wing 7:66 draft.m))))
53+ (ctor 7:76 %acked)))))
54+ (arm 8:5
55+ (cell 8:5 (lit 8:6 %toggled) (bind 8:15 id))
56+ (tuple 8:20
57+ (wing 8:21 m)
58+ (list 8:23
59+ (tuple 8:25
60+ (lit 8:26 %poke)
61+ (group 8:32
62+ (call 8:33
63+ (wing 8:33 todo-action.todo)
64+ (tuple 8:50 (lit 8:51 %toggle) (wing 8:59 id))))
65+ (ctor 8:64 %acked)))))
66+ (arm 9:5
67+ (cell 9:5 (lit 9:6 %got) (bind 9:11 ts))
68+ (tuple 9:20
69+ (change 9:21 m
70+ (edit 9:23 todos (wing 9:29 ts)))
71+ (lit 9:33 ~)))
72+ (arm 10:5
73+ (cell 10:5 (lit 10:6 %acked) (bind 10:13 err))
74+ (tuple 10:20
75+ (change 10:21 m
76+ (edit 10:23 error (wing 10:29 err)))
77+ (lit 10:34 ~))))))))
tests/golden/doc-grammar-01-imports/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (sur 1:1 todo)
3+ (mark 2:1 %todo-action)
4+ (jibb 3:1 card /ui/components/card))
tests/golden/doc-grammar-02-buttons/tree.txtnew file+21
@@ -0,0 +1,21 @@
1+(module
2+ (value 2:1 add-button
3+ (gate 2:15
4+ (face 2:18 label (aura 2:24 @t))
5+ (body 3:3
6+ (call 3:3 (wing 3:3 button) (wing 3:10 label) (lit 3:16 %add)))))
7+ (value 4:1 labelled
8+ (gate 4:13
9+ (cell 4:16
10+ (face 4:17 label (aura 4:23 @t))
11+ (face 4:26 msg (tvar 4:30 M)))
12+ (body 5:3
13+ (call 5:3 (wing 5:3 button) (wing 5:10 label) (wing 5:16 msg)))))
14+ (value 6:1 wide
15+ (cast 6:10
16+ (apply 6:13 list (ref 6:19 attr))
17+ (body 7:3
18+ (list 7:3
19+ (pair 7:5 width
20+ (tuple 7:11 (lit 7:12 %fill) (lit 7:18 1)))
21+ (pair 7:21 pad (lit 7:25 %s2)))))))
tests/golden/doc-grammar-03-view-day/tree.txtnew file+20
@@ -0,0 +1,20 @@
1+(module
2+ (value 1:1 view
3+ (gate 1:9
4+ (cell 1:12
5+ (face 1:13 day (aura 1:17 @da))
6+ (face 1:21 n (aura 1:23 @ud)))
7+ (body 2:3
8+ (call 2:3
9+ (wing 2:3 column)
10+ (list 2:10
11+ (pair 2:12 gap (lit 2:16 %s1)))
12+ (list 2:21
13+ (group 3:5
14+ (call 3:6
15+ (wing 3:6 text)
16+ (str 3:11 "Updated " (wing 3:21 day))))
17+ (group 4:5
18+ (call 4:6
19+ (wing 4:6 text)
20+ (str 4:11 (wing 4:13 n) " items")))))))))
tests/golden/doc-grammar-04-step/tree.txtnew file+38
@@ -0,0 +1,38 @@
1+(module
2+ (mold 1:1 step
3+ (union 1:9
4+ (cell 2:3
5+ (const 2:4 %move)
6+ (const 2:10 %left)
7+ (face 2:16 n (aura 2:18 @ud)))
8+ (cell 3:3
9+ (const 3:4 %move)
10+ (const 3:10 %right)
11+ (face 3:17 n (aura 3:19 @ud)))
12+ (cell 4:3
13+ (face 4:4 text (aura 4:9 @t))
14+ (const 4:12 %draft))
15+ (cell 5:3
16+ (face 5:4 text (aura 5:9 @t))
17+ (const 5:12 %sent)
18+ (face 5:18 at (aura 5:21 @da)))
19+ (const 6:3 %stop)))
20+ (value 8:1 describe
21+ (gate 8:13
22+ (face 8:16 s (ref 8:18 step))
23+ (body 9:3
24+ (branch 9:3
25+ (wing 9:6 s)
26+ (arm 10:5
27+ (cell 10:5 (lit 10:6 %move) (lit 10:12 %left) (bind 10:18 n))
28+ (str 10:23 "left " (wing 10:30 n)))
29+ (arm 11:5
30+ (cell 11:5 (lit 11:6 %move) (lit 11:12 %right) (bind 11:19 n))
31+ (str 11:23 "right " (wing 11:31 n)))
32+ (arm 12:5
33+ (cell 12:5 (bind 12:6 t) (lit 12:8 %draft))
34+ (wing 12:23 t))
35+ (arm 13:5
36+ (cell 13:5 (bind 13:6 t) (lit 13:8 %sent) (bind 13:14 at))
37+ (wing 13:23 t))
38+ (arm 14:5 (lit 14:5 %stop) (str 14:23 "stop")))))))
tests/golden/doc-grammar-06-cart-store/tree.txtnew file+39
@@ -0,0 +1,39 @@
1+(module
2+ (mold 2:1 state
3+ (cell 2:10
4+ (face 2:11 items
5+ (apply 2:17 list (aura 2:23 @t)))
6+ (face 2:27 open (flag 2:32))))
7+ (mold 3:1 cart-action
8+ (union 3:16
9+ (cell 4:3
10+ (const 4:4 %add)
11+ (face 4:9 item (aura 4:14 @t)))
12+ (const 5:3 %toggle)))
13+ (mold 6:1 poke (ref 6:9 cart-action))
14+ (value 8:1 main
15+ (group 8:9
16+ (call 8:10 (wing 8:10 store) (wing 8:16 init) (wing 8:21 update))))
17+ (value 9:1 init
18+ (cast 9:9
19+ (ref 9:12 state)
20+ (tuple 9:18 (lit 9:19 ~) (lit 9:21 %.n))))
21+ (value 10:1 update
22+ (gate 10:11
23+ (cell 10:14
24+ (face 10:15 a (ref 10:17 cart-action))
25+ (face 10:29 s (ref 10:31 state)))
26+ (body 11:3
27+ (branch 11:3
28+ (wing 11:6 a)
29+ (arm 12:5
30+ (cell 12:5 (lit 12:6 %add) (bind 12:11 item))
31+ (change 12:18 s
32+ (edit 12:20 items
33+ (tuple 12:26 (wing 12:27 item) (wing 12:32 items.s)))))
34+ (arm 13:5
35+ (lit 13:5 %toggle)
36+ (change 13:18 s
37+ (edit 13:20 open
38+ (group 13:25
39+ (call 13:26 (wing 13:26 not) (wing 13:30 open.s)))))))))))
tests/golden/doc-grammar-07-basket/tree.txtnew file+103
@@ -0,0 +1,103 @@
1+(module
2+ (jibb 2:1 cart /ui/stores/cart)
3+ (value 4:1 main
4+ (group 4:9
5+ (call 4:10 (wing 4:10 program) (wing 4:18 init) (wing 4:23 update) (wing 4:30 view) (wing 4:35 subs))))
6+ (mold 6:1 model
7+ (cell 6:10
8+ (face 6:11 cart (ref 6:16 state.cart))
9+ (face 6:27 note (aura 6:32 @t))))
10+ (mold 7:1 msg
11+ (union 7:8
12+ (cell 8:3
13+ (const 8:4 %noted)
14+ (face 8:11 text (aura 8:16 @t)))
15+ (const 9:3 %add)
16+ (const 10:3 %toggle)
17+ (cell 11:3
18+ (const 11:4 %got)
19+ (face 11:9 cart (ref 11:14 state.cart)))
20+ (cell 12:3
21+ (const 12:4 %acked)
22+ (face 12:11 err
23+ (apply 12:15 unit (aura 12:21 @t))))))
24+ (value 14:1 init
25+ (gate 14:9
26+ (const 14:12 ~)
27+ (body 15:3
28+ (tuple 15:3
29+ (tuple 15:4 (lit 15:5 ~) (lit 15:7 %.n))
30+ (str 15:12 "")))))
31+ (value 17:1 update
32+ (gate 17:11
33+ (cell 17:14
34+ (pun 17:15 msg)
35+ (face 17:20 m (ref 17:22 model)))
36+ (body 18:3
37+ (branch 18:3
38+ (wing 18:6 msg)
39+ (arm 19:5
40+ (cell 19:5 (lit 19:6 %noted) (bind 19:13 t))
41+ (tuple 19:20
42+ (change 19:21 m
43+ (edit 19:23 note (wing 19:28 t)))
44+ (lit 19:31 ~)))
45+ (arm 20:5
46+ (lit 20:5 %add)
47+ (tuple 20:20
48+ (change 20:21 m
49+ (edit 20:23 note (str 20:28 "")))
50+ (list 20:32
51+ (tuple 20:34
52+ (lit 20:35 %poke)
53+ (group 20:41
54+ (call 20:42
55+ (wing 20:42 cart-action.cart)
56+ (tuple 20:59 (lit 20:60 %add) (wing 20:65 note.m))))
57+ (ctor 20:74 %acked)))))
58+ (arm 21:5
59+ (lit 21:5 %toggle)
60+ (tuple 21:20
61+ (wing 21:21 m)
62+ (list 21:23
63+ (tuple 21:25
64+ (lit 21:26 %poke)
65+ (group 21:32
66+ (call 21:33 (wing 21:33 cart-action.cart) (lit 21:50 %toggle)))
67+ (ctor 21:59 %acked)))))
68+ (arm 22:5
69+ (cell 22:5 (lit 22:6 %got) (bind 22:11 c))
70+ (tuple 22:20
71+ (change 22:21 m
72+ (edit 22:23 cart (wing 22:28 c)))
73+ (lit 22:31 ~)))
74+ (arm 23:5
75+ (cell 23:5 (lit 23:6 %acked) (bind 23:13 err))
76+ (tuple 23:20 (wing 23:21 m) (lit 23:23 ~)))))))
77+ (value 25:1 subs
78+ (gate 25:9
79+ (face 25:12 m (ref 25:14 model))
80+ (body 26:3
81+ (list 26:3
82+ (tuple 26:5
83+ (lit 26:6 %watch)
84+ (group 26:13
85+ (call 26:14 (wing 26:14 state.cart) (ctor 26:25 %got))))))))
86+ (value 28:1 view
87+ (gate 28:9
88+ (face 28:12 m (ref 28:14 model))
89+ (body 29:3
90+ (call 29:3
91+ (wing 29:3 column)
92+ (list 29:10
93+ (pair 29:12 gap (lit 29:16 %s1)))
94+ (list 29:21
95+ (group 30:5
96+ (call 30:6
97+ (wing 30:6 text)
98+ (str 30:11
99+ (group 30:13
100+ (call 30:14 (wing 30:14 lent) (wing 30:19 items.cart.m)))
101+ " items")))
102+ (call 31:5 (wing 31:5 field) (str 31:11 "Item") (wing 31:18 note.m) (ctor 31:25 %noted))
103+ (call 32:5 (wing 32:5 button) (str 32:12 "Add") (lit 32:18 %add))))))))
tests/golden/doc-overview-01-cmd-sub/tree.txtnew file+42
@@ -0,0 +1,42 @@
1+(module
2+ (mold 1:1 cmd
3+ (generic 1:8 M
4+ (union 1:15
5+ (cell 2:3
6+ (const 2:4 %poke)
7+ (face 2:10 p (ref 2:12 poke))
8+ (face 2:17 reply
9+ (fn 2:23
10+ (apply 2:26 unit (aura 2:32 @t))
11+ (tvar 2:36 M))))
12+ (cell 3:3
13+ (const 3:4 %go)
14+ (face 3:8 url (aura 3:12 @t)))
15+ (cell 4:3
16+ (const 4:4 %wait)
17+ (face 4:10 gap (aura 4:14 @dr))
18+ (face 4:18 msg (tvar 4:22 M)))
19+ (cell 5:3
20+ (const 5:4 %now)
21+ (face 5:9 reply
22+ (fn 5:15 (aura 5:18 @da) (tvar 5:22 M))))
23+ (cell 6:3
24+ (const 6:4 %who)
25+ (face 6:9 reply
26+ (fn 6:15 (aura 6:18 @p) (tvar 6:21 M)))))))
27+ (mold 7:1 sub
28+ (generic 7:8 M
29+ (union 7:15
30+ (cell 8:3
31+ (const 8:4 %watch)
32+ (face 8:11 a
33+ (apply 8:13 ask (tvar 8:18 M))))
34+ (cell 9:3
35+ (const 9:4 %every)
36+ (face 9:11 gap (aura 9:15 @dr))
37+ (face 9:19 reply
38+ (fn 9:25 (aura 9:28 @da) (tvar 9:32 M))))
39+ (cell 10:3
40+ (const 10:4 %url)
41+ (face 10:9 reply
42+ (fn 10:15 (ref 10:18 path) (tvar 10:23 M))))))))
tests/golden/doc-overview-02-theme/tree.txtnew file+32
@@ -0,0 +1,32 @@
1+(module
2+ (value 1:1 theme
3+ (cast 1:11
4+ (ref 1:14 theme)
5+ (body 2:3
6+ (tuple 2:3
7+ (face 2:5 space
8+ (tuple 2:11
9+ (face 2:12 s1 (str 2:15 "4px"))
10+ (face 2:21 s2 (str 2:24 "8px"))
11+ (face 2:30 s3 (str 2:33 "16px"))))
12+ (face 3:5 tones
13+ (tuple 3:11
14+ (face 3:12 normal (str 3:19 "#222"))
15+ (face 3:26 background (str 3:37 "#fff"))
16+ (face 3:44 accent (str 3:51 "#17734f"))
17+ (face 3:61 danger (str 3:68 "#b3261e"))
18+ (face 3:78 muted (str 3:84 "#5f5f5f"))))
19+ (face 4:5 wide (str 4:10 "60rem"))
20+ (face 5:5 lang (str 5:10 "en"))
21+ (face 6:5 zone (str 6:10 "UTC"))
22+ (face 7:5 font
23+ (unit 7:10 (qath 7:11 static fonts inter.woff2)))
24+ (face 8:5 dark
25+ (tuple 8:10
26+ (face 8:11 tones
27+ (tuple 8:17
28+ (face 8:18 normal (str 8:25 "#eee"))
29+ (face 8:32 background (str 8:43 "#111"))
30+ (face 8:50 accent (str 8:57 "#4c9"))
31+ (face 8:64 danger (str 8:71 "#f28b82"))
32+ (face 8:81 muted (str 8:87 "#aaa")))))))))))
tests/golden/doc-overview-04-todo-api/tree.txtnew file+16
@@ -0,0 +1,16 @@
1+(module
2+ (sur 2:1 todo)
3+ (mark 3:1 %todo-action)
4+ (mark 4:1 %todos)
5+ (mark 5:1 %todo-update)
6+ (mark 6:1 %todo-item)
7+ (mold 8:1 item (ref 8:9 item.todo))
8+ (mold 9:1 poke (ref 9:9 todo-action))
9+ (mold 10:1 paths
10+ (union 10:10
11+ (cell 11:3 (const 11:4 %todos) (path 11:11 /todos) (ref 11:18 todos))
12+ (cell 12:3
13+ (const 12:4 %changes)
14+ (path 12:13 /changes)
15+ (apply 12:22 facts (ref 12:29 todos) (ref 12:35 todo-update)))
16+ (cell 13:3 (const 13:4 %todo) (path 13:10 /todo/[id=@ud]) (ref 13:25 todo-item)))))
tests/golden/doc-overview-08-about/tree.txtnew file+24
@@ -0,0 +1,24 @@
1+(module
2+ (value 1:1 main (wing 1:9 view))
3+ (value 3:1 view
4+ (body 4:3
5+ (call 4:3
6+ (wing 4:3 column)
7+ (list 4:10
8+ (pair 4:12 width
9+ (tuple 4:18 (lit 4:19 %fill) (lit 4:25 1)))
10+ (pair 4:28 pad (lit 4:32 %s3))
11+ (pair 4:36 gap (lit 4:40 %s2)))
12+ (list 4:45
13+ (call 5:5 (wing 5:5 heading) (lit 5:13 1) (str 5:15 "About this ship"))
14+ (call 6:5
15+ (wing 6:5 para)
16+ (list 6:10
17+ (group 6:12
18+ (call 6:13 (wing 6:13 text) (str 6:18 "Hosted on Urbit. This page ships no JavaScript.")))))
19+ (call 7:5
20+ (wing 7:5 el)
21+ (list 7:8
22+ (pair 7:10 tone (lit 7:15 %accent)))
23+ (group 7:24
24+ (call 7:25 (wing 7:25 link) (qath 7:30 blog) (str 7:37 "Read the blog")))))))))
tests/golden/doc-overview-09-blog-index/tree.txtnew file+23
@@ -0,0 +1,23 @@
1+(module
2+ (sur 1:1 blog)
3+ (jibb 2:1 api /ui/api/blog)
4+ (jibb 3:1 card /ui/components/card)
5+ (value 5:1 main
6+ (group 5:9
7+ (call 5:10 (wing 5:10 page) (wing 5:15 load) (wing 5:20 view))))
8+ (value 6:1 load
9+ (gate-wide 6:9
10+ (const 6:12 ~)
11+ (group 6:14
12+ (call 6:15 (wing 6:15 posts.api) (wing 6:25 same)))))
13+ (value 8:1 view
14+ (gate 8:9
15+ (face 8:12 ps
16+ (apply 8:15 list (ref 8:21 post.blog)))
17+ (body 9:3
18+ (call 9:3
19+ (wing 9:3 column)
20+ (list 9:10
21+ (pair 9:12 gap (lit 9:16 %s2)))
22+ (group 9:21
23+ (call 9:22 (wing 9:22 turn) (wing 9:27 ps) (wing 9:30 card.card))))))))
tests/golden/doc-overview-10-todo-list/tree.txtnew file+168
@@ -0,0 +1,168 @@
1+(module
2+ (jibb 1:1 todo /ui/api/todo)
3+ (value 3:1 main
4+ (group 3:9
5+ (call 3:10 (wing 3:10 program) (wing 3:18 init) (wing 3:23 update) (wing 3:30 view) (wing 3:35 subs))))
6+ (mold 5:1 model
7+ (cell 5:10
8+ (face 5:11 todos
9+ (apply 5:17 list (ref 5:23 item.todo)))
10+ (face 5:34 draft (aura 5:40 @t))
11+ (face 5:43 error
12+ (apply 5:49 unit (aura 5:55 @t)))))
13+ (mold 6:1 msg
14+ (union 6:8
15+ (cell 7:3
16+ (const 7:4 %typed)
17+ (face 7:11 text (aura 7:16 @t)))
18+ (const 8:3 %submit)
19+ (cell 9:3
20+ (const 9:4 %toggled)
21+ (face 9:13 id (aura 9:16 @ud)))
22+ (cell 10:3
23+ (const 10:4 %got)
24+ (face 10:9 todos
25+ (apply 10:15 list (ref 10:21 item.todo))))
26+ (cell 11:3
27+ (const 11:4 %acked)
28+ (face 11:11 err
29+ (apply 11:15 unit (aura 11:21 @t))))))
30+ (value 13:1 init
31+ (gate 13:9
32+ (face 13:12 ts
33+ (apply 13:15 list (ref 13:21 item.todo)))
34+ (body 14:3
35+ (tuple 14:3 (wing 14:4 ts) (str 14:7 "") (lit 14:10 ~)))))
36+ (value 16:1 update
37+ (gate 16:11
38+ (cell 16:14
39+ (pun 16:15 msg)
40+ (face 16:20 m (ref 16:22 model)))
41+ (body 17:3
42+ (branch 17:3
43+ (wing 17:6 msg)
44+ (arm 18:5
45+ (cell 18:5 (lit 18:6 %typed) (bind 18:13 t))
46+ (body 19:7
47+ (branch 19:7
48+ (group 19:10
49+ (call 19:11
50+ (wing 19:11 gth)
51+ (group 19:15
52+ (call 19:16
53+ (wing 19:16 lent)
54+ (group 19:21
55+ (call 19:22
56+ (wing 19:22 tuba)
57+ (group 19:27
58+ (call 19:28 (wing 19:28 trip) (wing 19:33 t)))))))
59+ (lit 19:38 80)))
60+ (arm 20:9
61+ (lit 20:9 %.y)
62+ (tuple 20:14
63+ (change 20:15 m
64+ (edit 20:17 draft (wing 20:23 t))
65+ (edit 20:25 error
66+ (unit 20:31 (str 20:32 "Too long"))))
67+ (lit 20:44 ~)))
68+ (arm 21:9
69+ (lit 21:9 %.n)
70+ (tuple 21:14
71+ (change 21:15 m
72+ (edit 21:17 draft (wing 21:23 t))
73+ (edit 21:25 error (lit 21:31 ~)))
74+ (lit 21:34 ~))))))
75+ (arm 22:5
76+ (lit 22:5 %submit)
77+ (tuple 22:20
78+ (change 22:21 m
79+ (edit 22:23 draft (str 22:29 "")))
80+ (list 22:33
81+ (tuple 22:35
82+ (lit 22:36 %poke)
83+ (group 22:42
84+ (call 22:43
85+ (wing 22:43 todo-action.todo)
86+ (tuple 22:60 (lit 22:61 %add) (wing 22:66 draft.m))))
87+ (ctor 22:76 %acked)))))
88+ (arm 23:5
89+ (cell 23:5 (lit 23:6 %toggled) (bind 23:15 id))
90+ (tuple 23:20
91+ (wing 23:21 m)
92+ (list 23:23
93+ (tuple 23:25
94+ (lit 23:26 %poke)
95+ (group 23:32
96+ (call 23:33
97+ (wing 23:33 todo-action.todo)
98+ (tuple 23:50 (lit 23:51 %toggle) (wing 23:59 id))))
99+ (ctor 23:64 %acked)))))
100+ (arm 24:5
101+ (cell 24:5 (lit 24:6 %got) (bind 24:11 ts))
102+ (tuple 24:20
103+ (change 24:21 m
104+ (edit 24:23 todos (wing 24:29 ts)))
105+ (lit 24:33 ~)))
106+ (arm 25:5
107+ (cell 25:5 (lit 25:6 %acked) (bind 25:13 err))
108+ (tuple 25:20
109+ (change 25:21 m
110+ (edit 25:23 error (wing 25:29 err)))
111+ (lit 25:34 ~)))))))
112+ (value 27:1 subs
113+ (gate 27:9
114+ (face 27:12 m (ref 27:14 model))
115+ (body 28:3
116+ (list 28:3
117+ (tuple 28:5
118+ (lit 28:6 %watch)
119+ (group 28:13
120+ (call 28:14 (wing 28:14 todos.todo) (ctor 28:25 %got))))))))
121+ (value 30:1 view
122+ (gate 30:9
123+ (face 30:12 m (ref 30:14 model))
124+ (body 31:3
125+ (call 31:3
126+ (wing 31:3 column)
127+ (list 31:10
128+ (pair 31:12 gap (lit 31:16 %s2)))
129+ (list 31:21
130+ (call 32:5 (wing 32:5 heading) (lit 32:13 2) (str 32:15 "Todos"))
131+ (call 33:5
132+ (wing 33:5 each)
133+ (group 33:10
134+ (call 33:11 (wing 33:11 turn) (wing 33:16 todos.m) (wing 33:24 row-of))))
135+ (call 34:5
136+ (wing 34:5 row)
137+ (list 34:9
138+ (pair 34:11 gap (lit 34:15 %s1)))
139+ (list 34:20
140+ (call 35:7
141+ (wing 35:7 el)
142+ (list 35:10
143+ (pair 35:12 width
144+ (tuple 35:18 (lit 35:19 %fill) (lit 35:25 1))))
145+ (group 35:29
146+ (call 35:30 (wing 35:30 field) (str 35:36 "New todo") (wing 35:47 draft.m) (ctor 35:55 %typed))))
147+ (call 36:7 (wing 36:7 button) (str 36:14 "Add") (lit 36:20 %submit))))
148+ (call 37:5
149+ (wing 37:5 el)
150+ (list 37:8
151+ (pair 37:10 tone (lit 37:15 %danger)))
152+ (group 37:24
153+ (call 37:25
154+ (wing 37:25 text)
155+ (group 37:30
156+ (call 37:31 (wing 37:31 fall) (wing 37:36 error.m) (str 37:44 "")))))))))))
157+ (value 39:1 row-of
158+ (gate 39:11
159+ (face 39:14 t (ref 39:16 item.todo))
160+ (body 40:3
161+ (tuple 40:3
162+ (wing 40:4 id.t)
163+ (group 40:9
164+ (call 40:10
165+ (wing 40:10 toggle)
166+ (wing 40:17 done.t)
167+ (wing 40:24 text.t)
168+ (tuple 40:31 (lit 40:32 %toggled) (wing 40:41 id.t)))))))))
tests/golden/doc-overview-11-index/tree.txtnew file+23
@@ -0,0 +1,23 @@
1+(module
2+ (jibb 1:1 todo /ui/api/todo)
3+ (jibb 2:1 todo-list /ui/todo-list)
4+ (value 4:1 main
5+ (group 4:9
6+ (call 4:10 (wing 4:10 page) (wing 4:15 load) (wing 4:20 view))))
7+ (value 5:1 load
8+ (gate-wide 5:9
9+ (const 5:12 ~)
10+ (group 5:14
11+ (call 5:15 (wing 5:15 todos.todo) (wing 5:26 same)))))
12+ (value 7:1 view
13+ (gate 7:9
14+ (face 7:12 ts
15+ (apply 7:15 list (ref 7:21 item.todo)))
16+ (body 8:3
17+ (call 8:3
18+ (wing 8:3 column)
19+ (list 8:10
20+ (pair 8:12 pad (lit 8:16 %s3)))
21+ (list 8:21
22+ (call 9:5 (wing 9:5 heading) (lit 9:13 1) (str 9:15 "My ship"))
23+ (call 10:5 (wing 10:5 island) (wing 10:12 main.todo-list) (wing 10:27 ts))))))))
tests/golden/inline-base32/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 0v5.fdf99)))
tests/golden/inline-call/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6 (wing 1:6 f) (wing 1:8 a) (wing 1:10 b))))
tests/golden/inline-cell/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (tuple 1:6 (wing 1:7 a) (wing 1:9 b) (wing 1:11 c)))
4+ (value 2:1 y
5+ (tuple 2:6
6+ (face 2:7 text (str 2:12 "milk"))
7+ (face 2:19 done (lit 2:24 %.n)))))
tests/golden/inline-change-done/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 x
3+ (change 1:6 m
4+ (edit 1:8 done (lit 1:13 %.y)))))
tests/golden/inline-change-draft/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (change 1:6 m
4+ (edit 1:8 draft (str 1:14 "x"))
5+ (edit 1:18 error (lit 1:24 ~)))))
tests/golden/inline-crash/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (crash 1:6))
3+ (mold 2:1 y (void 2:6)))
tests/golden/inline-ctor-typed/tree.txtnew file+10
@@ -0,0 +1,10 @@
1+(module
2+ (value 1:1 a (ctor 1:6 %typed))
3+ (mold 2:1 b
4+ (fn 2:6 (aura 2:9 @t) (tvar 2:12 M)))
5+ (value 3:1 c
6+ (gate-wide 3:6
7+ (bind 3:9 t)
8+ (tuple 3:11 (lit 3:12 %typed) (wing 3:19 t))))
9+ (mold 4:1 d
10+ (cell 4:6 (const 4:7 %typed) (aura 4:14 @t))))
tests/golden/inline-date/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (lit 1:6 ~2026.10.23))
3+ (value 2:1 y (lit 2:6 ~2026.10.23..14.30.00)))
tests/golden/inline-decimal/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 1.000)))
tests/golden/inline-duration/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (lit 1:6 ~s30))
3+ (value 2:1 y (lit 2:6 ~h1.m30)))
tests/golden/inline-fold-mold/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (mold 1:1 fold
3+ (fn 1:9
4+ (cell 1:12
5+ (cell 1:13 (const 1:14 %todo-update) (ref 1:27 todo-update))
6+ (ref 1:40 todos))
7+ (ref 1:47 todos))))
tests/golden/inline-gate-mold/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (fn 1:6 (ref 1:9 sample) (ref 1:16 product))))
tests/golden/inline-gate-samples/tree.txtnew file+13
@@ -0,0 +1,13 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 m (ref 1:11 model))
5+ (wing 1:17 m)))
6+ (value 2:1 g
7+ (gate 2:6 (pun 2:9 msg) (wing 2:14 msg)))
8+ (value 3:1 h
9+ (gate 3:6
10+ (cell 3:9
11+ (face 3:10 a (aura 3:12 @))
12+ (face 3:14 b (aura 3:16 @)))
13+ (body 4:3 (wing 4:3 a)))))
tests/golden/inline-gate-wide/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (gate-wide 1:6
4+ (face 1:9 p (ref 1:11 post.blog))
5+ (wing 1:21 title.p)))
6+ (value 2:1 y
7+ (gate-wide 2:6 (bind 2:9 p) (wing 2:11 title.p))))
tests/golden/inline-generic-mold/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (generic 1:6 A (ref 1:13 mold))))
tests/golden/inline-hex/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 0x1f)))
tests/golden/inline-import-mark-face-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-import-mark-face-bad/source.jibb:1:5: expected a mark's term, as `%todo-action`, found `act`; `/%` takes no face: it names the type after its mark
2+/% act %todo-action
3+ ^
tests/golden/inline-imports-after-definition/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-imports-after-definition/source.jibb:2:1: expected a definition, found `/-`; imports come first
2+/- todo
3+^
tests/golden/inline-island/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6 (wing 1:6 island) (wing 1:13 main.todo-list) (wing 1:28 ts))))
tests/golden/inline-kinds/tree.txtnew file+18
@@ -0,0 +1,18 @@
1+(module
2+ (mold 1:1 a
3+ (apply 1:6 element (void 1:15)))
4+ (mold 2:1 b
5+ (apply 2:6 page (tvar 2:12 R) (tvar 2:14 D)))
6+ (mold 3:1 c
7+ (apply 3:6 program (tvar 3:15 D) (tvar 3:17 X) (tvar 3:19 M)))
8+ (mold 4:1 d
9+ (apply 4:6 store (tvar 4:13 S)))
10+ (value 5:1 e
11+ (group 5:6
12+ (call 5:7 (wing 5:7 page) (wing 5:12 load) (wing 5:17 view))))
13+ (value 6:1 f
14+ (group 6:6
15+ (call 6:7 (wing 6:7 program) (wing 6:15 init) (wing 6:20 update) (wing 6:27 view) (wing 6:32 subs))))
16+ (value 7:1 g
17+ (group 7:6
18+ (call 7:7 (wing 7:7 store) (wing 7:13 init) (wing 7:18 update)))))
tests/golden/inline-knot/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 ~.my-post)))
tests/golden/inline-leftout-barcab/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-barcab/source.jibb:1:7: `|_` is left out: modules are records
2+++ x |_ s=@
3+ ^
tests/golden/inline-leftout-barcen/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-barcen/source.jibb:1:7: `|%` is left out: modules are records
2+++ x |%
3+ ^
tests/golden/inline-leftout-barhep/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-barhep/source.jibb:1:7: `|-` is left out: gates recurse by name
2+++ x |- 1
3+ ^
tests/golden/inline-leftout-bartar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-bartar/source.jibb:1:7: `|*` is left out: modules are records
2+++ x |* a=* a
3+ ^
tests/golden/inline-leftout-buc-paren/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-buc-paren/source.jibb:1:6: `$(…)` is left out: gates recurse by name
2+++ x $(n 1)
3+ ^
tests/golden/inline-leftout-buccen/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-buccen/source.jibb:1:7: `$%` is left out: `$?` covers unions
2++$ x $%
3+ ^
tests/golden/inline-leftout-cencol/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-cencol/source.jibb:1:7: `%:` is left out: indentation covers it
2+++ x %: f a b
3+ ^
tests/golden/inline-leftout-centis/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-centis/source.jibb:1:7: `%=` is left out: indentation covers it; write a change, as m(a=b)
2+++ x %= m note 1
3+ ^
tests/golden/inline-leftout-colon-wing/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-colon-wing/source.jibb:1:8: `a:b` is left out: names never shadow, and `.` reads imports too; write a.b
2+++ x a:b
3+ ^
tests/golden/inline-leftout-colsig/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-colsig/source.jibb:1:7: `:~` is left out: indentation covers it; write ~[…]
2+++ x :~ 1 2
3+ ^
tests/golden/inline-leftout-coltar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-coltar/source.jibb:1:7: `:*` is left out: indentation covers it; write […]
2+++ x :* 1 2
3+ ^
tests/golden/inline-leftout-dottar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-dottar/source.jibb:1:6: `.*` is left out: names never shadow, and `.` reads imports too
2+++ x .* a b
3+ ^
tests/golden/inline-leftout-dottis/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-dottis/source.jibb:1:6: `.=` is left out: eq and not are gates
2+++ x .= a b
3+ ^
tests/golden/inline-leftout-faslus/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-faslus/source.jibb:1:2: `/+` is left out: code also runs in the browser
2+/+ foo
3+ ^
tests/golden/inline-leftout-hephep/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-hephep/source.jibb:2:1: the closer `--` is left out: indentation covers it
2+--
3+^
tests/golden/inline-leftout-kethep-wide/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-kethep-wide/source.jibb:1:8: expected a space after `^-`, found `(`; the wide form `^-(…)` is left out: indentation covers it
2+++ x ^-(@ud 5)
3+ ^
tests/golden/inline-leftout-kettar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-kettar/source.jibb:1:6: expected an expression, found `*`; `*mold` is left out: no defaults
2+++ x *@ud
3+ ^
tests/golden/inline-leftout-sail/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-sail/source.jibb:1:6: Sail's `;` runes are left out: layout is Jibb's elements
2+++ x ;p: hello
3+ ^
tests/golden/inline-leftout-sigbar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-sigbar/source.jibb:1:7: `~|` is left out: `~&` covers debugging
2+++ x ~| %oops 1
3+ ^
tests/golden/inline-leftout-signed-float-auras/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-signed-float-auras/source.jibb:1:7: signed and floating-point auras are left out of Jibb
2++$ a @sd
3+ ^
tests/golden/inline-leftout-tis-paren/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-tis-paren/source.jibb:1:6: expected an expression, found `=`; `=(a b)` is left out: eq is a gate
2+++ x =(a b)
3+ ^
tests/golden/inline-leftout-tisfas/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-tisfas/source.jibb:2:3: expected an expression, found `=`; `=/` is left out: `++` defines values
2+ =/ m (add n 1)
3+ ^
tests/golden/inline-leftout-tisgal/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-tisgal/source.jibb:1:6: `=<` is left out: names never shadow, and `.` reads imports too
2+++ x =< a b
3+ ^
tests/golden/inline-leftout-tisgar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-tisgar/source.jibb:1:6: `=>` is left out: names never shadow, and `.` reads imports too
2+++ x => a b
3+ ^
tests/golden/inline-leftout-tistis/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-tistis/source.jibb:4:1: the closer `==` is left out: indentation covers it
2+==
3+^
tests/golden/inline-leftout-wutcol/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-wutcol/source.jibb:2:4: `?:` is left out: `?-` is the branch
2+ ?: b 1 2
3+ ^
tests/golden/inline-leftout-wuthep-wide/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-wuthep-wide/source.jibb:1:8: expected a space after `?-`, found `(`; the wide form `?-(…)` is left out: indentation covers it
2+++ x ?-(b %.y 1 %.n 2)
3+ ^
tests/golden/inline-leftout-wutlus/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-wutlus/source.jibb:2:4: `?+` is left out: `?-` is the branch
2+ ?+ n ~
3+ ^
tests/golden/inline-leftout-wutzap/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-wutzap/source.jibb:1:7: `?!` is left out: eq and not are gates
2+++ x ?! %.y
3+ ^
tests/golden/inline-leftout-zap-not/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-zap-not/source.jibb:1:7: `!` begins only `!!`: `!x` is left out, as not is a gate
2+++ x !x
3+ ^
tests/golden/inline-leftout-zapgar/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-leftout-zapgar/source.jibb:1:7: `!>` is left out: code also runs in the browser
2+++ x !>(5)
3+ ^
tests/golden/inline-list-parens/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (list 1:6
4+ (group 1:8
5+ (call 1:9 (wing 1:9 text) (str 1:14 "hi")))))
6+ (value 2:1 y
7+ (list 2:6 (wing 2:8 text) (str 2:13 "hi"))))
tests/golden/inline-list/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (list 1:6 (lit 1:8 1) (lit 1:10 2) (lit 1:12 3)))
4+ (value 2:1 y
5+ (list 2:6 (wing 2:8 a) (wing 2:10 b) (wing 2:12 c))))
tests/golden/inline-literal-defaults/tree.txtnew file+6
@@ -0,0 +1,6 @@
1+(module
2+ (value 1:1 a (lit 1:6 %a))
3+ (value 2:1 b (lit 2:6 ~))
4+ (value 3:1 c (lit 3:6 5))
5+ (value 4:1 d
6+ (tuple 4:6 (wing 4:7 x) (wing 4:9 xs))))
tests/golden/inline-load-slug/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 load
3+ (gate-wide 1:9
4+ (cell 1:12
5+ (face 1:13 slug (aura 1:18 @ta)))
6+ (group 1:23
7+ (call 1:24 (wing 1:24 post.api) (wing 1:33 slug) (wing 1:38 same))))))
tests/golden/inline-local-names/tree.txtnew file+15
@@ -0,0 +1,15 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 n (aura 1:11 @ud))
5+ (body 2:3
6+ (value 2:3 m
7+ (group 2:8
8+ (call 2:9 (wing 2:9 add) (wing 2:13 n) (lit 2:15 1))))
9+ (mold 3:3 pair
10+ (cell 3:11
11+ (face 3:12 a (aura 3:14 @ud))
12+ (face 3:18 b (aura 3:20 @ud))))
13+ (cast 4:3
14+ (ref 4:6 pair)
15+ (tuple 4:11 (wing 4:12 n) (wing 4:14 m)))))))
tests/golden/inline-loobean/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (lit 1:6 %.y))
3+ (value 2:1 y (lit 2:6 %.n)))
tests/golden/inline-mark-digit/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (mark 1:1 %todo-action-1))
tests/golden/inline-module-definitions/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 name (ref 1:9 mold))
3+ (value 2:1 name (wing 2:9 expr)))
tests/golden/inline-mold-add/tree.txtnew file+8
@@ -0,0 +1,8 @@
1+(module
2+ (mold 1:1 x
3+ (cell 1:6 (aura 1:7 @) (aura 1:9 @)))
4+ (value 2:1 y
5+ (gate 2:6
6+ (face 2:9 n (aura 2:11 @ud))
7+ (group 2:15
8+ (call 2:16 (wing 2:16 add) (wing 2:20 n) (lit 2:22 1))))))
tests/golden/inline-mold-any-empty/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 a (noun 1:6))
3+ (mold 2:1 b (void 2:6)))
tests/golden/inline-mold-atoms/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (mold 1:1 a (aura 1:6 @))
3+ (mold 2:1 b (aura 2:6 @ud))
4+ (mold 3:1 c (aura 3:6 @t))
5+ (mold 4:1 d (aura 4:6 @p))
6+ (mold 5:1 e (aura 5:6 @da))
7+ (mold 6:1 f (flag 6:6))
8+ (mold 7:1 g (aura 7:6 @tas))
9+ (mold 8:1 h (aura 8:6 @ta)))
tests/golden/inline-mold-constants/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (mold 1:1 a (const 1:6 %add))
3+ (mold 2:1 b (const 2:6 ~))
4+ (mold 3:1 c (const 3:6 %.y))
5+ (mold 4:1 d (const 4:6 %.n)))
tests/golden/inline-mold-containers/tree.txtnew file+17
@@ -0,0 +1,17 @@
1+(module
2+ (mold 1:1 a
3+ (apply 1:6 list (tvar 1:12 A)))
4+ (mold 2:1 b
5+ (apply 2:6 unit (tvar 2:12 A)))
6+ (mold 3:1 c
7+ (apply 3:6 set (tvar 3:11 A)))
8+ (mold 4:1 d
9+ (apply 4:6 map (tvar 4:11 K) (tvar 4:13 V)))
10+ (mold 5:1 e
11+ (apply 5:6 mop (tvar 5:11 K) (tvar 5:13 V)))
12+ (mold 6:1 f
13+ (apply 6:6 qeu (tvar 6:11 A)))
14+ (mold 7:1 g
15+ (apply 7:6 jar (tvar 7:11 K) (tvar 7:13 V)))
16+ (mold 8:1 h
17+ (apply 8:6 jug (tvar 8:11 K) (tvar 8:13 V))))
tests/golden/inline-mold-gate/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (fn 1:6 (tvar 1:9 A) (tvar 1:11 B))))
tests/golden/inline-mold-generic/tree.txtnew file+10
@@ -0,0 +1,10 @@
1+(module
2+ (mold 1:1 result
3+ (generic 1:11 V E
4+ (union 1:20
5+ (cell 2:3
6+ (const 2:4 %ok)
7+ (face 2:8 value (tvar 2:14 V)))
8+ (cell 3:3
9+ (const 3:4 %err)
10+ (face 3:9 error (tvar 3:15 E)))))))
tests/golden/inline-mold-opaque/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (mold 1:1 a (ref 1:6 poke))
3+ (mold 2:1 b (ref 2:6 ask))
4+ (mold 3:1 c (ref 3:6 qath)))
tests/golden/inline-mold-paths/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (mold 1:1 a (path 1:6 /todos))
3+ (mold 2:1 b (path 2:6 /))
4+ (mold 3:1 c (path 3:6 /todo/[id=@ud])))
tests/golden/inline-mold-records/tree.txtnew file+15
@@ -0,0 +1,15 @@
1+(module
2+ (mold 1:1 a
3+ (cell 1:6
4+ (face 1:7 text (aura 1:12 @t))
5+ (face 1:15 done (flag 1:20))))
6+ (mold 2:1 b
7+ (cell 2:6 (aura 2:7 @t) (flag 2:10)))
8+ (mold 3:1 c
9+ (cell 3:6
10+ (face 3:7 a (aura 3:9 @))
11+ (face 3:11 b (aura 3:13 @))))
12+ (mold 4:1 d
13+ (cell 4:6
14+ (face 4:7 x (aura 4:9 @))
15+ (face 4:11 y (aura 4:13 @)))))
tests/golden/inline-namespaces/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (mold 1:1 a (ref 1:6 todo-action.todo))
3+ (value 2:1 b (wing 2:6 todo-action.todo))
4+ (mold 3:1 c (ref 3:6 todos.todo))
5+ (value 4:1 d (wing 4:6 todos.todo)))
tests/golden/inline-no-operators/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6 (wing 1:6 eq) (wing 1:9 a) (wing 1:11 b)))
4+ (value 2:1 y
5+ (call 2:6 (wing 2:6 not) (wing 2:10 x)))
6+ (value 3:1 z
7+ (call 3:6 (wing 3:6 gth) (wing 3:10 a) (wing 3:12 b))))
tests/golden/inline-no-subs/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 subs
3+ (gate-wide 1:9 (bind 1:12 m) (lit 1:14 ~))))
tests/golden/inline-null/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 ~)))
tests/golden/inline-pair/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x
3+ (pair 1:6 gap (lit 1:10 %s2))))
tests/golden/inline-pairs-two-items/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (list 1:6
4+ (pair 1:8 pad (lit 1:12 %s3))
5+ (pair 1:16 gap (lit 1:20 %s2)))))
tests/golden/inline-path/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (path 1:6 /posts/~zod)))
tests/golden/inline-pattern-any/tree.txtnew file+8
@@ -0,0 +1,8 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5 (any 3:5) (lit 3:8 ~)))))))
tests/golden/inline-pattern-cell/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5
9+ (cell 3:5 (bind 3:6 a) (bind 3:8 b))
10+ (wing 3:12 b))
11+ (arm 4:5 (any 4:5) (lit 4:12 ~)))))))
tests/golden/inline-pattern-crash-arm/tree.txtnew file+10
@@ -0,0 +1,10 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s
5+ (union 1:11 (const 1:14 %go) (const 1:18 %stop)))
6+ (body 2:3
7+ (branch 2:3
8+ (wing 2:6 s)
9+ (arm 3:5 (lit 3:5 %go) (lit 3:12 1))
10+ (arm 4:5 (lit 4:5 %stop) (crash 4:12)))))))
tests/golden/inline-pattern-date-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-pattern-date-bad/source.jibb:3:6: expected a pattern, found `~2026.10.23`; patterns take no dates: compare values with ?- (eq a b)
2+ ~2026.10.23 1
3+ ^
tests/golden/inline-pattern-eq/tree.txtnew file+12
@@ -0,0 +1,12 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (cell 1:9
5+ (face 1:10 a (aura 1:12 @))
6+ (face 1:14 b (aura 1:16 @)))
7+ (body 2:3
8+ (branch 2:3
9+ (group 2:6
10+ (call 2:7 (wing 2:7 eq) (wing 2:10 a) (wing 2:12 b)))
11+ (arm 3:5 (lit 3:5 %.y) (str 3:10 "equal"))
12+ (arm 4:5 (lit 4:5 %.n) (str 4:10 "different")))))))
tests/golden/inline-pattern-head-tag/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5
9+ (cell 3:5 (lit 3:6 %add) (bind 3:11 t))
10+ (wing 3:15 t))
11+ (arm 4:5 (any 4:5) (lit 4:15 ~)))))))
tests/golden/inline-pattern-interpolated-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-pattern-interpolated-bad/source.jibb:3:7: expected a pattern, found a string with `{…}`; patterns take strings without `{…}`
2+ "a{b}" 1
3+ ^
tests/golden/inline-pattern-list-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-pattern-list-bad/source.jibb:3:6: expected a pattern, found `~[`; patterns take no lists
2+ ~[a] 1
3+ ^
tests/golden/inline-pattern-literals/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5 (lit 3:5 1.000) (lit 3:13 %number))
9+ (arm 4:5 (str 4:5 "milk") (lit 4:13 %string))
10+ (arm 5:5 (lit 5:5 ~zod) (lit 5:13 %ship))
11+ (arm 6:5 (any 6:5) (lit 6:13 %other)))))))
tests/golden/inline-pattern-loobean/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 b (flag 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 b)
8+ (arm 3:5 (lit 3:5 %.y) (lit 3:10 1))
9+ (arm 4:5 (lit 4:5 %.n) (lit 4:10 2)))))))
tests/golden/inline-pattern-move-any/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5
9+ (cell 3:5 (lit 3:6 %move) (any 3:12) (any 3:14))
10+ (lit 3:18 1))
11+ (arm 4:5 (any 4:5) (lit 4:18 2)))))))
tests/golden/inline-pattern-name/tree.txtnew file+8
@@ -0,0 +1,8 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5 (bind 3:5 x) (wing 3:8 x)))))))
tests/golden/inline-pattern-null/tree.txtnew file+10
@@ -0,0 +1,10 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 u
5+ (apply 1:11 unit (aura 1:17 @t)))
6+ (body 2:3
7+ (branch 2:3
8+ (wing 2:6 u)
9+ (arm 3:5 (lit 3:5 ~) (str 3:8 ""))
10+ (arm 4:5 (any 4:5) (str 4:8 "something")))))))
tests/golden/inline-pattern-pair-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-pattern-pair-bad/source.jibb:3:8: expected a space after the pattern, found `+`; patterns take no pairs: write a cell, as [%gap %s2]
2+ gap+%s2 1
3+ ^
tests/golden/inline-pattern-tail-tag/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5
9+ (cell 3:5 (bind 3:6 t) (lit 3:8 %draft))
10+ (wing 3:17 t))
11+ (arm 4:5 (any 4:5) (lit 4:17 ~)))))))
tests/golden/inline-pattern-term/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5 (lit 3:5 %add) (lit 3:11 1))
9+ (arm 4:5 (any 4:5) (lit 4:11 2)))))))
tests/golden/inline-pattern-two-tags/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 s (noun 1:11))
5+ (body 2:3
6+ (branch 2:3
7+ (wing 2:6 s)
8+ (arm 3:5
9+ (cell 3:5 (lit 3:6 %move) (lit 3:12 %left) (bind 3:18 n))
10+ (wing 3:22 n))
11+ (arm 4:5 (any 4:5) (lit 4:22 ~)))))))
tests/golden/inline-pattern-unit/tree.txtnew file+12
@@ -0,0 +1,12 @@
1+(module
2+ (value 1:1 f
3+ (gate 1:6
4+ (face 1:9 u
5+ (apply 1:11 unit (aura 1:17 @t)))
6+ (body 2:3
7+ (branch 2:3
8+ (wing 2:6 u)
9+ (arm 3:5
10+ (cell 3:5 (lit 3:6 ~) (bind 3:8 x))
11+ (wing 3:12 x))
12+ (arm 4:5 (any 4:5) (str 4:12 "")))))))
tests/golden/inline-qath/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 x (qath 1:6 blog))
3+ (value 2:1 y
4+ (qath 2:6 blog (wing 2:14 slug))))
tests/golden/inline-requests/tree.txtnew file+12
@@ -0,0 +1,12 @@
1+(module
2+ (value 1:1 a
3+ (group 1:6
4+ (call 1:7
5+ (wing 1:7 todo-action.todo)
6+ (tuple 1:24 (lit 1:25 %add) (wing 1:30 draft.m)))))
7+ (value 2:1 b
8+ (group 2:6
9+ (call 2:7 (wing 2:7 todos.todo) (ctor 2:18 %got))))
10+ (value 3:1 c
11+ (group 3:6
12+ (call 3:7 (wing 3:7 changes.todo) (ctor 3:20 %got) (wing 3:27 apply)))))
tests/golden/inline-scry-case/tree.txtnew file+8
@@ -0,0 +1,8 @@
1+(module
2+ (mold 1:1 paths
3+ (union 1:10
4+ (cell 2:3
5+ (const 2:4 %changes)
6+ (path 2:13 /updates)
7+ (apply 2:22 facts (ref 2:29 todos) (ref 2:35 todo-update))
8+ (face 2:48 scry (path 2:53 /todos))))))
tests/golden/inline-self-reference/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 title
3+ (group 1:10
4+ (call 1:11 (wing 1:11 trim) (wing 1:16 title)))))
tests/golden/inline-ship/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (lit 1:6 ~zod))
3+ (value 2:1 y (lit 2:6 ~sampel-palnet)))
tests/golden/inline-static-image/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 logo
3+ (group 1:9
4+ (call 1:10 (wing 1:10 image) (qath 1:16 static img logo.png) (str 1:38 "The logo")))))
tests/golden/inline-string/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 x (str 1:6 "milk"))
3+ (value 2:1 y
4+ (str 2:6 "Since " (wing 2:14 day))))
tests/golden/inline-tag-shape/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (cell 1:6 (aura 1:7 @t) (const 1:10 %draft))))
tests/golden/inline-term/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (lit 1:6 %add)))
tests/golden/inline-text-items/tree.txtnew file+6
@@ -0,0 +1,6 @@
1+(module
2+ (value 1:1 x
3+ (group 1:6
4+ (call 1:7
5+ (wing 1:7 text)
6+ (str 1:12 (wing 1:14 n) " items")))))
tests/golden/inline-union-wide/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (union 1:6 (const 1:9 %a) (const 1:12 %b))))
tests/golden/inline-unit/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x
3+ (unit 1:6 (wing 1:7 x))))
tests/golden/inline-wide-form-rune-bad/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/inline-wide-form-rune-bad/source.jibb:1:11: expected an expression, found `^-`; the wide gate's body is an operand, so a rune goes in parentheses
2+++ x |=(n ^- @ud n)
3+ ^
tests/golden/inline-wide-forms/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (gate-wide 1:6 (bind 1:9 sample) (wing 1:16 expr)))
4+ (mold 2:1 y
5+ (union 2:6 (ref 2:9 case) (ref 2:14 case)))
6+ (mold 3:1 z
7+ (fn 3:6 (ref 3:9 mold) (ref 3:14 mold))))
tests/golden/inline-wide-union-call/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (mold 1:1 x
3+ (union 1:6 (const 1:9 %a) (ref 1:12 list) (aura 1:17 @t))))
tests/golden/inline-wings/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (wing 1:6 title.p))
3+ (value 2:1 b (wing 2:6 card.card))
4+ (value 3:1 c (wing 3:6 space.theme.theme))
5+ (value 4:1 d (wing 4:6 get.by)))
tests/golden/lex-base32-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-base32-bad-1/source.jibb:1:13: a base-32 number is 0v and digits 0-9 and a-v, in groups of five joined by dots, as 0v5.fdf99
2+++ x 0v5.fdfz9
3+ ^
tests/golden/lex-base32-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (lit 1:6 0v0))
3+ (value 2:1 b (lit 2:6 0vv))
4+ (value 3:1 c (lit 3:6 0v5.fdf99))
5+ (value 4:1 d (lit 4:6 0v1.00000)))
tests/golden/lex-call-open-bad-1/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x
3+ (group 1:6
4+ (call 1:7
5+ (wing 1:7 f)
6+ (wing 1:9 a)
7+ (call 2:3 (wing 2:3 b) (wing 2:5 c))))))
tests/golden/lex-call-open-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-call-open-bad-2/source.jibb:3:5: expected the end of the line, found a deeper line; only a bracket open at the end of a line, or a rune's body, takes deeper lines
2+ c
3+ ^
tests/golden/lex-call-open-bad-3/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 x
3+ (group 1:6
4+ (call 2:3 (wing 2:3 f) (wing 3:3 a) (wing 4:3 b)))))
tests/golden/lex-call-open-ok-1/tree.txtnew file+14
@@ -0,0 +1,14 @@
1+(module
2+ (value 1:1 x
3+ (group 1:6
4+ (call 1:7
5+ (wing 1:7 f)
6+ (wing 1:9 a)
7+ (wing 1:11 b)
8+ (wing 2:3 c)
9+ (call 3:3 (wing 3:3 g) (wing 3:5 d))
10+ (group 4:3
11+ (call 4:4 (wing 4:4 h) (wing 4:6 e))))))
12+ (value 5:1 y
13+ (group 5:6
14+ (call 5:7 (wing 5:7 f) (wing 6:3 a) (wing 7:3 b)))))
tests/golden/lex-cell-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-cell-bad-1/source.jibb:1:8: unexpected `,`: items are separated by spaces
2+++ x [a, b]
3+ ^
tests/golden/lex-cell-ok-1/tree.txtnew file+15
@@ -0,0 +1,15 @@
1+(module
2+ (value 1:1 a
3+ (tuple 1:6 (wing 1:7 a) (wing 1:9 b) (wing 1:11 c)))
4+ (value 2:1 b
5+ (tuple 2:6
6+ (face 2:7 text (str 2:12 "milk"))
7+ (face 2:19 done (lit 2:24 %.n))))
8+ (value 3:1 c
9+ (tuple 3:6
10+ (tuple 3:7 (wing 3:8 a) (wing 3:10 b))
11+ (wing 3:13 c)))
12+ (value 4:1 d
13+ (tuple 4:6
14+ (wing 4:7 a)
15+ (tuple 4:9 (wing 4:10 b) (wing 4:12 c)))))
tests/golden/lex-comment-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-comment-bad-1/source.jibb:1:10: a comment starts with `::`
2+++ x 5 : not a comment
3+ ^
tests/golden/lex-comment-ok-1/tree.txtnew file+6
@@ -0,0 +1,6 @@
1+(module
2+ (value 2:1 x (lit 2:6 5))
3+ (value 3:1 y
4+ (body 4:3 (lit 4:3 6)))
5+ (value 6:1 z
6+ (list 6:6 (lit 7:3 1))))
tests/golden/lex-comment-ok-2/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (str 1:6 "a::b")))
tests/golden/lex-comment-ok-3/tree.txtnew file+1
@@ -0,0 +1 @@
1+(module)
tests/golden/lex-date-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-date-bad-1/source.jibb:1:21: a date is ~year.month.day, then optionally ..hours.minutes.seconds, as ~2026.10.23..14.30.00
2+++ x ~2026.10.23..14:30:00
3+ ^
tests/golden/lex-date-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-date-bad-2/source.jibb:1:24: a date is ~year.month.day, then optionally ..hours.minutes.seconds, as ~2026.10.23..14.30.00
2+++ x ~2026.10.29..14.30
3+ ^
tests/golden/lex-date-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (lit 1:6 ~2026.10.23))
3+ (value 2:1 b (lit 2:6 ~2026.10.23..14.30.00))
4+ (value 3:1 c (lit 3:6 ~2026.1.5))
5+ (value 4:1 d (lit 4:6 ~2026.10.23..14.30.00..ffff)))
tests/golden/lex-decimal-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-decimal-bad-1/source.jibb:1:9: a decimal is digits in groups of three joined by dots, as 1.000
2+++ x 1000
3+ ^
tests/golden/lex-decimal-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-decimal-bad-2/source.jibb:1:11: a decimal is digits in groups of three joined by dots, as 1.000
2+++ x 1.0000
3+ ^
tests/golden/lex-decimal-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (lit 1:6 0))
3+ (value 2:1 b (lit 2:6 42))
4+ (value 3:1 c (lit 3:6 1.000))
5+ (value 4:1 d (lit 4:6 1.000.000)))
tests/golden/lex-duration-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-duration-bad-1/source.jibb:1:9: a duration is units of d, h, m and s joined by dots, as ~h1.m30
2+++ x ~h1m30
3+ ^
tests/golden/lex-duration-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (lit 1:6 ~s30))
3+ (value 2:1 b (lit 2:6 ~h1.m30))
4+ (value 3:1 c (lit 3:6 ~m5))
5+ (value 4:1 d (lit 4:6 ~d1.h2.m3.s4)))
tests/golden/lex-hex-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-hex-bad-1/source.jibb:1:8: a hexadecimal number is 0x and digits 0-9 and a-f, in groups of four joined by dots, as 0x1.ffff
2+++ x 0xg1
3+ ^
tests/golden/lex-hex-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 a (lit 1:6 0x0))
3+ (value 2:1 b (lit 2:6 0x1f))
4+ (value 3:1 c (lit 3:6 0x1.ffff))
5+ (value 4:1 d (lit 4:6 0xdead.beef)))
tests/golden/lex-indent-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-indent-bad-1/source.jibb:2:1: a tab: Jibb uses spaces only
2+ 5
3+^
tests/golden/lex-indent-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-indent-bad-2/source.jibb:4:3: this line's indentation matches no enclosing line: indent it to column 1, 5 or 7
2+ (text "b")
3+ ^
tests/golden/lex-indent-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-indent-bad-3/source.jibb:1:3: the first line is indented: top-level lines start at column 1
2+ ++ x 5
3+ ^
tests/golden/lex-indent-ok-1/tree.txtnew file+21
@@ -0,0 +1,21 @@
1+(module
2+ (value 1:1 view
3+ (gate 1:9
4+ (face 1:12 m (ref 1:14 model))
5+ (body 2:5
6+ (call 2:5
7+ (wing 2:5 column)
8+ (list 2:12
9+ (pair 2:14 gap (lit 2:18 %s1)))
10+ (list 2:23
11+ (group 3:6
12+ (call 3:7 (wing 3:7 text) (str 3:12 "one")))
13+ (call 4:6
14+ (wing 4:6 row)
15+ (lit 4:10 ~)
16+ (list 4:12
17+ (group 5:12
18+ (call 5:13 (wing 5:13 text) (str 5:18 "two")))))
19+ (group 6:6
20+ (call 6:7 (wing 6:7 text) (str 6:12 "three"))))))))
21+ (value 7:1 main (wing 7:9 view)))
tests/golden/lex-indent-ok-2/tree.txtnew file+17
@@ -0,0 +1,17 @@
1+(module
2+ (value 1:1 view
3+ (gate 1:9
4+ (face 1:12 m (ref 1:14 model))
5+ (body 2:3
6+ (call 2:3
7+ (wing 2:3 column)
8+ (list 2:10
9+ (pair 2:12 gap (lit 2:16 %s1)))
10+ (list 2:21
11+ (group 3:5
12+ (call 3:6 (wing 3:6 text) (str 3:11 "a")))
13+ (group 7:5
14+ (call 7:6 (wing 7:6 text) (str 7:11 "b")))
15+ (group 10:5
16+ (call 10:6 (wing 10:6 text) (str 10:11 "c"))))))))
17+ (value 12:1 main (wing 12:9 view)))
tests/golden/lex-indent-ok-3/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (mold 2:1 msg
3+ (union 2:8 (const 4:3 %a) (const 6:3 %b)))
4+ (value 7:1 f
5+ (gate 7:6
6+ (face 7:9 b (flag 7:11))
7+ (body 8:3
8+ (branch 8:3
9+ (wing 8:6 b)
10+ (arm 10:5 (lit 10:5 %.y) (lit 10:10 1))
11+ (arm 13:5 (lit 13:5 %.n) (lit 13:10 2)))))))
tests/golden/lex-interp-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-interp-bad-1/source.jibb:1:9: a `\` begins `\\`, `\"`, `\{` or two hex digits
2+++ x "a\qb"
3+ ^
tests/golden/lex-interp-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-interp-bad-2/source.jibb:1:8: unexpected `<`: there is no `<…>`, since `{…}` prints a value by its aura
2+++ x "{<n>}"
3+ ^
tests/golden/lex-interp-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-interp-bad-3/source.jibb:1:8: expected an expression, found `}`
2+++ x "{}"
3+ ^
tests/golden/lex-interp-bad-4/tree.txtnew file+2
@@ -0,0 +1,2 @@
1+(module
2+ (value 1:1 x (str 1:6 "a \\ b \0a c")))
tests/golden/lex-interp-ok-1/tree.txtnew file+22
@@ -0,0 +1,22 @@
1+(module
2+ (value 1:1 a
3+ (str 1:6 "Since " (wing 1:14 day)))
4+ (value 2:1 b
5+ (str 2:6
6+ (group 2:8
7+ (call 2:9 (wing 2:9 lent) (wing 2:14 items.cart.m)))
8+ " items"))
9+ (value 3:1 c
10+ (str 3:6 (wing 3:8 n)))
11+ (value 4:1 d
12+ (str 4:6 "left " (wing 4:13 n) " and right " (wing 4:27 m)))
13+ (value 5:1 e (str 5:6 "a \{ brace and a \" quote"))
14+ (value 6:1 f
15+ (str 6:6
16+ (call 6:8 (wing 6:8 add) (wing 6:12 n) (lit 6:14 1))
17+ " is a call without parentheses"))
18+ (value 7:1 g
19+ (str 7:6
20+ (cast 7:8 (aura 7:11 @ud) (wing 7:15 n))
21+ " holds a rune"))
22+ (value 8:1 h (str 8:6 "\{x} is text")))
tests/golden/lex-interp-ok-2/tree.txtnew file+17
@@ -0,0 +1,17 @@
1+(module
2+ (value 1:1 x
3+ (str 1:6
4+ "a "
5+ (group 1:10
6+ (call 1:11
7+ (wing 1:11 weld)
8+ (str 1:16 "b " (wing 1:20 c) " d")
9+ (str 1:26 "e")))
10+ " f"))
11+ (value 2:1 y
12+ (str 2:6
13+ (group 2:8
14+ (call 2:9 (wing 2:9 f) (str 2:11 "}")))
15+ " and "
16+ (group 2:22
17+ (call 2:23 (wing 2:23 g) (str 2:25 "\""))))))
tests/golden/lex-knot-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-knot-bad-1/source.jibb:1:8: unexpected `M`: a knot holds lowercase letters, digits and - . ~ _
2+++ x ~.My-post
3+ ^
tests/golden/lex-knot-ok-1/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 a (lit 1:6 ~.my-post))
3+ (value 2:1 b (lit 2:6 ~.))
4+ (value 3:1 c (lit 3:6 ~.a_b.c~d-1)))
tests/golden/lex-layout-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-layout-bad-1/source.jibb:2:3: expected the end of the line, found a deeper line; only a bracket open at the end of a line, or a rune's body, takes deeper lines
2+ bar
3+ ^
tests/golden/lex-layout-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-layout-bad-2/source.jibb:2:1: expected an expression, or a body on deeper lines, found a line at the same depth
2+++ main view
3+^
tests/golden/lex-layout-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-layout-bad-3/source.jibb:3:3: expected the end of the body, found a line at the same depth; a body's final expression is its last line
2+ 1
3+ ^
tests/golden/lex-layout-bad-4/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-layout-bad-4/source.jibb:4:3: expected the end of the body, found a line at the same depth; a body's final expression is its last line
2+ * ~
3+ ^
tests/golden/lex-layout-ok-1/tree.txtnew file+20
@@ -0,0 +1,20 @@
1+(module
2+ (value 1:1 view
3+ (gate 1:9
4+ (face 1:12 m (ref 1:14 model))
5+ (body 2:3
6+ (call 2:3
7+ (wing 2:3 column)
8+ (lit 2:10 ~)
9+ (list 2:12
10+ (group 3:5
11+ (call 3:6 (wing 3:6 text) (str 3:11 "one")))
12+ (call 4:5
13+ (wing 4:5 row)
14+ (lit 4:9 ~)
15+ (list 4:11
16+ (group 5:7
17+ (call 5:8 (wing 5:8 text) (str 5:13 "two")))
18+ (group 6:7
19+ (call 6:8 (wing 6:8 text) (str 6:13 "three"))))))))))
20+ (value 7:1 main (wing 7:9 view)))
tests/golden/lex-list-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-list-bad-1/source.jibb:1:13: expected `]` to close the `~[` at 1:6, found `)`
2+++ x ~[1 2 3)
3+ ^
tests/golden/lex-list-ok-1/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 a
3+ (list 1:6 (lit 1:8 1) (lit 1:10 2) (lit 1:12 3)))
4+ (value 2:1 b
5+ (list 2:6
6+ (group 2:8
7+ (call 2:9 (wing 2:9 text) (str 2:14 "hi")))))
8+ (value 3:1 c
9+ (list 3:6
10+ (list 3:8 (lit 3:10 1))
11+ (list 3:13 (lit 3:15 2) (lit 3:17 3)))))
tests/golden/lex-loobean-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-loobean-bad-1/source.jibb:1:8: the loobeans are `%.y` and `%.n`
2+++ x %.x
3+ ^
tests/golden/lex-loobean-ok-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x
3+ (tuple 1:6 (lit 1:7 %.y) (lit 1:11 %.n))))
tests/golden/lex-name-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-name-bad-1/source.jibb:1:6: names are lowercase letters, digits and -
2+++ myView 5
3+ ^
tests/golden/lex-name-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-name-bad-2/source.jibb:1:8: names are lowercase letters, digits and -
2+++ x my_view
3+ ^
tests/golden/lex-name-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-name-bad-3/source.jibb:1:4: expected a name, found `2`
2+++ 2nd 5
3+ ^
tests/golden/lex-name-bad-4/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-name-bad-4/source.jibb:1:4: unexpected `-`: a name starts with a letter, and Jibb has no operators
2+++ -view 5
3+ ^
tests/golden/lex-name-ok-1/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 a (lit 1:6 1))
3+ (value 2:1 todo-list-2 (lit 2:16 2))
4+ (value 3:1 x1y2 (lit 3:9 3))
5+ (mold 4:1 my-mold-9 (aura 4:14 @ud))
6+ (value 5:1 f
7+ (gate 5:6
8+ (cell 5:9
9+ (face 5:10 some-face (aura 5:20 @))
10+ (face 5:22 a1 (aura 5:25 @)))
11+ (body 6:3 (wing 6:3 some-face)))))
tests/golden/lex-null-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-null-bad-1/source.jibb:1:7: `~` alone is null, and nothing here reads as a ship, date, duration or knot
2+++ x ~x
3+ ^
tests/golden/lex-null-ok-1/tree.txtnew file+19
@@ -0,0 +1,19 @@
1+(module
2+ (value 1:1 a (lit 1:6 ~))
3+ (value 2:1 b
4+ (tuple 2:6 (lit 2:7 ~) (lit 2:9 ~)))
5+ (value 3:1 c
6+ (group 3:6
7+ (call 3:7 (wing 3:7 f) (lit 3:9 ~))))
8+ (mold 4:1 d (const 4:6 ~))
9+ (value 5:1 e
10+ (gate 5:6
11+ (face 5:9 u
12+ (apply 5:11 unit (aura 5:17 @t)))
13+ (body 6:3
14+ (branch 6:3
15+ (wing 6:6 u)
16+ (arm 7:5 (lit 7:5 ~) (str 7:12 ""))
17+ (arm 8:5
18+ (cell 8:5 (lit 8:6 ~) (bind 8:8 x))
19+ (wing 8:12 x)))))))
tests/golden/lex-open-bracket-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-open-bracket-bad-1/source.jibb:2:1: expected `]` or an item on a deeper line, found a line at the same depth
2+++ y 5
3+^
tests/golden/lex-open-bracket-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-open-bracket-bad-2/source.jibb:4:1: expected a definition, found `]`; this closes no bracket, as one open at the end of its line needs none
2+]
3+^
tests/golden/lex-open-bracket-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-open-bracket-bad-3/source.jibb:3:4: expected the end of the line, found `]`; a bracket open at the end of its line takes no closer
2+ 2]
3+ ^
tests/golden/lex-open-bracket-bad-4/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-open-bracket-bad-4/source.jibb:2:15: expected `)` to close the `(` at 1:6, found the end of the file; only the last bracket open at the end of a line takes the deeper lines
2+ (text "a")
3+ ^
tests/golden/lex-open-bracket-ok-1/tree.txtnew file+21
@@ -0,0 +1,21 @@
1+(module
2+ (value 1:1 items
3+ (body 2:3
4+ (list 2:3
5+ (group 3:5
6+ (call 3:6 (wing 3:6 text) (str 3:11 "a")))
7+ (call 4:5 (wing 4:5 text) (str 4:10 "b")))))
8+ (value 5:1 record
9+ (body 6:3
10+ (tuple 6:3
11+ (face 7:5 text (str 7:10 "milk"))
12+ (face 8:5 done (lit 8:10 %.n)))))
13+ (value 9:1 changed
14+ (body 10:3
15+ (change 10:3 m
16+ (edit 11:5 note (str 11:10 "x"))
17+ (edit 12:5 error (lit 12:11 ~)))))
18+ (value 13:1 grouped
19+ (body 14:3
20+ (group 14:3
21+ (call 14:4 (wing 14:4 f) (wing 14:6 a) (wing 15:5 b) (wing 16:5 c))))))
tests/golden/lex-open-bracket-ok-2/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (value 1:1 x
3+ (list 1:6
4+ (list 2:3 (lit 3:5 1) (lit 4:5 2))
5+ (list 5:3 (lit 5:5 3) (lit 5:7 4))
6+ (tuple 6:3
7+ (face 6:4 a (lit 6:6 1))
8+ (face 7:5 b (lit 7:7 2)))
9+ (lit 8:3 5))))
tests/golden/lex-pair-binding-bad-1/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6
4+ (pair 1:6 pad (wing 1:10 f))
5+ (wing 1:12 a)))
6+ (value 2:1 y
7+ (call 2:6
8+ (unit 2:6 (wing 2:7 f))
9+ (wing 2:9 a))))
tests/golden/lex-pair-binding-ok-1/tree.txtnew file+11
@@ -0,0 +1,11 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6
4+ (wing 1:6 f)
5+ (pair 1:8 pad (lit 1:12 %s3))
6+ (pair 1:16 gap (lit 1:20 %s2))))
7+ (value 2:1 y
8+ (call 2:6
9+ (wing 2:6 f)
10+ (unit 2:8 (wing 2:9 a))
11+ (wing 2:11 b))))
tests/golden/lex-path-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-path-bad-1/source.jibb:1:7: unexpected `P`: a path segment holds lowercase letters, digits and - . ~ _
2++$ x /Posts
3+ ^
tests/golden/lex-path-ok-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (jibb 1:1 card /ui/components/card)
3+ (mold 2:1 a (path 2:6 /posts/~zod))
4+ (mold 3:1 b (path 3:6 /))
5+ (mold 4:1 c (path 4:6 /todo/[id=@ud]/comments)))
tests/golden/lex-rune-layout-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-rune-layout-bad-1/source.jibb:2:1: expected an expression, or a body on deeper lines, found a line at the same depth
2+(add n 1)
3+^
tests/golden/lex-rune-layout-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-rune-layout-bad-2/source.jibb:2:1: expected `~&`'s body on deeper lines, found a line at the same depth
2+++ y 6
3+^
tests/golden/lex-rune-layout-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-rune-layout-bad-3/source.jibb:3:3: expected `~&`'s body on deeper lines, found a line at the same depth
2+ 5
3+ ^
tests/golden/lex-rune-layout-bad-4/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-rune-layout-bad-4/source.jibb:3:1: expected `?-`'s arms on deeper lines, found a shallower line
2+++ g 3
3+^
tests/golden/lex-rune-layout-ok-1/tree.txtnew file+42
@@ -0,0 +1,42 @@
1+(module
2+ (value 1:1 a
3+ (gate 1:6
4+ (face 1:9 n (aura 1:11 @ud))
5+ (call 1:15 (wing 1:15 add) (wing 1:19 n) (lit 1:21 1))))
6+ (value 2:1 b
7+ (gate 2:6
8+ (face 2:9 n (aura 2:11 @ud))
9+ (body 3:3
10+ (group 3:3
11+ (call 3:4 (wing 3:4 add) (wing 3:8 n) (lit 3:10 1))))))
12+ (value 4:1 c
13+ (cast 4:6 (aura 4:9 @ud) (lit 4:13 5)))
14+ (value 5:1 d
15+ (cast 5:6
16+ (aura 5:9 @ud)
17+ (body 6:3 (lit 6:3 5))))
18+ (value 7:1 e
19+ (gate 7:6
20+ (face 7:9 n (aura 7:11 @ud))
21+ (body 8:3
22+ (trace 8:3
23+ (wing 8:6 n)
24+ (body 9:5
25+ (group 9:5
26+ (call 9:6 (wing 9:6 add) (wing 9:10 n) (lit 9:12 1))))))))
27+ (value 10:1 f
28+ (gate 10:6
29+ (face 10:9 b (flag 10:11))
30+ (body 11:3
31+ (branch 11:3
32+ (wing 11:6 b)
33+ (arm 12:5 (lit 12:5 %.y) (lit 12:10 1))
34+ (arm 13:5
35+ (lit 13:5 %.n)
36+ (body 14:7 (lit 14:7 2)))))))
37+ (mold 15:1 g
38+ (cell 16:3
39+ (face 16:4 a (aura 16:6 @))
40+ (face 16:8 b (aura 16:10 @))))
41+ (mold 17:1 h
42+ (union 18:3 (const 19:5 %a) (const 20:5 %b))))
tests/golden/lex-ship-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-ship-bad-1/source.jibb:1:13: a ship is syllables in pairs joined by hyphens, as ~zod, ~marzod or ~sampel-palnet
2+++ x ~sampelpalnet
3+ ^
tests/golden/lex-ship-ok-1/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 a (lit 1:6 ~zod))
3+ (value 2:1 b (lit 2:6 ~marzod))
4+ (value 3:1 c (lit 3:6 ~sampel-palnet)))
tests/golden/lex-spacing-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-spacing-bad-1/source.jibb:1:18: expected a space between items, found `(`
2+++ x ~[(text "a")(text "b")]
3+ ^
tests/golden/lex-spacing-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-spacing-bad-2/source.jibb:1:7: a tab: Jibb uses spaces only
2+++ x f a
3+ ^
tests/golden/lex-spacing-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+(module
2+ (value 1:1 x (lit 1:6 5))
3+ (value 2:1 y (lit 2:6 6)))
tests/golden/lex-spacing-bad-4/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (tuple 1:6 (wing 1:8 a) (wing 1:10 b)))
4+ (value 2:1 y
5+ (list 2:6 (lit 2:9 1) (lit 2:11 2))))
tests/golden/lex-spacing-ok-1/tree.txtnew file+17
@@ -0,0 +1,17 @@
1+(module
2+ (jibb 1:1 api /ui/api/blog)
3+ (jibb 2:1 card /ui/components/card)
4+ (value 4:1 short (lit 4:12 1))
5+ (value 5:1 longer
6+ (list 5:12 (lit 5:14 1) (lit 5:19 2)))
7+ (value 6:1 f
8+ (gate 6:6
9+ (face 6:9 s (noun 6:11))
10+ (body 7:3
11+ (branch 7:3
12+ (wing 7:6 s)
13+ (arm 8:5
14+ (lit 8:5 %a)
15+ (group 8:11
16+ (call 8:12 (wing 8:12 add) (lit 8:17 1) (lit 8:20 2))))
17+ (arm 9:5 (any 9:5) (lit 9:11 ~)))))))
tests/golden/lex-string-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-string-bad-1/source.jibb:1:6: there is no '…' form: strings are "…"
2+++ x 'milk'
3+ ^
tests/golden/lex-string-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-string-bad-2/source.jibb:1:11: this string has no closing `"` on its line
2+++ x "milk
3+ ^
tests/golden/lex-string-ok-1/tree.txtnew file+4
@@ -0,0 +1,4 @@
1+(module
2+ (value 1:1 a (str 1:6 "milk"))
3+ (value 2:1 b (str 2:6 ""))
4+ (value 3:1 c (str 3:6 "it's fine: 'single quotes', [brackets], ~tildes, %percents and /slashes are text")))
tests/golden/lex-term-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-term-bad-1/source.jibb:1:7: `%` begins a term, a loobean or `%/`
2+++ x %Add
3+ ^
tests/golden/lex-term-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-term-bad-2/source.jibb:1:8: unexpected `a`: a numeric term is `%` and digits only, as %1000
2+++ x %9a
3+ ^
tests/golden/lex-term-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-term-bad-3/source.jibb:1:8: unexpected `.`: a numeric term is `%` and digits only, as %1000
2+++ x %1.000
3+ ^
tests/golden/lex-term-ok-1/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 a (lit 1:6 %add))
3+ (value 2:1 b (lit 2:6 %a1-b))
4+ (value 3:1 c (lit 3:6 %0))
5+ (value 4:1 d (lit 4:6 %42))
6+ (value 5:1 e (lit 5:6 %&))
7+ (value 6:1 f (lit 6:6 %|)))
tests/golden/lex-tight-change-bad-1/tree.txtnew file+6
@@ -0,0 +1,6 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6
4+ (wing 1:6 m)
5+ (group 1:8
6+ (call 1:9 (wing 1:9 note) (wing 1:14 text))))))
tests/golden/lex-tight-change-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-change-bad-2/source.jibb:1:13: expected a space between items, found `=`; `name=value` goes in a cell, as [a=1], or a change, as m(a=1)
2+++ x m (note=text)
3+ ^
tests/golden/lex-tight-change-ok-1/tree.txtnew file+14
@@ -0,0 +1,14 @@
1+(module
2+ (value 1:1 a
3+ (change 1:6 m
4+ (edit 1:8 note (wing 1:13 text))))
5+ (value 2:1 b
6+ (change 2:6 s
7+ (edit 2:8 items
8+ (tuple 2:14 (wing 2:15 item) (wing 2:20 items.s)))
9+ (edit 2:29 open
10+ (group 2:34
11+ (call 2:35 (wing 2:35 not) (wing 2:39 open.s))))))
12+ (value 3:1 c
13+ (change 3:6 cart.m
14+ (edit 3:13 note (str 3:18 "")))))
tests/golden/lex-tight-ctor-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-ctor-bad-1/source.jibb:1:20: expected a term right after `|=`, found a space
2+++ x (state.cart |= %got)
3+ ^
tests/golden/lex-tight-ctor-bad-2/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (gate 1:6
4+ (const 1:9 %got)
5+ (body 2:3 (lit 2:3 ~)))))
tests/golden/lex-tight-ctor-ok-1/tree.txtnew file+7
@@ -0,0 +1,7 @@
1+(module
2+ (value 1:1 x (ctor 1:6 %got))
3+ (value 2:1 y
4+ (group 2:6
5+ (call 2:7 (wing 2:7 state.cart) (ctor 2:18 %got))))
6+ (value 3:1 z
7+ (list 3:6 (ctor 3:8 %noted) (ctor 3:17 %acked))))
tests/golden/lex-tight-opener-bad-1/tree.txtnew file+5
@@ -0,0 +1,5 @@
1+(module
2+ (value 1:1 x
3+ (call 1:6
4+ (lit 1:6 ~)
5+ (tuple 1:8 (wing 1:9 a)))))
tests/golden/lex-tight-opener-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-opener-bad-2/source.jibb:1:17: expected a term right after `|=`, found a space
2+++ x (turn ps |= (p title.p))
3+ ^
tests/golden/lex-tight-opener-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-opener-bad-3/source.jibb:1:9: expected the end of the line, found `(`; `$?` takes its cases on deeper lines, one per line, or write $?(%a %b)
2++$ x $? (%a %b)
3+ ^
tests/golden/lex-tight-opener-bad-4/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-opener-bad-4/source.jibb:1:8: `$-` has only the wide form `$-(sample product)`
2++$ x $- (@t @t)
3+ ^
tests/golden/lex-tight-opener-ok-1/tree.txtnew file+12
@@ -0,0 +1,12 @@
1+(module
2+ (value 1:1 a
3+ (list 1:6 (lit 1:8 1) (lit 1:10 2)))
4+ (value 2:1 b
5+ (gate-wide 2:6
6+ (bind 2:9 n)
7+ (group 2:11
8+ (call 2:12 (wing 2:12 add) (wing 2:16 n) (lit 2:18 1)))))
9+ (mold 3:1 c
10+ (union 3:6 (const 3:9 %a) (const 3:12 %b)))
11+ (mold 4:1 d
12+ (fn 4:6 (aura 4:9 @t) (aura 4:12 @t))))
tests/golden/lex-tight-pair-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-pair-bad-1/source.jibb:1:12: expected an expression, found `+`; a pair takes no spaces, as gap+%s2
2+++ x ~[gap + %s2]
3+ ^
tests/golden/lex-tight-pair-ok-1/tree.txtnew file+18
@@ -0,0 +1,18 @@
1+(module
2+ (value 1:1 x
3+ (pair 1:6 a (wing 1:8 b)))
4+ (value 2:1 y
5+ (list 2:6
6+ (pair 2:8 gap (lit 2:12 %s2))
7+ (pair 2:16 width
8+ (tuple 2:22 (lit 2:23 %fill) (lit 2:29 1)))
9+ (pair 2:32 pad
10+ (group 2:36
11+ (call 2:37 (wing 2:37 f) (wing 2:39 a))))
12+ (pair 2:42 mark
13+ (unit 2:47 (wing 2:48 b)))
14+ (pair 2:50 list
15+ (list 2:55 (lit 2:57 1) (lit 2:59 2)))
16+ (pair 2:62 link (qath 2:67 blog))
17+ (pair 2:74 nested
18+ (pair 2:81 a (wing 2:83 b))))))
tests/golden/lex-tight-qath-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-qath-bad-1/source.jibb:1:7: `%` begins a term, a loobean or `%/`
2+++ x % /blog
3+ ^
tests/golden/lex-tight-qath-bad-2/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-qath-bad-2/source.jibb:1:12: unexpected `?`: a path carries no query, and a segment holds lowercase letters, digits and - . ~ _
2+++ x %/blog?page=2
3+ ^
tests/golden/lex-tight-qath-bad-3/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-qath-bad-3/source.jibb:1:12: unexpected `#`: a path carries no fragment, and a segment holds lowercase letters, digits and - . ~ _
2+++ x %/blog#top
3+ ^
tests/golden/lex-tight-qath-ok-1/tree.txtnew file+9
@@ -0,0 +1,9 @@
1+(module
2+ (value 1:1 a
3+ (qath 1:6 blog (wing 1:14 slug)))
4+ (value 2:1 b (qath 2:6))
5+ (value 3:1 c (qath 3:6 static img logo.png))
6+ (value 4:1 d
7+ (qath 4:6 blog (wing 4:14 slug.p) comments))
8+ (value 5:1 e
9+ (qath 5:6 todo (wing 5:14 id))))
tests/golden/lex-tight-unit-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-unit-bad-1/source.jibb:1:7: expected an operand right after `` ` ``, found a space
2+++ x ` x
3+ ^
tests/golden/lex-tight-unit-ok-1/tree.txtnew file+13
@@ -0,0 +1,13 @@
1+(module
2+ (value 1:1 x
3+ (list 1:6
4+ (unit 1:8 (str 1:9 "Too long"))
5+ (unit 1:20
6+ (tuple 1:21 (wing 1:22 a) (wing 1:24 b)))
7+ (unit 1:27
8+ (unit 1:28 (wing 1:29 c)))
9+ (unit 1:31 (qath 1:32 blog))
10+ (unit 1:39
11+ (group 1:40
12+ (call 1:41 (wing 1:41 f) (wing 1:43 a))))
13+ (unit 1:46 (lit 1:47 ~)))))
tests/golden/lex-tight-wing-bad-1/tree.txtnew file+3
@@ -0,0 +1,3 @@
1+/tests/golden/lex-tight-wing-bad-1/source.jibb:1:12: unexpected `.`: a `.` joins the names of a wing, as title.p
2+++ x title . p
3+ ^
tests/golden/lex-tight-wing-ok-1/tree.txtnew file+8
@@ -0,0 +1,8 @@
1+(module
2+ (value 1:1 a (wing 1:6 a.b))
3+ (value 2:1 b (wing 2:6 space.theme.theme))
4+ (value 3:1 c
5+ (group 3:6
6+ (call 3:7 (wing 3:7 lent) (wing 3:12 items.cart.m))))
7+ (mold 4:1 d
8+ (apply 4:6 list (ref 4:12 post.blog))))