Skip to main content

rl_lang/lexer/types/
identifier.rs

1//! Identifier and keyword scanner.
2//!
3//! Consumes a run of alphanumeric/underscore characters and maps the result to
4//! the appropriate keyword [`TokenType`] or falls back to [`TokenType::Identifier`].
5use crate::lexer::{tokenizer::Tokenizer, tokentypes::TokenType};
6
7impl Tokenizer {
8    /// Scans an identifier or keyword starting at the current position.
9    ///
10    /// Consumes alphanumeric characters and underscores, then checks if the
11    /// result is a reserved word. If not, emits [`TokenType::Identifier`].
12    ///
13    /// # Reserved Words
14    ///
15    /// | Category       | Keywords                                              |
16    /// |----------------|-------------------------------------------------------|
17    /// | Control flow   | `if`, `else`, `for`, `while`, `return`, `break`, `continue` |
18    /// | Functions      | `fn`                                                  |
19    /// | Imports        | `get`, `from`, `in`                                   |
20    /// | Logical        | `and`, `or`                                           |
21    /// | Types          | `int`, `float`, `bool`, `string`, `byte`, `char`, `arr`, `error` |
22    /// | Declarations   | `dec`, `CONST`                                        |
23    /// | Literals       | `true`, `false`, `null`                               |
24    /// | Special        | `as`                                                  |
25    ///
26    /// `CONST` in uppercase in intentional
27    pub fn identifier(&mut self) {
28        while self.peek().is_alphanumeric() || self.peek() == '_' {
29            self.advance();
30        }
31
32        let value: String = self.source[self.start..self.current].iter().collect();
33
34        match value.as_str() {
35            "fn" => self.add_token(TokenType::Fn),
36            "for" => self.add_token(TokenType::For),
37            "while" => self.add_token(TokenType::While),
38            "return" => self.add_token(TokenType::Return),
39            "continue" => self.add_token(TokenType::Continue),
40            "break" => self.add_token(TokenType::Break),
41            "get" => self.add_token(TokenType::Get),
42            "from" => self.add_token(TokenType::From),
43            "in" => self.add_token(TokenType::In),
44            "or" => self.add_token(TokenType::Or),
45            "and" => self.add_token(TokenType::And),
46            "null" => self.add_token(TokenType::Null),
47            "int" => self.add_token(TokenType::Int),
48            "CONST" => self.add_token(TokenType::Const),
49            "float" => self.add_token(TokenType::Float),
50            "bool" => self.add_token(TokenType::Bool),
51            "string" => self.add_token(TokenType::String),
52            "byte" => self.add_token(TokenType::Byte),
53            "char" => self.add_token(TokenType::Char),
54            "true" => self.add_token(TokenType::BoolLiteral(true)),
55            "false" => self.add_token(TokenType::BoolLiteral(false)),
56            "dec" => self.add_token(TokenType::Dec),
57            "if" => self.add_token(TokenType::If),
58            "else" => self.add_token(TokenType::Else),
59            "arr" => self.add_token(TokenType::Array),
60            "as" => self.add_token(TokenType::As),
61            "error" => self.add_token(TokenType::Error),
62            "result" => self.add_token(TokenType::Result),
63            "ok" => self.add_token(TokenType::Ok),
64            "err" => self.add_token(TokenType::Err),
65            "match" => self.add_token(TokenType::Match),
66            "record" => self.add_token(TokenType::Record),
67            "tag" => self.add_token(TokenType::Tag),
68            "map" => self.add_token(TokenType::Map),
69            "set" => self.add_token(TokenType::Set),
70            "_" => self.add_token(TokenType::Wildcard),
71
72            &_ => self.add_token(TokenType::Identifier(value)),
73        }
74    }
75}