gralha-text-scan Releases (2): 0.1.0.1 0x2370002bb215388f2e71cae632c87c34 indexed https://jend.leeeet.dev/files.txt?path=gralha-text-scan@0.1.0.1 0.1.0.0 0xaff2b2d0565125a37b5df94a39451ef8 unindexed https://jend.leeeet.dev/files.txt?path=gralha-text-scan@0.1.0.0 Definitions (50): Scan.choose (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=choose) def choose(-A: Type, yes: Bool, a: A, b: A) -> A: Scan.max.u32 (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=max.u32) def max.u32(+a: U32, +b: U32) -> U32: Scan.min.u32 (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=min.u32) def min.u32(+a: U32, +b: U32) -> U32: Scan.min (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=min) def min(+a: F32, +b: F32) -> F32: Scan.max (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=max) def max(+a: F32, +b: F32) -> F32: Scan.clamp (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=clamp) def clamp(x: F32, lo: F32, hi: F32) -> F32: Scan.code (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=code) def code(c: Char) -> U32: Scan.space (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=space) def space(+c: U32) -> Bool: Scan.digit (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=digit) def digit(+c: U32) -> Bool: Scan.rev (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=rev) def rev(s: String, acc: String) -> String: Scan.string.equal.go (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=string.equal.go) # `same` says whether the characters before `a` and `b` matched: deciding # it one step ahead keeps the loop a tail call on the shrinking `a`. def string.equal.go(a: String, b: String, same: Bool) -> Bool: Scan.string.equal (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=string.equal) def string.equal(a: String, b: String) -> Bool: Scan.branch (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=branch) def branch(-A: Type, yes: Bool, a: Unit -> A, b: Unit -> A) -> A: Scan.trim (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=trim) def trim(+s: String) -> String: Scan.Scan (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=Scan) type Scan is Data: Scan{head: String, tail: String} Scan.until.go (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=until.go) # Scanning loops decide each character one step ahead (`hit` says whether # `c`, the character before `t`, ends the scan), so the rest of the text is # only ever held once: a shared tail would make every step pay for the # sharing. The rest comes first, as the argument that shrinks. def until.go(t: String, hit: Bool, +c: U32, +end: U32, acc: String) -> Scan: Scan.until (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=until) def until(s: String, +end: U32, acc: String) -> Scan: Scan.prefix (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=prefix) def prefix(s: String, p: String) -> Bool: Scan.drop (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=drop) def drop(s: String, p: String) -> String: Scan.through (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=through) def through(+s: String, +p: String) -> String: Scan.until.sequence (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=until.sequence) def until.sequence(+s: String, +end: String, +acc: String) -> Scan: Scan.separator (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=separator) # SVG number grammar, including adjacent signs and scientific notation. def separator(+c: U32) -> Bool: Scan.separators.go (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=separators.go) def separators.go(t: String, skip: Bool, +c: U32) -> String: Scan.separators (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=separators) def separators(s: String) -> String: Scan.number.exponent (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.exponent) def number.exponent(+s: String) -> Bool: Scan.Number (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=Number) type Number is Data: Number{value: F32, tail: String, valid: Bool} Scan.number.class (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.class) # A number is read straight into a float: digits accumulate the mantissa # (fraction digits also scale a divisor), an exponent accumulates its own # digits, and a sign is taken where it may appear. Nothing is copied into a # scratch string. Each character is classified one step ahead, so the loop # branches on parameters: class 0 digit, 1 dot, 2 exponent mark, 3 sign, # 4 anything else; stage 0 start, 1 mantissa, 2 fraction, 3 after the # mark, 4 exponent digits. An exponent mark that no digit follows is not # part of the number (as in "1em"), so `mark` keeps what was read from the # mark on (the mark and any signs, reversed) to give back in that case. def number.class(+c: U32) -> U32: Scan.number.accepts (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.accepts) def number.accepts(+k: U32, +stage: U32, +digits: Bool) -> Bool: Scan.number.stage (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.stage) def number.stage(+k: U32, +stage: U32) -> U32: Scan.number.mark (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.mark) def number.mark(keep: Bool, +c: U32, mark: String) -> String: Scan.number.pow10 (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.pow10) def number.pow10(n: Nat, +acc: F32) -> F32: Scan.number.tail (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.tail) def number.tail(dangling: Bool, mark: String, rest: String) -> String: Scan.number.finish (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.finish) # The value from the parts; `rest` is the string from the stop. def number.finish(rest: String, mark: String, +stage: U32, +sign: F32, +mant: F32, +div: F32, +esign: F32, +ev: U32, +digits: Bool, +edigits: Bool) -> Number: Scan.number.go (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.go) # `c` is the character before `t`; `ok` says whether it was read, and the # parts are the ones after it. The next character is read when the stage # accepts it, and otherwise the parts are kept and the number stops there. def number.go(t: String, ok: Bool, +c: U32, mark: String, +stage: U32, +sign: F32, +mant: F32, +div: F32, +esign: F32, +ev: U32, +digits: Bool, +edigits: Bool) -> Number: Scan.number (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number) # The loop starts as if after a character that was read, with nothing yet. def number(s: String) -> Number: Scan.number.default (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=number.default) def number.default(num: Number, fallback: F32) -> F32: Scan.scalar (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=scalar) def scalar(s: String, fallback: F32) -> F32: Scan.numbers.next (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=numbers.next) def numbers.next(num: Number, next: String -> List<&2, F32>) -> List<&2, F32>: Scan.numbers.go (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=numbers.go) # Every number read takes at least one character (a digit), so the text's # length bounds how many there are. def numbers.go(fuel: Nat, s: String) -> List<&2, F32>: Scan.numbers (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=numbers) def numbers(+s: String) -> List<&2, F32>: Scan.nth (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=nth) def nth(xs: List<&2, F32>, i: Nat, fallback: F32) -> F32: Scan.uints.nth (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=uints.nth) def uints.nth(xs: List<&2, U32>, n: Nat, +fallback: U32) -> U32: Scan.hex.digit (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=hex.digit) def hex.digit(+c: U32) -> U32: Scan.hex (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=hex) def hex(s: String, acc: U32) -> U32: Scan.trim.both (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=trim.both) def trim.both(s: String) -> String: Scan.unit (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=unit) def unit(num: Number, reference: F32) -> F32: Scan.string.contains (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=string.contains) def string.contains(+s: String, +part: String) -> Bool: Scan.scan.head (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=scan.head) def scan.head(s: Scan) -> String: Scan.unquote (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=unquote) def unquote(+s: String) -> String: Scan.strings.has (https://jend.leeeet.dev/definition.txt?path=gralha-text-scan@0.1.0.1/scan.bend&name=strings.has) def strings.has(xs: List<&2, String>, +s: String) -> Bool: