src/syntax/tree.bend checks
raw source on the hub · import 0x013e0f9a479bbebad5ed196725eede95/src/syntax/tree.bend as Tree
src/syntax/tree: a source as a concrete syntax tree over its significant tokens:
statements by line and indentation, groups by brackets. Built by one stack
machine over the token list, so a half-written file still yields a tree:
- a bracket that never closes is closed by the next line at column 0
(so damage stays inside one item), or by the end of the file;
- a close bracket that matches nothing on the stack is a stray leaf;
- < opens type arguments only when glued to a name (List<, Maybe<&);
a >-only operator closes as many angle groups as it has >s, each
only while an angle group is the innermost open one: in
List<f(a > b)> the first > is an operator inside (..).
Trivia (spaces, newlines, comments) is not in the tree: read the tokens for
that. The cells (NNil, NCons) live inside the type, as json/value does, so
every walk is a structural recursion on one argument.
3 imports
import Base import ../lazy/lazy.bend as Lazy import ./lex.bend as Lex
Types
type StmtKind source · line 22 · raw
Data
what a statement is, by its shape: SDef def f(..) (also @unsafe def),
SType, SLaw, SImport, SCase case p:, SFor for x: T / exs x: T, SLet
(a = or <- among its own tokens), else STerm (match x:, do M<T>:,
return e, a call)
SDefStmtKind
STypeStmtKind
SLawStmtKind
SImportStmtKind
SCaseStmtKind
SForStmtKind
SLetStmtKind
STermStmtKind
type Node source · line 35 · raw
Data
a leaf holds one token; a group its bracket, what is inside, and its close (None when it never closed); a statement its own tokens and the statements under it; NNil and NCons chain nodes
Leaf@tok:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> Node
Group@open:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> @kids:Node -> @close:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> Node
Stmt@kind:StmtKind -> @kids:Node -> @body:Node -> Node
NNilNode
NCons@head:Node -> @tail:Node -> Node
type Frame source · line 138 · raw
Data
an open group (its kids reversed), or an open statement (its kids and the finished statements under it, both reversed); the root holds the items
FGroup@open:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> @kids:Node -> Frame
FStmt@indent:U32 -> @kids:Node -> @body:Node -> Frame
FRoot@body:Node -> Frame
type B source · line 144 · raw
Data
fresh: the next significant token starts a line
B@fresh:Bool -> @stack:List<&2, Frame> -> B
Definitions
def reverse source · line 46 · raw
@cells:Node -> @acc:Node -> Node
a chain, reversed onto acc
def first source · line 54 · raw
@nn:Node -> Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok>
the token a leaf holds; a group's open, a statement's first token
def text.of source · line 67 · raw
@mm:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> String
def text source · line 75 · raw
@nn:Node -> String
the text of a node's first token ("" for none)
def line.of source · line 78 · raw
@mm:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> U32
def line source · line 86 · raw
@nn:Node -> U32
the line of a node's first token (0 for none)
def col.of source · line 89 · raw
@mm:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> U32
def col source · line 97 · raw
@nn:Node -> U32
the column of a node's first token (0 for none)
def opens source · line 101 · raw
@nn:Node -> @+ss:String -> Bool
is it a group opened by this bracket?
def leaf_close source · line 109 · raw
@close:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> @acc:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok>
the leaves of a tree, in order: the significant tokens
def leaves.go source · line 116 · raw
@nn:Node -> @acc:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok>
def leaves source · line 130 · raw
@nn:Node -> List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok>
the leaves of a tree, in order: the significant tokens when the tree is faithful
def closer source · line 148 · raw
@+oo:String -> String
the bracket that closes an opener (> for < and <&)
def all_gt source · line 154 · raw
@cs:List<&2, Char> -> Bool
is every char a >?
def closes_with source · line 162 · raw
@kk:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.TokKind -> @+tt:String -> Bool
a token that closes a group: ), ], } or a run of >
def opens_angle source · line 172 · raw
@kk:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.TokKind -> @+tt:String -> @glued:Bool -> Bool
< or <& right after a name opens type arguments
def put source · line 180 · raw
@stack:List<&2, Frame> -> @nn:Node -> List<&2, Frame>
a finished node lands in the frame below
def close_one source · line 192 · raw
@stack:List<&2, Frame> -> @close:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, Frame>
the innermost open group, closed by close (None: never closed)
def depth_to.up source · line 200 · raw
@below:Nat -> Nat
one more group above the one found below, when one was
def depth_to source · line 210 · raw
@stack:List<&2, Frame> -> @+cc:String -> Nat
how many groups sit open above the one that c closes (counting it); 0 when
none does. A > closes only an angle group on top: inside (..), [..]
or {..} it is an operator, even within <..>
def groups source · line 221 · raw
@stack:List<&2, Frame> -> Nat
how many groups sit open on top of the stack
def close_n source · line 229 · raw
@nn:Nat -> @stack:List<&2, Frame> -> @close:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, Frame>
n groups close, innermost first; only the last gets the close token
def close_all source · line 239 · raw
@+stack:List<&2, Frame> -> List<&2, Frame>
every open group closes, unclosed
def close_tok source · line 243 · raw
@+stack:List<&2, Frame> -> @+close:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> List<&2, Frame>
a close bracket: to its match if it has one, else a stray leaf
def close_gts source · line 249 · raw
@cs:List<&2, Char> -> @stack:List<&2, Frame> -> @+ll:U32 -> @+cc:U32 -> List<&2, Frame>
>> closes two angle groups
def close_any.at source · line 258 · raw
@+gt:Bool -> @+stack:List<&2, Frame> -> @+close:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> @+tt:String -> @+ll:U32 -> @+cc:U32 -> List<&2, Frame>
the close a bracket makes, given whether it is a run of >: a match, so
only the side taken runs
def close_any source · line 273 · raw
@+stack:List<&2, Frame> -> @+close:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> List<&2, Frame>
a close bracket, or a run of >, closes what it can
def put_stmt source · line 278 · raw
@stack:List<&2, Frame> -> @nn:Node -> List<&2, Frame>
a finished statement lands in the body of the frame below
def binds_in source · line 288 · raw
@kids:Node -> Bool
a = or <- among a statement's own tokens
def keyword_kind source · line 300 · raw
@+tt:String -> StmtKind
the kind of a statement led by this keyword
def classify source · line 309 · raw
@kids:Node -> StmtKind
a statement's kind from its own tokens
def end_stmt source · line 319 · raw
@stack:List<&2, Frame> -> List<&2, Frame>
the innermost open statement is finished and lands in its parent
def end_n source · line 328 · raw
@nn:Nat -> @stack:List<&2, Frame> -> List<&2, Frame>
n statements finish, innermost first
def deeper source · line 336 · raw
@stack:List<&2, Frame> -> @+col:U32 -> Nat
the statements a line at column col ends: those not shallower than it
def stmts source · line 345 · raw
@stack:List<&2, Frame> -> Nat
how many statements sit open on the stack
def in_group source · line 353 · raw
@stack:List<&2, Frame> -> Bool
is the innermost frame an open group?
def open_stmt source · line 362 · raw
@+stack:List<&2, Frame> -> @+cc:U32 -> List<&2, Frame>
a new statement at column c, once the ones it ends are finished; inside a group a line is just more tokens
def fresh source · line 369 · raw
@+stack:List<&2, Frame> -> @+tok:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> List<&2, Frame>
a significant token that starts a line: at column 0 it closes every open group (unless it is a bracket closing one of them); outside a group it opens a statement
def push source · line 375 · raw
@+stack:List<&2, Frame> -> @+tok:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> @glued:Bool -> List<&2, Frame>
an open bracket or a leaf into the innermost frame
def step source · line 383 · raw
@+tok:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> @st:B -> @glued:Bool -> B
glued: the previous token was a name with nothing between
def is_name_tok source · line 390 · raw
@tok:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok -> Bool
an identifier of any kind (what < glues to)
def run source · line 395 · raw
@toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> @st:B -> @glued:Bool -> B
every token, in order
def root source · line 404 · raw
@stack:List<&2, Frame> -> Node
the items gathered in the root frame
def finish source · line 412 · raw
@st:B -> Node
the tree once the tokens are over: every group and statement closes
def of_tokens source · line 418 · raw
@toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> Node
the items of a source: a chain of statements
def parse source · line 422 · raw
@source:String -> Node
the items of a source: a chain of statements
def show_close source · line 429 · raw
@close:Maybe<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> String
a group's close bracket, .. when it never closed
def show source · line 439 · raw
@nn:Node -> String
[def f (x : U32) -> U32 : {[match x {[case A {} : {[1]}]}]}]: a statement
in brackets, its body in braces, a group as its brackets (an unclosed one
ends in ..)