Grip.Scan: total scanners and repetition #
The looping combinators, all total (structural on arr.size - q) rather than partial.
The raw scan loops scanFwd/foldFwd/natFwd with their forward-progress lemmas, and
the parsers built on them: takeWhile/takeWhile1, foldMany/many, and nat. Also
the JSON string scanners: the lenient scanStrFwd/takeStringBody (escape-aware, never
fails) and the strict scanStrBody/scanStrLit/stringLit (validates escapes and
control bytes). The @[specialize] on each loop lets a statically-known predicate
monomorphize into it. The point combinators are in Grip.Byte; the graded type and
fix in Grip.Graded.
Scan forward while f holds. Total: structural on the measure
arr.size - q (each step advances one byte, bounded by arr.size). @[specialize] so
a known predicate (e.g. Ascii.isWs) is monomorphized into the loop rather than called
indirectly per byte.
Equations
Instances For
Scan a JSON-style string body: advance until an unescaped " (0x22), treating a
backslash (0x5c) as an escape that consumes the next byte too. Total: structural on
arr.size - q.
Equations
- One or more equations did not get rendered due to their size.
Instances For
scanStrFwd never rewinds.
scanStrFwd stays within bounds when it starts within bounds.
Scan a JSON string body (escape-aware), returning the number of bytes consumed.
Always succeeds (result is .ok). Pair with a " on each side for a full string literal.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Scan a strict RFC-8259 string body: from just after the opening " at q, advance to
and past the closing ", validating escapes. Returns some end (just past the closing quote)
on a well-formed body, or none on a malformed one: an unescaped control byte (< 0x20), an
unknown \-escape, a \u not followed by four hex digits, or end of input before the closing
quote. Total (structural on arr.size - q). Unlike scanStrFwd, this validates and can
reject, so the parser built on it is conditional, not flexible.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A successful scanStrBody never rewinds.
A successful scanStrBody stays within bounds.
Scan a strict JSON string literal starting at the opening ": some end (past the
closing ") or none.
Equations
Instances For
A successful scanStrLit strictly advances (it consumes the opening quote).
A successful scanStrLit stays within bounds.
A validated JSON string literal "..." in one scan, returning the number of bytes
consumed (both quotes included). Fails on a malformed literal (see scanStrBody). This is the
strict, single-pass counterpart to ch '"' *> takeStringBody *> ch '"': it validates
escapes and rejects control bytes without per-byte combinator dispatch. On failure the furthest
offset is the current position.
Equations
- One or more equations did not get rendered due to their size.
Instances For
One-or-more bytes satisfying f.
On failure the furthest offset is the current position.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Total repetition core: fold p's results into a, advancing while p succeeds
and strictly consumes (in bounds). Total: structural on arr.size - q; the
guard q < q' ≤ arr.size guarantees the measure drops. @[specialize] so the step
and the element parser fuse into the loop when they are statically known.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Fold p zero-or-more times into acc (no list). Total (see foldFwd).
Always succeeds (result is .ok).
Equations
- One or more equations did not get rendered due to their size.
Instances For
natFwd unfolded one step with the let inlined (so split sees the branch).
Parse a decimal natural number (one or more digits). Always consumes on success. On failure the furthest offset is the current position.
Equations
- One or more equations did not get rendered due to their size.