~/bend-docscommunity

src/syntax/tree.bend checks

raw source on the hub · import 0xde9bb08f7de298b03207fb5797ede9a5/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)

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

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

type B source · line 144 · raw

Data

fresh: the next significant token starts a line

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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/src/syntax/lex.Tok> -> @acc:List<&2, 0xde9bb08f7de298b03207fb5797ede9a5/src/syntax/lex.Tok> -> List<&2, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/src/syntax/lex.Tok> -> List<&2, 0xde9bb08f7de298b03207fb5797ede9a5/src/syntax/lex.Tok>

def leaves source · line 130 · raw

@nn:Node -> List<&2, 0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/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:0xde9bb08f7de298b03207fb5797ede9a5/src/syntax/lex.Tok -> Bool

an identifier of any kind (what < glues to)

def run source · line 395 · raw

@toks:List<&2, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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, 0xde9bb08f7de298b03207fb5797ede9a5/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 ..)