Branch data Line data Source code
1 : : /*
2 : : ** $Id: llex.c $
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 : :
31 : :
32 : : #define next(ls) (ls->current = zgetc(ls->z))
33 : :
34 : :
35 : :
36 : : #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
37 : :
38 : :
39 : : /* ORDER RESERVED */
40 : : static const char *const luaX_tokens [] = {
41 : : "and", "break", "do", "else", "elseif",
42 : : "end", "false", "for", "function", "goto", "if",
43 : : "in", "local", "nil", "not", "or", "repeat",
44 : : "return", "then", "true", "until", "while",
45 : : "//", "..", "...", "==", ">=", "<=", "~=",
46 : : "<<", ">>", "::", "<eof>",
47 : : "<number>", "<integer>", "<name>", "<string>"
48 : : };
49 : :
50 : :
51 : : #define save_and_next(ls) (save(ls, ls->current), next(ls))
52 : :
53 : :
54 : : static l_noret lexerror (LexState *ls, const char *msg, int token);
55 : :
56 : :
57 : 20625 : static void save (LexState *ls, int c) {
58 : 20625 : Mbuffer *b = ls->buff;
59 [ + + ]: 20625 : if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
60 : : size_t newsize;
61 [ - + ]: 16 : if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
62 : 0 : lexerror(ls, "lexical element too long", 0);
63 : 16 : newsize = luaZ_sizebuffer(b) * 2;
64 : 16 : luaZ_resizebuffer(ls->L, b, newsize);
65 : 16 : }
66 : 20625 : b->buffer[luaZ_bufflen(b)++] = cast_char(c);
67 : 20625 : }
68 : :
69 : :
70 : 810 : void luaX_init (lua_State *L) {
71 : : int i;
72 : 810 : TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
73 : 810 : luaC_fix(L, obj2gco(e)); /* never collect this name */
74 [ + + ]: 18630 : for (i=0; i<NUM_RESERVED; i++) {
75 : 17820 : TString *ts = luaS_new(L, luaX_tokens[i]);
76 : 17820 : luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
77 : 17820 : ts->extra = cast_byte(i+1); /* reserved word */
78 : 17820 : }
79 : 810 : }
80 : :
81 : :
82 : 5 : const char *luaX_token2str (LexState *ls, int token) {
83 [ + + ]: 5 : if (token < FIRST_RESERVED) { /* single-byte symbols? */
84 [ + - ]: 4 : if (lisprint(token))
85 : 4 : return luaO_pushfstring(ls->L, "'%c'", token);
86 : : else /* control character */
87 : 0 : return luaO_pushfstring(ls->L, "'<\\%d>'", token);
88 : : }
89 : : else {
90 : 1 : const char *s = luaX_tokens[token - FIRST_RESERVED];
91 [ - + ]: 1 : 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 : 1 : return s;
95 : : }
96 : 5 : }
97 : :
98 : :
99 : 4 : static const char *txtToken (LexState *ls, int token) {
100 [ + - ]: 4 : switch (token) {
101 : : 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 : : default:
106 : 4 : return luaX_token2str(ls, token);
107 : : }
108 : 4 : }
109 : :
110 : :
111 : 4 : static l_noret lexerror (LexState *ls, const char *msg, int token) {
112 : 4 : msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
113 [ - + ]: 4 : if (token)
114 : 4 : luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
115 : 4 : luaD_throw(ls->L, LUA_ERRSYNTAX);
116 : : }
117 : :
118 : :
119 : 4 : l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
120 : 4 : 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 : 3813 : TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
130 : 3813 : lua_State *L = ls->L;
131 : : TValue *o; /* entry for 'str' */
132 : 3813 : TString *ts = luaS_newlstr(L, str, l); /* create new string */
133 : 3813 : setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
134 : 3813 : o = luaH_set(L, ls->h, s2v(L->top - 1));
135 [ + + ]: 3813 : if (isempty(o)) { /* not in use yet? */
136 : : /* boolean value does not need GC barrier;
137 : : table is not a metatable, so it does not need to invalidate cache */
138 : 3304 : setbtvalue(o); /* t[string] = true */
139 [ + + ]: 3304 : luaC_checkGC(L);
140 : 3304 : }
141 : : else { /* string already present */
142 : 509 : ts = keystrval(nodefromval(o)); /* re-use value previously stored */
143 : : }
144 : 3813 : L->top--; /* remove string from stack */
145 : 3813 : 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 : 369 : static void inclinenumber (LexState *ls) {
154 : 369 : int old = ls->current;
155 : : lua_assert(currIsNewline(ls));
156 [ + - ]: 369 : next(ls); /* skip '\n' or '\r' */
157 [ + - + - ]: 369 : if (currIsNewline(ls) && ls->current != old)
158 [ # # ]: 0 : next(ls); /* skip '\n\r' or '\r\n' */
159 [ - + ]: 369 : if (++ls->linenumber >= MAX_INT)
160 : 0 : lexerror(ls, "chunk has too many lines", 0);
161 : 369 : }
162 : :
163 : :
164 : 656 : void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
165 : : int firstchar) {
166 : 656 : ls->t.token = 0;
167 : 656 : ls->L = L;
168 : 656 : ls->current = firstchar;
169 : 656 : ls->lookahead.token = TK_EOS; /* no look-ahead token */
170 : 656 : ls->z = z;
171 : 656 : ls->fs = NULL;
172 : 656 : ls->linenumber = 1;
173 : 656 : ls->lastline = 1;
174 : 656 : ls->source = source;
175 : 656 : ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
176 : 656 : luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
177 : 656 : }
178 : :
179 : :
180 : :
181 : : /*
182 : : ** =======================================================
183 : : ** LEXICAL ANALYZER
184 : : ** =======================================================
185 : : */
186 : :
187 : :
188 : 1172 : static int check_next1 (LexState *ls, int c) {
189 [ + + ]: 1172 : if (ls->current == c) {
190 [ + - ]: 235 : next(ls);
191 : 235 : return 1;
192 : : }
193 : 937 : else return 0;
194 : 1172 : }
195 : :
196 : :
197 : : /*
198 : : ** Check whether current char is in set 'set' (with two chars) and
199 : : ** saves it
200 : : */
201 : 462 : static int check_next2 (LexState *ls, const char *set) {
202 : : lua_assert(set[2] == '\0');
203 [ + - - + ]: 462 : if (ls->current == set[0] || ls->current == set[1]) {
204 [ # # ]: 0 : save_and_next(ls);
205 : 0 : return 1;
206 : : }
207 : 462 : else return 0;
208 : 462 : }
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. Roughly, it accepts the following
215 : : ** pattern:
216 : : **
217 : : ** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))*
218 : : **
219 : : ** The only tricky part is to accept [+-] only after a valid exponent
220 : : ** mark, to avoid reading '3-4' or '0xe+1' as a single number.
221 : : **
222 : : ** The caller might have already read an initial dot.
223 : : */
224 : 446 : static int read_numeral (LexState *ls, SemInfo *seminfo) {
225 : : TValue obj;
226 : 446 : const char *expo = "Ee";
227 : 446 : int first = ls->current;
228 : : lua_assert(lisdigit(ls->current));
229 [ + + ]: 446 : save_and_next(ls);
230 [ + + + - ]: 446 : if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */
231 : 0 : expo = "Pp";
232 : 446 : for (;;) {
233 [ - + ]: 446 : if (check_next2(ls, expo)) /* exponent mark? */
234 : 0 : check_next2(ls, "-+"); /* optional exponent sign */
235 [ + - - + ]: 446 : else if (lisxdigit(ls->current) || ls->current == '.') /* '%x|%.' */
236 [ # # ]: 0 : save_and_next(ls);
237 : 446 : else break;
238 : : }
239 [ + - ]: 446 : if (lislalpha(ls->current)) /* is numeral touching a letter? */
240 [ # # ]: 0 : save_and_next(ls); /* force an error */
241 : 446 : save(ls, '\0');
242 [ - + ]: 446 : if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
243 : 0 : lexerror(ls, "malformed number", TK_FLT);
244 [ + - ]: 446 : if (ttisinteger(&obj)) {
245 : 446 : seminfo->i = ivalue(&obj);
246 : 446 : return TK_INT;
247 : : }
248 : : else {
249 : : lua_assert(ttisfloat(&obj));
250 : 0 : seminfo->r = fltvalue(&obj);
251 : 0 : return TK_FLT;
252 : : }
253 : 446 : }
254 : :
255 : :
256 : : /*
257 : : ** read a sequence '[=*[' or ']=*]', leaving the last bracket. If
258 : : ** sequence is well formed, return its number of '='s + 2; otherwise,
259 : : ** return 1 if it is a single bracket (no '='s and no 2nd bracket);
260 : : ** otherwise (an unfinished '[==...') return 0.
261 : : */
262 : 57 : static size_t skip_sep (LexState *ls) {
263 : 57 : size_t count = 0;
264 : 57 : int s = ls->current;
265 : : lua_assert(s == '[' || s == ']');
266 [ + - ]: 57 : save_and_next(ls);
267 [ - + ]: 57 : while (ls->current == '=') {
268 [ # # ]: 0 : save_and_next(ls);
269 : 0 : count++;
270 : : }
271 [ - + ]: 57 : return (ls->current == s) ? count + 2
272 : 57 : : (count == 0) ? 1
273 : : : 0;
274 : : }
275 : :
276 : :
277 : 0 : static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
278 : 0 : int line = ls->linenumber; /* initial line (for error message) */
279 [ # # ]: 0 : save_and_next(ls); /* skip 2nd '[' */
280 [ # # # # ]: 0 : if (currIsNewline(ls)) /* string starts with a newline? */
281 : 0 : inclinenumber(ls); /* skip it */
282 : 0 : for (;;) {
283 [ # # # # ]: 0 : switch (ls->current) {
284 : : case EOZ: { /* error */
285 : 0 : const char *what = (seminfo ? "string" : "comment");
286 : 0 : const char *msg = luaO_pushfstring(ls->L,
287 : 0 : "unfinished long %s (starting at line %d)", what, line);
288 : 0 : lexerror(ls, msg, TK_EOS);
289 : : break; /* to avoid warnings */
290 : : }
291 : : case ']': {
292 [ # # ]: 0 : if (skip_sep(ls) == sep) {
293 [ # # ]: 0 : save_and_next(ls); /* skip 2nd ']' */
294 : 0 : goto endloop;
295 : : }
296 : 0 : break;
297 : : }
298 : : case '\n': case '\r': {
299 : 0 : save(ls, '\n');
300 : 0 : inclinenumber(ls);
301 [ # # ]: 0 : if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
302 : 0 : break;
303 : : }
304 : : default: {
305 [ # # # # ]: 0 : if (seminfo) save_and_next(ls);
306 [ # # ]: 0 : else next(ls);
307 : : }
308 : 0 : }
309 : : } endloop:
310 [ # # ]: 0 : if (seminfo)
311 : 0 : seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep,
312 : 0 : luaZ_bufflen(ls->buff) - 2 * sep);
313 : 0 : }
314 : :
315 : :
316 : 0 : static void esccheck (LexState *ls, int c, const char *msg) {
317 [ # # ]: 0 : if (!c) {
318 [ # # ]: 0 : if (ls->current != EOZ)
319 [ # # ]: 0 : save_and_next(ls); /* add current to buffer for error message */
320 : 0 : lexerror(ls, msg, TK_STRING);
321 : : }
322 : 0 : }
323 : :
324 : :
325 : 0 : static int gethexa (LexState *ls) {
326 [ # # ]: 0 : save_and_next(ls);
327 : 0 : esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
328 : 0 : return luaO_hexavalue(ls->current);
329 : : }
330 : :
331 : :
332 : 0 : static int readhexaesc (LexState *ls) {
333 : 0 : int r = gethexa(ls);
334 : 0 : r = (r << 4) + gethexa(ls);
335 : 0 : luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */
336 : 0 : return r;
337 : : }
338 : :
339 : :
340 : 0 : static unsigned long readutf8esc (LexState *ls) {
341 : : unsigned long r;
342 : 0 : int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
343 [ # # ]: 0 : save_and_next(ls); /* skip 'u' */
344 : 0 : esccheck(ls, ls->current == '{', "missing '{'");
345 : 0 : r = gethexa(ls); /* must have at least one digit */
346 [ # # # # ]: 0 : while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) {
347 : 0 : i++;
348 : 0 : esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large");
349 : 0 : r = (r << 4) + luaO_hexavalue(ls->current);
350 : : }
351 : 0 : esccheck(ls, ls->current == '}', "missing '}'");
352 [ # # ]: 0 : next(ls); /* skip '}' */
353 : 0 : luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */
354 : 0 : return r;
355 : : }
356 : :
357 : :
358 : 0 : static void utf8esc (LexState *ls) {
359 : : char buff[UTF8BUFFSZ];
360 : 0 : int n = luaO_utf8esc(buff, readutf8esc(ls));
361 [ # # ]: 0 : for (; n > 0; n--) /* add 'buff' to string */
362 : 0 : save(ls, buff[UTF8BUFFSZ - n]);
363 : 0 : }
364 : :
365 : :
366 : 0 : static int readdecesc (LexState *ls) {
367 : : int i;
368 : 0 : int r = 0; /* result accumulator */
369 [ # # # # ]: 0 : for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
370 : 0 : r = 10*r + ls->current - '0';
371 [ # # ]: 0 : save_and_next(ls);
372 : 0 : }
373 : 0 : esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
374 : 0 : luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */
375 : 0 : return r;
376 : : }
377 : :
378 : :
379 : 703 : static void read_string (LexState *ls, int del, SemInfo *seminfo) {
380 [ + - ]: 703 : save_and_next(ls); /* keep delimiter (for error messages) */
381 [ + + ]: 5774 : while (ls->current != del) {
382 [ - + + - ]: 5071 : switch (ls->current) {
383 : : case EOZ:
384 : 0 : lexerror(ls, "unfinished string", TK_EOS);
385 : : break; /* to avoid warnings */
386 : : case '\n':
387 : : case '\r':
388 : 0 : lexerror(ls, "unfinished string", TK_STRING);
389 : : break; /* to avoid warnings */
390 : : case '\\': { /* escape sequences */
391 : : int c; /* final character to be saved */
392 [ + - ]: 48 : save_and_next(ls); /* keep '\\' for error messages */
393 [ - - - - : 48 : switch (ls->current) {
- - + - -
- - - -
- ]
394 : 0 : case 'a': c = '\a'; goto read_save;
395 : 0 : case 'b': c = '\b'; goto read_save;
396 : 0 : case 'f': c = '\f'; goto read_save;
397 : 48 : case 'n': c = '\n'; goto read_save;
398 : 0 : case 'r': c = '\r'; goto read_save;
399 : 0 : case 't': c = '\t'; goto read_save;
400 : 0 : case 'v': c = '\v'; goto read_save;
401 : 0 : case 'x': c = readhexaesc(ls); goto read_save;
402 : 0 : case 'u': utf8esc(ls); goto no_save;
403 : : case '\n': case '\r':
404 : 0 : inclinenumber(ls); c = '\n'; goto only_save;
405 : : case '\\': case '\"': case '\'':
406 : 0 : c = ls->current; goto read_save;
407 : 0 : case EOZ: goto no_save; /* will raise an error next loop */
408 : : case 'z': { /* zap following span of spaces */
409 : 0 : luaZ_buffremove(ls->buff, 1); /* remove '\\' */
410 [ # # ]: 0 : next(ls); /* skip the 'z' */
411 [ # # ]: 0 : while (lisspace(ls->current)) {
412 [ # # # # ]: 0 : if (currIsNewline(ls)) inclinenumber(ls);
413 [ # # ]: 0 : else next(ls);
414 : : }
415 : 0 : goto no_save;
416 : : }
417 : : default: {
418 : 0 : esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
419 : 0 : c = readdecesc(ls); /* digital escape '\ddd' */
420 : 0 : goto only_save;
421 : : }
422 : : }
423 : : read_save:
424 [ + - ]: 48 : next(ls);
425 : : /* go through */
426 : : only_save:
427 : 48 : luaZ_buffremove(ls->buff, 1); /* remove '\\' */
428 : 48 : save(ls, c);
429 : : /* go through */
430 : 48 : no_save: break;
431 : : }
432 : : default:
433 [ + - ]: 5023 : save_and_next(ls);
434 : 5023 : }
435 : : }
436 [ + + ]: 703 : save_and_next(ls); /* skip delimiter */
437 : 1406 : seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
438 : 703 : luaZ_bufflen(ls->buff) - 2);
439 : 703 : }
440 : :
441 : :
442 : 8416 : static int llex (LexState *ls, SemInfo *seminfo) {
443 : 8416 : luaZ_resetbuffer(ls->buff);
444 : 10968 : for (;;) {
445 [ + + + + : 10968 : switch (ls->current) {
- + + + -
- - + + +
+ ]
446 : : case '\n': case '\r': { /* line breaks */
447 : 369 : inclinenumber(ls);
448 : 369 : break;
449 : : }
450 : : case ' ': case '\f': case '\t': case '\v': { /* spaces */
451 [ + - ]: 2183 : next(ls);
452 : 2183 : break;
453 : : }
454 : : case '-': { /* '-' or '--' (comment) */
455 [ # # ]: 0 : next(ls);
456 [ # # ]: 0 : if (ls->current != '-') return '-';
457 : : /* else is a comment */
458 [ # # ]: 0 : next(ls);
459 [ # # ]: 0 : if (ls->current == '[') { /* long comment? */
460 : 0 : size_t sep = skip_sep(ls);
461 : 0 : luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */
462 [ # # ]: 0 : if (sep >= 2) {
463 : 0 : read_long_string(ls, NULL, sep); /* skip long comment */
464 : 0 : luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
465 : 0 : break;
466 : : }
467 : 0 : }
468 : : /* else short comment */
469 [ # # # # : 0 : while (!currIsNewline(ls) && ls->current != EOZ)
# # ]
470 [ # # ]: 0 : next(ls); /* skip until end of line (or end of file) */
471 : 0 : break;
472 : : }
473 : : case '[': { /* long string or simply '[' */
474 : 57 : size_t sep = skip_sep(ls);
475 [ - + ]: 57 : if (sep >= 2) {
476 : 0 : read_long_string(ls, seminfo, sep);
477 : 0 : return TK_STRING;
478 : : }
479 [ - + ]: 57 : else if (sep == 0) /* '[=...' missing second bracket? */
480 : 0 : lexerror(ls, "invalid long string delimiter", TK_STRING);
481 : 57 : return '[';
482 : : }
483 : : case '=': {
484 [ + - ]: 176 : next(ls);
485 [ + + ]: 176 : if (check_next1(ls, '=')) return TK_EQ; /* '==' */
486 : 118 : else return '=';
487 : : }
488 : : case '<': {
489 [ # # ]: 0 : next(ls);
490 [ # # ]: 0 : if (check_next1(ls, '=')) return TK_LE; /* '<=' */
491 [ # # ]: 0 : else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */
492 : 0 : else return '<';
493 : : }
494 : : case '>': {
495 [ # # ]: 0 : next(ls);
496 [ # # ]: 0 : if (check_next1(ls, '=')) return TK_GE; /* '>=' */
497 [ # # ]: 0 : else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */
498 : 0 : else return '>';
499 : : }
500 : : case '/': {
501 [ # # ]: 0 : next(ls);
502 [ # # ]: 0 : if (check_next1(ls, '/')) return TK_IDIV; /* '//' */
503 : 0 : else return '/';
504 : : }
505 : : case '~': {
506 [ + - ]: 129 : next(ls);
507 [ + - ]: 129 : if (check_next1(ls, '=')) return TK_NE; /* '~=' */
508 : 0 : else return '~';
509 : : }
510 : : case ':': {
511 [ + - ]: 48 : next(ls);
512 [ - + ]: 48 : if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */
513 : 48 : else return ':';
514 : : }
515 : : case '"': case '\'': { /* short literal strings */
516 : 703 : read_string(ls, ls->current, seminfo);
517 : 703 : return TK_STRING;
518 : : }
519 : : case '.': { /* '.', '..', '...', or number */
520 [ + - ]: 771 : save_and_next(ls);
521 [ + + ]: 771 : if (check_next1(ls, '.')) {
522 [ - + ]: 48 : if (check_next1(ls, '.'))
523 : 0 : return TK_DOTS; /* '...' */
524 : 48 : else return TK_CONCAT; /* '..' */
525 : : }
526 [ - + ]: 723 : else if (!lisdigit(ls->current)) return '.';
527 : 0 : else return read_numeral(ls, seminfo);
528 : : }
529 : : case '0': case '1': case '2': case '3': case '4':
530 : : case '5': case '6': case '7': case '8': case '9': {
531 : 446 : return read_numeral(ls, seminfo);
532 : : }
533 : : case EOZ: {
534 : 653 : return TK_EOS;
535 : : }
536 : : default: {
537 [ + + ]: 5433 : if (lislalpha(ls->current)) { /* identifier or reserved word? */
538 : : TString *ts;
539 : 3086 : do {
540 [ + + ]: 12380 : save_and_next(ls);
541 [ + + ]: 12380 : } while (lislalnum(ls->current));
542 : 6172 : ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
543 : 3086 : luaZ_bufflen(ls->buff));
544 : 3086 : seminfo->ts = ts;
545 [ + - + + ]: 3086 : if (isreserved(ts)) /* reserved word? */
546 : 972 : return ts->extra - 1 + FIRST_RESERVED;
547 : : else {
548 : 2114 : return TK_NAME;
549 : : }
550 : : }
551 : : else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
552 : 2347 : int c = ls->current;
553 [ + + ]: 2347 : next(ls);
554 : 2347 : return c;
555 : : }
556 : : }
557 : : }
558 : : }
559 : 8416 : }
560 : :
561 : :
562 : 8416 : void luaX_next (LexState *ls) {
563 : 8416 : ls->lastline = ls->linenumber;
564 [ - + ]: 8416 : if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
565 : 0 : ls->t = ls->lookahead; /* use this one */
566 : 0 : ls->lookahead.token = TK_EOS; /* and discharge it */
567 : 0 : }
568 : : else
569 : 8416 : ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
570 : 8416 : }
571 : :
572 : :
573 : 0 : int luaX_lookahead (LexState *ls) {
574 : : lua_assert(ls->lookahead.token == TK_EOS);
575 : 0 : ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
576 : 0 : return ls->lookahead.token;
577 : : }
578 : :
|