1use crate::{
4 prelude::{
5 Comment, CompoundOperator, Keyword, Lexable, Lexer, Literal, Operator, Error,
6 PartialKeyword, Symbol, TokenType,
7 },
8 utils::is_identifier_start,
9};
10
11impl Lexable for TokenType {
12 fn try_lex(lexer: &mut Lexer) -> Option<Self> {
13 let character = lexer.current_char()?;
14 let start = lexer.lexer_position;
15
16 match character {
17 '0'..='9' => {
18 if let Some(number) = Literal::parse_number(lexer) {
19 return Some(Self::Literal(number));
20 }
21 }
22 '.' => {
23 let next_character = lexer.next_char();
24 if matches!(next_character, Some('0'..='9')) {
25 if let Some(number) = Literal::parse_number(lexer) {
26 return Some(Self::Literal(number));
27 }
28 }
29 lexer.consume('.');
30
31 let next_character = lexer.current_char();
32 if next_character == Some('.') {
33 lexer.consume('.');
34
35 if lexer.consume('.') {
36 return Some(Self::Symbol(Symbol::Ellipses));
37 } else {
38 let operator = Operator::Concatenation;
39
40 return CompoundOperator::try_from_operator(operator, lexer)
41 .map(Self::CompoundOperator)
42 .or(Some(Self::Operator(operator)));
43 }
44 } else {
45 return Some(Self::Symbol(Symbol::Dot));
46 }
47 }
48 '\'' | '"' | '`' => {
49 if let Some(string) = Literal::parse_string(lexer) {
50 return Some(Self::Literal(string));
51 }
52 }
53 '[' => {
54 if matches!(lexer.next_char(), Some('[' | '=')) {
55 if let Some(string) = Literal::parse_string(lexer) {
56 return Some(Self::Literal(string));
57 }
58 }
59 lexer.consume('[');
60
61 return Some(Self::Symbol(Symbol::OpeningBrackets));
62 }
63 '>' if lexer.consume_with_next('=') => {
64 return Some(Self::CompoundOperator(
65 CompoundOperator::GreaterThanOrEqualTo,
66 ));
67 }
68 '<' if lexer.consume_with_next('=') => {
69 return Some(Self::CompoundOperator(CompoundOperator::LessThanOrEqualTo));
70 }
71 '-' if lexer.consume_with_next('-') => {
72 return Comment::try_lex(lexer).map(Self::Comment)
73 }
74 '-' if lexer.consume_with_next('>') => {
75 return Some(Self::Symbol(Symbol::Arrow));
76 }
77 '=' => {
78 lexer.consume('=');
79
80 if lexer.consume('=') {
81 return Some(Self::CompoundOperator(CompoundOperator::EqualEqual));
82 } else {
83 return Some(Self::Symbol(Symbol::Equal));
84 }
85 }
86 ':' if lexer.consume_with_next(':') => {
87 return Some(Self::Symbol(Symbol::Typecast));
88 }
89 _ if is_identifier_start(character) => {
90 let word = lexer.consume_identifier();
91
92 if let Some(keyword) = Keyword::try_from_str(&word) {
93 return Some(Self::Keyword(keyword));
94 } else if let Some(partial_keyword) = PartialKeyword::try_from_str(&word) {
95 return Some(Self::PartialKeyword(partial_keyword));
96 }
97
98 match word.as_str() {
99 "true" => return Some(Self::Literal(Literal::Boolean(true))),
100 "false" => return Some(Self::Literal(Literal::Boolean(false))),
101 "and" => return Some(Self::Operator(Operator::And)),
102 "or" => return Some(Self::Operator(Operator::Or)),
103 "not" => return Some(Self::Operator(Operator::Not)),
104 _ => return Some(Self::Identifier(word)),
105 }
106 }
107 _ => {
108 if let Some(symbol) = Symbol::try_from_char(character, lexer) {
109 return Some(Self::Symbol(symbol));
110 }
111 if let Some(operator) = Operator::try_from_chars(character, lexer) {
112 return CompoundOperator::try_from_operator(operator, lexer)
113 .map(Self::CompoundOperator)
114 .or(Some(Self::Operator(operator)));
115 }
116 }
117 }
118
119 lexer.increment_position(1);
120
121 Some(Self::Error(Error::new(
122 start,
123 format!("Unexpected character: {}", character),
124 Some(lexer.lexer_position),
125 )))
126 }
127}