jetcrab\lexer\scanners/
identifier.rs1use 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}