Decoding and encoding iterators #
Decoders and encoders transform pure iterators, Std.Iter over Id, of one kind of token into
another: bytes into code units, code units into characters, and back.
A decoder d : δ with [Decoder δ τ σ] reads one token of type σ from the tokens of type τ
at an iterator: Decoder.decode d it continues with the token and the iterator after it, with a
DecodeError.Kind and the iterator after the ill-formed input, or with the end of the input. It
looks ahead by stepping copies of it, so it needs no buffer. DecodeIterator δ ι repeats it over
an iterator of type ι. A strict decoding iterator stops at ill-formed input, where
it.decodeError? tells why, it.decodeFailure? finds the first ill-formed input ahead, and
it.decodeContinue? goes on after it; a lossy one yields Decoder.replacement d instead and goes on
after the ill-formed input. it.decodeFold folds over the tokens and returns the iterator where
decoding stopped.
DecodeError.Kind and DecodeError have ToString instances for error messages.
An encoder e : ε with [Encoder ε σ τ] gives the tokens of type τ that encode a token of
type σ, and EncodeIterator ε ι yields them for each token of an iterator of type ι.
Each step of these iterators either moves the inner iterator strictly forward or, for encoders,
yields a token that is still pending from the last one. The inner iterator is it.decodeBase or
it.encodeBase, and it.encodeBoundary tells whether nothing is pending. Decoders always stop
between two tokens, so the position of the inner iterator is the position of the error.
it' is reachable from it by one or more plausible successor steps.
Equations
- Unicode.Advanced it' it = it'.finitelyManySteps!.Rel it.finitelyManySteps!
Instances For
Steps it past any skip steps. Calls yield with the next token and the iterator after it, or
done at the end of the input. Written in continuation-passing style, and inlined, so that
specialization avoids allocating an intermediate result. Further skip steps go through a loop that
returns data rather than taking yield: a continuation passed into that loop would become a closure,
allocated for every token even when nothing skips.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Why input is ill-formed.
- illFormedUTF8 : Kind
A maximal subpart of an ill-formed UTF-8 byte sequence.
- unpairedSurrogate : Kind
A UTF-16 surrogate code unit that is not part of a surrogate pair.
- notScalarValue : Kind
A UTF-32 code unit that is not a Unicode scalar value.
- incompleteCodeUnit : Kind
An incomplete code unit at the end of the bytes of UTF-16 or UTF-32 code units.
Instances For
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
A description of ill-formed input of kind k, for error messages.
Equations
- Unicode.DecodeError.Kind.illFormedUTF8.toString = "ill-formed UTF-8"
- Unicode.DecodeError.Kind.unpairedSurrogate.toString = "unpaired surrogate"
- Unicode.DecodeError.Kind.notScalarValue.toString = "not a Unicode scalar value"
- Unicode.DecodeError.Kind.incompleteCodeUnit.toString = "incomplete code unit"
Instances For
Equations
- Unicode.instToStringKind = { toString := Unicode.DecodeError.Kind.toString }
Ill-formed input: why, and where. The position is the index of the first token of the ill-formed input: of the code unit for UTF-16 and UTF-32, and of the byte for UTF-8 and the encoding schemes, counting a byte order mark or signature.
- kind : Kind
Why the input is ill-formed.
- pos : Nat
The index of the first token of the ill-formed input, in code units or bytes.
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Unicode.instReprDecodeError = { reprPrec := Unicode.instReprDecodeError.repr }
A description of the error e for error messages, such as unpaired surrogate at offset 2. The
offset is e.pos, in code units or bytes as the decoding function tells.
Instances For
Equations
- Unicode.instToStringDecodeError = { toString := Unicode.DecodeError.toString }
Decoders #
A decoder d : δ reads tokens of type σ from tokens of type τ.
- replacement : δ → σ
The token that lossy decoding yields for ill-formed input.
- decode {ι : Type} [Std.Iterator ι Id τ] [Std.Iterators.Productive ι Id] {β : Type} (d : δ) (it : Std.Iter τ) (yield : (rest : Std.Iter τ) → Advanced rest it → σ → β) (error : DecodeError.Kind → (rest : Std.Iter τ) → Advanced rest it → β) (done : Unit → β) : β
Decodes one token from
it. Callsyieldwith the token and the iterator after it,errorwith the error and the iterator after the ill-formed input, ordoneat the end of the input.
Instances
Iterator over the tokens decoded by decoder from an iterator of type ι.
- decoder : δ
The decoder.
- lossy : Bool
Whether ill-formed input yields
Decoder.replacement decoderrather than ending. - inner : Std.Iter τ
The input iterator.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Every step moves the input iterator strictly forward.
The loop behind for loops and the Std.Iterators consumers on decoding iterators. Logically it
is Std.IteratorLoop.defaultImplementation, which steps the iterator one token at a time; it is
implemented by decoding directly from the input iterator.
Equations
- Unicode.DecodeIterator.forIn lift γ Pl it init f = Std.IteratorLoop.forIn lift γ Pl it init f
Instances For
Equations
The input iterator, at the start of the next token to decode.
Equations
- it.decodeBase = it.internalState.inner
Instances For
The error in the input at it, if the input there is ill-formed. When a strict decoding iterator
stops, this is why: none means that it reached the end of the input.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The kind of the ill-formed input at it, if there is one, and the iterator after it, with the same
decoder and mode. A strict decoding iterator stops at ill-formed input: this is how a client such as
a parser goes on after it. The iterator after the ill-formed input comes with the proof that it is
reachable from it, for clients that track progress.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Whether it yields Decoder.replacement for ill-formed input rather than ending there.
Equations
- it.decodeIsLossy = it.internalState.lossy
Instances For
Decodes the tokens of it with d, stopping at the first ill-formed input.
A for loop or fold over the result ends at ill-formed input just as at the end of the input. To
tell them apart, fold with decodeFold, which also returns the iterator where decoding stopped, and
check decodeError? there, find the first ill-formed input ahead with decodeFailure?, or decode
with Decoder.iterLossy instead.
Equations
Instances For
Decodes the tokens of it with d, replacing each ill-formed input with
Decoder.replacement d.
Equations
Instances For
Decodes the tokens of it with d and folds them with f from init, up to the first ill-formed
input. Returns the result, and the kind of error and the iterator at the ill-formed input, if any.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Decodes the tokens of it with d and folds them with f from init, with
Decoder.replacement d for each ill-formed input.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The first ill-formed input from it on, if any: its kind, and the iterator with the same decoder at
its start. A strict decoding iterator stops there, so this finds where and why a parser or a loop
over it would see the end of the input early.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Folds f over the tokens of it from init, and returns the result with the iterator where
decoding stopped: at the end of the input, or for a strict decoding iterator at ill-formed input.
There, decodeError? tells why and decodeContinue? goes on after it. A for loop or fold
gives the result alone.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Encoders #
Iterator over the tokens that encoder writes for each token of an iterator of type ι. The
encoding of the last input token current has length tokens, of which those before index have
been yielded.
- encoder : ε
The encoder.
- inner : Std.Iter σ
The input iterator, after
current. - current : σ
The last input token.
- index : Nat
The index of the next token of the encoding of
current. - length : Nat
The number of tokens of the encoding of
current.
Instances For
Plausible steps: yield a pending token, or read the next input token.
Equations
- One or more equations did not get rendered due to their size.
- Unicode.EncodeIterator.PlausibleStep it Std.IterStep.done = (¬it.internalState.index < it.internalState.length ∧ it.internalState.inner.IsPlausibleStep Std.IterStep.done)
Instances For
Equations
- One or more equations did not get rendered due to their size.
The loop behind for loops and the Std.Iterators consumers on encoding iterators. Logically it
is Std.IteratorLoop.defaultImplementation, which steps the iterator one token at a time; it is
implemented by reading the input iterator directly.
Equations
- Unicode.EncodeIterator.forIn lift γ Pl it init f = Std.IteratorLoop.forIn lift γ Pl it init f
Instances For
The input iterator, after the token whose encoding is being yielded.
Equations
- it.encodeBase = it.internalState.inner
Instances For
Whether the encoding of the last input token has been yielded entirely.
Equations
- it.encodeBoundary = decide (it.internalState.length ≤ it.internalState.index)