Skip to content

Commit 93b0dfc

Browse files
feat(lexer): add string literal and raw string literal handlers
1 parent 8ba0191 commit 93b0dfc

1 file changed

Lines changed: 49 additions & 13 deletions

File tree

wheel_lexer/include/wheel_lexer/handlers.hxx

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,50 @@ WHEEL_LEXER_NAMESPACE
1919
DEBUG_PRINT(FORMAT("'{}': {}", #label, source)); \
2020
return make_token(kind, source, start, cursor.position()); \
2121
} while(0)
22+
#define _WHEEL_CONSUME_ALL_IF(condition, cursor) \
23+
do { \
24+
while(condition) cursor.bump(); \
25+
} while(0)
2226

2327
using TokenHandler = Token(*)(Cursor&, size_t);
2428
using StrView = std::string_view;
2529
using Kind = TokenKind;
2630

2731
_WHEEL_HANDLERS(if_tab) {
28-
cursor.bump();
32+
cursor.bump();
2933
return make_token(Kind::TAB, "\t", start, cursor.position());
3034
}
3135

36+
_WHEEL_HANDLERS(if_string_literal) {
37+
cursor.bump();
38+
39+
while (true) {
40+
auto closed_str = cursor.bump();
41+
42+
if(is_newline_like(closed_str)) break;
43+
if(closed_str == '\"' || closed_str == '\0') break;
44+
}
45+
46+
_WHEEL_MAKE_TOKEN(TokenKind::STRING_LITERAL, _SOURCE_TEXT(cursor, start), if_string_literal);
47+
}
48+
49+
_WHEEL_HANDLERS(if_raw_string_literal) {
50+
cursor.bump();
51+
52+
if (cursor.first() == '\"') {
53+
cursor.bump();
54+
55+
while(true) {
56+
auto closed_str = cursor.bump();
57+
if (closed_str == '\"' || closed_str == '\0') break;
58+
}
59+
60+
_WHEEL_MAKE_TOKEN(TokenKind::RAW_STRING_LITERAL, _SOURCE_TEXT(cursor, start), if_string_literal);
61+
}
62+
63+
_WHEEL_MAKE_TOKEN(TokenKind::IDENT, _SOURCE_TEXT(cursor, start), if_string_literal);
64+
}
65+
3266
_WHEEL_HANDLERS(if_newline) {
3367
if(cursor.first() == '\r' && cursor.second() == '\n') {
3468
cursor.bump();
@@ -74,20 +108,17 @@ WHEEL_LEXER_NAMESPACE
74108
}
75109

76110
_WHEEL_HANDLERS(if_digit) {
77-
while(is_digit(cursor.first())) {
78-
cursor.bump();
79-
}
111+
_WHEEL_CONSUME_ALL_IF(is_digit(cursor.first()), cursor);
80112

81113
if (cursor.first() == '.' && is_digit(cursor.second())) {
82114
cursor.bump();
83115

84-
while(is_digit(cursor.first())) cursor.bump();
85-
116+
_WHEEL_CONSUME_ALL_IF(is_digit(cursor.first()), cursor);
86117
if(is_exponent_marker(cursor.first())) {
87118
cursor.bump();
88119

89-
while(is_sign(cursor.first())) cursor.bump();
90-
while(is_digit(cursor.first())) cursor.bump();
120+
_WHEEL_CONSUME_ALL_IF(is_sign(cursor.first()), cursor);
121+
_WHEEL_CONSUME_ALL_IF(is_digit(cursor.first()), cursor);
91122
}
92123

93124
_WHEEL_MAKE_TOKEN(Kind::FLOAT_LITERAL, _SOURCE_TEXT(cursor, start), if_digit);
@@ -96,12 +127,12 @@ WHEEL_LEXER_NAMESPACE
96127
if(is_exponent_marker(cursor.first())) {
97128
cursor.bump();
98129

99-
while(is_sign(cursor.first())) cursor.bump();
100-
while(is_digit(cursor.first())) cursor.bump();
130+
_WHEEL_CONSUME_ALL_IF(is_sign(cursor.first()), cursor);
131+
_WHEEL_CONSUME_ALL_IF(is_digit(cursor.first()), cursor);
101132
_WHEEL_MAKE_TOKEN(Kind::FLOAT_LITERAL, _SOURCE_TEXT(cursor, start), if_digit);
102133
}
103134

104-
return make_token(Kind::INT_LITERAL, _SOURCE_TEXT(cursor, start), start, cursor.position());
135+
_WHEEL_MAKE_TOKEN(Kind::INT_LITERAL, _SOURCE_TEXT(cursor, start), if_digit);
105136
}
106137

107138
_WHEEL_HANDLERS(if_space) {
@@ -203,18 +234,23 @@ WHEEL_LEXER_NAMESPACE
203234
table[' '] = if_space;
204235
table['/'] = if_slash;
205236

237+
table['\"'] = if_string_literal;
238+
table['r'] = if_raw_string_literal;
239+
206240
/* Operator(s) */
207241
table['='] = if_equal;
208242
table['+'] = if_plus;
209243
table['-'] = if_minus;
210244
table['*'] = if_star;
211245

212246
for(int character = 0; character < 256; character++) {
213-
if(is_ident_start(static_cast<char>(character))) {
247+
char char_str = static_cast<char>(character);
248+
249+
if(is_ident_start(char_str) && !is_special_ident(char_str)) {
214250
table[character] = if_ident;
215251
}
216252

217-
if (is_digit(static_cast<char>(character))) {
253+
if (is_digit(char_str)) {
218254
table[character] = if_digit;
219255
}
220256
}

0 commit comments

Comments
 (0)