jetcrab\lexer\scanners/
identifier.rs

1use crate::lexer::tokens::Keyword;
2use crate::lexer::{LexerError, TokenKind};
3
4pub trait IdentifierReader {
5    fn read_identifier_or_keyword(&mut self) -> Result<TokenKind, LexerError>;
6}
7
8impl<T> IdentifierReader for T
9where
10    T: LexerCore,
11{
12    fn read_identifier_or_keyword(&mut self) -> Result<TokenKind, LexerError> {
13        let mut identifier = String::new();
14
15        while self.pos() < self.source().len() {
16            let c = self.source()[self.pos()];
17            if c.is_alphanumeric() || c == '_' || c == '$' || c.is_alphabetic() || !c.is_ascii() {
18                identifier.push(c);
19                self.advance_pos();
20            } else {
21                break;
22            }
23        }
24
25        match identifier.as_str() {
26            "true" => Ok(TokenKind::Boolean(true)),
27            "false" => Ok(TokenKind::Boolean(false)),
28            "null" => Ok(TokenKind::Null),
29            "undefined" => Ok(TokenKind::Undefined),
30            "this" => Ok(TokenKind::Keyword(Keyword::This)),
31            "super" => Ok(TokenKind::Keyword(Keyword::Super)),
32            _ => {
33                if let Some(keyword) = Keyword::from_string(&identifier) {
34                    Ok(TokenKind::Keyword(keyword))
35                } else {
36                    Ok(TokenKind::Identifier(identifier))
37                }
38            }
39        }
40    }
41}
42
43pub trait LexerCore {
44    fn source(&self) -> &[char];
45    fn pos(&self) -> usize;
46    fn advance_pos(&mut self);
47}