~/bend-docscommunity

src/pull.bend checks

raw source on the hub · import emerging-ezjson@1.1.0.0/src/pull.bend as Pull

src/pull: one JSON text, one event at a time. cursor holds the unread suffix of the source. next returns one event and the cursor after it. skip drops one value. A span event keeps the suffix it points at, so it stays readable while that event is held and is gone when the event is dropped. Commas and colons are not events.

3 imports
import Base
import ./value.bend as V
import ./lex.bend as Lex

Types

type Slot source · line 11 · raw

Data

where the next token of an open array or object has to be

type Frame source · line 18 · raw

Data

an open array or object. fresh is the empty container, before any value

type Ev source · line 23 · raw

Data

one event. A span is the first nn chars of a source suffix, not a copy

type Cur source · line 40 · raw

Data

the cursor. rest is the unread suffix. done is set once the root value has ended. bad sticks after the first error

type Goal source · line 44 · raw

Data

read the next event, or drop one whole value

type Stop source · line 49 · raw

Data

what a step hands back: an event, or a finished skip

type Atom source · line 54 · raw

Data

a bare word, once it has been classified

type Piece source · line 62 · raw

Data

a string's text: a span of the source, or chars decoded from escapes

type Skind source · line 68 · raw

Data

what one character of a string does. The usual one is KGo: stay in the string. The others leave it

type Spot source · line 75 · raw

Data

where a finished value lands, or that the slot cannot take one

type Mode source · line 81 · raw

Data

what the scanner is inside. Skip-modes (MSk*) walk a string they will not keep, so a dropped value does not build its text

type St source · line 109 · raw

Data

the scanner's state, apart from the unread suffix it is walking

type Out source · line 114 · raw

Type

what a walk hands back: a finished step, or a budget used up, to resume on txt in state st

type Wst source · line 633 · raw

Data

where a plain word run stopped. A stop keeps the delimiter, already consumed

Definitions

def err.st source · line 119 · raw

@goal:Goal -> St

a failed step. The unread suffix is dropped

def bad.cur source · line 123 · raw

Pair(Stop, Cur)

a failed cursor

def copy.rev source · line 127 · raw

@src:String -> @+nn:U32 -> @zero:Bool -> @acc:List<&2, Char> -> List<&2, Char>

the first nn chars of src, reversed, for the escape copier

def expect.val.go source · line 137 · raw

@stack:List<&2, Frame> -> Bool

a value can start here

def expect.val source · line 149 · raw

@stack:List<&2, Frame> -> @done:Bool -> Bool

a value can start here, and the root is not already finished

def expect.str.go source · line 157 · raw

@stack:List<&2, Frame> -> Bool

a string can start here: a value, or an object key

def expect.str source · line 171 · raw

@stack:List<&2, Frame> -> @done:Bool -> Bool

a string can start here, and the root is not already finished

def expect.str.for source · line 180 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> Bool

a string can start here for this goal. A skip of one whole value must start a value, so a key there fails at once, as it would once read

def place.spot source · line 188 · raw

@stack:List<&2, Frame> -> Spot

the stack after a value, and whether that value was the root

def place.val.ok source · line 200 · raw

@ev:Ev -> @rest:String -> @goal:Goal -> @stack:List<&2, Frame> -> @root:Bool -> St

a value has landed in a slot that can take it

def place.val.on source · line 210 · raw

@ev:Ev -> @rest:String -> @goal:Goal -> @spot:Spot -> St

a value has landed. rest is the suffix the cursor keeps

def place.val source · line 218 · raw

@ev:Ev -> @rest:String -> @stack:List<&2, Frame> -> @goal:Goal -> St

a value has landed

def place.key source · line 222 · raw

@ev:Ev -> @rest:String -> @frames:List<&2, Frame> -> @goal:Goal -> St

an object key has landed. The value comes after the colon

def str.ev source · line 232 · raw

@piece:Piece -> @key:Bool -> Ev

a string event, span or owned, as a key or a value

def str.cont.on source · line 244 · raw

@goal:Goal -> @spot:Spot -> St

a string value inside a skip, once the slot is known

def str.cont source · line 252 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a string value inside a skip: keep the slot, not the text

def str.val source · line 256 · raw

@ev:Ev -> @rest:String -> @stack:List<&2, Frame> -> @goal:Goal -> St

a string value. A skip that is still inside a container keeps scanning

def str.place source · line 266 · raw

@piece:Piece -> @rest:String -> @stack:List<&2, Frame> -> @goal:Goal -> St

a finished string. A key goes to the open object; anything else is a value

def str.skip source · line 274 · raw

