Module
LinkCode predicates classify an integer. Indexed predicates classify one Unicode scalar in a string. Span scans return the first position after consecutive matches. Every position uses the same scalar unit as string indexing.
Why
LinkExplicit ASCII classes give parsers stable boundaries without locale rules. Scalar positions compose with existing string indexing and slicing.
Availability
LinkImport std.parser in language mode 5.21. The current compiler selects std/parser.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Public API
Linkstd.parser.isAsciiWhitespaceCode
std.parser.takeWhileAsciiDigit
std.parser.takeWhileAsciiAlpha
Pending contracts
LinkClassify integer ASCII codes
LinkClassify integer ASCII codes
is returns true for integers from 48 through 57, inclusive. These are the ASCII digits from 0 through 9.
is returns true for integers from 65 through 90 or from 97 through 122, inclusive. These are ASCII uppercase and lowercase letters.
is returns true when the digit predicate or the letter predicate returns true.
is returns true for 9, 10, 11, 12, 13, and 32. These represent tab, line feed, vertical tab, form feed, carriage return, and space.
Every other int returns false. Negative values, surrogate code values, non ASCII characters, and integers above the Unicode range do not cause a diagnostic.
Each call evaluates its input once. Classification has no side effects and does not consult a locale, normalize text, or fold case.
Why
Exact integer sets make ASCII parsing independent of host text rules. A false result handles a value outside the class without introducing an error channel.
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 72 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 307 -
topaz.stdlib.contract.parser-ascii-codesatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Include each ASCII endpoint and exclude its neighbors
Linkimport std.parserimport std.iofor cp in ([47, 48, 57, 58, 64, 65, 90, 91, 96, 97, 122, 123, 8, 9, 10, 11, 12, 13, 14, 31, 32, 33]) {let digit = parser.isAsciiDigitCode(cp)let alpha = parser.isAsciiAlphaCode(cp)let alnum = parser.isAsciiAlnumCode(cp)let space = parser.isAsciiWhitespaceCode(cp)io.writeLine("{digit}/{alpha}/{alnum}/{space}")}
false/false/false/false true/false/true/false true/false/true/false false/false/false/false false/false/false/false false/true/true/false false/true/true/false false/false/false/false false/false/false/false false/true/true/false false/true/true/false false/false/false/false false/false/false/false false/false/false/true false/false/false/true false/false/false/true false/false/false/true false/false/false/true false/false/false/false false/false/false/false false/false/false/true false/false/false/false
Expected result
Expected result
Execution completes. Exit code 0.
false/false/false/falsetrue/false/true/falsetrue/false/true/falsefalse/false/false/falsefalse/false/false/falsefalse/true/true/falsefalse/true/true/falsefalse/false/false/falsefalse/false/false/falsefalse/true/true/falsefalse/true/true/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/truefalse/false/false/truefalse/false/false/truefalse/false/false/truefalse/false/false/truefalse/false/false/falsefalse/false/false/falsefalse/false/false/truefalse/false/false/false
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 72 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 307 -
topaz.stdlib.contract.parser-ascii-codesatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Return false for invalid code points and non ASCII values
Linkimport std.parserimport std.iofor cp in ([-1, 128, 233, 55296, 1114112, 9223372036854775807]) {let digit = parser.isAsciiDigitCode(cp)let alpha = parser.isAsciiAlphaCode(cp)let alnum = parser.isAsciiAlnumCode(cp)let space = parser.isAsciiWhitespaceCode(cp)io.writeLine("{digit}/{alpha}/{alnum}/{space}")}
false/false/false/false false/false/false/false false/false/false/false false/false/false/false false/false/false/false false/false/false/false
Expected result
Expected result
Execution completes. Exit code 0.
false/false/false/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/false
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 72 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 307 -
topaz.stdlib.contract.parser-ascii-codesatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Classify a scalar position
LinkClassify a scalar position
The index counts Unicode scalars from zero. A multibyte scalar occupies one position. A combining scalar occupies its own position.
A present scalar is classified by the corresponding code predicate. Non ASCII scalars return false, including a nonbreaking space and letters outside the ASCII ranges.
A negative index or an index at or beyond the scalar length returns false. Index zero in an empty string also returns false. These cases do not produce a diagnostic.
The result agrees with applying the corresponding code predicate to text. when it returns Some(code). A None() result means false.
The text expression is evaluated before the index expression, once each. Classification leaves the string unchanged and performs no I/O.
Why
A shared scalar coordinate system lets parser positions pass directly to string operations. An absent position is a failed predicate, so end of input needs no exceptional control flow.
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 324 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1148 -
topaz.stdlib.contract.parser-ascii-positionsatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Keep scalar positions through multibyte and combining text
Linkimport std.parserimport std.iolet text = "é5éZ "for index in ([0, 1, 2, 3, 4, 5, 6]) {let digit = parser.isAsciiDigit(text, index)let alpha = parser.isAsciiAlpha(text, index)let alnum = parser.isAsciiAlnum(text, index)let space = parser.isAsciiWhitespace(text, index)io.writeLine("{digit}/{alpha}/{alnum}/{space}")}
false/false/false/false true/false/true/false false/true/true/false false/false/false/false false/true/true/false false/false/false/false false/false/false/true
Expected result
Expected result
Execution completes. Exit code 0.
false/false/false/falsetrue/false/true/falsefalse/true/true/falsefalse/false/false/falsefalse/true/true/falsefalse/false/false/falsefalse/false/false/true
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 324 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1148 -
topaz.stdlib.contract.parser-ascii-positionsatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Treat negative positions and end of input as false
Linkimport std.parserimport std.iolet text = "7"for index in ([-1, 1, 2, 9223372036854775807]) {let digit = parser.isAsciiDigit(text, index)let alpha = parser.isAsciiAlpha(text, index)let alnum = parser.isAsciiAlnum(text, index)let space = parser.isAsciiWhitespace(text, index)io.writeLine("{digit}/{alpha}/{alnum}/{space}")}let empty = ""let digit = parser.isAsciiDigit(empty, 0)let alpha = parser.isAsciiAlpha(empty, 0)let alnum = parser.isAsciiAlnum(empty, 0)let space = parser.isAsciiWhitespace(empty, 0)io.writeLine("{digit}/{alpha}/{alnum}/{space}")
false/false/false/false false/false/false/false false/false/false/false false/false/false/false false/false/false/false
Expected result
Expected result
Execution completes. Exit code 0.
false/false/false/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/falsefalse/false/false/false
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 324 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1148 -
topaz.stdlib.contract.parser-ascii-positionsatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Scan a maximal ASCII span
LinkScan a maximal ASCII span
Each scan uses the class named by its corresponding ASCII predicate. The starting position and result follow the zero based scalar positions.
Clamp a negative start to zero. Clamp a start greater than the scalar length to that length. The first position examined is the clamped start.
Inspect consecutive positions from left to right. Stop at the first nonmatching scalar or at the scalar length. Return that exclusive end position.
If the first scalar does not match, return the clamped start. Starting at end of input returns that end. Every scan of an empty string returns zero.
A non ASCII scalar ends the span. Scanning does not skip it, normalize it, or advance across it to find a later match.
The text expression is evaluated before the start expression, once each. Scans do not modify the text or perform I/O. An out of range start produces a bounded result without a diagnostic.
For a clamped start begin and returned end, text. is the matched text. The scan reports a position rather than a character count.
Why
Maximal spans let callers resume at the first unconsumed scalar. Clamping uses the same bounds as string slicing and gives empty input a useful result.
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 352 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1215 -
topaz.stdlib.contract.parser-ascii-spansatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Find the exclusive end for every ASCII class
Linkimport std.parserimport std.iolet digit = parser.takeWhileAsciiDigit("123x", 0)let alpha = parser.takeWhileAsciiAlpha("abZ9", 0)let alnum = parser.takeWhileAsciiAlnum("a9Z_", 0)let space = parser.takeWhileAsciiWhitespace("\t\n\r x", 0)io.writeLine("{digit}/{alpha}/{alnum}/{space}")
3/3/3/4
Expected result
Expected result
Execution completes. Exit code 0.
3/3/3/4
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 352 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1215 -
topaz.stdlib.contract.parser-ascii-spansatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Stop at non ASCII scalars without changing position units
Linkimport std.parserimport std.iolet digit = parser.takeWhileAsciiDigit("é12x", 1)let combining = parser.takeWhileAsciiAlpha("éA", 0)let suffix = parser.takeWhileAsciiAlpha("éA", 2)let nonbreaking = parser.takeWhileAsciiWhitespace(" ", 0)let alnum = parser.takeWhileAsciiAlnum("Aé", 0)io.writeLine("{digit}/{combining}/{suffix}/{nonbreaking}/{alnum}")
3/1/3/0/1
Expected result
Expected result
Execution completes. Exit code 0.
3/1/3/0/1
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 352 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1215 -
topaz.stdlib.contract.parser-ascii-spansatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi
Clamp starts and keep the first failing position
Linkimport std.parserimport std.iolet text = "12"for start in ([-3, 0, 1, 2, 99]) {let digit = parser.takeWhileAsciiDigit(text, start)let alpha = parser.takeWhileAsciiAlpha(text, start)let alnum = parser.takeWhileAsciiAlnum(text, start)let space = parser.takeWhileAsciiWhitespace(text, start)io.writeLine("{digit}/{alpha}/{alnum}/{space}")}let empty = ""let digit = parser.takeWhileAsciiDigit(empty, 99)let alpha = parser.takeWhileAsciiAlpha(empty, -1)let alnum = parser.takeWhileAsciiAlnum(empty, 0)let space = parser.takeWhileAsciiWhitespace(empty, 1)io.writeLine("{digit}/{alpha}/{alnum}/{space}")
2/0/2/0 2/0/2/0 2/1/2/1 2/2/2/2 2/2/2/2 0/0/0/0
Expected result
Expected result
Execution completes. Exit code 0.
2/0/2/02/0/2/02/1/2/12/2/2/22/2/2/20/0/0/0
Source evidence
- compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 352 - compiler/crates/topaz_resolve/src/stdlib.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 1215 -
topaz.stdlib.contract.parser-ascii-spansatworking-tree - topaz.decision.parser-scalar-ascii.1 at
topaz.decisi