LCOV - code coverage report
Current view: top level - AP_Scripting/lua/src - llex.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 252 304 82.9 %
Date: 2026-09-09 11:02:08 Functions: 18 22 81.8 %

          Line data    Source code
       1             : /*
       2             : ** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
       3             : ** Lexical Analyzer
       4             : ** See Copyright Notice in lua.h
       5             : */
       6             : 
       7             : #define llex_c
       8             : #define LUA_CORE
       9             : 
      10             : #include "lprefix.h"
      11             : 
      12             : 
      13             : #include <locale.h>
      14             : #include <string.h>
      15             : 
      16             : #include "lua.h"
      17             : 
      18             : #include "lctype.h"
      19             : #include "ldebug.h"
      20             : #include "ldo.h"
      21             : #include "lgc.h"
      22             : #include "llex.h"
      23             : #include "lobject.h"
      24             : #include "lparser.h"
      25             : #include "lstate.h"
      26             : #include "lstring.h"
      27             : #include "ltable.h"
      28             : #include "lzio.h"
      29             : 
      30             : // lua code does lots of casting, these warnings are not helpful
      31             : #pragma GCC diagnostic ignored "-Wcast-align"
      32             : 
      33             : 
      34             : #define next(ls) (ls->current = zgetc(ls->z))
      35             : 
      36             : 
      37             : 
      38             : #define currIsNewline(ls)       (ls->current == '\n' || ls->current == '\r')
      39             : 
      40             : 
      41             : /* ORDER RESERVED */
      42             : static const char *const luaX_tokens [] = {
      43             :     "and", "break", "do", "else", "elseif",
      44             :     "end", "false", "for", "function", "goto", "if",
      45             :     "in", "local", "nil", "not", "or", "repeat",
      46             :     "return", "then", "true", "until", "while",
      47             :     "//", "..", "...", "==", ">=", "<=", "~=",
      48             :     "<<", ">>", "::", "<eof>",
      49             :     "<number>", "<integer>", "<name>", "<string>"
      50             : };
      51             : 
      52             : 
      53             : #define save_and_next(ls) (save(ls, ls->current), next(ls))
      54             : 
      55             : 
      56             : static l_noret lexerror (LexState *ls, const char *msg, int token);
      57             : 
      58             : 
      59      804083 : static void save (LexState *ls, int c) {
      60      804083 :   Mbuffer *b = ls->buff;
      61      804083 :   if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
      62             :     size_t newsize;
      63          99 :     if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
      64           0 :       lexerror(ls, "lexical element too long", 0);
      65          99 :     newsize = luaZ_sizebuffer(b) * 2;
      66          99 :     luaZ_resizebuffer(ls->L, b, newsize);
      67             :   }
      68      804083 :   b->buffer[luaZ_bufflen(b)++] = cast(char, c);
      69      804083 : }
      70             : 
      71             : 
      72          97 : void luaX_init (lua_State *L) {
      73             :   int i;
      74          97 :   TString *e = luaS_newliteral(L, LUA_ENV);  /* create env name */
      75          97 :   luaC_fix(L, obj2gco(e));  /* never collect this name */
      76        2231 :   for (i=0; i<NUM_RESERVED; i++) {
      77        2134 :     TString *ts = luaS_new(L, luaX_tokens[i]);
      78        2134 :     luaC_fix(L, obj2gco(ts));  /* reserved words are never collected */
      79        2134 :     ts->extra = cast_byte(i+1);  /* reserved word */
      80             :   }
      81          97 : }
      82             : 
      83             : 
      84           0 : const char *luaX_token2str (LexState *ls, int token) {
      85           0 :   if (token < FIRST_RESERVED) {  /* single-byte symbols? */
      86             :     lua_assert(token == cast_uchar(token));
      87           0 :     return luaO_pushfstring(ls->L, "'%c'", token);
      88             :   }
      89             :   else {
      90           0 :     const char *s = luaX_tokens[token - FIRST_RESERVED];
      91           0 :     if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
      92           0 :       return luaO_pushfstring(ls->L, "'%s'", s);
      93             :     else  /* names, strings, and numerals */
      94           0 :       return s;
      95             :   }
      96             : }
      97             : 
      98             : 
      99           0 : static const char *txtToken (LexState *ls, int token) {
     100           0 :   switch (token) {
     101           0 :     case TK_NAME: case TK_STRING:
     102             :     case TK_FLT: case TK_INT:
     103           0 :       save(ls, '\0');
     104           0 :       return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
     105           0 :     default:
     106           0 :       return luaX_token2str(ls, token);
     107             :   }
     108             : }
     109             : 
     110             : 
     111           0 : static l_noret lexerror (LexState *ls, const char *msg, int token) {
     112           0 :   msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
     113           0 :   if (token)
     114           0 :     luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
     115           0 :   luaD_throw(ls->L, LUA_ERRSYNTAX);
     116             : }
     117             : 
     118             : 
     119           0 : l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
     120           0 :   lexerror(ls, msg, ls->t.token);
     121             : }
     122             : 
     123             : 
     124             : /*
     125             : ** creates a new string and anchors it in scanner's table so that
     126             : ** it will not be collected until the end of the compilation
     127             : ** (by that time it should be anchored somewhere)
     128             : */
     129       98172 : TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
     130       98172 :   lua_State *L = ls->L;
     131             :   TValue *o;  /* entry for 'str' */
     132       98172 :   TString *ts = luaS_newlstr(L, str, l);  /* create new string */
     133       98172 :   setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
     134       98172 :   o = luaH_set(L, ls->h, L->top - 1);
     135       98172 :   if (ttisnil(o)) {  /* not in use yet? */
     136             :     /* boolean value does not need GC barrier;
     137             :        table has no metatable, so it does not need to invalidate cache */
     138       18121 :     setbvalue(o, 1);  /* t[string] = true */
     139       18121 :     luaC_checkGC(L);
     140             :   }
     141             :   else {  /* string already present */
     142       80051 :     ts = tsvalue(keyfromval(o));  /* re-use value previously stored */
     143             :   }
     144       98172 :   L->top--;  /* remove string from stack */
     145       98172 :   return ts;
     146             : }
     147             : 
     148             : 
     149             : /*
     150             : ** increment line number and skips newline sequence (any of
     151             : ** \n, \r, \n\r, or \r\n)
     152             : */
     153       45309 : static void inclinenumber (LexState *ls) {
     154       45309 :   int old = ls->current;
     155             :   lua_assert(currIsNewline(ls));
     156       45309 :   next(ls);  /* skip '\n' or '\r' */
     157       45309 :   if (currIsNewline(ls) && ls->current != old)
     158         906 :     next(ls);  /* skip '\n\r' or '\r\n' */
     159       45309 :   if (++ls->linenumber >= MAX_INT)
     160           0 :     lexerror(ls, "chunk has too many lines", 0);
     161       45309 : }
     162             : 
     163             : 
     164         120 : void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
     165             :                     int firstchar) {
     166         120 :   ls->t.token = 0;
     167         120 :   ls->L = L;
     168         120 :   ls->current = firstchar;
     169         120 :   ls->lookahead.token = TK_EOS;  /* no look-ahead token */
     170         120 :   ls->z = z;
     171         120 :   ls->fs = NULL;
     172         120 :   ls->linenumber = 1;
     173         120 :   ls->lastline = 1;
     174         120 :   ls->source = source;
     175         120 :   ls->envn = luaS_newliteral(L, LUA_ENV);  /* get env name */
     176         120 :   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
     177         120 : }
     178             : 
     179             : 
     180             : 
     181             : /*
     182             : ** =======================================================
     183             : ** LEXICAL ANALYZER
     184             : ** =======================================================
     185             : */
     186             : 
     187             : 
     188       32511 : static int check_next1 (LexState *ls, int c) {
     189       32511 :   if (ls->current == c) {
     190        4181 :     next(ls);
     191        4181 :     return 1;
     192             :   }
     193       28330 :   else return 0;
     194             : }
     195             : 
     196             : 
     197             : /*
     198             : ** Check whether current char is in set 'set' (with two chars) and
     199             : ** saves it
     200             : */
     201       24290 : static int check_next2 (LexState *ls, const char *set) {
     202             :   lua_assert(set[2] == '\0');
     203       24290 :   if (ls->current == set[0] || ls->current == set[1]) {
     204         270 :     save_and_next(ls);
     205         270 :     return 1;
     206             :   }
     207       24020 :   else return 0;
     208             : }
     209             : 
     210             : 
     211             : /* LUA_NUMBER */
     212             : /*
     213             : ** this function is quite liberal in what it accepts, as 'luaO_str2num'
     214             : ** will reject ill-formed numerals.
     215             : */
     216       11539 : static int read_numeral (LexState *ls, SemInfo *seminfo) {
     217             :   TValue obj;
     218       11539 :   const char *expo = "Ee";
     219       11539 :   int first = ls->current;
     220             :   lua_assert(lisdigit(ls->current));
     221       11539 :   save_and_next(ls);
     222       11539 :   if (first == '0' && check_next2(ls, "xX"))  /* hexadecimal? */
     223          72 :     expo = "Pp";
     224             :   for (;;) {
     225       20547 :     if (check_next2(ls, expo))  /* exponent part? */
     226         131 :       check_next2(ls, "-+");  /* optional exponent sign */
     227       20547 :     if (lisxdigit(ls->current))
     228        7283 :       save_and_next(ls);
     229       13264 :     else if (ls->current == '.')
     230        1725 :       save_and_next(ls);
     231       11539 :     else break;
     232             :   }
     233       11539 :   save(ls, '\0');
     234       11539 :   if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0)  /* format error? */
     235           0 :     lexerror(ls, "malformed number", TK_FLT);
     236       11539 :   if (ttisinteger(&obj)) {
     237        9704 :     seminfo->i = ivalue(&obj);
     238        9704 :     return TK_INT;
     239             :   }
     240             :   else {
     241             :     lua_assert(ttisfloat(&obj));
     242        1835 :     seminfo->r = fltvalue(&obj);
     243        1835 :     return TK_FLT;
     244             :   }
     245             : }
     246             : 
     247             : 
     248             : /*
     249             : ** reads a sequence '[=*[' or ']=*]', leaving the last bracket.
     250             : ** If sequence is well formed, return its number of '='s + 2; otherwise,
     251             : ** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...').
     252             : */
     253        3929 : static size_t skip_sep (LexState *ls) {
     254        3929 :   size_t count = 0;
     255        3929 :   int s = ls->current;
     256             :   lua_assert(s == '[' || s == ']');
     257        3929 :   save_and_next(ls);
     258        3929 :   while (ls->current == '=') {
     259           0 :     save_and_next(ls);
     260           0 :     count++;
     261             :   }
     262        3929 :   return (ls->current == s) ? count + 2
     263        6280 :          : (count == 0) ? 1
     264        2351 :          : 0;
     265             : 
     266             : }
     267             : 
     268             : 
     269         789 : static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
     270         789 :   int line = ls->linenumber;  /* initial line (for error message) */
     271         789 :   save_and_next(ls);  /* skip 2nd '[' */
     272         789 :   if (currIsNewline(ls))  /* string starts with a newline? */
     273         767 :     inclinenumber(ls);  /* skip it */
     274             :   for (;;) {
     275      181933 :     switch (ls->current) {
     276           0 :       case EOZ: {  /* error */
     277           0 :         const char *what = (seminfo ? "string" : "comment");
     278           0 :         const char *msg = luaO_pushfstring(ls->L,
     279             :                      "unfinished long %s (starting at line %d)", what, line);
     280           0 :         lexerror(ls, msg, TK_EOS);
     281             :         break;  /* to avoid warnings */
     282             :       }
     283         791 :       case ']': {
     284         791 :         if (skip_sep(ls) == sep) {
     285         789 :           save_and_next(ls);  /* skip 2nd ']' */
     286         789 :           goto endloop;
     287             :         }
     288           2 :         break;
     289             :       }
     290        3398 :       case '\n': case '\r': {
     291        3398 :         save(ls, '\n');
     292        3398 :         inclinenumber(ls);
     293        3398 :         if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
     294        3398 :         break;
     295             :       }
     296      177744 :       default: {
     297      177744 :         if (seminfo) save_and_next(ls);
     298      173222 :         else next(ls);
     299             :       }
     300             :     }
     301         789 :   } endloop:
     302         789 :   if (seminfo)
     303          16 :     seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep,
     304          16 :                                      luaZ_bufflen(ls->buff) - 2 * sep);
     305         789 : }
     306             : 
     307             : 
     308         776 : static void esccheck (LexState *ls, int c, const char *msg) {
     309         776 :   if (!c) {
     310           0 :     if (ls->current != EOZ)
     311           0 :       save_and_next(ls);  /* add current to buffer for error message */
     312           0 :     lexerror(ls, msg, TK_STRING);
     313             :   }
     314         776 : }
     315             : 
     316             : 
     317          40 : static int gethexa (LexState *ls) {
     318          40 :   save_and_next(ls);
     319          40 :   esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
     320          40 :   return luaO_hexavalue(ls->current);
     321             : }
     322             : 
     323             : 
     324          20 : static int readhexaesc (LexState *ls) {
     325          20 :   int r = gethexa(ls);
     326          20 :   r = (r << 4) + gethexa(ls);
     327          20 :   luaZ_buffremove(ls->buff, 2);  /* remove saved chars from buffer */
     328          20 :   return r;
     329             : }
     330             : 
     331             : #if !defined(ARDUPILOT_BUILD)
     332             : static unsigned long readutf8esc (LexState *ls) {
     333             :   unsigned long r;
     334             :   int i = 4;  /* chars to be removed: '\', 'u', '{', and first digit */
     335             :   save_and_next(ls);  /* skip 'u' */
     336             :   esccheck(ls, ls->current == '{', "missing '{'");
     337             :   r = gethexa(ls);  /* must have at least one digit */
     338             :   while ((save_and_next(ls), lisxdigit(ls->current))) {
     339             :     i++;
     340             :     r = (r << 4) + luaO_hexavalue(ls->current);
     341             :     esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
     342             :   }
     343             :   esccheck(ls, ls->current == '}', "missing '}'");
     344             :   next(ls);  /* skip '}' */
     345             :   luaZ_buffremove(ls->buff, i);  /* remove saved chars from buffer */
     346             :   return r;
     347             : }
     348             : 
     349             : 
     350             : static void utf8esc (LexState *ls) {
     351             :   char buff[UTF8BUFFSZ];
     352             :   int n = luaO_utf8esc(buff, readutf8esc(ls));
     353             :   for (; n > 0; n--)  /* add 'buff' to string */
     354             :     save(ls, buff[UTF8BUFFSZ - n]);
     355             : }
     356             : #endif
     357             : 
     358         368 : static int readdecesc (LexState *ls) {
     359             :   int i;
     360         368 :   int r = 0;  /* result accumulator */
     361         766 :   for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
     362         398 :     r = 10*r + ls->current - '0';
     363         398 :     save_and_next(ls);
     364             :   }
     365         368 :   esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
     366         368 :   luaZ_buffremove(ls->buff, i);  /* remove read digits from buffer */
     367         368 :   return r;
     368             : }
     369             : 
     370             : 
     371        6175 : static void read_string (LexState *ls, int del, SemInfo *seminfo) {
     372        6175 :   save_and_next(ls);  /* keep delimiter (for error messages) */
     373       86408 :   while (ls->current != del) {
     374       80233 :     switch (ls->current) {
     375           0 :       case EOZ:
     376           0 :         lexerror(ls, "unfinished string", TK_EOS);
     377             :         break;  /* to avoid warnings */
     378           0 :       case '\n':
     379             :       case '\r':
     380           0 :         lexerror(ls, "unfinished string", TK_STRING);
     381             :         break;  /* to avoid warnings */
     382         486 :       case '\\': {  /* escape sequences */
     383             :         int c;  /* final character to be saved */
     384         486 :         save_and_next(ls);  /* keep '\\' for error messages */
     385         486 :         switch (ls->current) {
     386           0 :           case 'a': c = '\a'; goto read_save;
     387           0 :           case 'b': c = '\b'; goto read_save;
     388           0 :           case 'f': c = '\f'; goto read_save;
     389          42 :           case 'n': c = '\n'; goto read_save;
     390           8 :           case 'r': c = '\r'; goto read_save;
     391           6 :           case 't': c = '\t'; goto read_save;
     392           0 :           case 'v': c = '\v'; goto read_save;
     393          20 :           case 'x': c = readhexaesc(ls); goto read_save;
     394             : #if !defined(ARDUPILOT_BUILD)
     395             :           case 'u': utf8esc(ls);  goto no_save;
     396             : #endif
     397           0 :           case '\n': case '\r':
     398           0 :             inclinenumber(ls); c = '\n'; goto only_save;
     399          42 :           case '\\': case '\"': case '\'':
     400          42 :             c = ls->current; goto read_save;
     401           0 :           case EOZ: goto no_save;  /* will raise an error next loop */
     402           0 :           case 'z': {  /* zap following span of spaces */
     403           0 :             luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
     404           0 :             next(ls);  /* skip the 'z' */
     405           0 :             while (lisspace(ls->current)) {
     406           0 :               if (currIsNewline(ls)) inclinenumber(ls);
     407           0 :               else next(ls);
     408             :             }
     409           0 :             goto no_save;
     410             :           }
     411         368 :           default: {
     412         368 :             esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
     413         368 :             c = readdecesc(ls);  /* digital escape '\ddd' */
     414         368 :             goto only_save;
     415             :           }
     416             :         }
     417         118 :        read_save:
     418         118 :          next(ls);
     419             :          /* go through */
     420         486 :        only_save:
     421         486 :          luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
     422         486 :          save(ls, c);
     423             :          /* go through */
     424         486 :        no_save: break;
     425             :       }
     426       79747 :       default:
     427       79747 :         save_and_next(ls);
     428             :     }
     429             :   }
     430        6175 :   save_and_next(ls);  /* skip delimiter */
     431       12350 :   seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
     432        6175 :                                    luaZ_bufflen(ls->buff) - 2);
     433        6175 : }
     434             : 
     435             : 
     436      199552 : static int llex (LexState *ls, SemInfo *seminfo) {
     437      199552 :   luaZ_resetbuffer(ls->buff);
     438             :   for (;;) {
     439      496980 :     switch (ls->current) {
     440       41144 :       case '\n': case '\r': {  /* line breaks */
     441       41144 :         inclinenumber(ls);
     442       41144 :         break;
     443             :       }
     444      250376 :       case ' ': case '\f': case '\t': case '\v': {  /* spaces */
     445      250376 :         next(ls);
     446      250376 :         break;
     447             :       }
     448        7611 :       case '-': {  /* '-' or '--' (comment) */
     449        7611 :         next(ls);
     450        7611 :         if (ls->current != '-') return '-';
     451             :         /* else is a comment */
     452        5908 :         next(ls);
     453        5908 :         if (ls->current == '[') {  /* long comment? */
     454         773 :           size_t sep = skip_sep(ls);
     455         773 :           luaZ_resetbuffer(ls->buff);  /* 'skip_sep' may dirty the buffer */
     456         773 :           if (sep >= 2) {
     457         773 :             read_long_string(ls, NULL, sep);  /* skip long comment */
     458         773 :             luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
     459         773 :             break;
     460             :           }
     461             :         }
     462             :         /* else short comment */
     463      259616 :         while (!currIsNewline(ls) && ls->current != EOZ)
     464      254481 :           next(ls);  /* skip until end of line (or end of file) */
     465        5135 :         break;
     466             :       }
     467        2365 :       case '[': {  /* long string or simply '[' */
     468        2365 :         size_t sep = skip_sep(ls);
     469        2365 :         if (sep >= 2) {
     470          16 :           read_long_string(ls, seminfo, sep);
     471          16 :           return TK_STRING;
     472             :         }
     473        2349 :         else if (sep == 0)  /* '[=...' missing second bracket */
     474           0 :           lexerror(ls, "invalid long string delimiter", TK_STRING);
     475        2349 :         return '[';
     476             :       }
     477       13437 :       case '=': {
     478       13437 :         next(ls);
     479       13437 :         if (check_next1(ls, '=')) return TK_EQ;
     480       11406 :         else return '=';
     481             :       }
     482         808 :       case '<': {
     483         808 :         next(ls);
     484         808 :         if (check_next1(ls, '=')) return TK_LE;
     485         574 :         else if (check_next1(ls, '<')) return TK_SHL;
     486         486 :         else return '<';
     487             :       }
     488         771 :       case '>': {
     489         771 :         next(ls);
     490         771 :         if (check_next1(ls, '=')) return TK_GE;
     491         658 :         else if (check_next1(ls, '>')) return TK_SHR;
     492         651 :         else return '>';
     493             :       }
     494         600 :       case '/': {
     495         600 :         next(ls);
     496         600 :         if (check_next1(ls, '/')) return TK_IDIV;
     497         540 :         else return '/';
     498             :       }
     499         690 :       case '~': {
     500         690 :         next(ls);
     501         690 :         if (check_next1(ls, '=')) return TK_NE;
     502          18 :         else return '~';
     503             :       }
     504        5182 :       case ':': {
     505        5182 :         next(ls);
     506        5182 :         if (check_next1(ls, ':')) return TK_DBCOLON;
     507        5050 :         else return ':';
     508             :       }
     509        6175 :       case '"': case '\'': {  /* short literal strings */
     510        6175 :         read_string(ls, ls->current, seminfo);
     511        6175 :         return TK_STRING;
     512             :       }
     513        8955 :       case '.': {  /* '.', '..', '...', or number */
     514        8955 :         save_and_next(ls);
     515        8955 :         if (check_next1(ls, '.')) {
     516         836 :           if (check_next1(ls, '.'))
     517           8 :             return TK_DOTS;   /* '...' */
     518         828 :           else return TK_CONCAT;   /* '..' */
     519             :         }
     520        8119 :         else if (!lisdigit(ls->current)) return '.';
     521          32 :         else return read_numeral(ls, seminfo);
     522             :       }
     523       11507 :       case '0': case '1': case '2': case '3': case '4':
     524             :       case '5': case '6': case '7': case '8': case '9': {
     525       11507 :         return read_numeral(ls, seminfo);
     526             :       }
     527         120 :       case EOZ: {
     528         120 :         return TK_EOS;
     529             :       }
     530      147239 :       default: {
     531      147239 :         if (lislalpha(ls->current)) {  /* identifier or reserved word? */
     532             :           TString *ts;
     533             :           do {
     534      655838 :             save_and_next(ls);
     535      655838 :           } while (lislalnum(ls->current));
     536       90666 :           ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
     537       90666 :                                   luaZ_bufflen(ls->buff));
     538       90666 :           seminfo->ts = ts;
     539       90666 :           if (isreserved(ts))  /* reserved word? */
     540       28975 :             return ts->extra - 1 + FIRST_RESERVED;
     541             :           else {
     542       61691 :             return TK_NAME;
     543             :           }
     544             :         }
     545             :         else {  /* single-char tokens (+ - / ...) */
     546       56573 :           int c = ls->current;
     547       56573 :           next(ls);
     548       56573 :           return c;
     549             :         }
     550             :       }
     551             :     }
     552             :   }
     553             : }
     554             : 
     555             : 
     556      199552 : void luaX_next (LexState *ls) {
     557      199552 :   ls->lastline = ls->linenumber;
     558      199552 :   if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
     559        2386 :     ls->t = ls->lookahead;  /* use this one */
     560        2386 :     ls->lookahead.token = TK_EOS;  /* and discharge it */
     561             :   }
     562             :   else
     563      197166 :     ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
     564      199552 : }
     565             : 
     566             : 
     567        2386 : int luaX_lookahead (LexState *ls) {
     568             :   lua_assert(ls->lookahead.token == TK_EOS);
     569        2386 :   ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
     570        2386 :   return ls->lookahead.token;
     571             : }
     572             : 

Generated by: LCOV version 1.14