@rest:String -> @stack:List<&2, Frame> -> @goal:Goal -> St

a string a skip will not keep

def place.val.ok.here source · line 282 · raw

@ev:Ev -> @goal:Goal -> @stack:List<&2, Frame> -> @root:Bool -> St

a value has landed, and the cursor rest is the suffix already in hand

def place.val.on.here source · line 292 · raw

@ev:Ev -> @goal:Goal -> @spot:Spot -> St

a value has landed on the suffix in hand, once the slot is known

def place.val.here source · line 300 · raw

@ev:Ev -> @stack:List<&2, Frame> -> @goal:Goal -> St

a value has landed on the suffix in hand

def place.key.here source · line 304 · raw

@ev:Ev -> @frames:List<&2, Frame> -> @goal:Goal -> St

an object key has landed on the suffix in hand

def str.val.here source · line 314 · raw

@ev:Ev -> @stack:List<&2, Frame> -> @goal:Goal -> St

a string value on the suffix in hand. A skip inside a container keeps scanning

def str.place.here source · line 324 · raw

@piece:Piece -> @stack:List<&2, Frame> -> @goal:Goal -> St

a finished string whose rest is the suffix the stepper is on

def str.skip.here source · line 332 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a skipped string closed on the suffix in hand

def span.kind source · line 340 · raw

@cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> @ctrl:Bool -> Skind

one character of a string: stay in it, close it, start an escape, or fail

def span.kind.of source · line 352 · raw

@+ch:Char -> Skind

classify one string character. ch is a code point, so the keep is a word

def close.skip.go source · line 357 · raw

@stack:List<&2, Frame> -> @left:Nat -> @root:Bool -> St

] or } of a skip: depth 1 finishes the value, deeper keeps going. The cursor rest is the suffix the stepper is already on

def close.skip source · line 365 · raw

@stack:List<&2, Frame> -> @depth:Nat -> @root:Bool -> St

] or } of a skip, once the frame has been popped

def close.next source · line 373 · raw

@ev:Ev -> @stack:List<&2, Frame> -> @root:Bool -> St

the parent after a container closes, for a reader

def close.out source · line 377 · raw

@ev:Ev -> @frames:List<&2, Frame> -> @goal:Goal -> St

a container closed. frames is the stack with that frame popped

def close.arr source · line 395 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a ]. Empty, or just after a value

def close.obj source · line 405 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a }. Empty, or just after a value

def punct.comma source · line 415 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a comma between values, or between object members

def punct.colon source · line 425 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

a colon after a key

def punct.arr.go source · line 433 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

