xref: /freebsd-src/sys/contrib/openzfs/module/lua/llex.c (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy /* BEGIN CSTYLED */
2*eda14cbcSMatt Macy /*
3*eda14cbcSMatt Macy ** $Id: llex.c,v 2.63.1.3 2015/02/09 17:56:34 roberto Exp $
4*eda14cbcSMatt Macy ** Lexical Analyzer
5*eda14cbcSMatt Macy ** See Copyright Notice in lua.h
6*eda14cbcSMatt Macy */
7*eda14cbcSMatt Macy 
8*eda14cbcSMatt Macy #define llex_c
9*eda14cbcSMatt Macy #define LUA_CORE
10*eda14cbcSMatt Macy 
11*eda14cbcSMatt Macy #include <sys/lua/lua.h>
12*eda14cbcSMatt Macy 
13*eda14cbcSMatt Macy #include "lctype.h"
14*eda14cbcSMatt Macy #include "ldo.h"
15*eda14cbcSMatt Macy #include "llex.h"
16*eda14cbcSMatt Macy #include "lobject.h"
17*eda14cbcSMatt Macy #include "lparser.h"
18*eda14cbcSMatt Macy #include "lstate.h"
19*eda14cbcSMatt Macy #include "lstring.h"
20*eda14cbcSMatt Macy #include "ltable.h"
21*eda14cbcSMatt Macy #include "lzio.h"
22*eda14cbcSMatt Macy 
23*eda14cbcSMatt Macy 
24*eda14cbcSMatt Macy 
25*eda14cbcSMatt Macy #define next(ls) (ls->current = zgetc(ls->z))
26*eda14cbcSMatt Macy 
27*eda14cbcSMatt Macy 
28*eda14cbcSMatt Macy 
29*eda14cbcSMatt Macy #define currIsNewline(ls)	(ls->current == '\n' || ls->current == '\r')
30*eda14cbcSMatt Macy 
31*eda14cbcSMatt Macy 
32*eda14cbcSMatt Macy /* ORDER RESERVED */
33*eda14cbcSMatt Macy static const char *const luaX_tokens [] = {
34*eda14cbcSMatt Macy     "and", "break", "do", "else", "elseif",
35*eda14cbcSMatt Macy     "end", "false", "for", "function", "goto", "if",
36*eda14cbcSMatt Macy     "in", "local", "nil", "not", "or", "repeat",
37*eda14cbcSMatt Macy     "return", "then", "true", "until", "while",
38*eda14cbcSMatt Macy     "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
39*eda14cbcSMatt Macy     "<number>", "<name>", "<string>"
40*eda14cbcSMatt Macy };
41*eda14cbcSMatt Macy 
42*eda14cbcSMatt Macy 
43*eda14cbcSMatt Macy #define save_and_next(ls) (save(ls, ls->current), next(ls))
44*eda14cbcSMatt Macy 
45*eda14cbcSMatt Macy 
46*eda14cbcSMatt Macy static l_noret lexerror (LexState *ls, const char *msg, int token);
47*eda14cbcSMatt Macy 
48*eda14cbcSMatt Macy 
49*eda14cbcSMatt Macy static void save (LexState *ls, int c) {
50*eda14cbcSMatt Macy   Mbuffer *b = ls->buff;
51*eda14cbcSMatt Macy   if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
52*eda14cbcSMatt Macy     size_t newsize;
53*eda14cbcSMatt Macy     if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
54*eda14cbcSMatt Macy       lexerror(ls, "lexical element too long", 0);
55*eda14cbcSMatt Macy     newsize = luaZ_sizebuffer(b) * 2;
56*eda14cbcSMatt Macy     luaZ_resizebuffer(ls->L, b, newsize);
57*eda14cbcSMatt Macy   }
58*eda14cbcSMatt Macy   b->buffer[luaZ_bufflen(b)++] = cast(char, c);
59*eda14cbcSMatt Macy }
60*eda14cbcSMatt Macy 
61*eda14cbcSMatt Macy 
62*eda14cbcSMatt Macy void luaX_init (lua_State *L) {
63*eda14cbcSMatt Macy   int i;
64*eda14cbcSMatt Macy   for (i=0; i<NUM_RESERVED; i++) {
65*eda14cbcSMatt Macy     TString *ts = luaS_new(L, luaX_tokens[i]);
66*eda14cbcSMatt Macy     luaS_fix(ts);  /* reserved words are never collected */
67*eda14cbcSMatt Macy     ts->tsv.extra = cast_byte(i+1);  /* reserved word */
68*eda14cbcSMatt Macy   }
69*eda14cbcSMatt Macy }
70*eda14cbcSMatt Macy 
71*eda14cbcSMatt Macy 
72*eda14cbcSMatt Macy const char *luaX_token2str (LexState *ls, int token) {
73*eda14cbcSMatt Macy   if (token < FIRST_RESERVED) {  /* single-byte symbols? */
74*eda14cbcSMatt Macy     lua_assert(token == cast(unsigned char, token));
75*eda14cbcSMatt Macy     return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
76*eda14cbcSMatt Macy                               luaO_pushfstring(ls->L, "char(%d)", token);
77*eda14cbcSMatt Macy   }
78*eda14cbcSMatt Macy   else {
79*eda14cbcSMatt Macy     const char *s = luaX_tokens[token - FIRST_RESERVED];
80*eda14cbcSMatt Macy     if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
81*eda14cbcSMatt Macy       return luaO_pushfstring(ls->L, LUA_QS, s);
82*eda14cbcSMatt Macy     else  /* names, strings, and numerals */
83*eda14cbcSMatt Macy       return s;
84*eda14cbcSMatt Macy   }
85*eda14cbcSMatt Macy }
86*eda14cbcSMatt Macy 
87*eda14cbcSMatt Macy 
88*eda14cbcSMatt Macy static const char *txtToken (LexState *ls, int token) {
89*eda14cbcSMatt Macy   switch (token) {
90*eda14cbcSMatt Macy     case TK_NAME:
91*eda14cbcSMatt Macy     case TK_STRING:
92*eda14cbcSMatt Macy     case TK_NUMBER:
93*eda14cbcSMatt Macy       save(ls, '\0');
94*eda14cbcSMatt Macy       return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
95*eda14cbcSMatt Macy     default:
96*eda14cbcSMatt Macy       return luaX_token2str(ls, token);
97*eda14cbcSMatt Macy   }
98*eda14cbcSMatt Macy }
99*eda14cbcSMatt Macy 
100*eda14cbcSMatt Macy 
101*eda14cbcSMatt Macy static l_noret lexerror (LexState *ls, const char *msg, int token) {
102*eda14cbcSMatt Macy   char buff[LUA_IDSIZE];
103*eda14cbcSMatt Macy   luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
104*eda14cbcSMatt Macy   msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
105*eda14cbcSMatt Macy   if (token)
106*eda14cbcSMatt Macy     luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
107*eda14cbcSMatt Macy   luaD_throw(ls->L, LUA_ERRSYNTAX);
108*eda14cbcSMatt Macy }
109*eda14cbcSMatt Macy 
110*eda14cbcSMatt Macy 
111*eda14cbcSMatt Macy l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
112*eda14cbcSMatt Macy   lexerror(ls, msg, ls->t.token);
113*eda14cbcSMatt Macy }
114*eda14cbcSMatt Macy 
115*eda14cbcSMatt Macy 
116*eda14cbcSMatt Macy /*
117*eda14cbcSMatt Macy ** creates a new string and anchors it in function's table so that
118*eda14cbcSMatt Macy ** it will not be collected until the end of the function's compilation
119*eda14cbcSMatt Macy ** (by that time it should be anchored in function's prototype)
120*eda14cbcSMatt Macy */
121*eda14cbcSMatt Macy TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
122*eda14cbcSMatt Macy   lua_State *L = ls->L;
123*eda14cbcSMatt Macy   TValue *o;  /* entry for `str' */
124*eda14cbcSMatt Macy   TString *ts = luaS_newlstr(L, str, l);  /* create new string */
125*eda14cbcSMatt Macy   setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
126*eda14cbcSMatt Macy   o = luaH_set(L, ls->fs->h, L->top - 1);
127*eda14cbcSMatt Macy   if (ttisnil(o)) {  /* not in use yet? (see 'addK') */
128*eda14cbcSMatt Macy     /* boolean value does not need GC barrier;
129*eda14cbcSMatt Macy        table has no metatable, so it does not need to invalidate cache */
130*eda14cbcSMatt Macy     setbvalue(o, 1);  /* t[string] = true */
131*eda14cbcSMatt Macy     luaC_checkGC(L);
132*eda14cbcSMatt Macy   }
133*eda14cbcSMatt Macy   else {  /* string already present */
134*eda14cbcSMatt Macy     ts = rawtsvalue(keyfromval(o));  /* re-use value previously stored */
135*eda14cbcSMatt Macy   }
136*eda14cbcSMatt Macy   L->top--;  /* remove string from stack */
137*eda14cbcSMatt Macy   return ts;
138*eda14cbcSMatt Macy }
139*eda14cbcSMatt Macy 
140*eda14cbcSMatt Macy 
141*eda14cbcSMatt Macy /*
142*eda14cbcSMatt Macy ** increment line number and skips newline sequence (any of
143*eda14cbcSMatt Macy ** \n, \r, \n\r, or \r\n)
144*eda14cbcSMatt Macy */
145*eda14cbcSMatt Macy static void inclinenumber (LexState *ls) {
146*eda14cbcSMatt Macy   int old = ls->current;
147*eda14cbcSMatt Macy   lua_assert(currIsNewline(ls));
148*eda14cbcSMatt Macy   next(ls);  /* skip `\n' or `\r' */
149*eda14cbcSMatt Macy   if (currIsNewline(ls) && ls->current != old)
150*eda14cbcSMatt Macy     next(ls);  /* skip `\n\r' or `\r\n' */
151*eda14cbcSMatt Macy   if (++ls->linenumber >= MAX_INT)
152*eda14cbcSMatt Macy     lexerror(ls, "chunk has too many lines", 0);
153*eda14cbcSMatt Macy }
154*eda14cbcSMatt Macy 
155*eda14cbcSMatt Macy 
156*eda14cbcSMatt Macy void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
157*eda14cbcSMatt Macy                     int firstchar) {
158*eda14cbcSMatt Macy   ls->decpoint = '.';
159*eda14cbcSMatt Macy   ls->L = L;
160*eda14cbcSMatt Macy   ls->current = firstchar;
161*eda14cbcSMatt Macy   ls->lookahead.token = TK_EOS;  /* no look-ahead token */
162*eda14cbcSMatt Macy   ls->z = z;
163*eda14cbcSMatt Macy   ls->fs = NULL;
164*eda14cbcSMatt Macy   ls->linenumber = 1;
165*eda14cbcSMatt Macy   ls->lastline = 1;
166*eda14cbcSMatt Macy   ls->source = source;
167*eda14cbcSMatt Macy   ls->envn = luaS_new(L, LUA_ENV);  /* create env name */
168*eda14cbcSMatt Macy   luaS_fix(ls->envn);  /* never collect this name */
169*eda14cbcSMatt Macy   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
170*eda14cbcSMatt Macy }
171*eda14cbcSMatt Macy 
172*eda14cbcSMatt Macy 
173*eda14cbcSMatt Macy 
174*eda14cbcSMatt Macy /*
175*eda14cbcSMatt Macy ** =======================================================
176*eda14cbcSMatt Macy ** LEXICAL ANALYZER
177*eda14cbcSMatt Macy ** =======================================================
178*eda14cbcSMatt Macy */
179*eda14cbcSMatt Macy 
180*eda14cbcSMatt Macy 
181*eda14cbcSMatt Macy 
182*eda14cbcSMatt Macy static int check_next (LexState *ls, const char *set) {
183*eda14cbcSMatt Macy   if (ls->current == '\0' || !strchr(set, ls->current))
184*eda14cbcSMatt Macy     return 0;
185*eda14cbcSMatt Macy   save_and_next(ls);
186*eda14cbcSMatt Macy   return 1;
187*eda14cbcSMatt Macy }
188*eda14cbcSMatt Macy 
189*eda14cbcSMatt Macy 
190*eda14cbcSMatt Macy /*
191*eda14cbcSMatt Macy ** change all characters 'from' in buffer to 'to'
192*eda14cbcSMatt Macy */
193*eda14cbcSMatt Macy static void buffreplace (LexState *ls, char from, char to) {
194*eda14cbcSMatt Macy   size_t n = luaZ_bufflen(ls->buff);
195*eda14cbcSMatt Macy   char *p = luaZ_buffer(ls->buff);
196*eda14cbcSMatt Macy   while (n--)
197*eda14cbcSMatt Macy     if (p[n] == from) p[n] = to;
198*eda14cbcSMatt Macy }
199*eda14cbcSMatt Macy 
200*eda14cbcSMatt Macy 
201*eda14cbcSMatt Macy #if !defined(getlocaledecpoint)
202*eda14cbcSMatt Macy #define getlocaledecpoint()	(localeconv()->decimal_point[0])
203*eda14cbcSMatt Macy #endif
204*eda14cbcSMatt Macy 
205*eda14cbcSMatt Macy 
206*eda14cbcSMatt Macy #define buff2d(b,e)	luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
207*eda14cbcSMatt Macy 
208*eda14cbcSMatt Macy /*
209*eda14cbcSMatt Macy ** in case of format error, try to change decimal point separator to
210*eda14cbcSMatt Macy ** the one defined in the current locale and check again
211*eda14cbcSMatt Macy */
212*eda14cbcSMatt Macy static void trydecpoint (LexState *ls, SemInfo *seminfo) {
213*eda14cbcSMatt Macy   char old = ls->decpoint;
214*eda14cbcSMatt Macy   ls->decpoint = getlocaledecpoint();
215*eda14cbcSMatt Macy   buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
216*eda14cbcSMatt Macy   if (!buff2d(ls->buff, &seminfo->r)) {
217*eda14cbcSMatt Macy     /* format error with correct decimal point: no more options */
218*eda14cbcSMatt Macy     buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
219*eda14cbcSMatt Macy     lexerror(ls, "malformed number", TK_NUMBER);
220*eda14cbcSMatt Macy   }
221*eda14cbcSMatt Macy }
222*eda14cbcSMatt Macy 
223*eda14cbcSMatt Macy 
224*eda14cbcSMatt Macy /* LUA_NUMBER */
225*eda14cbcSMatt Macy /*
226*eda14cbcSMatt Macy ** this function is quite liberal in what it accepts, as 'luaO_str2d'
227*eda14cbcSMatt Macy ** will reject ill-formed numerals.
228*eda14cbcSMatt Macy */
229*eda14cbcSMatt Macy static void read_numeral (LexState *ls, SemInfo *seminfo) {
230*eda14cbcSMatt Macy   const char *expo = "Ee";
231*eda14cbcSMatt Macy   int first = ls->current;
232*eda14cbcSMatt Macy   lua_assert(lisdigit(ls->current));
233*eda14cbcSMatt Macy   save_and_next(ls);
234*eda14cbcSMatt Macy   if (first == '0' && check_next(ls, "Xx"))  /* hexadecimal? */
235*eda14cbcSMatt Macy     expo = "Pp";
236*eda14cbcSMatt Macy   for (;;) {
237*eda14cbcSMatt Macy     if (check_next(ls, expo))  /* exponent part? */
238*eda14cbcSMatt Macy       (void) check_next(ls, "+-");  /* optional exponent sign */
239*eda14cbcSMatt Macy     if (lisxdigit(ls->current) || ls->current == '.')
240*eda14cbcSMatt Macy       save_and_next(ls);
241*eda14cbcSMatt Macy     else  break;
242*eda14cbcSMatt Macy   }
243*eda14cbcSMatt Macy   save(ls, '\0');
244*eda14cbcSMatt Macy   buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
245*eda14cbcSMatt Macy   if (!buff2d(ls->buff, &seminfo->r))  /* format error? */
246*eda14cbcSMatt Macy     trydecpoint(ls, seminfo); /* try to update decimal point separator */
247*eda14cbcSMatt Macy }
248*eda14cbcSMatt Macy 
249*eda14cbcSMatt Macy 
250*eda14cbcSMatt Macy /*
251*eda14cbcSMatt Macy ** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
252*eda14cbcSMatt Macy ** -1 if sequence is malformed
253*eda14cbcSMatt Macy */
254*eda14cbcSMatt Macy static int skip_sep (LexState *ls) {
255*eda14cbcSMatt Macy   int count = 0;
256*eda14cbcSMatt Macy   int s = ls->current;
257*eda14cbcSMatt Macy   lua_assert(s == '[' || s == ']');
258*eda14cbcSMatt Macy   save_and_next(ls);
259*eda14cbcSMatt Macy   while (ls->current == '=') {
260*eda14cbcSMatt Macy     save_and_next(ls);
261*eda14cbcSMatt Macy     count++;
262*eda14cbcSMatt Macy   }
263*eda14cbcSMatt Macy   return (ls->current == s) ? count : (-count) - 1;
264*eda14cbcSMatt Macy }
265*eda14cbcSMatt Macy 
266*eda14cbcSMatt Macy 
267*eda14cbcSMatt Macy static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
268*eda14cbcSMatt Macy   save_and_next(ls);  /* skip 2nd `[' */
269*eda14cbcSMatt Macy   if (currIsNewline(ls))  /* string starts with a newline? */
270*eda14cbcSMatt Macy     inclinenumber(ls);  /* skip it */
271*eda14cbcSMatt Macy   for (;;) {
272*eda14cbcSMatt Macy     switch (ls->current) {
273*eda14cbcSMatt Macy       case EOZ:
274*eda14cbcSMatt Macy         lexerror(ls, (seminfo) ? "unfinished long string" :
275*eda14cbcSMatt Macy                                  "unfinished long comment", TK_EOS);
276*eda14cbcSMatt Macy         break;  /* to avoid warnings */
277*eda14cbcSMatt Macy       case ']': {
278*eda14cbcSMatt Macy         if (skip_sep(ls) == sep) {
279*eda14cbcSMatt Macy           save_and_next(ls);  /* skip 2nd `]' */
280*eda14cbcSMatt Macy           goto endloop;
281*eda14cbcSMatt Macy         }
282*eda14cbcSMatt Macy         break;
283*eda14cbcSMatt Macy       }
284*eda14cbcSMatt Macy       case '\n': case '\r': {
285*eda14cbcSMatt Macy         save(ls, '\n');
286*eda14cbcSMatt Macy         inclinenumber(ls);
287*eda14cbcSMatt Macy         if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
288*eda14cbcSMatt Macy         break;
289*eda14cbcSMatt Macy       }
290*eda14cbcSMatt Macy       default: {
291*eda14cbcSMatt Macy         if (seminfo) save_and_next(ls);
292*eda14cbcSMatt Macy         else next(ls);
293*eda14cbcSMatt Macy       }
294*eda14cbcSMatt Macy     }
295*eda14cbcSMatt Macy   } endloop:
296*eda14cbcSMatt Macy   if (seminfo)
297*eda14cbcSMatt Macy     seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
298*eda14cbcSMatt Macy                                      luaZ_bufflen(ls->buff) - 2*(2 + sep));
299*eda14cbcSMatt Macy }
300*eda14cbcSMatt Macy 
301*eda14cbcSMatt Macy 
302*eda14cbcSMatt Macy static void escerror (LexState *ls, int *c, int n, const char *msg) {
303*eda14cbcSMatt Macy   int i;
304*eda14cbcSMatt Macy   luaZ_resetbuffer(ls->buff);  /* prepare error message */
305*eda14cbcSMatt Macy   save(ls, '\\');
306*eda14cbcSMatt Macy   for (i = 0; i < n && c[i] != EOZ; i++)
307*eda14cbcSMatt Macy     save(ls, c[i]);
308*eda14cbcSMatt Macy   lexerror(ls, msg, TK_STRING);
309*eda14cbcSMatt Macy }
310*eda14cbcSMatt Macy 
311*eda14cbcSMatt Macy 
312*eda14cbcSMatt Macy static int readhexaesc (LexState *ls) {
313*eda14cbcSMatt Macy   int c[3], i;  /* keep input for error message */
314*eda14cbcSMatt Macy   int r = 0;  /* result accumulator */
315*eda14cbcSMatt Macy   c[0] = 'x';  /* for error message */
316*eda14cbcSMatt Macy   for (i = 1; i < 3; i++) {  /* read two hexadecimal digits */
317*eda14cbcSMatt Macy     c[i] = next(ls);
318*eda14cbcSMatt Macy     if (!lisxdigit(c[i]))
319*eda14cbcSMatt Macy       escerror(ls, c, i + 1, "hexadecimal digit expected");
320*eda14cbcSMatt Macy     r = (r << 4) + luaO_hexavalue(c[i]);
321*eda14cbcSMatt Macy   }
322*eda14cbcSMatt Macy   return r;
323*eda14cbcSMatt Macy }
324*eda14cbcSMatt Macy 
325*eda14cbcSMatt Macy 
326*eda14cbcSMatt Macy static int readdecesc (LexState *ls) {
327*eda14cbcSMatt Macy   int c[3], i;
328*eda14cbcSMatt Macy   int r = 0;  /* result accumulator */
329*eda14cbcSMatt Macy   for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
330*eda14cbcSMatt Macy     c[i] = ls->current;
331*eda14cbcSMatt Macy     r = 10*r + c[i] - '0';
332*eda14cbcSMatt Macy     next(ls);
333*eda14cbcSMatt Macy   }
334*eda14cbcSMatt Macy   if (r > UCHAR_MAX)
335*eda14cbcSMatt Macy     escerror(ls, c, i, "decimal escape too large");
336*eda14cbcSMatt Macy   return r;
337*eda14cbcSMatt Macy }
338*eda14cbcSMatt Macy 
339*eda14cbcSMatt Macy 
340*eda14cbcSMatt Macy static void read_string (LexState *ls, int del, SemInfo *seminfo) {
341*eda14cbcSMatt Macy   save_and_next(ls);  /* keep delimiter (for error messages) */
342*eda14cbcSMatt Macy   while (ls->current != del) {
343*eda14cbcSMatt Macy     switch (ls->current) {
344*eda14cbcSMatt Macy       case EOZ:
345*eda14cbcSMatt Macy         lexerror(ls, "unfinished string", TK_EOS);
346*eda14cbcSMatt Macy         break;  /* to avoid warnings */
347*eda14cbcSMatt Macy       case '\n':
348*eda14cbcSMatt Macy       case '\r':
349*eda14cbcSMatt Macy         lexerror(ls, "unfinished string", TK_STRING);
350*eda14cbcSMatt Macy         break;  /* to avoid warnings */
351*eda14cbcSMatt Macy       case '\\': {  /* escape sequences */
352*eda14cbcSMatt Macy         int c;  /* final character to be saved */
353*eda14cbcSMatt Macy         next(ls);  /* do not save the `\' */
354*eda14cbcSMatt Macy         switch (ls->current) {
355*eda14cbcSMatt Macy           case 'a': c = '\a'; goto read_save;
356*eda14cbcSMatt Macy           case 'b': c = '\b'; goto read_save;
357*eda14cbcSMatt Macy           case 'f': c = '\f'; goto read_save;
358*eda14cbcSMatt Macy           case 'n': c = '\n'; goto read_save;
359*eda14cbcSMatt Macy           case 'r': c = '\r'; goto read_save;
360*eda14cbcSMatt Macy           case 't': c = '\t'; goto read_save;
361*eda14cbcSMatt Macy           case 'v': c = '\v'; goto read_save;
362*eda14cbcSMatt Macy           case 'x': c = readhexaesc(ls); goto read_save;
363*eda14cbcSMatt Macy           case '\n': case '\r':
364*eda14cbcSMatt Macy             inclinenumber(ls); c = '\n'; goto only_save;
365*eda14cbcSMatt Macy           case '\\': case '\"': case '\'':
366*eda14cbcSMatt Macy             c = ls->current; goto read_save;
367*eda14cbcSMatt Macy           case EOZ: goto no_save;  /* will raise an error next loop */
368*eda14cbcSMatt Macy           case 'z': {  /* zap following span of spaces */
369*eda14cbcSMatt Macy             next(ls);  /* skip the 'z' */
370*eda14cbcSMatt Macy             while (lisspace(ls->current)) {
371*eda14cbcSMatt Macy               if (currIsNewline(ls)) inclinenumber(ls);
372*eda14cbcSMatt Macy               else next(ls);
373*eda14cbcSMatt Macy             }
374*eda14cbcSMatt Macy             goto no_save;
375*eda14cbcSMatt Macy           }
376*eda14cbcSMatt Macy           default: {
377*eda14cbcSMatt Macy             if (!lisdigit(ls->current))
378*eda14cbcSMatt Macy               escerror(ls, &ls->current, 1, "invalid escape sequence");
379*eda14cbcSMatt Macy             /* digital escape \ddd */
380*eda14cbcSMatt Macy             c = readdecesc(ls);
381*eda14cbcSMatt Macy             goto only_save;
382*eda14cbcSMatt Macy           }
383*eda14cbcSMatt Macy         }
384*eda14cbcSMatt Macy        read_save: next(ls);  /* read next character */
385*eda14cbcSMatt Macy        only_save: save(ls, c);  /* save 'c' */
386*eda14cbcSMatt Macy        no_save: break;
387*eda14cbcSMatt Macy       }
388*eda14cbcSMatt Macy       default:
389*eda14cbcSMatt Macy         save_and_next(ls);
390*eda14cbcSMatt Macy     }
391*eda14cbcSMatt Macy   }
392*eda14cbcSMatt Macy   save_and_next(ls);  /* skip delimiter */
393*eda14cbcSMatt Macy   seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
394*eda14cbcSMatt Macy                                    luaZ_bufflen(ls->buff) - 2);
395*eda14cbcSMatt Macy }
396*eda14cbcSMatt Macy 
397*eda14cbcSMatt Macy 
398*eda14cbcSMatt Macy static int llex (LexState *ls, SemInfo *seminfo) {
399*eda14cbcSMatt Macy   luaZ_resetbuffer(ls->buff);
400*eda14cbcSMatt Macy   for (;;) {
401*eda14cbcSMatt Macy     switch (ls->current) {
402*eda14cbcSMatt Macy       case '\n': case '\r': {  /* line breaks */
403*eda14cbcSMatt Macy         inclinenumber(ls);
404*eda14cbcSMatt Macy         break;
405*eda14cbcSMatt Macy       }
406*eda14cbcSMatt Macy       case ' ': case '\f': case '\t': case '\v': {  /* spaces */
407*eda14cbcSMatt Macy         next(ls);
408*eda14cbcSMatt Macy         break;
409*eda14cbcSMatt Macy       }
410*eda14cbcSMatt Macy       case '-': {  /* '-' or '--' (comment) */
411*eda14cbcSMatt Macy         next(ls);
412*eda14cbcSMatt Macy         if (ls->current != '-') return '-';
413*eda14cbcSMatt Macy         /* else is a comment */
414*eda14cbcSMatt Macy         next(ls);
415*eda14cbcSMatt Macy         if (ls->current == '[') {  /* long comment? */
416*eda14cbcSMatt Macy           int sep = skip_sep(ls);
417*eda14cbcSMatt Macy           luaZ_resetbuffer(ls->buff);  /* `skip_sep' may dirty the buffer */
418*eda14cbcSMatt Macy           if (sep >= 0) {
419*eda14cbcSMatt Macy             read_long_string(ls, NULL, sep);  /* skip long comment */
420*eda14cbcSMatt Macy             luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
421*eda14cbcSMatt Macy             break;
422*eda14cbcSMatt Macy           }
423*eda14cbcSMatt Macy         }
424*eda14cbcSMatt Macy         /* else short comment */
425*eda14cbcSMatt Macy         while (!currIsNewline(ls) && ls->current != EOZ)
426*eda14cbcSMatt Macy           next(ls);  /* skip until end of line (or end of file) */
427*eda14cbcSMatt Macy         break;
428*eda14cbcSMatt Macy       }
429*eda14cbcSMatt Macy       case '[': {  /* long string or simply '[' */
430*eda14cbcSMatt Macy         int sep = skip_sep(ls);
431*eda14cbcSMatt Macy         if (sep >= 0) {
432*eda14cbcSMatt Macy           read_long_string(ls, seminfo, sep);
433*eda14cbcSMatt Macy           return TK_STRING;
434*eda14cbcSMatt Macy         } else if (sep == -1) {
435*eda14cbcSMatt Macy 		return '[';
436*eda14cbcSMatt Macy         } else {
437*eda14cbcSMatt Macy 		lexerror(ls, "invalid long string delimiter", TK_STRING);
438*eda14cbcSMatt Macy 		break;
439*eda14cbcSMatt Macy 	}
440*eda14cbcSMatt Macy       }
441*eda14cbcSMatt Macy       case '=': {
442*eda14cbcSMatt Macy         next(ls);
443*eda14cbcSMatt Macy         if (ls->current != '=') return '=';
444*eda14cbcSMatt Macy         else { next(ls); return TK_EQ; }
445*eda14cbcSMatt Macy       }
446*eda14cbcSMatt Macy       case '<': {
447*eda14cbcSMatt Macy         next(ls);
448*eda14cbcSMatt Macy         if (ls->current != '=') return '<';
449*eda14cbcSMatt Macy         else { next(ls); return TK_LE; }
450*eda14cbcSMatt Macy       }
451*eda14cbcSMatt Macy       case '>': {
452*eda14cbcSMatt Macy         next(ls);
453*eda14cbcSMatt Macy         if (ls->current != '=') return '>';
454*eda14cbcSMatt Macy         else { next(ls); return TK_GE; }
455*eda14cbcSMatt Macy       }
456*eda14cbcSMatt Macy       case '~': {
457*eda14cbcSMatt Macy         next(ls);
458*eda14cbcSMatt Macy         if (ls->current != '=') return '~';
459*eda14cbcSMatt Macy         else { next(ls); return TK_NE; }
460*eda14cbcSMatt Macy       }
461*eda14cbcSMatt Macy       case ':': {
462*eda14cbcSMatt Macy         next(ls);
463*eda14cbcSMatt Macy         if (ls->current != ':') return ':';
464*eda14cbcSMatt Macy         else { next(ls); return TK_DBCOLON; }
465*eda14cbcSMatt Macy       }
466*eda14cbcSMatt Macy       case '"': case '\'': {  /* short literal strings */
467*eda14cbcSMatt Macy         read_string(ls, ls->current, seminfo);
468*eda14cbcSMatt Macy         return TK_STRING;
469*eda14cbcSMatt Macy       }
470*eda14cbcSMatt Macy       case '.': {  /* '.', '..', '...', or number */
471*eda14cbcSMatt Macy         save_and_next(ls);
472*eda14cbcSMatt Macy         if (check_next(ls, ".")) {
473*eda14cbcSMatt Macy           if (check_next(ls, "."))
474*eda14cbcSMatt Macy             return TK_DOTS;   /* '...' */
475*eda14cbcSMatt Macy           else return TK_CONCAT;   /* '..' */
476*eda14cbcSMatt Macy         }
477*eda14cbcSMatt Macy         else if (!lisdigit(ls->current)) return '.';
478*eda14cbcSMatt Macy         /* else go through */
479*eda14cbcSMatt Macy       }
480*eda14cbcSMatt Macy       /* FALLTHROUGH */
481*eda14cbcSMatt Macy       case '0': case '1': case '2': case '3': case '4':
482*eda14cbcSMatt Macy       case '5': case '6': case '7': case '8': case '9': {
483*eda14cbcSMatt Macy         read_numeral(ls, seminfo);
484*eda14cbcSMatt Macy         return TK_NUMBER;
485*eda14cbcSMatt Macy       }
486*eda14cbcSMatt Macy       case EOZ: {
487*eda14cbcSMatt Macy         return TK_EOS;
488*eda14cbcSMatt Macy       }
489*eda14cbcSMatt Macy       default: {
490*eda14cbcSMatt Macy         if (lislalpha(ls->current)) {  /* identifier or reserved word? */
491*eda14cbcSMatt Macy           TString *ts;
492*eda14cbcSMatt Macy           do {
493*eda14cbcSMatt Macy             save_and_next(ls);
494*eda14cbcSMatt Macy           } while (lislalnum(ls->current));
495*eda14cbcSMatt Macy           ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
496*eda14cbcSMatt Macy                                   luaZ_bufflen(ls->buff));
497*eda14cbcSMatt Macy           seminfo->ts = ts;
498*eda14cbcSMatt Macy           if (isreserved(ts))  /* reserved word? */
499*eda14cbcSMatt Macy             return ts->tsv.extra - 1 + FIRST_RESERVED;
500*eda14cbcSMatt Macy           else {
501*eda14cbcSMatt Macy             return TK_NAME;
502*eda14cbcSMatt Macy           }
503*eda14cbcSMatt Macy         }
504*eda14cbcSMatt Macy         else {  /* single-char tokens (+ - / ...) */
505*eda14cbcSMatt Macy           int c = ls->current;
506*eda14cbcSMatt Macy           next(ls);
507*eda14cbcSMatt Macy           return c;
508*eda14cbcSMatt Macy         }
509*eda14cbcSMatt Macy       }
510*eda14cbcSMatt Macy     }
511*eda14cbcSMatt Macy   }
512*eda14cbcSMatt Macy }
513*eda14cbcSMatt Macy 
514*eda14cbcSMatt Macy 
515*eda14cbcSMatt Macy void luaX_next (LexState *ls) {
516*eda14cbcSMatt Macy   ls->lastline = ls->linenumber;
517*eda14cbcSMatt Macy   if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
518*eda14cbcSMatt Macy     ls->t = ls->lookahead;  /* use this one */
519*eda14cbcSMatt Macy     ls->lookahead.token = TK_EOS;  /* and discharge it */
520*eda14cbcSMatt Macy   }
521*eda14cbcSMatt Macy   else
522*eda14cbcSMatt Macy     ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
523*eda14cbcSMatt Macy }
524*eda14cbcSMatt Macy 
525*eda14cbcSMatt Macy 
526*eda14cbcSMatt Macy int luaX_lookahead (LexState *ls) {
527*eda14cbcSMatt Macy   lua_assert(ls->lookahead.token == TK_EOS);
528*eda14cbcSMatt Macy   ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
529*eda14cbcSMatt Macy   return ls->lookahead.token;
530*eda14cbcSMatt Macy }
531*eda14cbcSMatt Macy /* END CSTYLED */
532