LCOV - code coverage report
Current view: top level - src - c_tokenizer.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 566 0.0 %
Date: 1970-01-01 00:00:01 Functions: 0 7 0.0 %
Branches: 0 170 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016 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 "c_tokenizer.hpp"
       9                 :            : #include <inttypes.h>
      10                 :            : 
      11                 :            : #define WHITESPACE_EXCEPT_N \
      12                 :            :          ' ': \
      13                 :            :     case '\t': \
      14                 :            :     case '\v': \
      15                 :            :     case '\f'
      16                 :            : 
      17                 :            : #define DIGIT_NON_ZERO \
      18                 :            :          '1': \
      19                 :            :     case '2': \
      20                 :            :     case '3': \
      21                 :            :     case '4': \
      22                 :            :     case '5': \
      23                 :            :     case '6': \
      24                 :            :     case '7': \
      25                 :            :     case '8': \
      26                 :            :     case '9'
      27                 :            : 
      28                 :            : #define DIGIT \
      29                 :            :          '0': \
      30                 :            :     case DIGIT_NON_ZERO
      31                 :            : 
      32                 :            : #define ALPHA \
      33                 :            :          'a': \
      34                 :            :     case 'b': \
      35                 :            :     case 'c': \
      36                 :            :     case 'd': \
      37                 :            :     case 'e': \
      38                 :            :     case 'f': \
      39                 :            :     case 'g': \
      40                 :            :     case 'h': \
      41                 :            :     case 'i': \
      42                 :            :     case 'j': \
      43                 :            :     case 'k': \
      44                 :            :     case 'l': \
      45                 :            :     case 'm': \
      46                 :            :     case 'n': \
      47                 :            :     case 'o': \
      48                 :            :     case 'p': \
      49                 :            :     case 'q': \
      50                 :            :     case 'r': \
      51                 :            :     case 's': \
      52                 :            :     case 't': \
      53                 :            :     case 'u': \
      54                 :            :     case 'v': \
      55                 :            :     case 'w': \
      56                 :            :     case 'x': \
      57                 :            :     case 'y': \
      58                 :            :     case 'z': \
      59                 :            :     case 'A': \
      60                 :            :     case 'B': \
      61                 :            :     case 'C': \
      62                 :            :     case 'D': \
      63                 :            :     case 'E': \
      64                 :            :     case 'F': \
      65                 :            :     case 'G': \
      66                 :            :     case 'H': \
      67                 :            :     case 'I': \
      68                 :            :     case 'J': \
      69                 :            :     case 'K': \
      70                 :            :     case 'L': \
      71                 :            :     case 'M': \
      72                 :            :     case 'N': \
      73                 :            :     case 'O': \
      74                 :            :     case 'P': \
      75                 :            :     case 'Q': \
      76                 :            :     case 'R': \
      77                 :            :     case 'S': \
      78                 :            :     case 'T': \
      79                 :            :     case 'U': \
      80                 :            :     case 'V': \
      81                 :            :     case 'W': \
      82                 :            :     case 'X': \
      83                 :            :     case 'Y': \
      84                 :            :     case 'Z'
      85                 :            : 
      86                 :            : #define IDENT_START \
      87                 :            :     ALPHA: \
      88                 :            :     case '_'
      89                 :            : 
      90                 :            : #define IDENT \
      91                 :            :     IDENT_START: \
      92                 :            :     case DIGIT
      93                 :            : 
      94                 :            : #define LINE_ENDING \
      95                 :            :          '\r': \
      96                 :            :     case '\n'
      97                 :            : 
      98                 :          0 : static void begin_token(CTokenize *ctok, CTokId id) {
      99                 :          0 :     assert(ctok->cur_tok == nullptr);
     100                 :          0 :     ctok->tokens.add_one();
     101                 :          0 :     ctok->cur_tok = &ctok->tokens.last();
     102                 :          0 :     ctok->cur_tok->id = id;
     103                 :            : 
     104   [ #  #  #  #  :          0 :     switch (id) {
                      # ]
     105                 :          0 :         case CTokIdStrLit:
     106                 :          0 :             memset(&ctok->cur_tok->data.str_lit, 0, sizeof(Buf));
     107                 :          0 :             buf_resize(&ctok->cur_tok->data.str_lit, 0);
     108                 :          0 :             break;
     109                 :          0 :         case CTokIdSymbol:
     110                 :          0 :             memset(&ctok->cur_tok->data.symbol, 0, sizeof(Buf));
     111                 :          0 :             buf_resize(&ctok->cur_tok->data.symbol, 0);
     112                 :          0 :             break;
     113                 :          0 :         case CTokIdNumLitInt:
     114                 :          0 :             ctok->cur_tok->data.num_lit_int.x = 0;
     115                 :          0 :             ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixNone;
     116                 :          0 :             break;
     117                 :          0 :         case CTokIdCharLit:
     118                 :            :         case CTokIdNumLitFloat:
     119                 :            :         case CTokIdMinus:
     120                 :            :         case CTokIdLParen:
     121                 :            :         case CTokIdRParen:
     122                 :            :         case CTokIdEOF:
     123                 :            :         case CTokIdDot:
     124                 :            :         case CTokIdAsterisk:
     125                 :            :         case CTokIdBang:
     126                 :            :         case CTokIdTilde:
     127                 :            :         case CTokIdShl:
     128                 :            :         case CTokIdLt:
     129                 :          0 :             break;
     130                 :            :     }
     131                 :          0 : }
     132                 :            : 
     133                 :          0 : static void end_token(CTokenize *ctok) {
     134                 :          0 :     ctok->cur_tok = nullptr;
     135                 :          0 : }
     136                 :            : 
     137                 :          0 : static void mark_error(CTokenize *ctok) {
     138                 :          0 :     ctok->error = true;
     139                 :          0 : }
     140                 :            : 
     141                 :          0 : static void add_char(CTokenize *ctok, uint8_t c) {
     142                 :          0 :     assert(ctok->cur_tok);
     143         [ #  # ]:          0 :     if (ctok->cur_tok->id == CTokIdCharLit) {
     144                 :          0 :         ctok->cur_tok->data.char_lit = c;
     145                 :          0 :         ctok->state = CTokStateExpectEndQuot;
     146         [ #  # ]:          0 :     } else if (ctok->cur_tok->id == CTokIdStrLit) {
     147                 :          0 :         buf_append_char(&ctok->cur_tok->data.str_lit, c);
     148                 :          0 :         ctok->state = CTokStateString;
     149                 :            :     } else {
     150                 :          0 :         zig_unreachable();
     151                 :            :     }
     152                 :          0 : }
     153                 :            : 
     154                 :          0 : static void hex_digit(CTokenize *ctok, uint8_t value) {
     155                 :            :     // TODO @mul_with_overflow
     156                 :          0 :     ctok->cur_tok->data.num_lit_int.x *= 16;
     157                 :            :     // TODO @add_with_overflow
     158                 :          0 :     ctok->cur_tok->data.num_lit_int.x += value;
     159                 :            : 
     160                 :            :     static const uint8_t hex_digit[] = "0123456789abcdef";
     161                 :          0 :     buf_append_char(&ctok->buf, hex_digit[value]);
     162                 :          0 : }
     163                 :            : 
     164                 :          0 : static void end_float(CTokenize *ctok) {
     165                 :            :     // TODO detect errors, overflow, and underflow
     166                 :          0 :     double value = strtod(buf_ptr(&ctok->buf), nullptr);
     167                 :            : 
     168                 :          0 :     ctok->cur_tok->data.num_lit_float = value;
     169                 :            : 
     170                 :          0 :     end_token(ctok);
     171                 :          0 :     ctok->state = CTokStateStart;
     172                 :            : 
     173                 :          0 : }
     174                 :            : 
     175                 :          0 : void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
     176                 :          0 :     ctok->tokens.resize(0);
     177                 :          0 :     ctok->state = CTokStateStart;
     178                 :          0 :     ctok->error = false;
     179                 :          0 :     ctok->cur_tok = nullptr;
     180                 :            : 
     181                 :          0 :     buf_resize(&ctok->buf, 0);
     182                 :            : 
     183         [ #  # ]:          0 :     for (; *c; c += 1) {
     184   [ #  #  #  #  :          0 :         switch (ctok->state) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     185                 :          0 :             case CTokStateStart:
     186   [ #  #  #  #  :          0 :                 switch (*c) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     187                 :          0 :                     case WHITESPACE_EXCEPT_N:
     188                 :          0 :                         break;
     189                 :          0 :                     case '\'':
     190                 :          0 :                         ctok->state = CTokStateExpectChar;
     191                 :          0 :                         begin_token(ctok, CTokIdCharLit);
     192                 :          0 :                         break;
     193                 :          0 :                     case '\"':
     194                 :          0 :                         ctok->state = CTokStateString;
     195                 :          0 :                         begin_token(ctok, CTokIdStrLit);
     196                 :          0 :                         break;
     197                 :          0 :                     case '/':
     198                 :          0 :                         ctok->state = CTokStateOpenComment;
     199                 :          0 :                         break;
     200                 :          0 :                     case '\\':
     201                 :          0 :                         ctok->state = CTokStateBackslash;
     202                 :          0 :                         break;
     203                 :          0 :                     case LINE_ENDING:
     204                 :          0 :                         goto found_end_of_macro;
     205                 :          0 :                     case IDENT_START:
     206                 :          0 :                         ctok->state = CTokStateIdentifier;
     207                 :          0 :                         begin_token(ctok, CTokIdSymbol);
     208                 :          0 :                         buf_append_char(&ctok->cur_tok->data.symbol, *c);
     209                 :          0 :                         break;
     210                 :          0 :                     case DIGIT_NON_ZERO:
     211                 :          0 :                         ctok->state = CTokStateDecimal;
     212                 :          0 :                         begin_token(ctok, CTokIdNumLitInt);
     213                 :          0 :                         ctok->cur_tok->data.num_lit_int.x = *c - '0';
     214                 :          0 :                         buf_resize(&ctok->buf, 0);
     215                 :          0 :                         buf_append_char(&ctok->buf, *c);
     216                 :          0 :                         break;
     217                 :          0 :                     case '0':
     218                 :          0 :                         ctok->state = CTokStateGotZero;
     219                 :          0 :                         begin_token(ctok, CTokIdNumLitInt);
     220                 :          0 :                         ctok->cur_tok->data.num_lit_int.x = 0;
     221                 :          0 :                         buf_resize(&ctok->buf, 0);
     222                 :          0 :                         buf_append_char(&ctok->buf, '0');
     223                 :          0 :                         break;
     224                 :          0 :                     case '.':
     225                 :          0 :                         begin_token(ctok, CTokIdDot);
     226                 :          0 :                         end_token(ctok);
     227                 :          0 :                         break;
     228                 :          0 :                     case '<':
     229                 :          0 :                         begin_token(ctok, CTokIdLt);
     230                 :          0 :                         ctok->state = CTokStateGotLt;
     231                 :          0 :                         break;
     232                 :          0 :                     case '(':
     233                 :          0 :                         begin_token(ctok, CTokIdLParen);
     234                 :          0 :                         end_token(ctok);
     235                 :          0 :                         break;
     236                 :          0 :                     case ')':
     237                 :          0 :                         begin_token(ctok, CTokIdRParen);
     238                 :          0 :                         end_token(ctok);
     239                 :          0 :                         break;
     240                 :          0 :                     case '*':
     241                 :          0 :                         begin_token(ctok, CTokIdAsterisk);
     242                 :          0 :                         end_token(ctok);
     243                 :          0 :                         break;
     244                 :          0 :                     case '-':
     245                 :          0 :                         begin_token(ctok, CTokIdMinus);
     246                 :          0 :                         end_token(ctok);
     247                 :          0 :                         break;
     248                 :          0 :                     case '!':
     249                 :          0 :                         begin_token(ctok, CTokIdBang);
     250                 :          0 :                         end_token(ctok);
     251                 :          0 :                         break;
     252                 :          0 :                     case '~':
     253                 :          0 :                         begin_token(ctok, CTokIdTilde);
     254                 :          0 :                         end_token(ctok);
     255                 :          0 :                         break;
     256                 :          0 :                     default:
     257                 :          0 :                         return mark_error(ctok);
     258                 :            :                 }
     259                 :          0 :                 break;
     260                 :          0 :             case CTokStateGotLt:
     261         [ #  # ]:          0 :                 switch (*c) {
     262                 :          0 :                     case '<':
     263                 :          0 :                         ctok->cur_tok->id = CTokIdShl;
     264                 :          0 :                         end_token(ctok);
     265                 :          0 :                         ctok->state = CTokStateStart;
     266                 :          0 :                         break;
     267                 :          0 :                     default:
     268                 :          0 :                         end_token(ctok);
     269                 :          0 :                         ctok->state = CTokStateStart;
     270                 :          0 :                         continue;
     271                 :            :                 }
     272                 :          0 :                 break;
     273                 :          0 :             case CTokStateFloat:
     274   [ #  #  #  #  :          0 :                 switch (*c) {
                      # ]
     275                 :          0 :                     case '.':
     276                 :          0 :                         break;
     277                 :          0 :                     case 'e':
     278                 :            :                     case 'E':
     279                 :          0 :                         buf_append_char(&ctok->buf, 'e');
     280                 :          0 :                         ctok->state = CTokStateExpSign;
     281                 :          0 :                         break;
     282                 :          0 :                     case 'f':
     283                 :            :                     case 'F':
     284                 :            :                     case 'l':
     285                 :            :                     case 'L':
     286                 :          0 :                         end_float(ctok);
     287                 :          0 :                         break;
     288                 :          0 :                     case DIGIT:
     289                 :          0 :                         buf_append_char(&ctok->buf, *c);
     290                 :          0 :                         break;
     291                 :          0 :                     default:
     292                 :          0 :                         c -= 1;
     293                 :          0 :                         end_float(ctok);
     294                 :          0 :                         continue;
     295                 :            :                 }
     296                 :          0 :                 break;
     297                 :          0 :             case CTokStateExpSign:
     298      [ #  #  # ]:          0 :                 switch (*c) {
     299                 :          0 :                     case '+':
     300                 :            :                     case '-':
     301                 :          0 :                         ctok->state = CTokStateFloatExpFirst;
     302                 :          0 :                         buf_append_char(&ctok->buf, *c);
     303                 :          0 :                         break;
     304                 :          0 :                     case DIGIT:
     305                 :          0 :                         ctok->state = CTokStateFloatExp;
     306                 :          0 :                         buf_append_char(&ctok->buf, *c);
     307                 :          0 :                         break;
     308                 :          0 :                     default:
     309                 :          0 :                         return mark_error(ctok);
     310                 :            :                 }
     311                 :          0 :                 break;
     312                 :          0 :             case CTokStateFloatExpFirst:
     313         [ #  # ]:          0 :                 switch (*c) {
     314                 :          0 :                     case DIGIT:
     315                 :          0 :                         buf_append_char(&ctok->buf, *c);
     316                 :          0 :                         ctok->state = CTokStateFloatExp;
     317                 :          0 :                         break;
     318                 :          0 :                     default:
     319                 :          0 :                         return mark_error(ctok);
     320                 :            :                 }
     321                 :          0 :                 break;
     322                 :          0 :             case CTokStateFloatExp:
     323      [ #  #  # ]:          0 :                 switch (*c) {
     324                 :          0 :                     case DIGIT:
     325                 :          0 :                         buf_append_char(&ctok->buf, *c);
     326                 :          0 :                         break;
     327                 :          0 :                     case 'f':
     328                 :            :                     case 'F':
     329                 :            :                     case 'l':
     330                 :            :                     case 'L':
     331                 :          0 :                         end_float(ctok);
     332                 :          0 :                         break;
     333                 :          0 :                     default:
     334                 :          0 :                         c -= 1;
     335                 :          0 :                         end_float(ctok);
     336                 :          0 :                         continue;
     337                 :            :                 }
     338                 :          0 :                 break;
     339                 :          0 :             case CTokStateDecimal:
     340   [ #  #  #  #  :          0 :                 switch (*c) {
                   #  # ]
     341                 :          0 :                     case DIGIT:
     342                 :          0 :                         buf_append_char(&ctok->buf, *c);
     343                 :            : 
     344                 :            :                         // TODO @mul_with_overflow
     345                 :          0 :                         ctok->cur_tok->data.num_lit_int.x *= 10;
     346                 :            :                         // TODO @add_with_overflow
     347                 :          0 :                         ctok->cur_tok->data.num_lit_int.x += *c - '0';
     348                 :          0 :                         break;
     349                 :          0 :                     case '\'':
     350                 :          0 :                         break;
     351                 :          0 :                     case 'u':
     352                 :            :                     case 'U':
     353                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixU;
     354                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
     355                 :          0 :                         break;
     356                 :          0 :                     case 'l':
     357                 :            :                     case 'L':
     358                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixL;
     359                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
     360                 :          0 :                         break;
     361                 :          0 :                     case '.':
     362                 :          0 :                         buf_append_char(&ctok->buf, '.');
     363                 :          0 :                         ctok->cur_tok->id = CTokIdNumLitFloat;
     364                 :          0 :                         ctok->state = CTokStateFloat;
     365                 :          0 :                         break;
     366                 :          0 :                     default:
     367                 :          0 :                         c -= 1;
     368                 :          0 :                         end_token(ctok);
     369                 :          0 :                         ctok->state = CTokStateStart;
     370                 :          0 :                         continue;
     371                 :            :                 }
     372                 :          0 :                 break;
     373                 :          0 :             case CTokStateGotZero:
     374   [ #  #  #  # ]:          0 :                 switch (*c) {
     375                 :          0 :                     case 'x':
     376                 :            :                     case 'X':
     377                 :          0 :                         ctok->state = CTokStateHex;
     378                 :          0 :                         break;
     379                 :          0 :                     case '.':
     380                 :          0 :                         ctok->state = CTokStateFloat;
     381                 :          0 :                         ctok->cur_tok->id = CTokIdNumLitFloat;
     382                 :          0 :                         buf_append_char(&ctok->buf, '.');
     383                 :          0 :                         break;
     384                 :          0 :                     case 'l':
     385                 :            :                     case 'L':
     386                 :            :                     case 'u':
     387                 :            :                     case 'U':
     388                 :          0 :                         c -= 1;
     389                 :          0 :                         ctok->state = CTokStateDecimal;
     390                 :          0 :                         continue;
     391                 :          0 :                     default:
     392                 :          0 :                         c -= 1;
     393                 :          0 :                         ctok->state = CTokStateOctal;
     394                 :          0 :                         continue;
     395                 :            :                 }
     396                 :          0 :                 break;
     397                 :          0 :             case CTokStateOctal:
     398   [ #  #  #  # ]:          0 :                 switch (*c) {
     399                 :          0 :                     case '0':
     400                 :            :                     case '1':
     401                 :            :                     case '2':
     402                 :            :                     case '3':
     403                 :            :                     case '4':
     404                 :            :                     case '5':
     405                 :            :                     case '6':
     406                 :            :                     case '7':
     407                 :            :                         // TODO @mul_with_overflow
     408                 :          0 :                         ctok->cur_tok->data.num_lit_int.x *= 8;
     409                 :            :                         // TODO @add_with_overflow
     410                 :          0 :                         ctok->cur_tok->data.num_lit_int.x += *c - '0';
     411                 :          0 :                         break;
     412                 :          0 :                     case '8':
     413                 :            :                     case '9':
     414                 :          0 :                         return mark_error(ctok);
     415                 :          0 :                     case '\'':
     416                 :          0 :                         break;
     417                 :          0 :                     default:
     418                 :          0 :                         c -= 1;
     419                 :          0 :                         end_token(ctok);
     420                 :          0 :                         ctok->state = CTokStateStart;
     421                 :          0 :                         continue;
     422                 :            :                 }
     423                 :          0 :                 break;
     424                 :          0 :             case CTokStateHex:
     425   [ #  #  #  #  :          0 :                 switch (*c) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     426                 :          0 :                     case '0':
     427                 :          0 :                         hex_digit(ctok, 0);
     428                 :          0 :                         break;
     429                 :          0 :                     case '1':
     430                 :          0 :                         hex_digit(ctok, 1);
     431                 :          0 :                         break;
     432                 :          0 :                     case '2':
     433                 :          0 :                         hex_digit(ctok, 2);
     434                 :          0 :                         break;
     435                 :          0 :                     case '3':
     436                 :          0 :                         hex_digit(ctok, 3);
     437                 :          0 :                         break;
     438                 :          0 :                     case '4':
     439                 :          0 :                         hex_digit(ctok, 4);
     440                 :          0 :                         break;
     441                 :          0 :                     case '5':
     442                 :          0 :                         hex_digit(ctok, 5);
     443                 :          0 :                         break;
     444                 :          0 :                     case '6':
     445                 :          0 :                         hex_digit(ctok, 6);
     446                 :          0 :                         break;
     447                 :          0 :                     case '7':
     448                 :          0 :                         hex_digit(ctok, 7);
     449                 :          0 :                         break;
     450                 :          0 :                     case '8':
     451                 :          0 :                         hex_digit(ctok, 8);
     452                 :          0 :                         break;
     453                 :          0 :                     case '9':
     454                 :          0 :                         hex_digit(ctok, 9);
     455                 :          0 :                         break;
     456                 :          0 :                     case 'a':
     457                 :            :                     case 'A':
     458                 :          0 :                         hex_digit(ctok, 10);
     459                 :          0 :                         break;
     460                 :          0 :                     case 'b':
     461                 :            :                     case 'B':
     462                 :          0 :                         hex_digit(ctok, 11);
     463                 :          0 :                         break;
     464                 :          0 :                     case 'c':
     465                 :            :                     case 'C':
     466                 :          0 :                         hex_digit(ctok, 12);
     467                 :          0 :                         break;
     468                 :          0 :                     case 'd':
     469                 :            :                     case 'D':
     470                 :          0 :                         hex_digit(ctok, 13);
     471                 :          0 :                         break;
     472                 :          0 :                     case 'e':
     473                 :            :                     case 'E':
     474                 :          0 :                         hex_digit(ctok, 14);
     475                 :          0 :                         break;
     476                 :          0 :                     case 'f':
     477                 :            :                     case 'F':
     478                 :          0 :                         hex_digit(ctok, 15);
     479                 :          0 :                         break;
     480                 :          0 :                     case 'p':
     481                 :            :                     case 'P':
     482                 :          0 :                         ctok->cur_tok->id = CTokIdNumLitFloat;
     483                 :          0 :                         ctok->state = CTokStateExpSign;
     484                 :          0 :                         break;
     485                 :          0 :                     case 'u':
     486                 :            :                     case 'U':
     487                 :            :                         // marks the number literal as unsigned
     488                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixU;
     489                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
     490                 :          0 :                         break;
     491                 :          0 :                     case 'l':
     492                 :            :                     case 'L':
     493                 :            :                         // marks the number literal as long
     494                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixL;
     495                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
     496                 :          0 :                         break;
     497                 :          0 :                     default:
     498                 :          0 :                         c -= 1;
     499                 :          0 :                         end_token(ctok);
     500                 :          0 :                         ctok->state = CTokStateStart;
     501                 :          0 :                         continue;
     502                 :            :                 }
     503                 :          0 :                 break;
     504                 :          0 :             case CTokStateNumLitIntSuffixU:
     505         [ #  # ]:          0 :                 switch (*c) {
     506                 :          0 :                     case 'l':
     507                 :            :                     case 'L':
     508                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
     509                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixUL;
     510                 :          0 :                         break;
     511                 :          0 :                     default:
     512                 :          0 :                         c -= 1;
     513                 :          0 :                         end_token(ctok);
     514                 :          0 :                         ctok->state = CTokStateStart;
     515                 :          0 :                         continue;
     516                 :            :                 }
     517                 :          0 :                 break;
     518                 :          0 :             case CTokStateNumLitIntSuffixL:
     519      [ #  #  # ]:          0 :                 switch (*c) {
     520                 :          0 :                     case 'l':
     521                 :            :                     case 'L':
     522                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLL;
     523                 :          0 :                         ctok->state = CTokStateNumLitIntSuffixLL;
     524                 :          0 :                         break;
     525                 :          0 :                     case 'u':
     526                 :            :                     case 'U':
     527                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
     528                 :          0 :                         end_token(ctok);
     529                 :          0 :                         ctok->state = CTokStateStart;
     530                 :          0 :                         break;
     531                 :          0 :                     default:
     532                 :          0 :                         c -= 1;
     533                 :          0 :                         end_token(ctok);
     534                 :          0 :                         ctok->state = CTokStateStart;
     535                 :          0 :                         continue;
     536                 :            :                 }
     537                 :          0 :                 break;
     538                 :          0 :             case CTokStateNumLitIntSuffixLL:
     539         [ #  # ]:          0 :                 switch (*c) {
     540                 :          0 :                     case 'u':
     541                 :            :                     case 'U':
     542                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
     543                 :          0 :                         end_token(ctok);
     544                 :          0 :                         ctok->state = CTokStateStart;
     545                 :          0 :                         break;
     546                 :          0 :                     default:
     547                 :          0 :                         c -= 1;
     548                 :          0 :                         end_token(ctok);
     549                 :          0 :                         ctok->state = CTokStateStart;
     550                 :          0 :                         continue;
     551                 :            :                 }
     552                 :          0 :                 break;
     553                 :          0 :             case CTokStateNumLitIntSuffixUL:
     554         [ #  # ]:          0 :                 switch (*c) {
     555                 :          0 :                     case 'l':
     556                 :            :                     case 'L':
     557                 :          0 :                         ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
     558                 :          0 :                         end_token(ctok);
     559                 :          0 :                         ctok->state = CTokStateStart;
     560                 :          0 :                         break;
     561                 :          0 :                     default:
     562                 :          0 :                         c -= 1;
     563                 :          0 :                         end_token(ctok);
     564                 :          0 :                         ctok->state = CTokStateStart;
     565                 :          0 :                         continue;
     566                 :            :                 }
     567                 :          0 :                 break;
     568                 :          0 :             case CTokStateIdentifier:
     569         [ #  # ]:          0 :                 switch (*c) {
     570                 :          0 :                     case IDENT:
     571                 :          0 :                         buf_append_char(&ctok->cur_tok->data.symbol, *c);
     572                 :          0 :                         break;
     573                 :          0 :                     default:
     574                 :          0 :                         c -= 1;
     575                 :          0 :                         end_token(ctok);
     576                 :          0 :                         ctok->state = CTokStateStart;
     577                 :          0 :                         continue;
     578                 :            :                 }
     579                 :          0 :                 break;
     580                 :          0 :             case CTokStateString:
     581      [ #  #  # ]:          0 :                 switch (*c) {
     582                 :          0 :                     case '\\':
     583                 :          0 :                         ctok->state = CTokStateCharEscape;
     584                 :          0 :                         break;
     585                 :          0 :                     case '\"':
     586                 :          0 :                         end_token(ctok);
     587                 :          0 :                         ctok->state = CTokStateStart;
     588                 :          0 :                         break;
     589                 :          0 :                     default:
     590                 :          0 :                         buf_append_char(&ctok->cur_tok->data.str_lit, *c);
     591                 :            :                 }
     592                 :          0 :                 break;
     593                 :          0 :             case CTokStateExpectChar:
     594      [ #  #  # ]:          0 :                 switch (*c) {
     595                 :          0 :                     case '\\':
     596                 :          0 :                         ctok->state = CTokStateCharEscape;
     597                 :          0 :                         break;
     598                 :          0 :                     case '\'':
     599                 :          0 :                         return mark_error(ctok);
     600                 :          0 :                     default:
     601                 :          0 :                         ctok->cur_tok->data.char_lit = *c;
     602                 :          0 :                         ctok->state = CTokStateExpectEndQuot;
     603                 :            :                 }
     604                 :          0 :                 break;
     605                 :          0 :             case CTokStateCharEscape:
     606   [ #  #  #  #  :          0 :                 switch (*c) {
          #  #  #  #  #  
             #  #  #  # ]
     607                 :          0 :                     case '\'':
     608                 :            :                     case '"':
     609                 :            :                     case '?':
     610                 :            :                     case '\\':
     611                 :          0 :                         add_char(ctok, *c);
     612                 :          0 :                         break;
     613                 :          0 :                     case 'a':
     614                 :          0 :                         add_char(ctok, '\a');
     615                 :          0 :                         break;
     616                 :          0 :                     case 'b':
     617                 :          0 :                         add_char(ctok, '\b');
     618                 :          0 :                         break;
     619                 :          0 :                     case 'f':
     620                 :          0 :                         add_char(ctok, '\f');
     621                 :          0 :                         break;
     622                 :          0 :                     case 'n':
     623                 :          0 :                         add_char(ctok, '\n');
     624                 :          0 :                         break;
     625                 :          0 :                     case 'r':
     626                 :          0 :                         add_char(ctok, '\r');
     627                 :          0 :                         break;
     628                 :          0 :                     case 't':
     629                 :          0 :                         add_char(ctok, '\t');
     630                 :          0 :                         break;
     631                 :          0 :                     case 'v':
     632                 :          0 :                         add_char(ctok, '\v');
     633                 :          0 :                         break;
     634                 :          0 :                     case '0':
     635                 :            :                     case '1':
     636                 :            :                     case '2':
     637                 :            :                     case '3':
     638                 :            :                     case '4':
     639                 :            :                     case '5':
     640                 :            :                     case '6':
     641                 :            :                     case '7':
     642                 :          0 :                         ctok->state = CTokStateStrOctal;
     643                 :          0 :                         ctok->cur_char = (uint8_t)(*c - '0');
     644                 :          0 :                         ctok->octal_index = 1;
     645                 :          0 :                         break;
     646                 :          0 :                     case 'x':
     647                 :          0 :                         ctok->state = CTokStateStrHex;
     648                 :          0 :                         ctok->cur_char = 0;
     649                 :          0 :                         break;
     650                 :          0 :                     case 'u':
     651                 :          0 :                         zig_panic("TODO unicode");
     652                 :            :                         break;
     653                 :          0 :                     case 'U':
     654                 :          0 :                         zig_panic("TODO Unicode");
     655                 :            :                         break;
     656                 :          0 :                     default:
     657                 :          0 :                         return mark_error(ctok);
     658                 :            :                 }
     659                 :          0 :                 break;
     660                 :          0 :             case CTokStateStrHex: {
     661                 :          0 :                 uint8_t value = 0;
     662   [ #  #  #  # ]:          0 :                 switch (*c) {
     663                 :          0 :                     case '0':
     664                 :            :                     case '1':
     665                 :            :                     case '2':
     666                 :            :                     case '3':
     667                 :            :                     case '4':
     668                 :            :                     case '5':
     669                 :            :                     case '6':
     670                 :            :                     case '7':
     671                 :            :                     case '8':
     672                 :            :                     case '9':
     673                 :          0 :                         value = *c - '0';
     674                 :          0 :                         break;
     675                 :          0 :                     case 'a':
     676                 :            :                     case 'b':
     677                 :            :                     case 'c':
     678                 :            :                     case 'd':
     679                 :            :                     case 'e':
     680                 :            :                     case 'f':
     681                 :          0 :                         value = (*c - 'a') + 10;
     682                 :          0 :                         break;
     683                 :          0 :                     case 'A':
     684                 :            :                     case 'B':
     685                 :            :                     case 'C':
     686                 :            :                     case 'D':
     687                 :            :                     case 'E':
     688                 :            :                     case 'F':
     689                 :          0 :                         value = (*c - 'A') + 10;
     690                 :          0 :                         break;
     691                 :          0 :                     default:
     692                 :          0 :                         c -= 1;
     693                 :          0 :                         add_char(ctok, ctok->cur_char);
     694                 :          0 :                         continue;
     695                 :            :                 }
     696                 :            :                 // TODO @mul_with_overflow
     697         [ #  # ]:          0 :                 if (((long)ctok->cur_char) * 16 >= 256) {
     698                 :          0 :                     zig_panic("TODO str hex mul overflow");
     699                 :            :                 }
     700                 :          0 :                 ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
     701                 :            :                 // TODO @add_with_overflow
     702         [ #  # ]:          0 :                 if (((long)ctok->cur_char) + (long)(value) >= 256) {
     703                 :          0 :                     zig_panic("TODO str hex add overflow");
     704                 :            :                 }
     705                 :          0 :                 ctok->cur_char = (uint8_t)(ctok->cur_char + value);
     706                 :          0 :                 break;
     707                 :            :             }
     708                 :          0 :             case CTokStateStrOctal:
     709         [ #  # ]:          0 :                 switch (*c) {
     710                 :          0 :                     case '0':
     711                 :            :                     case '1':
     712                 :            :                     case '2':
     713                 :            :                     case '3':
     714                 :            :                     case '4':
     715                 :            :                     case '5':
     716                 :            :                     case '6':
     717                 :            :                     case '7':
     718                 :            :                         // TODO @mul_with_overflow
     719         [ #  # ]:          0 :                         if (((long)ctok->cur_char) * 8 >= 256) {
     720                 :          0 :                             zig_panic("TODO");
     721                 :            :                         }
     722                 :          0 :                         ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)8);
     723                 :            :                         // TODO @add_with_overflow
     724         [ #  # ]:          0 :                         if (((long)ctok->cur_char) + (long)(*c - '0') >= 256) {
     725                 :          0 :                             zig_panic("TODO");
     726                 :            :                         }
     727                 :          0 :                         ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
     728                 :          0 :                         ctok->octal_index += 1;
     729         [ #  # ]:          0 :                         if (ctok->octal_index == 3) {
     730                 :          0 :                             add_char(ctok, ctok->cur_char);
     731                 :            :                         }
     732                 :          0 :                         break;
     733                 :          0 :                     default:
     734                 :          0 :                         c -= 1;
     735                 :          0 :                         add_char(ctok, ctok->cur_char);
     736                 :          0 :                         continue;
     737                 :            :                 }
     738                 :          0 :                 break;
     739                 :          0 :             case CTokStateExpectEndQuot:
     740         [ #  # ]:          0 :                 switch (*c) {
     741                 :          0 :                     case '\'':
     742                 :          0 :                         end_token(ctok);
     743                 :          0 :                         ctok->state = CTokStateStart;
     744                 :          0 :                         break;
     745                 :          0 :                     default:
     746                 :          0 :                         return mark_error(ctok);
     747                 :            :                 }
     748                 :          0 :                 break;
     749                 :          0 :             case CTokStateOpenComment:
     750      [ #  #  # ]:          0 :                 switch (*c) {
     751                 :          0 :                     case '/':
     752                 :          0 :                         ctok->state = CTokStateLineComment;
     753                 :          0 :                         break;
     754                 :          0 :                     case '*':
     755                 :          0 :                         ctok->state = CTokStateComment;
     756                 :          0 :                         break;
     757                 :          0 :                     default:
     758                 :          0 :                         return mark_error(ctok);
     759                 :            :                 }
     760                 :          0 :                 break;
     761                 :          0 :             case CTokStateLineComment:
     762         [ #  # ]:          0 :                 if (*c == '\n') {
     763                 :          0 :                     ctok->state = CTokStateStart;
     764                 :          0 :                     goto found_end_of_macro;
     765                 :            :                 }
     766                 :          0 :                 break;
     767                 :          0 :             case CTokStateComment:
     768         [ #  # ]:          0 :                 switch (*c) {
     769                 :          0 :                     case '*':
     770                 :          0 :                         ctok->state = CTokStateCommentStar;
     771                 :          0 :                         break;
     772                 :          0 :                     default:
     773                 :          0 :                         break;
     774                 :            :                 }
     775                 :          0 :                 break;
     776                 :          0 :             case CTokStateCommentStar:
     777      [ #  #  # ]:          0 :                 switch (*c) {
     778                 :          0 :                     case '/':
     779                 :          0 :                         ctok->state = CTokStateStart;
     780                 :          0 :                         break;
     781                 :          0 :                     case '*':
     782                 :          0 :                         break;
     783                 :          0 :                     default:
     784                 :          0 :                         ctok->state = CTokStateComment;
     785                 :          0 :                         break;
     786                 :            :                 }
     787                 :          0 :                 break;
     788                 :          0 :             case CTokStateBackslash:
     789         [ #  # ]:          0 :                 switch (*c) {
     790                 :          0 :                     case '\n':
     791                 :          0 :                         ctok->state = CTokStateStart;
     792                 :          0 :                         break;
     793                 :          0 :                     default:
     794                 :          0 :                         return mark_error(ctok);
     795                 :            :                 }
     796                 :          0 :                 break;
     797                 :            :         }
     798                 :            :     }
     799                 :          0 : found_end_of_macro:
     800                 :            : 
     801   [ #  #  #  #  :          0 :     switch (ctok->state) {
                      # ]
     802                 :          0 :         case CTokStateStart:
     803                 :          0 :             break;
     804                 :          0 :         case CTokStateIdentifier:
     805                 :            :         case CTokStateDecimal:
     806                 :            :         case CTokStateHex:
     807                 :            :         case CTokStateOctal:
     808                 :            :         case CTokStateGotZero:
     809                 :            :         case CTokStateNumLitIntSuffixU:
     810                 :            :         case CTokStateNumLitIntSuffixL:
     811                 :            :         case CTokStateNumLitIntSuffixUL:
     812                 :            :         case CTokStateNumLitIntSuffixLL:
     813                 :            :         case CTokStateGotLt:
     814                 :          0 :             end_token(ctok);
     815                 :          0 :             break;
     816                 :          0 :         case CTokStateFloat:
     817                 :            :         case CTokStateFloatExp:
     818                 :          0 :             end_float(ctok);
     819                 :          0 :             break;
     820                 :          0 :         case CTokStateExpectChar:
     821                 :            :         case CTokStateExpectEndQuot:
     822                 :            :         case CTokStateOpenComment:
     823                 :            :         case CTokStateLineComment:
     824                 :            :         case CTokStateComment:
     825                 :            :         case CTokStateCommentStar:
     826                 :            :         case CTokStateCharEscape:
     827                 :            :         case CTokStateBackslash:
     828                 :            :         case CTokStateString:
     829                 :            :         case CTokStateExpSign:
     830                 :            :         case CTokStateFloatExpFirst:
     831                 :            :         case CTokStateStrHex:
     832                 :            :         case CTokStateStrOctal:
     833                 :          0 :             return mark_error(ctok);
     834                 :            :     }
     835                 :            : 
     836                 :          0 :     assert(ctok->cur_tok == nullptr);
     837                 :            : 
     838                 :          0 :     begin_token(ctok, CTokIdEOF);
     839                 :          0 :     end_token(ctok);
     840                 :            : }

Generated by: LCOV version 1.14