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
SValSlot
SComSlot
SKeySlot
SColSlot
type Frame source · line 18 · raw
Data
an open array or object. fresh is the empty container, before any value
FArr@slot:Slot -> @fresh:Bool -> Frame
FObj@slot:Slot -> @fresh:Bool -> Frame
type Ev source · line 23 · raw
Data
one event. A span is the first nn chars of a source suffix, not a copy
ENullEv
EBool@b:Bool -> Ev
ENum@src:String -> @nn:U32 -> Ev
EStr@body:String -> Ev
EStrS@src:String -> @nn:U32 -> Ev
EKey@body:String -> Ev
EKeyS@src:String -> @nn:U32 -> Ev
EBeginArrEv
EEndArrEv
EBeginObjEv
EEndObjEv
EEndEv
EErrEv
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
Cur@rest:String -> @stack:List<&2, Frame> -> @done:Bool -> @bad:Bool -> Cur
type Goal source · line 44 · raw
Data
read the next event, or drop one whole value
GNextGoal
GSkip@depth:Nat -> Goal
type Stop source · line 49 · raw
Data
what a step hands back: an event, or a finished skip
SEv@ev:Ev -> Stop
SSkipStop
type Atom source · line 54 · raw
Data
a bare word, once it has been classified
ANullAtom
ATrueAtom
AFalseAtom
ANumAtom
ABadAtom
type Piece source · line 62 · raw
Data
a string's text: a span of the source, or chars decoded from escapes
PSpan@cut:String -> @nn:U32 -> Piece
POwn@body:String -> Piece
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
KGoSkind
KEndSkind
KEscSkind
KBadSkind
type Spot source · line 75 · raw
Data
where a finished value lands, or that the slot cannot take one
Spot@stack:List<&2, Frame> -> @root:Bool -> Spot
SpotBadSpot
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
MIdleMode
MWord@buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Mode
a bare word's characters, reversed, so the unread array is not kept
MSpan@cut:String -> @nn:U32 -> Mode
MCopy@buf:List<&2, Char> -> Mode
MEsc@buf:List<&2, Char> -> Mode
MUni@left:Nat -> @acc:U32 -> @buf:List<&2, Char> -> Mode
MHi@hi:U32 -> @buf:List<&2, Char> -> Mode
MHiEsc@hi:U32 -> @buf:List<&2, Char> -> Mode
MLo@left:Nat -> @acc:U32 -> @hi:U32 -> @buf:List<&2, Char> -> Mode
MSkStrMode
MSkEscMode
MSkUni@left:Nat -> @acc:U32 -> Mode
MSkHi@hi:U32 -> Mode
MSkHiEsc@hi:U32 -> Mode
MSkLo@left:Nat -> @acc:U32 -> @hi:U32 -> Mode
MDone@stop:Stop -> @saved:String -> Mode
MRest@stop:Stop -> Mode
the cursor rest is the suffix the stepper is already on, so closing a long string does not keep that suffix a second time
MQuoteMode
the quote is consumed; the next character is the first of the string
MJump@rest:String -> @mode:Mode -> Mode
resume
modeonrestafter a plain word, which the stepper did not walk byte by byte
type St source · line 109 · raw
Data
the scanner's state, apart from the unread suffix it is walking
S@mode:Mode -> @stack:List<&2, Frame> -> @goal:Goal -> @done:Bool -> @bad:Bool -> St
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
Fin@got:Pair(Stop, Cur) -> Out
More@txt:String -> @st:St -> Out
type Wst source · line 633 · raw
Data
where a plain word run stopped. A stop keeps the delimiter, already consumed
WMore@buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Wst
WStop@buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> @ch:Char -> Wst
WEof@buf:List<&2, Char> -> @nn:U32 -> @num:0x81c67699424929b5c44cd8577e18117f/src/value.Num -> Wst
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