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