LCOV - code coverage report
Current view: top level - src - tokenizer.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 878 1171 75.0 %
Date: 1970-01-01 00:00:01 Functions: 10 17 58.8 %
Branches: 271 468 57.9 %

           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                 :            : }

Generated by: LCOV version 1.14