Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #include "tokenizer.hpp"
9 : : #include "util.hpp"
10 : :
11 : : #include <stdarg.h>
12 : : #include <stdlib.h>
13 : : #include <stdio.h>
14 : : #include <inttypes.h>
15 : : #include <limits.h>
16 : : #include <errno.h>
17 : :
18 : : #define WHITESPACE \
19 : : ' ': \
20 : : case '\n'
21 : :
22 : : #define DIGIT_NON_ZERO \
23 : : '1': \
24 : : case '2': \
25 : : case '3': \
26 : : case '4': \
27 : : case '5': \
28 : : case '6': \
29 : : case '7': \
30 : : case '8': \
31 : : case '9'
32 : : #define DIGIT \
33 : : '0': \
34 : : case DIGIT_NON_ZERO
35 : :
36 : : #define ALPHA_EXCEPT_C \
37 : : 'a': \
38 : : case 'b': \
39 : : /*case 'c':*/ \
40 : : case 'd': \
41 : : case 'e': \
42 : : case 'f': \
43 : : case 'g': \
44 : : case 'h': \
45 : : case 'i': \
46 : : case 'j': \
47 : : case 'k': \
48 : : case 'l': \
49 : : case 'm': \
50 : : case 'n': \
51 : : case 'o': \
52 : : case 'p': \
53 : : case 'q': \
54 : : case 'r': \
55 : : case 's': \
56 : : case 't': \
57 : : case 'u': \
58 : : case 'v': \
59 : : case 'w': \
60 : : case 'x': \
61 : : case 'y': \
62 : : case 'z': \
63 : : case 'A': \
64 : : case 'B': \
65 : : case 'C': \
66 : : case 'D': \
67 : : case 'E': \
68 : : case 'F': \
69 : : case 'G': \
70 : : case 'H': \
71 : : case 'I': \
72 : : case 'J': \
73 : : case 'K': \
74 : : case 'L': \
75 : : case 'M': \
76 : : case 'N': \
77 : : case 'O': \
78 : : case 'P': \
79 : : case 'Q': \
80 : : case 'R': \
81 : : case 'S': \
82 : : case 'T': \
83 : : case 'U': \
84 : : case 'V': \
85 : : case 'W': \
86 : : case 'X': \
87 : : case 'Y': \
88 : : case 'Z'
89 : :
90 : : #define ALPHA \
91 : : ALPHA_EXCEPT_C: \
92 : : case 'c'
93 : :
94 : : #define SYMBOL_CHAR \
95 : : ALPHA: \
96 : : case DIGIT: \
97 : : case '_'
98 : :
99 : : #define SYMBOL_START \
100 : : ALPHA: \
101 : : case '_'
102 : :
103 : : struct ZigKeyword {
104 : : const char *text;
105 : : TokenId token_id;
106 : : };
107 : :
108 : : static const struct ZigKeyword zig_keywords[] = {
109 : : {"align", TokenIdKeywordAlign},
110 : : {"allowzero", TokenIdKeywordAllowZero},
111 : : {"and", TokenIdKeywordAnd},
112 : : {"anyframe", TokenIdKeywordAnyFrame},
113 : : {"asm", TokenIdKeywordAsm},
114 : : {"async", TokenIdKeywordAsync},
115 : : {"await", TokenIdKeywordAwait},
116 : : {"break", TokenIdKeywordBreak},
117 : : {"catch", TokenIdKeywordCatch},
118 : : {"comptime", TokenIdKeywordCompTime},
119 : : {"const", TokenIdKeywordConst},
120 : : {"continue", TokenIdKeywordContinue},
121 : : {"defer", TokenIdKeywordDefer},
122 : : {"else", TokenIdKeywordElse},
123 : : {"enum", TokenIdKeywordEnum},
124 : : {"errdefer", TokenIdKeywordErrdefer},
125 : : {"error", TokenIdKeywordError},
126 : : {"export", TokenIdKeywordExport},
127 : : {"extern", TokenIdKeywordExtern},
128 : : {"false", TokenIdKeywordFalse},
129 : : {"fn", TokenIdKeywordFn},
130 : : {"for", TokenIdKeywordFor},
131 : : {"if", TokenIdKeywordIf},
132 : : {"inline", TokenIdKeywordInline},
133 : : {"nakedcc", TokenIdKeywordNakedCC},
134 : : {"noalias", TokenIdKeywordNoAlias},
135 : : {"noasync", TokenIdKeywordNoAsync},
136 : : {"noinline", TokenIdKeywordNoInline},
137 : : {"null", TokenIdKeywordNull},
138 : : {"or", TokenIdKeywordOr},
139 : : {"orelse", TokenIdKeywordOrElse},
140 : : {"packed", TokenIdKeywordPacked},
141 : : {"pub", TokenIdKeywordPub},
142 : : {"resume", TokenIdKeywordResume},
143 : : {"return", TokenIdKeywordReturn},
144 : : {"linksection", TokenIdKeywordLinkSection},
145 : : {"stdcallcc", TokenIdKeywordStdcallCC},
146 : : {"struct", TokenIdKeywordStruct},
147 : : {"suspend", TokenIdKeywordSuspend},
148 : : {"switch", TokenIdKeywordSwitch},
149 : : {"test", TokenIdKeywordTest},
150 : : {"threadlocal", TokenIdKeywordThreadLocal},
151 : : {"true", TokenIdKeywordTrue},
152 : : {"try", TokenIdKeywordTry},
153 : : {"undefined", TokenIdKeywordUndefined},
154 : : {"union", TokenIdKeywordUnion},
155 : : {"unreachable", TokenIdKeywordUnreachable},
156 : : {"use", TokenIdKeywordUsingNamespace},
157 : : {"usingnamespace", TokenIdKeywordUsingNamespace},
158 : : {"var", TokenIdKeywordVar},
159 : : {"volatile", TokenIdKeywordVolatile},
160 : : {"while", TokenIdKeywordWhile},
161 : : };
162 : :
163 : 0 : bool is_zig_keyword(Buf *buf) {
164 [ # # ]: 0 : for (size_t i = 0; i < array_length(zig_keywords); i += 1) {
165 [ # # ]: 0 : if (buf_eql_str(buf, zig_keywords[i].text)) {
166 : 0 : return true;
167 : : }
168 : : }
169 : 0 : return false;
170 : : }
171 : :
172 : 123336 : static bool is_symbol_char(uint8_t c) {
173 [ - + ]: 123336 : switch (c) {
174 : 0 : case SYMBOL_CHAR:
175 : 0 : return true;
176 : 123336 : default:
177 : 123336 : return false;
178 : : }
179 : : }
180 : :
181 : : enum TokenizeState {
182 : : TokenizeStateStart,
183 : : TokenizeStateSymbol,
184 : : TokenizeStateSymbolFirstC,
185 : : TokenizeStateZero, // "0", which might lead to "0x"
186 : : TokenizeStateNumber, // "123", "0x123"
187 : : TokenizeStateNumberDot,
188 : : TokenizeStateFloatFraction, // "123.456", "0x123.456"
189 : : TokenizeStateFloatExponentUnsigned, // "123.456e", "123e", "0x123p"
190 : : TokenizeStateFloatExponentNumber, // "123.456e-", "123.456e5", "123.456e5e-5"
191 : : TokenizeStateString,
192 : : TokenizeStateStringEscape,
193 : : TokenizeStateStringEscapeUnicodeStart,
194 : : TokenizeStateCharLiteral,
195 : : TokenizeStateCharLiteralEnd,
196 : : TokenizeStateSawStar,
197 : : TokenizeStateSawStarPercent,
198 : : TokenizeStateSawSlash,
199 : : TokenizeStateSawBackslash,
200 : : TokenizeStateSawPercent,
201 : : TokenizeStateSawPlus,
202 : : TokenizeStateSawPlusPercent,
203 : : TokenizeStateSawDash,
204 : : TokenizeStateSawMinusPercent,
205 : : TokenizeStateSawAmpersand,
206 : : TokenizeStateSawCaret,
207 : : TokenizeStateSawBar,
208 : : TokenizeStateSawBarBar,
209 : : TokenizeStateLineComment,
210 : : TokenizeStateLineString,
211 : : TokenizeStateLineStringEnd,
212 : : TokenizeStateLineStringContinue,
213 : : TokenizeStateLineStringContinueC,
214 : : TokenizeStateSawEq,
215 : : TokenizeStateSawBang,
216 : : TokenizeStateSawLessThan,
217 : : TokenizeStateSawLessThanLessThan,
218 : : TokenizeStateSawGreaterThan,
219 : : TokenizeStateSawGreaterThanGreaterThan,
220 : : TokenizeStateSawDot,
221 : : TokenizeStateSawDotDot,
222 : : TokenizeStateSawAtSign,
223 : : TokenizeStateCharCode,
224 : : TokenizeStateError,
225 : : TokenizeStateLBracket,
226 : : TokenizeStateLBracketStar,
227 : : TokenizeStateLBracketStarC,
228 : : TokenizeStateLBracketUnderscore,
229 : : };
230 : :
231 : :
232 : : struct Tokenize {
233 : : Buf *buf;
234 : : size_t pos;
235 : : TokenizeState state;
236 : : ZigList<Token> *tokens;
237 : : int line;
238 : : int column;
239 : : Token *cur_tok;
240 : : Tokenization *out;
241 : : uint32_t radix;
242 : : int32_t exp_add_amt;
243 : : bool is_exp_negative;
244 : : size_t char_code_index;
245 : : bool unicode;
246 : : uint32_t char_code;
247 : : int exponent_in_bin_or_dec;
248 : : BigInt specified_exponent;
249 : : BigInt significand;
250 : : };
251 : :
252 : : ATTRIBUTE_PRINTF(2, 3)
253 : 0 : static void tokenize_error(Tokenize *t, const char *format, ...) {
254 : 0 : t->state = TokenizeStateError;
255 : :
256 : 0 : t->out->err_line = t->line;
257 : 0 : t->out->err_column = t->column;
258 : :
259 : : va_list ap;
260 : 0 : va_start(ap, format);
261 : 0 : t->out->err = buf_vprintf(format, ap);
262 : 0 : va_end(ap);
263 : 0 : }
264 : :
265 : 2855002 : static void set_token_id(Tokenize *t, Token *token, TokenId id) {
266 : 2855002 : token->id = id;
267 : :
268 [ + + ]: 2855002 : if (id == TokenIdIntLiteral) {
269 : 127312 : bigint_init_unsigned(&token->data.int_lit.bigint, 0);
270 [ + + ]: 2727690 : } else if (id == TokenIdFloatLiteral) {
271 : 18535 : bigfloat_init_32(&token->data.float_lit.bigfloat, 0.0f);
272 : 18535 : token->data.float_lit.overflow = false;
273 [ + + ][ + + ]: 2709155 : } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) {
274 : 1116499 : memset(&token->data.str_lit.str, 0, sizeof(Buf));
275 : 1116499 : buf_resize(&token->data.str_lit.str, 0);
276 : 1116499 : token->data.str_lit.is_c_str = false;
277 : : }
278 : 2855002 : }
279 : :
280 : 2759581 : static void begin_token(Tokenize *t, TokenId id) {
281 : 2759581 : assert(!t->cur_tok);
282 : 2759581 : t->tokens->add_one();
283 : 2759581 : Token *token = &t->tokens->last();
284 : 2759581 : token->start_line = t->line;
285 : 2759581 : token->start_column = t->column;
286 : 2759581 : token->start_pos = t->pos;
287 : :
288 : 2759581 : set_token_id(t, token, id);
289 : :
290 : 2759581 : t->cur_tok = token;
291 : 2759581 : }
292 : :
293 : 32764 : static void cancel_token(Tokenize *t) {
294 : 32764 : t->tokens->pop();
295 : 32764 : t->cur_tok = nullptr;
296 : 32764 : }
297 : :
298 : 18535 : static void end_float_token(Tokenize *t) {
299 : 18535 : uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos;
300 : 18535 : size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos;
301 [ - + ]: 18535 : if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) {
302 : 0 : t->cur_tok->data.float_lit.overflow = true;
303 : : }
304 : 18535 : }
305 : :
306 : 2726817 : static void end_token(Tokenize *t) {
307 : 2726817 : assert(t->cur_tok);
308 : 2726817 : t->cur_tok->end_pos = t->pos + 1;
309 : :
310 [ + + ]: 2726817 : if (t->cur_tok->id == TokenIdFloatLiteral) {
311 : 18535 : end_float_token(t);
312 [ + + ]: 2708282 : } else if (t->cur_tok->id == TokenIdSymbol) {
313 : 1073690 : char *token_mem = buf_ptr(t->buf) + t->cur_tok->start_pos;
314 : 1073690 : int token_len = (int)(t->cur_tok->end_pos - t->cur_tok->start_pos);
315 : :
316 [ + + ]: 49167305 : for (size_t i = 0; i < array_length(zig_keywords); i += 1) {
317 [ + + ]: 48093615 : if (mem_eql_str(token_mem, token_len, zig_keywords[i].text)) {
318 : 292323 : t->cur_tok->id = zig_keywords[i].token_id;
319 : 292323 : break;
320 : : }
321 : : }
322 : : }
323 : :
324 : 2726817 : t->cur_tok = nullptr;
325 : 2726817 : }
326 : :
327 : 541462 : static bool is_exponent_signifier(uint8_t c, int radix) {
328 [ + + ]: 541462 : if (radix == 16) {
329 [ + + ][ - + ]: 215610 : return c == 'p' || c == 'P';
330 : : } else {
331 [ + + ][ + + ]: 325852 : return c == 'e' || c == 'E';
332 : : }
333 : : }
334 : :
335 : 655546 : static uint32_t get_digit_value(uint8_t c) {
336 [ + + ][ + + ]: 655546 : if ('0' <= c && c <= '9') {
337 : 471642 : return c - '0';
338 : : }
339 [ + + ][ + + ]: 183904 : if ('A' <= c && c <= 'Z') {
340 : 17276 : return c - 'A' + 10;
341 : : }
342 [ + + ][ + + ]: 166628 : if ('a' <= c && c <= 'z') {
343 : 43292 : return c - 'a' + 10;
344 : : }
345 : 123336 : return UINT32_MAX;
346 : : }
347 : :
348 : 8859 : static void handle_string_escape(Tokenize *t, uint8_t c) {
349 [ + + ]: 8859 : if (t->cur_tok->id == TokenIdCharLiteral) {
350 : 459 : t->cur_tok->data.char_lit.c = c;
351 : 459 : t->state = TokenizeStateCharLiteralEnd;
352 [ - + ][ # # ]: 8400 : } else if (t->cur_tok->id == TokenIdStringLiteral || t->cur_tok->id == TokenIdSymbol) {
353 : 8400 : buf_append_char(&t->cur_tok->data.str_lit.str, c);
354 : 8400 : t->state = TokenizeStateString;
355 : : } else {
356 : 0 : zig_unreachable();
357 : : }
358 : 8859 : }
359 : :
360 : 0 : static const char* get_escape_shorthand(uint8_t c) {
361 [ # # # # : 0 : switch (c) {
# # # #
# ]
362 : 0 : case '\0':
363 : 0 : return "\\0";
364 : 0 : case '\a':
365 : 0 : return "\\a";
366 : 0 : case '\b':
367 : 0 : return "\\b";
368 : 0 : case '\t':
369 : 0 : return "\\t";
370 : 0 : case '\n':
371 : 0 : return "\\n";
372 : 0 : case '\v':
373 : 0 : return "\\v";
374 : 0 : case '\f':
375 : 0 : return "\\f";
376 : 0 : case '\r':
377 : 0 : return "\\r";
378 : 0 : default:
379 : 0 : return nullptr;
380 : : }
381 : : }
382 : :
383 : 0 : static void invalid_char_error(Tokenize *t, uint8_t c) {
384 [ # # ]: 0 : if (c == '\r') {
385 : 0 : tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");
386 : 0 : return;
387 : : }
388 : :
389 : 0 : const char *sh = get_escape_shorthand(c);
390 [ # # ]: 0 : if (sh) {
391 : 0 : tokenize_error(t, "invalid character: '%s'", sh);
392 : 0 : return;
393 : : }
394 : :
395 [ # # ]: 0 : if (isprint(c)) {
396 : 0 : tokenize_error(t, "invalid character: '%c'", c);
397 : 0 : return;
398 : : }
399 : :
400 : 0 : tokenize_error(t, "invalid character: '\\x%02x'", c);
401 : : }
402 : :
403 : 1804 : void tokenize(Buf *buf, Tokenization *out) {
404 : 1804 : Tokenize t = {0};
405 : 1804 : t.out = out;
406 : 1804 : t.tokens = out->tokens = allocate<ZigList<Token>>(1);
407 : 1804 : t.buf = buf;
408 : :
409 : 1804 : out->line_offsets = allocate<ZigList<size_t>>(1);
410 : :
411 : 1804 : out->line_offsets->append(0);
412 [ + + ]: 16599303 : for (t.pos = 0; t.pos < buf_len(t.buf); t.pos += 1) {
413 : 16597499 : uint8_t c = buf_ptr(t.buf)[t.pos];
414 [ - + + + : 16597499 : switch (t.state) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
415 : 0 : case TokenizeStateError:
416 : 0 : break;
417 : 6304021 : case TokenizeStateStart:
418 [ + + + + : 6304021 : switch (c) {
+ + + + +
+ + + + +
+ + + - +
+ + + + +
+ + + + +
+ + + + +
- ]
419 : 3546244 : case WHITESPACE:
420 : 3546244 : break;
421 : 103172 : case 'c':
422 : 103172 : t.state = TokenizeStateSymbolFirstC;
423 : 103172 : begin_token(&t, TokenIdSymbol);
424 : 103172 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
425 : 103172 : break;
426 : 970648 : case ALPHA_EXCEPT_C:
427 : : case '_':
428 : 970648 : t.state = TokenizeStateSymbol;
429 : 970648 : begin_token(&t, TokenIdSymbol);
430 : 970648 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
431 : 970648 : break;
432 : 48585 : case '0':
433 : 48585 : t.state = TokenizeStateZero;
434 : 48585 : begin_token(&t, TokenIdIntLiteral);
435 : 48585 : t.radix = 10;
436 : 48585 : t.exp_add_amt = 1;
437 : 48585 : t.exponent_in_bin_or_dec = 0;
438 : 48585 : bigint_init_unsigned(&t.cur_tok->data.int_lit.bigint, 0);
439 : 48585 : bigint_init_unsigned(&t.specified_exponent, 0);
440 : 48585 : break;
441 : 78727 : case DIGIT_NON_ZERO:
442 : 78727 : t.state = TokenizeStateNumber;
443 : 78727 : begin_token(&t, TokenIdIntLiteral);
444 : 78727 : t.radix = 10;
445 : 78727 : t.exp_add_amt = 1;
446 : 78727 : t.exponent_in_bin_or_dec = 0;
447 : 78727 : bigint_init_unsigned(&t.cur_tok->data.int_lit.bigint, get_digit_value(c));
448 : 78727 : bigint_init_unsigned(&t.specified_exponent, 0);
449 : 78727 : break;
450 : 41204 : case '"':
451 : 41204 : begin_token(&t, TokenIdStringLiteral);
452 : 41204 : t.state = TokenizeStateString;
453 : 41204 : break;
454 : 4139 : case '\'':
455 : 4139 : begin_token(&t, TokenIdCharLiteral);
456 : 4139 : t.state = TokenizeStateCharLiteral;
457 : 4139 : break;
458 : 201374 : case '(':
459 : 201374 : begin_token(&t, TokenIdLParen);
460 : 201374 : end_token(&t);
461 : 201374 : break;
462 : 201374 : case ')':
463 : 201374 : begin_token(&t, TokenIdRParen);
464 : 201374 : end_token(&t);
465 : 201374 : break;
466 : 185674 : case ',':
467 : 185674 : begin_token(&t, TokenIdComma);
468 : 185674 : end_token(&t);
469 : 185674 : break;
470 : 4936 : case '?':
471 : 4936 : begin_token(&t, TokenIdQuestion);
472 : 4936 : end_token(&t);
473 : 4936 : break;
474 : 80138 : case '{':
475 : 80138 : begin_token(&t, TokenIdLBrace);
476 : 80138 : end_token(&t);
477 : 80138 : break;
478 : 80138 : case '}':
479 : 80138 : begin_token(&t, TokenIdRBrace);
480 : 80138 : end_token(&t);
481 : 80138 : break;
482 : 33350 : case '[':
483 : 33350 : t.state = TokenizeStateLBracket;
484 : 33350 : begin_token(&t, TokenIdLBracket);
485 : 33350 : break;
486 : 25243 : case ']':
487 : 25243 : begin_token(&t, TokenIdRBracket);
488 : 25243 : end_token(&t);
489 : 25243 : break;
490 : 166666 : case ';':
491 : 166666 : begin_token(&t, TokenIdSemicolon);
492 : 166666 : end_token(&t);
493 : 166666 : break;
494 : 62007 : case ':':
495 : 62007 : begin_token(&t, TokenIdColon);
496 : 62007 : end_token(&t);
497 : 62007 : break;
498 : 0 : case '#':
499 : 0 : begin_token(&t, TokenIdNumberSign);
500 : 0 : end_token(&t);
501 : 0 : break;
502 : 17473 : case '*':
503 : 17473 : begin_token(&t, TokenIdStar);
504 : 17473 : t.state = TokenizeStateSawStar;
505 : 17473 : break;
506 : 33951 : case '/':
507 : 33951 : begin_token(&t, TokenIdSlash);
508 : 33951 : t.state = TokenizeStateSawSlash;
509 : 33951 : break;
510 : 1035 : case '\\':
511 : 1035 : begin_token(&t, TokenIdStringLiteral);
512 : 1035 : t.state = TokenizeStateSawBackslash;
513 : 1035 : break;
514 : 600 : case '%':
515 : 600 : begin_token(&t, TokenIdPercent);
516 : 600 : t.state = TokenizeStateSawPercent;
517 : 600 : break;
518 : 12916 : case '+':
519 : 12916 : begin_token(&t, TokenIdPlus);
520 : 12916 : t.state = TokenizeStateSawPlus;
521 : 12916 : break;
522 : 197 : case '~':
523 : 197 : begin_token(&t, TokenIdTilde);
524 : 197 : end_token(&t);
525 : 197 : break;
526 : 37475 : case '@':
527 : 37475 : begin_token(&t, TokenIdAtSign);
528 : 37475 : t.state = TokenizeStateSawAtSign;
529 : 37475 : break;
530 : 14745 : case '-':
531 : 14745 : begin_token(&t, TokenIdDash);
532 : 14745 : t.state = TokenizeStateSawDash;
533 : 14745 : break;
534 : 8808 : case '&':
535 : 8808 : begin_token(&t, TokenIdAmpersand);
536 : 8808 : t.state = TokenizeStateSawAmpersand;
537 : 8808 : break;
538 : 794 : case '^':
539 : 794 : begin_token(&t, TokenIdBinXor);
540 : 794 : t.state = TokenizeStateSawCaret;
541 : 794 : break;
542 : 13681 : case '|':
543 : 13681 : begin_token(&t, TokenIdBinOr);
544 : 13681 : t.state = TokenizeStateSawBar;
545 : 13681 : break;
546 : 152619 : case '=':
547 : 152619 : begin_token(&t, TokenIdEq);
548 : 152619 : t.state = TokenizeStateSawEq;
549 : 152619 : break;
550 : 10861 : case '!':
551 : 10861 : begin_token(&t, TokenIdBang);
552 : 10861 : t.state = TokenizeStateSawBang;
553 : 10861 : break;
554 : 5452 : case '<':
555 : 5452 : begin_token(&t, TokenIdCmpLessThan);
556 : 5452 : t.state = TokenizeStateSawLessThan;
557 : 5452 : break;
558 : 5034 : case '>':
559 : 5034 : begin_token(&t, TokenIdCmpGreaterThan);
560 : 5034 : t.state = TokenizeStateSawGreaterThan;
561 : 5034 : break;
562 : 154761 : case '.':
563 : 154761 : begin_token(&t, TokenIdDot);
564 : 154761 : t.state = TokenizeStateSawDot;
565 : 154761 : break;
566 : 0 : default:
567 : 0 : invalid_char_error(&t, c);
568 : : }
569 : 6304021 : break;
570 : 154761 : case TokenizeStateSawDot:
571 [ + + ]: 154761 : switch (c) {
572 : 5431 : case '.':
573 : 5431 : t.state = TokenizeStateSawDotDot;
574 : 5431 : set_token_id(&t, t.cur_tok, TokenIdEllipsis2);
575 : 5431 : break;
576 : 149330 : default:
577 : 149330 : t.pos -= 1;
578 : 149330 : end_token(&t);
579 : 149330 : t.state = TokenizeStateStart;
580 : 149330 : continue;
581 : : }
582 : 5431 : break;
583 : 5431 : case TokenizeStateSawDotDot:
584 [ + + ]: 5431 : switch (c) {
585 : 382 : case '.':
586 : 382 : t.state = TokenizeStateStart;
587 : 382 : set_token_id(&t, t.cur_tok, TokenIdEllipsis3);
588 : 382 : end_token(&t);
589 : 382 : break;
590 : 5049 : default:
591 : 5049 : t.pos -= 1;
592 : 5049 : end_token(&t);
593 : 5049 : t.state = TokenizeStateStart;
594 : 5049 : continue;
595 : : }
596 : 382 : break;
597 : 5034 : case TokenizeStateSawGreaterThan:
598 [ + + + ]: 5034 : switch (c) {
599 : 1455 : case '=':
600 : 1455 : set_token_id(&t, t.cur_tok, TokenIdCmpGreaterOrEq);
601 : 1455 : end_token(&t);
602 : 1455 : t.state = TokenizeStateStart;
603 : 1455 : break;
604 : 2013 : case '>':
605 : 2013 : set_token_id(&t, t.cur_tok, TokenIdBitShiftRight);
606 : 2013 : t.state = TokenizeStateSawGreaterThanGreaterThan;
607 : 2013 : break;
608 : 1566 : default:
609 : 1566 : t.pos -= 1;
610 : 1566 : end_token(&t);
611 : 1566 : t.state = TokenizeStateStart;
612 : 1566 : continue;
613 : : }
614 : 3468 : break;
615 : 2013 : case TokenizeStateSawGreaterThanGreaterThan:
616 [ + + ]: 2013 : switch (c) {
617 : 282 : case '=':
618 : 282 : set_token_id(&t, t.cur_tok, TokenIdBitShiftRightEq);
619 : 282 : end_token(&t);
620 : 282 : t.state = TokenizeStateStart;
621 : 282 : break;
622 : 1731 : default:
623 : 1731 : t.pos -= 1;
624 : 1731 : end_token(&t);
625 : 1731 : t.state = TokenizeStateStart;
626 : 1731 : continue;
627 : : }
628 : 282 : break;
629 : 5452 : case TokenizeStateSawLessThan:
630 [ + + + ]: 5452 : switch (c) {
631 : 599 : case '=':
632 : 599 : set_token_id(&t, t.cur_tok, TokenIdCmpLessOrEq);
633 : 599 : end_token(&t);
634 : 599 : t.state = TokenizeStateStart;
635 : 599 : break;
636 : 2360 : case '<':
637 : 2360 : set_token_id(&t, t.cur_tok, TokenIdBitShiftLeft);
638 : 2360 : t.state = TokenizeStateSawLessThanLessThan;
639 : 2360 : break;
640 : 2493 : default:
641 : 2493 : t.pos -= 1;
642 : 2493 : end_token(&t);
643 : 2493 : t.state = TokenizeStateStart;
644 : 2493 : continue;
645 : : }
646 : 2959 : break;
647 : 2360 : case TokenizeStateSawLessThanLessThan:
648 [ + + ]: 2360 : switch (c) {
649 : 179 : case '=':
650 : 179 : set_token_id(&t, t.cur_tok, TokenIdBitShiftLeftEq);
651 : 179 : end_token(&t);
652 : 179 : t.state = TokenizeStateStart;
653 : 179 : break;
654 : 2181 : default:
655 : 2181 : t.pos -= 1;
656 : 2181 : end_token(&t);
657 : 2181 : t.state = TokenizeStateStart;
658 : 2181 : continue;
659 : : }
660 : 179 : break;
661 : 10861 : case TokenizeStateSawBang:
662 [ + + ]: 10861 : switch (c) {
663 : 3261 : case '=':
664 : 3261 : set_token_id(&t, t.cur_tok, TokenIdCmpNotEq);
665 : 3261 : end_token(&t);
666 : 3261 : t.state = TokenizeStateStart;
667 : 3261 : break;
668 : 7600 : default:
669 : 7600 : t.pos -= 1;
670 : 7600 : end_token(&t);
671 : 7600 : t.state = TokenizeStateStart;
672 : 7600 : continue;
673 : : }
674 : 3261 : break;
675 : 152619 : case TokenizeStateSawEq:
676 [ + + + ]: 152619 : switch (c) {
677 : 24542 : case '=':
678 : 24542 : set_token_id(&t, t.cur_tok, TokenIdCmpEq);
679 : 24542 : end_token(&t);
680 : 24542 : t.state = TokenizeStateStart;
681 : 24542 : break;
682 : 17501 : case '>':
683 : 17501 : set_token_id(&t, t.cur_tok, TokenIdFatArrow);
684 : 17501 : end_token(&t);
685 : 17501 : t.state = TokenizeStateStart;
686 : 17501 : break;
687 : 110576 : default:
688 : 110576 : t.pos -= 1;
689 : 110576 : end_token(&t);
690 : 110576 : t.state = TokenizeStateStart;
691 : 110576 : continue;
692 : : }
693 : 42043 : break;
694 : 17473 : case TokenizeStateSawStar:
695 [ + + + + ]: 17473 : switch (c) {
696 : 236 : case '=':
697 : 236 : set_token_id(&t, t.cur_tok, TokenIdTimesEq);
698 : 236 : end_token(&t);
699 : 236 : t.state = TokenizeStateStart;
700 : 236 : break;
701 : 306 : case '*':
702 : 306 : set_token_id(&t, t.cur_tok, TokenIdStarStar);
703 : 306 : end_token(&t);
704 : 306 : t.state = TokenizeStateStart;
705 : 306 : break;
706 : 205 : case '%':
707 : 205 : set_token_id(&t, t.cur_tok, TokenIdTimesPercent);
708 : 205 : t.state = TokenizeStateSawStarPercent;
709 : 205 : break;
710 : 16726 : default:
711 : 16726 : t.pos -= 1;
712 : 16726 : end_token(&t);
713 : 16726 : t.state = TokenizeStateStart;
714 : 16726 : continue;
715 : : }
716 : 747 : break;
717 : 205 : case TokenizeStateSawStarPercent:
718 [ - + ]: 205 : switch (c) {
719 : 0 : case '=':
720 : 0 : set_token_id(&t, t.cur_tok, TokenIdTimesPercentEq);
721 : 0 : end_token(&t);
722 : 0 : t.state = TokenizeStateStart;
723 : 0 : break;
724 : 205 : default:
725 : 205 : t.pos -= 1;
726 : 205 : end_token(&t);
727 : 205 : t.state = TokenizeStateStart;
728 : 205 : continue;
729 : : }
730 : 0 : break;
731 : 600 : case TokenizeStateSawPercent:
732 [ + - + ]: 600 : switch (c) {
733 : 26 : case '=':
734 : 26 : set_token_id(&t, t.cur_tok, TokenIdModEq);
735 : 26 : end_token(&t);
736 : 26 : t.state = TokenizeStateStart;
737 : 26 : break;
738 : 0 : case '.':
739 : 0 : set_token_id(&t, t.cur_tok, TokenIdPercentDot);
740 : 0 : end_token(&t);
741 : 0 : t.state = TokenizeStateStart;
742 : 0 : break;
743 : 574 : default:
744 : 574 : t.pos -= 1;
745 : 574 : end_token(&t);
746 : 574 : t.state = TokenizeStateStart;
747 : 574 : continue;
748 : : }
749 : 26 : break;
750 : 12916 : case TokenizeStateSawPlus:
751 [ + + + + ]: 12916 : switch (c) {
752 : 5020 : case '=':
753 : 5020 : set_token_id(&t, t.cur_tok, TokenIdPlusEq);
754 : 5020 : end_token(&t);
755 : 5020 : t.state = TokenizeStateStart;
756 : 5020 : break;
757 : 1427 : case '+':
758 : 1427 : set_token_id(&t, t.cur_tok, TokenIdPlusPlus);
759 : 1427 : end_token(&t);
760 : 1427 : t.state = TokenizeStateStart;
761 : 1427 : break;
762 : 689 : case '%':
763 : 689 : set_token_id(&t, t.cur_tok, TokenIdPlusPercent);
764 : 689 : t.state = TokenizeStateSawPlusPercent;
765 : 689 : break;
766 : 5780 : default:
767 : 5780 : t.pos -= 1;
768 : 5780 : end_token(&t);
769 : 5780 : t.state = TokenizeStateStart;
770 : 5780 : continue;
771 : : }
772 : 7136 : break;
773 : 33350 : case TokenizeStateLBracket:
774 [ + + + ]: 33350 : switch (c) {
775 : 3784 : case '*':
776 : 3784 : t.state = TokenizeStateLBracketStar;
777 : 3784 : break;
778 : 4323 : case '_':
779 : 4323 : t.state = TokenizeStateLBracketUnderscore;
780 : 4323 : break;
781 : 25243 : default:
782 : : // reinterpret as just an lbracket
783 : 25243 : t.pos -= 1;
784 : 25243 : end_token(&t);
785 : 25243 : t.state = TokenizeStateStart;
786 : 25243 : continue;
787 : : }
788 : 8107 : break;
789 : 4323 : case TokenizeStateLBracketUnderscore:
790 [ + - ]: 4323 : switch (c) {
791 : 4323 : case ']':
792 : 4323 : set_token_id(&t, t.cur_tok, TokenIdBracketUnderscoreBracket);
793 : 4323 : end_token(&t);
794 : 4323 : t.state = TokenizeStateStart;
795 : 4323 : break;
796 : 0 : default:
797 : : // reinterpret as just an lbracket
798 : 0 : t.pos -= 2;
799 : 0 : end_token(&t);
800 : 0 : t.state = TokenizeStateStart;
801 : 0 : continue;
802 : : }
803 : 4323 : break;
804 : 3784 : case TokenizeStateLBracketStar:
805 [ + + - ]: 3784 : switch (c) {
806 : 248 : case 'c':
807 : 248 : t.state = TokenizeStateLBracketStarC;
808 : 248 : set_token_id(&t, t.cur_tok, TokenIdBracketStarCBracket);
809 : 248 : break;
810 : 3536 : case ']':
811 : 3536 : set_token_id(&t, t.cur_tok, TokenIdBracketStarBracket);
812 : 3536 : end_token(&t);
813 : 3536 : t.state = TokenizeStateStart;
814 : 3536 : break;
815 : 0 : default:
816 : 0 : invalid_char_error(&t, c);
817 : : }
818 : 3784 : break;
819 : 248 : case TokenizeStateLBracketStarC:
820 [ + - ]: 248 : switch (c) {
821 : 248 : case ']':
822 : 248 : end_token(&t);
823 : 248 : t.state = TokenizeStateStart;
824 : 248 : break;
825 : 0 : default:
826 : 0 : invalid_char_error(&t, c);
827 : : }
828 : 248 : break;
829 : 689 : case TokenizeStateSawPlusPercent:
830 [ + + ]: 689 : switch (c) {
831 : 209 : case '=':
832 : 209 : set_token_id(&t, t.cur_tok, TokenIdPlusPercentEq);
833 : 209 : end_token(&t);
834 : 209 : t.state = TokenizeStateStart;
835 : 209 : break;
836 : 480 : default:
837 : 480 : t.pos -= 1;
838 : 480 : end_token(&t);
839 : 480 : t.state = TokenizeStateStart;
840 : 480 : continue;
841 : : }
842 : 209 : break;
843 : 8808 : case TokenizeStateSawAmpersand:
844 [ - + + ]: 8808 : switch (c) {
845 : 0 : case '&':
846 : 0 : tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND");
847 : 0 : break;
848 : 110 : case '=':
849 : 110 : set_token_id(&t, t.cur_tok, TokenIdBitAndEq);
850 : 110 : end_token(&t);
851 : 110 : t.state = TokenizeStateStart;
852 : 110 : break;
853 : 8698 : default:
854 : 8698 : t.pos -= 1;
855 : 8698 : end_token(&t);
856 : 8698 : t.state = TokenizeStateStart;
857 : 8698 : continue;
858 : : }
859 : 110 : break;
860 : 794 : case TokenizeStateSawCaret:
861 [ + + ]: 794 : switch (c) {
862 : 100 : case '=':
863 : 100 : set_token_id(&t, t.cur_tok, TokenIdBitXorEq);
864 : 100 : end_token(&t);
865 : 100 : t.state = TokenizeStateStart;
866 : 100 : break;
867 : 694 : default:
868 : 694 : t.pos -= 1;
869 : 694 : end_token(&t);
870 : 694 : t.state = TokenizeStateStart;
871 : 694 : continue;
872 : : }
873 : 100 : break;
874 : 13681 : case TokenizeStateSawBar:
875 [ + + + ]: 13681 : switch (c) {
876 : 353 : case '=':
877 : 353 : set_token_id(&t, t.cur_tok, TokenIdBitOrEq);
878 : 353 : end_token(&t);
879 : 353 : t.state = TokenizeStateStart;
880 : 353 : break;
881 : 95 : case '|':
882 : 95 : set_token_id(&t, t.cur_tok, TokenIdBarBar);
883 : 95 : t.state = TokenizeStateSawBarBar;
884 : 95 : break;
885 : 13233 : default:
886 : 13233 : t.pos -= 1;
887 : 13233 : end_token(&t);
888 : 13233 : t.state = TokenizeStateStart;
889 : 13233 : continue;
890 : : }
891 : 448 : break;
892 : 95 : case TokenizeStateSawBarBar:
893 [ - + ]: 95 : switch (c) {
894 : 0 : case '=':
895 : 0 : set_token_id(&t, t.cur_tok, TokenIdBarBarEq);
896 : 0 : end_token(&t);
897 : 0 : t.state = TokenizeStateStart;
898 : 0 : break;
899 : 95 : default:
900 : 95 : t.pos -= 1;
901 : 95 : end_token(&t);
902 : 95 : t.state = TokenizeStateStart;
903 : 95 : continue;
904 : : }
905 : : case TokenizeStateSawSlash:
906 [ + + + ]: 33951 : switch (c) {
907 : 32764 : case '/':
908 : 32764 : cancel_token(&t);
909 : 32764 : t.state = TokenizeStateLineComment;
910 : 32764 : break;
911 : 57 : case '=':
912 : 57 : set_token_id(&t, t.cur_tok, TokenIdDivEq);
913 : 57 : end_token(&t);
914 : 57 : t.state = TokenizeStateStart;
915 : 57 : break;
916 : 1130 : default:
917 : 1130 : t.pos -= 1;
918 : 1130 : end_token(&t);
919 : 1130 : t.state = TokenizeStateStart;
920 : 1130 : continue;
921 : : }
922 : 32821 : break;
923 : 1043 : case TokenizeStateSawBackslash:
924 [ + - ]: 1043 : switch (c) {
925 : 1043 : case '\\':
926 : 1043 : t.state = TokenizeStateLineString;
927 : 1043 : break;
928 : 0 : default:
929 : 0 : invalid_char_error(&t, c);
930 : 0 : break;
931 : : }
932 : 1043 : break;
933 : 402268 : case TokenizeStateLineString:
934 [ + + ]: 402268 : switch (c) {
935 : 13474 : case '\n':
936 : 13474 : t.state = TokenizeStateLineStringEnd;
937 : 13474 : break;
938 : 388794 : default:
939 : 388794 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
940 : 388794 : break;
941 : : }
942 : 402268 : break;
943 : 124758 : case TokenizeStateLineStringEnd:
944 [ + + + + ]: 124758 : switch (c) {
945 : 111284 : case WHITESPACE:
946 : 111284 : break;
947 : 16 : case 'c':
948 [ - + ]: 16 : if (!t.cur_tok->data.str_lit.is_c_str) {
949 : 0 : t.pos -= 1;
950 : 0 : end_token(&t);
951 : 0 : t.state = TokenizeStateStart;
952 : 0 : break;
953 : : }
954 : 16 : t.state = TokenizeStateLineStringContinueC;
955 : 16 : break;
956 : 12415 : case '\\':
957 [ - + ]: 12415 : if (t.cur_tok->data.str_lit.is_c_str) {
958 : 0 : invalid_char_error(&t, c);
959 : : }
960 : 12415 : t.state = TokenizeStateLineStringContinue;
961 : 12415 : break;
962 : 1043 : default:
963 : 1043 : t.pos -= 1;
964 : 1043 : end_token(&t);
965 : 1043 : t.state = TokenizeStateStart;
966 : 1043 : continue;
967 : : }
968 : 123715 : break;
969 : 16 : case TokenizeStateLineStringContinueC:
970 [ + - ]: 16 : switch (c) {
971 : 16 : case '\\':
972 : 16 : t.state = TokenizeStateLineStringContinue;
973 : 16 : break;
974 : 0 : default:
975 : 0 : t.pos -= 1;
976 : 0 : end_token(&t);
977 : 0 : t.state = TokenizeStateStart;
978 : 0 : continue;
979 : : }
980 : 16 : break;
981 : 12431 : case TokenizeStateLineStringContinue:
982 [ + - ]: 12431 : switch (c) {
983 : 12431 : case '\\':
984 : 12431 : t.state = TokenizeStateLineString;
985 : 12431 : buf_append_char(&t.cur_tok->data.str_lit.str, '\n');
986 : 12431 : break;
987 : 0 : default:
988 : 0 : invalid_char_error(&t, c);
989 : 0 : break;
990 : : }
991 : 12431 : break;
992 : 1608877 : case TokenizeStateLineComment:
993 [ + + ]: 1608877 : switch (c) {
994 : 32764 : case '\n':
995 : 32764 : t.state = TokenizeStateStart;
996 : 32764 : break;
997 : 1576113 : default:
998 : : // do nothing
999 : 1576113 : break;
1000 : : }
1001 : 1608877 : break;
1002 : 103172 : case TokenizeStateSymbolFirstC:
1003 [ + + + + ]: 103172 : switch (c) {
1004 : 277 : case '"':
1005 : 277 : set_token_id(&t, t.cur_tok, TokenIdStringLiteral);
1006 : 277 : t.cur_tok->data.str_lit.is_c_str = true;
1007 : 277 : t.state = TokenizeStateString;
1008 : 277 : break;
1009 : 8 : case '\\':
1010 : 8 : set_token_id(&t, t.cur_tok, TokenIdStringLiteral);
1011 : 8 : t.cur_tok->data.str_lit.is_c_str = true;
1012 : 8 : t.state = TokenizeStateSawBackslash;
1013 : 8 : break;
1014 : 100818 : case SYMBOL_CHAR:
1015 : 100818 : t.state = TokenizeStateSymbol;
1016 : 100818 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
1017 : 100818 : break;
1018 : 2069 : default:
1019 : 2069 : t.pos -= 1;
1020 : 2069 : end_token(&t);
1021 : 2069 : t.state = TokenizeStateStart;
1022 : 2069 : continue;
1023 : : }
1024 : 101103 : break;
1025 : 37475 : case TokenizeStateSawAtSign:
1026 [ + + ]: 37475 : switch (c) {
1027 : 155 : case '"':
1028 : 155 : set_token_id(&t, t.cur_tok, TokenIdSymbol);
1029 : 155 : t.state = TokenizeStateString;
1030 : 155 : break;
1031 : 37320 : default:
1032 : 37320 : t.pos -= 1;
1033 : 37320 : end_token(&t);
1034 : 37320 : t.state = TokenizeStateStart;
1035 : 37320 : continue;
1036 : : }
1037 : 155 : break;
1038 : 6127381 : case TokenizeStateSymbol:
1039 [ + + ]: 6127381 : switch (c) {
1040 : 5055915 : case SYMBOL_CHAR:
1041 : 5055915 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
1042 : 5055915 : break;
1043 : 1071466 : default:
1044 : 1071466 : t.pos -= 1;
1045 : 1071466 : end_token(&t);
1046 : 1071466 : t.state = TokenizeStateStart;
1047 : 1071466 : continue;
1048 : : }
1049 : 5055915 : break;
1050 : 679776 : case TokenizeStateString:
1051 [ + - + + ]: 679776 : switch (c) {
1052 : 41636 : case '"':
1053 : 41636 : end_token(&t);
1054 : 41636 : t.state = TokenizeStateStart;
1055 : 41636 : break;
1056 : 0 : case '\n':
1057 : 0 : tokenize_error(&t, "newline not allowed in string literal");
1058 : 0 : break;
1059 : 8384 : case '\\':
1060 : 8384 : t.state = TokenizeStateStringEscape;
1061 : 8384 : break;
1062 : 629756 : default:
1063 : 629756 : buf_append_char(&t.cur_tok->data.str_lit.str, c);
1064 : 629756 : break;
1065 : : }
1066 : 679776 : break;
1067 : 8851 : case TokenizeStateStringEscape:
1068 [ + + + + : 8851 : switch (c) {
+ + + +
- ]
1069 : 2650 : case 'x':
1070 : 2650 : t.state = TokenizeStateCharCode;
1071 : 2650 : t.radix = 16;
1072 : 2650 : t.char_code = 0;
1073 : 2650 : t.char_code_index = 0;
1074 : 2650 : t.unicode = false;
1075 : 2650 : break;
1076 : 32 : case 'u':
1077 : 32 : t.state = TokenizeStateStringEscapeUnicodeStart;
1078 : 32 : break;
1079 : 1952 : case 'n':
1080 : 1952 : handle_string_escape(&t, '\n');
1081 : 1952 : break;
1082 : 54 : case 'r':
1083 : 54 : handle_string_escape(&t, '\r');
1084 : 54 : break;
1085 : 3862 : case '\\':
1086 : 3862 : handle_string_escape(&t, '\\');
1087 : 3862 : break;
1088 : 82 : case 't':
1089 : 82 : handle_string_escape(&t, '\t');
1090 : 82 : break;
1091 : 24 : case '\'':
1092 : 24 : handle_string_escape(&t, '\'');
1093 : 24 : break;
1094 : 195 : case '"':
1095 : 195 : handle_string_escape(&t, '\"');
1096 : 195 : break;
1097 : 0 : default:
1098 : 0 : invalid_char_error(&t, c);
1099 : : }
1100 : 8851 : break;
1101 : 32 : case TokenizeStateStringEscapeUnicodeStart:
1102 [ + - ]: 32 : switch (c) {
1103 : 32 : case '{':
1104 : 32 : t.state = TokenizeStateCharCode;
1105 : 32 : t.radix = 16;
1106 : 32 : t.char_code = 0;
1107 : 32 : t.char_code_index = 0;
1108 : 32 : t.unicode = true;
1109 : 32 : break;
1110 : 0 : default:
1111 : 0 : invalid_char_error(&t, c);
1112 : : }
1113 : 32 : break;
1114 : 5444 : case TokenizeStateCharCode:
1115 : : {
1116 [ + + ][ + + ]: 5444 : if (t.unicode && c == '}') {
1117 [ - + ]: 32 : if (t.char_code_index == 0) {
1118 : 0 : tokenize_error(&t, "empty unicode escape sequence");
1119 : 0 : break;
1120 : : }
1121 [ - + ]: 32 : if (t.char_code > 0x10ffff) {
1122 : 0 : tokenize_error(&t, "unicode value out of range: %x", t.char_code);
1123 : 0 : break;
1124 : : }
1125 [ + + ]: 32 : if (t.cur_tok->id == TokenIdCharLiteral) {
1126 : 8 : t.cur_tok->data.char_lit.c = t.char_code;
1127 : 8 : t.state = TokenizeStateCharLiteralEnd;
1128 [ + + ]: 24 : } else if (t.char_code <= 0x7f) {
1129 : : // 00000000 00000000 00000000 0xxxxxxx
1130 : 16 : handle_string_escape(&t, (uint8_t)t.char_code);
1131 [ - + ]: 8 : } else if (t.char_code <= 0x7ff) {
1132 : : // 00000000 00000000 00000xxx xx000000
1133 : 0 : handle_string_escape(&t, (uint8_t)(0xc0 | (t.char_code >> 6)));
1134 : : // 00000000 00000000 00000000 00xxxxxx
1135 : 0 : handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1136 [ + - ]: 8 : } else if (t.char_code <= 0xffff) {
1137 : : // 00000000 00000000 xxxx0000 00000000
1138 : 8 : handle_string_escape(&t, (uint8_t)(0xe0 | (t.char_code >> 12)));
1139 : : // 00000000 00000000 0000xxxx xx000000
1140 : 8 : handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 6) & 0x3f)));
1141 : : // 00000000 00000000 00000000 00xxxxxx
1142 : 8 : handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1143 [ # # ]: 0 : } else if (t.char_code <= 0x10ffff) {
1144 : : // 00000000 000xxx00 00000000 00000000
1145 : 0 : handle_string_escape(&t, (uint8_t)(0xf0 | (t.char_code >> 18)));
1146 : : // 00000000 000000xx xxxx0000 00000000
1147 : 0 : handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 12) & 0x3f)));
1148 : : // 00000000 00000000 0000xxxx xx000000
1149 : 0 : handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 6) & 0x3f)));
1150 : : // 00000000 00000000 00000000 00xxxxxx
1151 : 0 : handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1152 : : } else {
1153 : 0 : zig_unreachable();
1154 : : }
1155 : 32 : break;
1156 : : }
1157 : :
1158 : 5412 : uint32_t digit_value = get_digit_value(c);
1159 [ - + ]: 5412 : if (digit_value >= t.radix) {
1160 : 0 : tokenize_error(&t, "invalid digit: '%c'", c);
1161 : 0 : break;
1162 : : }
1163 : 5412 : t.char_code *= t.radix;
1164 : 5412 : t.char_code += digit_value;
1165 : 5412 : t.char_code_index += 1;
1166 : :
1167 [ + + ][ + + ]: 5412 : if (!t.unicode && t.char_code_index >= 2) {
1168 : 2650 : assert(t.char_code <= 255);
1169 : 2650 : handle_string_escape(&t, (uint8_t)t.char_code);
1170 : : }
1171 : : }
1172 : 5412 : break;
1173 : 4139 : case TokenizeStateCharLiteral:
1174 [ - + + ]: 4139 : switch (c) {
1175 : 0 : case '\'':
1176 : 0 : tokenize_error(&t, "expected character");
1177 : 0 : break;
1178 : 467 : case '\\':
1179 : 467 : t.state = TokenizeStateStringEscape;
1180 : 467 : break;
1181 : 3672 : default:
1182 : 3672 : t.cur_tok->data.char_lit.c = c;
1183 : 3672 : t.state = TokenizeStateCharLiteralEnd;
1184 : 3672 : break;
1185 : : }
1186 : 4139 : break;
1187 : 4139 : case TokenizeStateCharLiteralEnd:
1188 [ + - ]: 4139 : switch (c) {
1189 : 4139 : case '\'':
1190 : 4139 : end_token(&t);
1191 : 4139 : t.state = TokenizeStateStart;
1192 : 4139 : break;
1193 : 0 : default:
1194 : 0 : invalid_char_error(&t, c);
1195 : : }
1196 : 4139 : break;
1197 : 48585 : case TokenizeStateZero:
1198 [ + + + + ]: 48585 : switch (c) {
1199 : 1179 : case 'b':
1200 : 1179 : t.radix = 2;
1201 : 1179 : t.state = TokenizeStateNumber;
1202 : 1179 : break;
1203 : 475 : case 'o':
1204 : 475 : t.radix = 8;
1205 : 475 : t.exp_add_amt = 3;
1206 : 475 : t.state = TokenizeStateNumber;
1207 : 475 : break;
1208 : 24973 : case 'x':
1209 : 24973 : t.radix = 16;
1210 : 24973 : t.exp_add_amt = 4;
1211 : 24973 : t.state = TokenizeStateNumber;
1212 : 24973 : break;
1213 : 21958 : default:
1214 : : // reinterpret as normal number
1215 : 21958 : t.pos -= 1;
1216 : 21958 : t.state = TokenizeStateNumber;
1217 : 21958 : continue;
1218 : : }
1219 : 26627 : break;
1220 : 390779 : case TokenizeStateNumber:
1221 : : {
1222 [ + + ]: 390779 : if (c == '.') {
1223 [ + + ][ - + ]: 22483 : if (t.radix != 16 && t.radix != 10) {
1224 : 0 : invalid_char_error(&t, c);
1225 : : }
1226 : 22483 : t.state = TokenizeStateNumberDot;
1227 : 285978 : break;
1228 : : }
1229 [ + + ]: 368296 : if (is_exponent_signifier(c, t.radix)) {
1230 [ + + ][ - + ]: 28 : if (t.radix != 16 && t.radix != 10) {
1231 : 0 : invalid_char_error(&t, c);
1232 : : }
1233 : 28 : t.state = TokenizeStateFloatExponentUnsigned;
1234 : 28 : assert(t.cur_tok->id == TokenIdIntLiteral);
1235 : 28 : bigint_init_bigint(&t.significand, &t.cur_tok->data.int_lit.bigint);
1236 : 28 : set_token_id(&t, t.cur_tok, TokenIdFloatLiteral);
1237 : 28 : break;
1238 : : }
1239 : 368268 : uint32_t digit_value = get_digit_value(c);
1240 [ + + ]: 368268 : if (digit_value >= t.radix) {
1241 [ - + ]: 104801 : if (is_symbol_char(c)) {
1242 : 0 : invalid_char_error(&t, c);
1243 : : }
1244 : : // not my char
1245 : 104801 : t.pos -= 1;
1246 : 104801 : end_token(&t);
1247 : 104801 : t.state = TokenizeStateStart;
1248 : 104801 : continue;
1249 : : }
1250 : : BigInt digit_value_bi;
1251 : 263467 : bigint_init_unsigned(&digit_value_bi, digit_value);
1252 : :
1253 : : BigInt radix_bi;
1254 : 263467 : bigint_init_unsigned(&radix_bi, t.radix);
1255 : :
1256 : : BigInt multiplied;
1257 : 263467 : bigint_mul(&multiplied, &t.cur_tok->data.int_lit.bigint, &radix_bi);
1258 : :
1259 : 263467 : bigint_add(&t.cur_tok->data.int_lit.bigint, &multiplied, &digit_value_bi);
1260 : 263467 : break;
1261 : : }
1262 : 22483 : case TokenizeStateNumberDot:
1263 : : {
1264 [ + + ]: 22483 : if (c == '.') {
1265 : 3976 : t.pos -= 2;
1266 : 3976 : end_token(&t);
1267 : 3976 : t.state = TokenizeStateStart;
1268 : 3976 : continue;
1269 : : }
1270 : 18507 : t.pos -= 1;
1271 : 18507 : t.state = TokenizeStateFloatFraction;
1272 : 18507 : assert(t.cur_tok->id == TokenIdIntLiteral);
1273 : 18507 : bigint_init_bigint(&t.significand, &t.cur_tok->data.int_lit.bigint);
1274 : 18507 : set_token_id(&t, t.cur_tok, TokenIdFloatLiteral);
1275 : 18507 : continue;
1276 : : }
1277 : 173166 : case TokenizeStateFloatFraction:
1278 : : {
1279 [ + + ]: 173166 : if (is_exponent_signifier(c, t.radix)) {
1280 : 12001 : t.state = TokenizeStateFloatExponentUnsigned;
1281 : 166660 : break;
1282 : : }
1283 : 161165 : uint32_t digit_value = get_digit_value(c);
1284 [ + + ]: 161165 : if (digit_value >= t.radix) {
1285 [ - + ]: 6506 : if (is_symbol_char(c)) {
1286 : 0 : invalid_char_error(&t, c);
1287 : : }
1288 : : // not my char
1289 : 6506 : t.pos -= 1;
1290 : 6506 : end_token(&t);
1291 : 6506 : t.state = TokenizeStateStart;
1292 : 6506 : continue;
1293 : : }
1294 : 154659 : t.exponent_in_bin_or_dec -= t.exp_add_amt;
1295 [ + + ]: 154659 : if (t.radix == 10) {
1296 : : // For now we use strtod to parse decimal floats, so we just have to get to the
1297 : : // end of the token.
1298 : 140781 : break;
1299 : : }
1300 : : BigInt digit_value_bi;
1301 : 13878 : bigint_init_unsigned(&digit_value_bi, digit_value);
1302 : :
1303 : : BigInt radix_bi;
1304 : 13878 : bigint_init_unsigned(&radix_bi, t.radix);
1305 : :
1306 : : BigInt multiplied;
1307 : 13878 : bigint_mul(&multiplied, &t.significand, &radix_bi);
1308 : :
1309 : 13878 : bigint_add(&t.significand, &multiplied, &digit_value_bi);
1310 : 13878 : break;
1311 : : }
1312 : 12029 : case TokenizeStateFloatExponentUnsigned:
1313 [ + + + ]: 12029 : switch (c) {
1314 : 5399 : case '+':
1315 : 5399 : t.is_exp_negative = false;
1316 : 5399 : t.state = TokenizeStateFloatExponentNumber;
1317 : 5399 : break;
1318 : 6283 : case '-':
1319 : 6283 : t.is_exp_negative = true;
1320 : 6283 : t.state = TokenizeStateFloatExponentNumber;
1321 : 6283 : break;
1322 : 347 : default:
1323 : : // reinterpret as normal exponent number
1324 : 347 : t.pos -= 1;
1325 : 347 : t.is_exp_negative = false;
1326 : 347 : t.state = TokenizeStateFloatExponentNumber;
1327 : 347 : continue;
1328 : : }
1329 : 11682 : break;
1330 : 41974 : case TokenizeStateFloatExponentNumber:
1331 : : {
1332 : 41974 : uint32_t digit_value = get_digit_value(c);
1333 [ + + ]: 41974 : if (digit_value >= t.radix) {
1334 [ - + ]: 12029 : if (is_symbol_char(c)) {
1335 : 0 : invalid_char_error(&t, c);
1336 : : }
1337 : : // not my char
1338 : 12029 : t.pos -= 1;
1339 : 12029 : end_token(&t);
1340 : 12029 : t.state = TokenizeStateStart;
1341 : 12029 : continue;
1342 : : }
1343 [ + + ]: 29945 : if (t.radix == 10) {
1344 : : // For now we use strtod to parse decimal floats, so we just have to get to the
1345 : : // end of the token.
1346 : 26923 : break;
1347 : : }
1348 : : BigInt digit_value_bi;
1349 : 3022 : bigint_init_unsigned(&digit_value_bi, digit_value);
1350 : :
1351 : : BigInt radix_bi;
1352 : 3022 : bigint_init_unsigned(&radix_bi, 10);
1353 : :
1354 : : BigInt multiplied;
1355 : 3022 : bigint_mul(&multiplied, &t.specified_exponent, &radix_bi);
1356 : :
1357 : 3022 : bigint_add(&t.specified_exponent, &multiplied, &digit_value_bi);
1358 : : }
1359 : 3022 : break;
1360 : 14745 : case TokenizeStateSawDash:
1361 [ + + + + ]: 14745 : switch (c) {
1362 : 162 : case '>':
1363 : 162 : set_token_id(&t, t.cur_tok, TokenIdArrow);
1364 : 162 : end_token(&t);
1365 : 162 : t.state = TokenizeStateStart;
1366 : 162 : break;
1367 : 774 : case '=':
1368 : 774 : set_token_id(&t, t.cur_tok, TokenIdMinusEq);
1369 : 774 : end_token(&t);
1370 : 774 : t.state = TokenizeStateStart;
1371 : 774 : break;
1372 : 467 : case '%':
1373 : 467 : set_token_id(&t, t.cur_tok, TokenIdMinusPercent);
1374 : 467 : t.state = TokenizeStateSawMinusPercent;
1375 : 467 : break;
1376 : 13342 : default:
1377 : 13342 : t.pos -= 1;
1378 : 13342 : end_token(&t);
1379 : 13342 : t.state = TokenizeStateStart;
1380 : 13342 : continue;
1381 : : }
1382 : 1403 : break;
1383 : 467 : case TokenizeStateSawMinusPercent:
1384 [ + + ]: 467 : switch (c) {
1385 : 98 : case '=':
1386 : 98 : set_token_id(&t, t.cur_tok, TokenIdMinusPercentEq);
1387 : 98 : end_token(&t);
1388 : 98 : t.state = TokenizeStateStart;
1389 : 98 : break;
1390 : 369 : default:
1391 : 369 : t.pos -= 1;
1392 : 369 : end_token(&t);
1393 : 369 : t.state = TokenizeStateStart;
1394 : 369 : continue;
1395 : : }
1396 : 98 : break;
1397 : : }
1398 [ + + ]: 14950382 : if (c == '\n') {
1399 : 468358 : out->line_offsets->append(t.pos + 1);
1400 : 468358 : t.line += 1;
1401 : 468358 : t.column = 0;
1402 : : } else {
1403 : 14482024 : t.column += 1;
1404 : : }
1405 : : }
1406 : : // EOF
1407 [ + - - - : 1804 : switch (t.state) {
- - - -
- ]
1408 : 1804 : case TokenizeStateStart:
1409 : : case TokenizeStateError:
1410 : 1804 : break;
1411 : 0 : case TokenizeStateNumberDot:
1412 : 0 : tokenize_error(&t, "unterminated number literal");
1413 : 0 : break;
1414 : 0 : case TokenizeStateString:
1415 : 0 : tokenize_error(&t, "unterminated string");
1416 : 0 : break;
1417 : 0 : case TokenizeStateStringEscape:
1418 : : case TokenizeStateStringEscapeUnicodeStart:
1419 : : case TokenizeStateCharCode:
1420 [ # # ]: 0 : if (t.cur_tok->id == TokenIdStringLiteral) {
1421 : 0 : tokenize_error(&t, "unterminated string");
1422 : 0 : break;
1423 [ # # ]: 0 : } else if (t.cur_tok->id == TokenIdCharLiteral) {
1424 : 0 : tokenize_error(&t, "unterminated character literal");
1425 : 0 : break;
1426 : : } else {
1427 : 0 : zig_unreachable();
1428 : : }
1429 : : break;
1430 : 0 : case TokenizeStateCharLiteral:
1431 : : case TokenizeStateCharLiteralEnd:
1432 : 0 : tokenize_error(&t, "unterminated character literal");
1433 : 0 : break;
1434 : 0 : case TokenizeStateSymbol:
1435 : : case TokenizeStateSymbolFirstC:
1436 : : case TokenizeStateZero:
1437 : : case TokenizeStateNumber:
1438 : : case TokenizeStateFloatFraction:
1439 : : case TokenizeStateFloatExponentUnsigned:
1440 : : case TokenizeStateFloatExponentNumber:
1441 : : case TokenizeStateSawStar:
1442 : : case TokenizeStateSawSlash:
1443 : : case TokenizeStateSawPercent:
1444 : : case TokenizeStateSawPlus:
1445 : : case TokenizeStateSawDash:
1446 : : case TokenizeStateSawAmpersand:
1447 : : case TokenizeStateSawCaret:
1448 : : case TokenizeStateSawBar:
1449 : : case TokenizeStateSawEq:
1450 : : case TokenizeStateSawBang:
1451 : : case TokenizeStateSawLessThan:
1452 : : case TokenizeStateSawLessThanLessThan:
1453 : : case TokenizeStateSawGreaterThan:
1454 : : case TokenizeStateSawGreaterThanGreaterThan:
1455 : : case TokenizeStateSawDot:
1456 : : case TokenizeStateSawAtSign:
1457 : : case TokenizeStateSawStarPercent:
1458 : : case TokenizeStateSawPlusPercent:
1459 : : case TokenizeStateSawMinusPercent:
1460 : : case TokenizeStateLineString:
1461 : : case TokenizeStateLineStringEnd:
1462 : : case TokenizeStateSawBarBar:
1463 : : case TokenizeStateLBracket:
1464 : 0 : end_token(&t);
1465 : 0 : break;
1466 : 0 : case TokenizeStateSawDotDot:
1467 : : case TokenizeStateSawBackslash:
1468 : : case TokenizeStateLineStringContinue:
1469 : : case TokenizeStateLineStringContinueC:
1470 : : case TokenizeStateLBracketStar:
1471 : : case TokenizeStateLBracketStarC:
1472 : : case TokenizeStateLBracketUnderscore:
1473 : 0 : tokenize_error(&t, "unexpected EOF");
1474 : 0 : break;
1475 : 0 : case TokenizeStateLineComment:
1476 : 0 : break;
1477 : : }
1478 [ + - ]: 1804 : if (t.state != TokenizeStateError) {
1479 [ + - ]: 1804 : if (t.tokens->length > 0) {
1480 : 1804 : Token *last_token = &t.tokens->last();
1481 : 1804 : t.line = (int)last_token->start_line;
1482 : 1804 : t.column = (int)last_token->start_column;
1483 : 1804 : t.pos = last_token->start_pos;
1484 : : } else {
1485 : 0 : t.pos = 0;
1486 : : }
1487 : 1804 : begin_token(&t, TokenIdEof);
1488 : 1804 : end_token(&t);
1489 : 1804 : assert(!t.cur_tok);
1490 : : }
1491 : 1804 : }
1492 : :
1493 : 0 : const char * token_name(TokenId id) {
1494 [ # # # # : 0 : switch (id) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
1495 : 0 : case TokenIdAmpersand: return "&";
1496 : 0 : case TokenIdArrow: return "->";
1497 : 0 : case TokenIdAtSign: return "@";
1498 : 0 : case TokenIdBang: return "!";
1499 : 0 : case TokenIdBarBar: return "||";
1500 : 0 : case TokenIdBinOr: return "|";
1501 : 0 : case TokenIdBinXor: return "^";
1502 : 0 : case TokenIdBitAndEq: return "&=";
1503 : 0 : case TokenIdBitOrEq: return "|=";
1504 : 0 : case TokenIdBitShiftLeft: return "<<";
1505 : 0 : case TokenIdBitShiftLeftEq: return "<<=";
1506 : 0 : case TokenIdBitShiftRight: return ">>";
1507 : 0 : case TokenIdBitShiftRightEq: return ">>=";
1508 : 0 : case TokenIdBitXorEq: return "^=";
1509 : 0 : case TokenIdBracketStarBracket: return "[*]";
1510 : 0 : case TokenIdBracketStarCBracket: return "[*c]";
1511 : 0 : case TokenIdCharLiteral: return "CharLiteral";
1512 : 0 : case TokenIdCmpEq: return "==";
1513 : 0 : case TokenIdCmpGreaterOrEq: return ">=";
1514 : 0 : case TokenIdCmpGreaterThan: return ">";
1515 : 0 : case TokenIdCmpLessOrEq: return "<=";
1516 : 0 : case TokenIdCmpLessThan: return "<";
1517 : 0 : case TokenIdCmpNotEq: return "!=";
1518 : 0 : case TokenIdColon: return ":";
1519 : 0 : case TokenIdComma: return ",";
1520 : 0 : case TokenIdDash: return "-";
1521 : 0 : case TokenIdDivEq: return "/=";
1522 : 0 : case TokenIdDot: return ".";
1523 : 0 : case TokenIdEllipsis2: return "..";
1524 : 0 : case TokenIdEllipsis3: return "...";
1525 : 0 : case TokenIdEof: return "EOF";
1526 : 0 : case TokenIdEq: return "=";
1527 : 0 : case TokenIdFatArrow: return "=>";
1528 : 0 : case TokenIdFloatLiteral: return "FloatLiteral";
1529 : 0 : case TokenIdIntLiteral: return "IntLiteral";
1530 : 0 : case TokenIdKeywordAsync: return "async";
1531 : 0 : case TokenIdKeywordAllowZero: return "allowzero";
1532 : 0 : case TokenIdKeywordAwait: return "await";
1533 : 0 : case TokenIdKeywordResume: return "resume";
1534 : 0 : case TokenIdKeywordSuspend: return "suspend";
1535 : 0 : case TokenIdKeywordAlign: return "align";
1536 : 0 : case TokenIdKeywordAnd: return "and";
1537 : 0 : case TokenIdKeywordAnyFrame: return "anyframe";
1538 : 0 : case TokenIdKeywordAsm: return "asm";
1539 : 0 : case TokenIdKeywordBreak: return "break";
1540 : 0 : case TokenIdKeywordCatch: return "catch";
1541 : 0 : case TokenIdKeywordCompTime: return "comptime";
1542 : 0 : case TokenIdKeywordConst: return "const";
1543 : 0 : case TokenIdKeywordContinue: return "continue";
1544 : 0 : case TokenIdKeywordDefer: return "defer";
1545 : 0 : case TokenIdKeywordElse: return "else";
1546 : 0 : case TokenIdKeywordEnum: return "enum";
1547 : 0 : case TokenIdKeywordErrdefer: return "errdefer";
1548 : 0 : case TokenIdKeywordError: return "error";
1549 : 0 : case TokenIdKeywordExport: return "export";
1550 : 0 : case TokenIdKeywordExtern: return "extern";
1551 : 0 : case TokenIdKeywordFalse: return "false";
1552 : 0 : case TokenIdKeywordFn: return "fn";
1553 : 0 : case TokenIdKeywordFor: return "for";
1554 : 0 : case TokenIdKeywordIf: return "if";
1555 : 0 : case TokenIdKeywordInline: return "inline";
1556 : 0 : case TokenIdKeywordNakedCC: return "nakedcc";
1557 : 0 : case TokenIdKeywordNoAlias: return "noalias";
1558 : 0 : case TokenIdKeywordNoAsync: return "noasync";
1559 : 0 : case TokenIdKeywordNoInline: return "noinline";
1560 : 0 : case TokenIdKeywordNull: return "null";
1561 : 0 : case TokenIdKeywordOr: return "or";
1562 : 0 : case TokenIdKeywordOrElse: return "orelse";
1563 : 0 : case TokenIdKeywordPacked: return "packed";
1564 : 0 : case TokenIdKeywordPub: return "pub";
1565 : 0 : case TokenIdKeywordReturn: return "return";
1566 : 0 : case TokenIdKeywordLinkSection: return "linksection";
1567 : 0 : case TokenIdKeywordStdcallCC: return "stdcallcc";
1568 : 0 : case TokenIdKeywordStruct: return "struct";
1569 : 0 : case TokenIdKeywordSwitch: return "switch";
1570 : 0 : case TokenIdKeywordTest: return "test";
1571 : 0 : case TokenIdKeywordThreadLocal: return "threadlocal";
1572 : 0 : case TokenIdKeywordTrue: return "true";
1573 : 0 : case TokenIdKeywordTry: return "try";
1574 : 0 : case TokenIdKeywordUndefined: return "undefined";
1575 : 0 : case TokenIdKeywordUnion: return "union";
1576 : 0 : case TokenIdKeywordUnreachable: return "unreachable";
1577 : 0 : case TokenIdKeywordUsingNamespace: return "usingnamespace";
1578 : 0 : case TokenIdKeywordVar: return "var";
1579 : 0 : case TokenIdKeywordVolatile: return "volatile";
1580 : 0 : case TokenIdKeywordWhile: return "while";
1581 : 0 : case TokenIdLBrace: return "{";
1582 : 0 : case TokenIdLBracket: return "[";
1583 : 0 : case TokenIdLParen: return "(";
1584 : 0 : case TokenIdQuestion: return "?";
1585 : 0 : case TokenIdMinusEq: return "-=";
1586 : 0 : case TokenIdMinusPercent: return "-%";
1587 : 0 : case TokenIdMinusPercentEq: return "-%=";
1588 : 0 : case TokenIdModEq: return "%=";
1589 : 0 : case TokenIdNumberSign: return "#";
1590 : 0 : case TokenIdPercent: return "%";
1591 : 0 : case TokenIdPercentDot: return "%.";
1592 : 0 : case TokenIdPlus: return "+";
1593 : 0 : case TokenIdPlusEq: return "+=";
1594 : 0 : case TokenIdPlusPercent: return "+%";
1595 : 0 : case TokenIdPlusPercentEq: return "+%=";
1596 : 0 : case TokenIdPlusPlus: return "++";
1597 : 0 : case TokenIdRBrace: return "}";
1598 : 0 : case TokenIdRBracket: return "]";
1599 : 0 : case TokenIdRParen: return ")";
1600 : 0 : case TokenIdSemicolon: return ";";
1601 : 0 : case TokenIdSlash: return "/";
1602 : 0 : case TokenIdStar: return "*";
1603 : 0 : case TokenIdStarStar: return "**";
1604 : 0 : case TokenIdStringLiteral: return "StringLiteral";
1605 : 0 : case TokenIdSymbol: return "Symbol";
1606 : 0 : case TokenIdTilde: return "~";
1607 : 0 : case TokenIdTimesEq: return "*=";
1608 : 0 : case TokenIdTimesPercent: return "*%";
1609 : 0 : case TokenIdTimesPercentEq: return "*%=";
1610 : 0 : case TokenIdBarBarEq: return "||=";
1611 : 0 : case TokenIdBracketUnderscoreBracket: return "[_]";
1612 : 0 : case TokenIdCount:
1613 : 0 : zig_unreachable();
1614 : : }
1615 : 0 : return "(invalid token)";
1616 : : }
1617 : :
1618 : 0 : void print_tokens(Buf *buf, ZigList<Token> *tokens) {
1619 [ # # ]: 0 : for (size_t i = 0; i < tokens->length; i += 1) {
1620 : 0 : Token *token = &tokens->at(i);
1621 : 0 : fprintf(stderr, "%s ", token_name(token->id));
1622 [ # # ]: 0 : if (token->start_pos != SIZE_MAX) {
1623 : 0 : fwrite(buf_ptr(buf) + token->start_pos, 1, token->end_pos - token->start_pos, stderr);
1624 : : }
1625 : 0 : fprintf(stderr, "\n");
1626 : : }
1627 : 0 : }
1628 : :
1629 : 0 : bool valid_symbol_starter(uint8_t c) {
1630 [ # # ]: 0 : switch (c) {
1631 : 0 : case SYMBOL_START:
1632 : 0 : return true;
1633 : : }
1634 : 0 : return false;
1635 : : }
|