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