devalang_wasm/language/syntax/lexer/
utils.rs

1pub fn compute_indent(line: &str) -> (usize, usize) {
2    let mut indent = 0usize;
3    let mut cursor = 0usize;
4    for ch in line.chars() {
5        match ch {
6            ' ' => {
7                indent += 1;
8                cursor += 1;
9            }
10            '\t' => {
11                indent += 4;
12                cursor += 1;
13            }
14            _ => break,
15        }
16    }
17    (indent, cursor)
18}
19
20pub fn is_identifier_start(ch: char) -> bool {
21    ch.is_ascii_alphabetic() || ch == '_' || ch == '$'
22}
23
24pub fn is_identifier_continue(ch: char) -> bool {
25    ch.is_ascii_alphanumeric() || matches!(ch, '_' | '-' | '$' | '.')
26}
27
28pub fn lex_identifier(line: &str, start: usize) -> usize {
29    let mut end = start;
30    for ch in line[start..].chars() {
31        if is_identifier_continue(ch) {
32            end += ch.len_utf8();
33        } else {
34            break;
35        }
36    }
37    end
38}
39
40pub fn lex_number(line: &str, start: usize) -> (usize, crate::language::syntax::tokens::TokenKind) {
41    let mut end = start;
42    let mut has_dot = false;
43    for ch in line[start..].chars() {
44        match ch {
45            '0'..='9' => {
46                end += 1;
47            }
48            '.' if !has_dot => {
49                has_dot = true;
50                end += 1;
51            }
52            _ => break,
53        }
54    }
55
56    let mut kind = crate::language::syntax::tokens::TokenKind::Number;
57
58    if line[end..].starts_with("ms") {
59        end += 2;
60        kind = crate::language::syntax::tokens::TokenKind::Duration;
61    }
62
63    (end, kind)
64}