summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/llex.c
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/llex.c
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz
rockbox-36378988ad4059982742f05f5eb50580b456840a.zip
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change reduces the number of modifications in the Lua source using some new defines and because the upstream source is now more flexible. Unless otherwise stated, l*.[ch] files are taken unmodified from the upstream lua-5.2.3. fscanf.c: file descriptors in rockbox are just ints, they are hidden behind a void* now so liolib requires less modifications. fscanf is updated to use void* too. getc.c: this is a new file required for getc implementation in lauxlib.c lauxlib.c: LoadF replaced FILE* with int, the rockbox file descriptor int are cast to FILE* (actually void* due to typedef). getc uses the PREFIX version. stdin is not used, as per 5.1.4. lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now rather than being commented out. lbitlib.c: use the built-in version from 5.2.3 rather than Reuben Thomas's external library. Backwards compatible and adds some new bit operations. ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have been removed from rockconf.h liolib.c: here the implementation has changed to use the LStream from the original source, and cast the FILE* pointers to int. This has reduced the number of modifications from the upstream version. llex.c: the only change from upstream is to remove the locale include. lmathlib.c: updated from the 5.2.3 version and re-applied the changes that were made vs 5.1.4 for random numbers and to remove unsupported float functions. loadlib.c: upstream version, with the 5.1.4 changes for missing functions. lobject.c: upstream version, with ctype.h added and sprintf changed to snprintf. loslib.c: upstream version with locale.h removed and 5.1.4 changes for unsupportable functions. lstrlib.c: sprintf changed to snprintf. ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp in luai_hashnum. luaconf.h: updated to 5.2.3 version, restored relevant parts from the original 5.1.4 configuration. The COMPAT defines that are no longer available are not included. lundump.c: VERSION macro conflicts with the core Rockbox equivalent. rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg equivalent. Moved checkboolean/optboolean functions to this file and out of core lua files. luaL_getn is no longer available, replaced by luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs replacements. rli_init has to be called before setting up the newlib to avoid overwriting the rb table. rocklib_aux.pl: use rli_checkboolean from rocklib.c. rocklua.c: new default bits library used, update the library loading code with idiomatic 5.2 code. strcspn.c: no longer needed, but strspn.c is required for strspn in lbaselib.c Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651 Reviewed-on: http://gerrit.rockbox.org/774 Tested: Richard Quirk <richard.quirk@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
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