Skip to main content

brink_syntax_native/lexer/
ident.rs

1use crate::SyntaxKind;
2
3/// Returns `true` if the byte at `pos` starts (or continues) a native
4/// identifier.
5///
6/// Finding #2 (`syntax_kind.rs` doc comment): ASCII-only (`[A-Za-z_]`), no
7/// digits at this call site (callers handle digit-start sequences
8/// separately to distinguish numbers from idents), no Unicode identifier
9/// ranges. The charter's S4 casing partition (`snake_case` modules /
10/// `UpperCamel` types) is an ASCII-shaped rule with no ruling extending it
11/// to ink's Unicode identifier table; widening later is additive.
12pub fn is_ident_start_byte(b: u8) -> bool {
13    b.is_ascii_alphabetic() || b == b'_'
14}
15
16/// Returns `true` if the byte at `pos` can continue an identifier
17/// (start-class plus digits).
18pub fn is_ident_continue_byte(b: u8) -> bool {
19    b.is_ascii_alphanumeric() || b == b'_'
20}
21
22/// Scan forward from `pos` (already past the first identifier byte) while
23/// bytes continue the identifier.
24pub fn scan_ident(bytes: &[u8], mut pos: usize) -> usize {
25    while pos < bytes.len() && is_ident_continue_byte(bytes[pos]) {
26        pos += 1;
27    }
28    pos
29}
30
31/// Classify an identifier string as a keyword or plain `IDENT`.
32pub fn classify_keyword(text: &str) -> SyntaxKind {
33    use SyntaxKind::{
34        IDENT, KW_AS, KW_BREAK, KW_CONST, KW_CONTINUE, KW_DONE, KW_ELSE, KW_END, KW_EXTERN,
35        KW_FALSE, KW_FLAGS, KW_FLOW, KW_FN, KW_FOR, KW_IF, KW_IMPORT, KW_IN, KW_LET, KW_MATCH,
36        KW_MODULE, KW_OR, KW_PUB, KW_REF, KW_RETURN, KW_STRUCT, KW_TRUE, KW_UNTIL, KW_USE, KW_VAR,
37        KW_WHILE,
38    };
39    match text {
40        "pub" => KW_PUB,
41        "flow" => KW_FLOW,
42        "fn" => KW_FN,
43        "var" => KW_VAR,
44        "const" => KW_CONST,
45        "let" => KW_LET,
46        "flags" => KW_FLAGS,
47        "struct" => KW_STRUCT,
48        "extern" => KW_EXTERN,
49        "import" => KW_IMPORT,
50        "use" => KW_USE,
51        "module" => KW_MODULE,
52        "return" => KW_RETURN,
53        "ref" => KW_REF,
54        "if" => KW_IF,
55        "match" => KW_MATCH,
56        "else" => KW_ELSE,
57        "while" => KW_WHILE,
58        "for" => KW_FOR,
59        "in" => KW_IN,
60        "until" => KW_UNTIL,
61        "break" => KW_BREAK,
62        "continue" => KW_CONTINUE,
63        "as" => KW_AS,
64        "or" => KW_OR,
65        "true" => KW_TRUE,
66        "false" => KW_FALSE,
67        "END" => KW_END,
68        "DONE" => KW_DONE,
69        _ => IDENT,
70    }
71}