[ pushed. A reader returns the begin; a skip counts the container

def punct.arr.if source · line 441 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @ok:Bool -> St

[, once it is known whether a value may start

def punct.arr source · line 449 · raw

@+stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

[, when a value may start

def punct.obj.go source · line 453 · raw

@stack:List<&2, Frame> -> @goal:Goal -> St

{ pushed

def punct.obj.if source · line 461 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @ok:Bool -> St

{, once it is known whether a value may start

def punct.obj source · line 469 · raw

@+stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

{, when a value may start

def punct.go source · line 474 · raw

@tok:0x81c67699424929b5c44cd8577e18117f/src/lex.Tok -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one punctuation token, once the root is still open. The suffix stays with the stepper: a bracket closes on it, and a comma does not keep it

def punct.on source · line 492 · raw

@tok:0x81c67699424929b5c44cd8577e18117f/src/lex.Tok -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one punctuation token

def idle.space source · line 500 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

whitespace, kept as the same state

def look.quote source · line 504 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

a " may open a string here

def look.word source · line 512 · raw

@+ch:Char -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

a word's first character. The buffer is that character, not the array behind it

def look.plan source · line 522 · raw

@ch:Char -> @+stack:List<&2, Frame> -> @+goal:Goal -> @+done:Bool -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

one character between tokens. The suffix stays with the stepper: a bracket closes on it, a comma does not keep it, and a word keeps only its own char

def idle.eof source · line 542 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> Pair(Stop, Cur)

the end of the text, between tokens

def word.kind.num source · line 550 · raw

@ok:Bool -> Atom

a number, when the word is not null, true, or false

def word.kind.go source · line 558 · raw

@num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @is_null:Bool -> @is_true:Bool -> @is_false:Bool -> Atom

null, true, false, or a number that kept a legal spelling

def word.kind source · line 570 · raw

@+cut:String -> @+nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Atom

what a bare word is

def word.eof.place source · line 575 · raw

@atom:Atom -> @cut:String -> @nn:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> St

a word that ended at the end of the text

def lay.plan source · line 596 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

the delimiter of a skipped word, once the value is inside the container. The delimiter is consumed. The caller resumes on the suffix after it

def see.more.on source · line 606 · raw

@goal:Goal -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> @spot:Spot -> St

place the word, then take the delimiter, because the skip is still open

def see.more source · line 614 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

place the word, then take the delimiter

def word.special source · line 619 · raw

@+cp:U32 -> Bool

a code point that ends a bare word: the same bytes classify calls punctuation, a quote, a backslash, or whitespace. A form feed stays in the word

def word.step source · line 639 · raw

@ch:Char -> @+cp:U32 -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Wst

one more plain byte of a word. The buffer grows by that character

def word.keep.go source · line 643 · raw

@ch:Char -> @cp:U32 -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @keep:Bool -> Wst

keep the byte when it is not a delimiter

def word.digit.go source · line 658 · raw

@ch:Char -> @+cp:U32 -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @dig:Bool -> Wst

a digit is never a delimiter, so a long number does not walk classify

def word.decide source · line 673 · raw

@ch:Char -> @+cp:U32 -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Wst

one byte of a word: another plain byte, or the delimiter that ends it

def word.run source · line 677 · raw

@txt:String -> @st:Wst -> Pair(String, Wst)

the suffix after a plain word. Tail call, so a long number is one loop

def word.drop source · line 689 · raw

@txt:String -> Bool

drop an unread suffix. Tail call, so a failed long value does not stack

def word.forget source · line 697 · raw

@buf:List<&2, Char> -> Bool

drop a word's characters. Tail call, so a long spelling does not stack

def word.burst.err source · line 705 · raw

@goal:Goal -> @dropped:Bool -> St

a failed word, once its buffer and the unread suffix are gone

def word.burst.dead source · line 711 · raw

@goal:Goal -> @dropped:Bool -> @buf:List<&2, Char> -> St

a failed word drops the buffer after the unread suffix

def jump.keep source · line 717 · raw

@dropped:Bool -> @st:St -> St

a finished event already carries its suffix. Anything else continues on rest

def jump.unless.done source · line 723 · raw

@+rest:String -> @st:St -> St

a state that already stopped drops rest. Anything else resumes on it

def word.burst.eof.raw source · line 731 · raw

@+raw:String -> @+nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @stack:List<&2, Frame> -> @goal:Goal -> St

a word that ended because the text did, once its spelling is in hand

def word.burst.eof.at source · line 747 · raw

@dropped:Bool -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @stack:List<&2, Frame> -> @goal:Goal -> St

the empty suffix of an eof is dropped, then the word is placed

def word.burst.skip source · line 761 · raw

@rest:String -> @+ch:Char -> @stack:List<&2, Frame> -> @goal:Goal -> St

the skip is still inside a container, so the delimiter is taken and the stepper continues. Only this path classifies that byte

def word.burst.goal source · line 766 · raw

@ev:Ev -> @ch:Char -> @rest:String -> @stack:List<&2, Frame> -> @goal:Goal -> St

a value landed on the delimiter. The suffix is consed back once, not copied. The number keeps its own spelling, so it does not hold the rest of the array

def word.burst.junk source · line 782 · raw

@goal:Goal -> @dropped:Bool -> @rest:String -> St

both the spelling and the unread suffix are dropped when the word is not one

def word.burst.atom source · line 788 · raw

@rest:String -> @ch:Char -> @raw:String -> @nn:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @atom:Atom -> St

place the word. A number keeps its own spelling; the delimiter stays unread

def word.burst.raw source · line 811 · raw

@rest:String -> @ch:Char -> @+raw:String -> @+nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @stack:List<&2, Frame> -> @goal:Goal -> St

the delimiter is classified once, and only when a skip must consume it. The plain bytes never were

def word.burst.stop source · line 823 · raw

@rest:String -> @ch:Char -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @stack:List<&2, Frame> -> @goal:Goal -> St

a word ended on a delimiter. Its spelling is its own text

def word.burst.fail source · line 835 · raw

@goal:Goal -> @dropped:Bool -> @buf:List<&2, Char> -> St

both the unread suffix and the buffer are dropped when the word cannot finish

def word.burst.at source · line 841 · raw

@got:Pair(String, Wst) -> @stack:List<&2, Frame> -> @goal:Goal -> St

got is the suffix after the run, and why it stopped

def word.burst source · line 852 · raw

@txt:String -> @buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @stack:List<&2, Frame> -> @goal:Goal -> @bad:Bool -> St

plain digits and letters in one loop. The delimiter is consed back once

def span.esc source · line 868 · raw

@+cut:String -> @+nn:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

a backslash in a span: copy the prefix, or drop it when skipping

def span.advance source · line 883 · raw

@key:Skind -> @cut:String -> @nn:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

the next state after one character of a span. The unread tail stays with the stepper, so the usual character does not keep it

def quote.go source · line 903 · raw

@key:Skind -> @ch:Char -> @tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

the first character inside a string. A normal one opens the span on this suffix; the stepper then walks the tail, so the keep is once per string

def quote.first source · line 922 · raw

@+ch:Char -> @tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

the first character inside a string

def sk.advance source · line 932 · raw

@key:Skind -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

the next state after one character of a string being skipped

def copy.hit.go source · line 944 · raw

@+ch:Char -> @+tl:String -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> @ctrl:Bool -> St

one character of a string that is being decoded

def copy.hit source · line 965 · raw

@+ch:Char -> @+tl:String -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> @ctrl:Bool -> St

one character of a string that is being decoded

def esc.put source · line 983 · raw

@_tl:String -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @got:Maybe<&2, Char> -> St

the character after a backslash, once u has been noticed

def esc.hit.go source · line 998 · raw

@+ch:Char -> @+tl:String -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @is_u:Bool -> St

the character after a backslash

def esc.hit source · line 1014 · raw

@+ch:Char -> @+tl:String -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

the character after a backslash

def uni.end.go source · line 1030 · raw

@_tl:String -> @cp:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @sur:0x81c67699424929b5c44cd8577e18117f/src/lex.Sur -> St

a \u code point that is not a surrogate

def uni.end source · line 1048 · raw

@tl:String -> @+cp:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

four hex digits are in

def uni.put source · line 1059 · raw

@tl:String -> @left:Nat -> @acc:U32 -> @dig:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one more hex digit, or the code point

def uni.hit.go source · line 1076 · raw

@+ch:Char -> @+tl:String -> @left:Nat -> @acc:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

one hex digit of a \u escape

def uni.hit source · line 1094 · raw

@+ch:Char -> @+tl:String -> @left:Nat -> @acc:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

one hex digit of a \u escape

def hi.hit.go source · line 1112 · raw

@_tl:String -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

the character after a high surrogate, on a live cursor

def hi.hit source · line 1128 · raw

@tl:String -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

the character after a high surrogate: it has to be a backslash

def hiesc.hit.go source · line 1145 · raw

@_tl:String -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @is_u:Bool -> St

the character after the backslash of a pair: it has to be u

def hiesc.hit source · line 1161 · raw

@+ch:Char -> @tl:String -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

the character after the backslash of a pair

def lo.end.go source · line 1178 · raw

@_tl:String -> @lo:U32 -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @sur:0x81c67699424929b5c44cd8577e18117f/src/lex.Sur -> St

the low surrogate is in, or it is not one

def lo.end source · line 1195 · raw

@tl:String -> @+lo:U32 -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

four hex digits of the low surrogate are in

def lo.put source · line 1207 · raw

@tl:String -> @left:Nat -> @acc:U32 -> @hi:U32 -> @dig:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one more hex digit of the low surrogate, or the code point

def lo.hit.go source · line 1225 · raw

@+ch:Char -> @+tl:String -> @left:Nat -> @acc:U32 -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

one hex digit of the low surrogate

def lo.hit source · line 1244 · raw

@+ch:Char -> @+tl:String -> @left:Nat -> @acc:U32 -> @hi:U32 -> @buf:List<&2, Char> -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

one hex digit of the low surrogate

def sk.esc.put source · line 1263 · raw

@_tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @got:Maybe<&2, Char> -> St

a decoded short escape puts the skip back in the string

def sk.esc.go source · line 1277 · raw

@+ch:Char -> @tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @is_u:Bool -> St

a short escape, or the start of \u, inside a skipped string

def sk.esc source · line 1292 · raw

@+ch:Char -> @tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

the character after a backslash in a skipped string

def sk.uni.end.go source · line 1307 · raw

@_tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @sur:0x81c67699424929b5c44cd8577e18117f/src/lex.Sur -> @cp:U32 -> St

a skipped \u that is not a surrogate

def sk.uni.end source · line 1324 · raw

@tl:String -> @+cp:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

four hex digits of a skipped \u are in

def sk.uni.put source · line 1334 · raw

@tl:String -> @left:Nat -> @acc:U32 -> @dig:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one more skipped hex digit, or the code point

def sk.uni.go source · line 1350 · raw

@+ch:Char -> @tl:String -> @left:Nat -> @acc:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

one hex digit of a skipped \u

def sk.uni source · line 1367 · raw

@+ch:Char -> @tl:String -> @left:Nat -> @acc:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St

one hex digit of a skipped \u

def sk.hi source · line 1384 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @hi:U32 -> @cls:0x81c67699424929b5c44cd8577e18117f/src/lex.Class -> St

the character after a skipped high surrogate

def sk.hiesc source · line 1392 · raw

@stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @hi:U32 -> @is_u:Bool -> St

u after the backslash of a skipped pair

def sk.lo.end source · line 1400 · raw

@_tl:String -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @sur:0x81c67699424929b5c44cd8577e18117f/src/lex.Sur -> St

the low half of a skipped pair is in, or it is not one

def sk.lo.put source · line 1408 · raw

@tl:String -> @left:Nat -> @acc:U32 -> @hi:U32 -> @dig:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> St

one more hex digit of a skipped low surrogate, or the code point

def sk.lo.go source · line 1425 · raw

@+ch:Char -> @tl:String -> @left:Nat -> @acc:U32 -> @hi:U32 -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @ok:Bool -> St

one hex digit of a skipped low surrogate

def next.levels source · line 1448 · raw

Nat

the levels of the walk's budget: next.grow runs levels 0 to 32 of leaves of next.leaf() jumps, so a walk may jump back from a plain word 4 (2^33 - 1) times, more than the 2^32 - 1 it had. A byte step keeps the count and shrinks the suffix instead, so a long string does not burn it. The levels, not the count, are the literal, so a proof about next never expands four billion successors

def next.go source · line 1455 · raw

@fuel:Nat -> @txt:String -> @st:St -> Out

one character, between events. A plain word is one tail loop. A finished event returns; everything else tail-calls on the shorter suffix. A string character and a bracket are not handed to the step twice, so a long row or a long array moves the suffix instead of keeping it

def next.leaf source · line 1541 · raw

Nat

the jumps one leaf of the budget allows. A plain word takes two (the burst and the jump back), so most events finish in one leaf. A leaf that runs out is not cut short: next.run resumes it in the next leaf

def next.run source · line 1546 · raw

@lvl:Nat -> @res:Out -> Out

a walk with a budget of 2^lvl jumps: one step's budget at depth 0, and the budget below it twice otherwise. A finished step passes through

def next.grow source · line 1558 · raw

@left:Nat -> @+lvl:Nat -> @res:Out -> Out

a walk that runs level lvl, then the next level up, until it finishes or left levels are done. Most events finish at level 0, one step's budget, so a walk pays for the levels only when it jumps many times

def next.fin source · line 1568 · raw

@res:Out -> Pair(Stop, Cur)

a step's answer. A budget used up is a failure, as it always was

def next.walk source · line 1576 · raw

@txt:String -> @st:St -> Pair(Stop, Cur)

a walk from the start of txt in state st, with the whole budget

def next.ended source · line 1580 · raw

@cur:Cur -> Cur

the cursor after an end: nothing left to read, and the root is over

def next.use source · line 1587 · raw

@got:Pair(Stop, Cur) -> Pair(Ev, Cur)

an event from a step. A skip that surfaces here is a broken reader. An error always comes with the failed cursor, and an end with an ended one, so both stick: the steps build them that way, and this says so where it is used

def next.open source · line 1600 · raw

@rest:String -> @stack:List<&2, Frame> -> @done:Bool -> @bad:Bool -> Pair(Ev, Cur)

the next event, unless the cursor has already failed

def skip.use source · line 1609 · raw

@got:Pair(Stop, Cur) -> Cur

the cursor after a skip. An event other than a failure means the skip stopped on something that was not one value

def skip.open source · line 1620 · raw

@rest:String -> @stack:List<&2, Frame> -> @done:Bool -> @bad:Bool -> Cur

drop one value, unless the cursor has already failed or the root is over

def cursor source · line 1632 · raw

@src:String -> Cur

a cursor at the start of src. It holds that string as its unread suffix, so dropping the caller's own variable does not drop the cursor, and dropping the cursor drops what it has not read yet

def next source · line 1638 · raw

@cur:Cur -> Pair(Ev, Cur)

the next event. A comma or a colon is consumed on the way to the event after it. After the root value, further calls are the end, or an error when another value follows

def skip source · line 1645 · raw

@cur:Cur -> Cur

drop the next value: one scalar, or one array or object with everything inside it. The cursor is left where that value ended. A string with no escapes is not copied; a string being skipped is not decoded into a buffer

def text source · line 1651 · raw

@ev:Ev -> Maybe<&2, String>

the text of a string, a key, or a number. A span is copied here. None when the event is not one of those