diff options
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 151 |
1 files changed, 77 insertions, 74 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.42 1999/10/19 13:33:22 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.43 1999/11/09 17:59:35 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -8,6 +8,8 @@ | |||
8 | #include <ctype.h> | 8 | #include <ctype.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | 10 | ||
11 | #define LUA_REENTRANT | ||
12 | |||
11 | #include "lauxlib.h" | 13 | #include "lauxlib.h" |
12 | #include "llex.h" | 14 | #include "llex.h" |
13 | #include "lmem.h" | 15 | #include "lmem.h" |
@@ -23,8 +25,8 @@ | |||
23 | #define next(LS) (LS->current = zgetc(LS->lex_z)) | 25 | #define next(LS) (LS->current = zgetc(LS->lex_z)) |
24 | 26 | ||
25 | 27 | ||
26 | #define save(c) luaL_addchar(c) | 28 | #define save(L, c) luaL_addchar(L, c) |
27 | #define save_and_next(LS) (save(LS->current), next(LS)) | 29 | #define save_and_next(L, LS) (save(L, LS->current), next(LS)) |
28 | 30 | ||
29 | 31 | ||
30 | /* ORDER RESERVED */ | 32 | /* ORDER RESERVED */ |
@@ -33,10 +35,10 @@ static const char *const reserved [] = {"and", "do", "else", "elseif", "end", | |||
33 | "until", "while"}; | 35 | "until", "while"}; |
34 | 36 | ||
35 | 37 | ||
36 | void luaX_init (void) { | 38 | void luaX_init (lua_State *L) { |
37 | unsigned int i; | 39 | unsigned int i; |
38 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { | 40 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { |
39 | TaggedString *ts = luaS_new(reserved[i]); | 41 | TaggedString *ts = luaS_new(L, reserved[i]); |
40 | ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */ | 42 | ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */ |
41 | } | 43 | } |
42 | } | 44 | } |
@@ -49,14 +51,14 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { | |||
49 | luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff)); | 51 | luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff)); |
50 | if (token[0] == '\0') | 52 | if (token[0] == '\0') |
51 | token = "<eof>"; | 53 | token = "<eof>"; |
52 | luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s", | 54 | luaL_verror(ls->L, "%.100s;\n last token read: `%.50s' at line %d in %.80s", |
53 | s, token, ls->linenumber, buff); | 55 | s, token, ls->linenumber, buff); |
54 | } | 56 | } |
55 | 57 | ||
56 | 58 | ||
57 | void luaX_error (LexState *ls, const char *s) { | 59 | void luaX_error (LexState *ls, const char *s) { |
58 | save('\0'); | 60 | save(ls->L, '\0'); |
59 | luaX_syntaxerror(ls, s, luaL_buffer()); | 61 | luaX_syntaxerror(ls, s, luaL_buffer(ls->L)); |
60 | } | 62 | } |
61 | 63 | ||
62 | 64 | ||
@@ -86,8 +88,8 @@ static void firstline (LexState *LS) | |||
86 | } | 88 | } |
87 | 89 | ||
88 | 90 | ||
89 | void luaX_setinput (LexState *LS, ZIO *z) | 91 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z) { |
90 | { | 92 | LS->L = L; |
91 | LS->current = '\n'; | 93 | LS->current = '\n'; |
92 | LS->linenumber = 0; | 94 | LS->linenumber = 0; |
93 | LS->iflevel = 0; | 95 | LS->iflevel = 0; |
@@ -96,7 +98,7 @@ void luaX_setinput (LexState *LS, ZIO *z) | |||
96 | LS->lex_z = z; | 98 | LS->lex_z = z; |
97 | LS->fs = NULL; | 99 | LS->fs = NULL; |
98 | firstline(LS); | 100 | firstline(LS); |
99 | luaL_resetbuffer(); | 101 | luaL_resetbuffer(L); |
100 | } | 102 | } |
101 | 103 | ||
102 | 104 | ||
@@ -117,12 +119,12 @@ static void skipspace (LexState *LS) { | |||
117 | } | 119 | } |
118 | 120 | ||
119 | 121 | ||
120 | static int checkcond (LexState *LS, const char *buff) { | 122 | static int checkcond (lua_State *L, LexState *LS, const char *buff) { |
121 | static const char *const opts[] = {"nil", "1", NULL}; | 123 | static const char *const opts[] = {"nil", "1", NULL}; |
122 | int i = luaL_findstring(buff, opts); | 124 | int i = luaL_findstring(buff, opts); |
123 | if (i >= 0) return i; | 125 | if (i >= 0) return i; |
124 | else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') | 126 | else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') |
125 | return luaS_globaldefined(buff); | 127 | return luaS_globaldefined(L, buff); |
126 | else { | 128 | else { |
127 | luaX_syntaxerror(LS, "invalid $if condition", buff); | 129 | luaX_syntaxerror(LS, "invalid $if condition", buff); |
128 | return 0; /* to avoid warnings */ | 130 | return 0; /* to avoid warnings */ |
@@ -145,13 +147,13 @@ static void readname (LexState *LS, char *buff) { | |||
145 | } | 147 | } |
146 | 148 | ||
147 | 149 | ||
148 | static void inclinenumber (LexState *LS); | 150 | static void inclinenumber (lua_State *L, LexState *LS); |
149 | 151 | ||
150 | 152 | ||
151 | static void ifskip (LexState *LS) { | 153 | static void ifskip (lua_State *L, LexState *LS) { |
152 | while (LS->ifstate[LS->iflevel].skip) { | 154 | while (LS->ifstate[LS->iflevel].skip) { |
153 | if (LS->current == '\n') | 155 | if (LS->current == '\n') |
154 | inclinenumber(LS); | 156 | inclinenumber(L, LS); |
155 | else if (LS->current == EOZ) | 157 | else if (LS->current == EOZ) |
156 | luaX_error(LS, "input ends inside a $if"); | 158 | luaX_error(LS, "input ends inside a $if"); |
157 | else next(LS); | 159 | else next(LS); |
@@ -159,7 +161,7 @@ static void ifskip (LexState *LS) { | |||
159 | } | 161 | } |
160 | 162 | ||
161 | 163 | ||
162 | static void inclinenumber (LexState *LS) { | 164 | static void inclinenumber (lua_State *L, LexState *LS) { |
163 | static const char *const pragmas [] = | 165 | static const char *const pragmas [] = |
164 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; | 166 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; |
165 | next(LS); /* skip '\n' */ | 167 | next(LS); /* skip '\n' */ |
@@ -196,7 +198,7 @@ static void inclinenumber (LexState *LS) { | |||
196 | readname(LS, buff); | 198 | readname(LS, buff); |
197 | LS->iflevel++; | 199 | LS->iflevel++; |
198 | LS->ifstate[LS->iflevel].elsepart = 0; | 200 | LS->ifstate[LS->iflevel].elsepart = 0; |
199 | LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot; | 201 | LS->ifstate[LS->iflevel].condition = checkcond(L, LS, buff) ? !ifnot : ifnot; |
200 | LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; | 202 | LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; |
201 | break; | 203 | break; |
202 | case 6: /* else */ | 204 | case 6: /* else */ |
@@ -211,10 +213,10 @@ static void inclinenumber (LexState *LS) { | |||
211 | } | 213 | } |
212 | skipspace(LS); | 214 | skipspace(LS); |
213 | if (LS->current == '\n') /* pragma must end with a '\n' ... */ | 215 | if (LS->current == '\n') /* pragma must end with a '\n' ... */ |
214 | inclinenumber(LS); | 216 | inclinenumber(L, LS); |
215 | else if (LS->current != EOZ) /* or eof */ | 217 | else if (LS->current != EOZ) /* or eof */ |
216 | luaX_syntaxerror(LS, "invalid pragma format", buff); | 218 | luaX_syntaxerror(LS, "invalid pragma format", buff); |
217 | ifskip(LS); | 219 | ifskip(L, LS); |
218 | } | 220 | } |
219 | } | 221 | } |
220 | 222 | ||
@@ -228,7 +230,7 @@ static void inclinenumber (LexState *LS) { | |||
228 | 230 | ||
229 | 231 | ||
230 | 232 | ||
231 | static int read_long_string (LexState *LS) { | 233 | static int read_long_string (lua_State *L, LexState *LS) { |
232 | int cont = 0; | 234 | int cont = 0; |
233 | for (;;) { | 235 | for (;;) { |
234 | switch (LS->current) { | 236 | switch (LS->current) { |
@@ -236,37 +238,38 @@ static int read_long_string (LexState *LS) { | |||
236 | luaX_error(LS, "unfinished long string"); | 238 | luaX_error(LS, "unfinished long string"); |
237 | return EOS; /* to avoid warnings */ | 239 | return EOS; /* to avoid warnings */ |
238 | case '[': | 240 | case '[': |
239 | save_and_next(LS); | 241 | save_and_next(L, LS); |
240 | if (LS->current == '[') { | 242 | if (LS->current == '[') { |
241 | cont++; | 243 | cont++; |
242 | save_and_next(LS); | 244 | save_and_next(L, LS); |
243 | } | 245 | } |
244 | continue; | 246 | continue; |
245 | case ']': | 247 | case ']': |
246 | save_and_next(LS); | 248 | save_and_next(L, LS); |
247 | if (LS->current == ']') { | 249 | if (LS->current == ']') { |
248 | if (cont == 0) goto endloop; | 250 | if (cont == 0) goto endloop; |
249 | cont--; | 251 | cont--; |
250 | save_and_next(LS); | 252 | save_and_next(L, LS); |
251 | } | 253 | } |
252 | continue; | 254 | continue; |
253 | case '\n': | 255 | case '\n': |
254 | save('\n'); | 256 | save(L, '\n'); |
255 | inclinenumber(LS); | 257 | inclinenumber(L, LS); |
256 | continue; | 258 | continue; |
257 | default: | 259 | default: |
258 | save_and_next(LS); | 260 | save_and_next(L, LS); |
259 | } | 261 | } |
260 | } endloop: | 262 | } endloop: |
261 | save_and_next(LS); /* skip the second ']' */ | 263 | save_and_next(L, LS); /* skip the second ']' */ |
262 | LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2), | 264 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), |
263 | L->Mbuffnext-L->Mbuffbase-4); | 265 | L->Mbuffnext-L->Mbuffbase-4); |
264 | return STRING; | 266 | return STRING; |
265 | } | 267 | } |
266 | 268 | ||
267 | 269 | ||
268 | int luaX_lex (LexState *LS) { | 270 | int luaX_lex (LexState *LS) { |
269 | luaL_resetbuffer(); | 271 | lua_State *L = LS->L; |
272 | luaL_resetbuffer(L); | ||
270 | for (;;) { | 273 | for (;;) { |
271 | switch (LS->current) { | 274 | switch (LS->current) { |
272 | 275 | ||
@@ -275,48 +278,48 @@ int luaX_lex (LexState *LS) { | |||
275 | continue; | 278 | continue; |
276 | 279 | ||
277 | case '\n': | 280 | case '\n': |
278 | inclinenumber(LS); | 281 | inclinenumber(L, LS); |
279 | continue; | 282 | continue; |
280 | 283 | ||
281 | case '-': | 284 | case '-': |
282 | save_and_next(LS); | 285 | save_and_next(L, LS); |
283 | if (LS->current != '-') return '-'; | 286 | if (LS->current != '-') return '-'; |
284 | do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); | 287 | do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); |
285 | luaL_resetbuffer(); | 288 | luaL_resetbuffer(L); |
286 | continue; | 289 | continue; |
287 | 290 | ||
288 | case '[': | 291 | case '[': |
289 | save_and_next(LS); | 292 | save_and_next(L, LS); |
290 | if (LS->current != '[') return '['; | 293 | if (LS->current != '[') return '['; |
291 | else { | 294 | else { |
292 | save_and_next(LS); /* pass the second '[' */ | 295 | save_and_next(L, LS); /* pass the second '[' */ |
293 | return read_long_string(LS); | 296 | return read_long_string(L, LS); |
294 | } | 297 | } |
295 | 298 | ||
296 | case '=': | 299 | case '=': |
297 | save_and_next(LS); | 300 | save_and_next(L, LS); |
298 | if (LS->current != '=') return '='; | 301 | if (LS->current != '=') return '='; |
299 | else { save_and_next(LS); return EQ; } | 302 | else { save_and_next(L, LS); return EQ; } |
300 | 303 | ||
301 | case '<': | 304 | case '<': |
302 | save_and_next(LS); | 305 | save_and_next(L, LS); |
303 | if (LS->current != '=') return '<'; | 306 | if (LS->current != '=') return '<'; |
304 | else { save_and_next(LS); return LE; } | 307 | else { save_and_next(L, LS); return LE; } |
305 | 308 | ||
306 | case '>': | 309 | case '>': |
307 | save_and_next(LS); | 310 | save_and_next(L, LS); |
308 | if (LS->current != '=') return '>'; | 311 | if (LS->current != '=') return '>'; |
309 | else { save_and_next(LS); return GE; } | 312 | else { save_and_next(L, LS); return GE; } |
310 | 313 | ||
311 | case '~': | 314 | case '~': |
312 | save_and_next(LS); | 315 | save_and_next(L, LS); |
313 | if (LS->current != '=') return '~'; | 316 | if (LS->current != '=') return '~'; |
314 | else { save_and_next(LS); return NE; } | 317 | else { save_and_next(L, LS); return NE; } |
315 | 318 | ||
316 | case '"': | 319 | case '"': |
317 | case '\'': { | 320 | case '\'': { |
318 | int del = LS->current; | 321 | int del = LS->current; |
319 | save_and_next(LS); | 322 | save_and_next(L, LS); |
320 | while (LS->current != del) { | 323 | while (LS->current != del) { |
321 | switch (LS->current) { | 324 | switch (LS->current) { |
322 | case EOZ: | 325 | case EOZ: |
@@ -326,14 +329,14 @@ int luaX_lex (LexState *LS) { | |||
326 | case '\\': | 329 | case '\\': |
327 | next(LS); /* do not save the '\' */ | 330 | next(LS); /* do not save the '\' */ |
328 | switch (LS->current) { | 331 | switch (LS->current) { |
329 | case 'a': save('\a'); next(LS); break; | 332 | case 'a': save(L, '\a'); next(LS); break; |
330 | case 'b': save('\b'); next(LS); break; | 333 | case 'b': save(L, '\b'); next(LS); break; |
331 | case 'f': save('\f'); next(LS); break; | 334 | case 'f': save(L, '\f'); next(LS); break; |
332 | case 'n': save('\n'); next(LS); break; | 335 | case 'n': save(L, '\n'); next(LS); break; |
333 | case 'r': save('\r'); next(LS); break; | 336 | case 'r': save(L, '\r'); next(LS); break; |
334 | case 't': save('\t'); next(LS); break; | 337 | case 't': save(L, '\t'); next(LS); break; |
335 | case 'v': save('\v'); next(LS); break; | 338 | case 'v': save(L, '\v'); next(LS); break; |
336 | case '\n': save('\n'); inclinenumber(LS); break; | 339 | case '\n': save(L, '\n'); inclinenumber(L, LS); break; |
337 | default : { | 340 | default : { |
338 | if (isdigit(LS->current)) { | 341 | if (isdigit(LS->current)) { |
339 | int c = 0; | 342 | int c = 0; |
@@ -344,10 +347,10 @@ int luaX_lex (LexState *LS) { | |||
344 | } while (++i<3 && isdigit(LS->current)); | 347 | } while (++i<3 && isdigit(LS->current)); |
345 | if (c != (unsigned char)c) | 348 | if (c != (unsigned char)c) |
346 | luaX_error(LS, "escape sequence too large"); | 349 | luaX_error(LS, "escape sequence too large"); |
347 | save(c); | 350 | save(L, c); |
348 | } | 351 | } |
349 | else { /* handles \, ", ', and ? */ | 352 | else { /* handles \, ", ', and ? */ |
350 | save(LS->current); | 353 | save(L, LS->current); |
351 | next(LS); | 354 | next(LS); |
352 | } | 355 | } |
353 | break; | 356 | break; |
@@ -355,23 +358,23 @@ int luaX_lex (LexState *LS) { | |||
355 | } | 358 | } |
356 | break; | 359 | break; |
357 | default: | 360 | default: |
358 | save_and_next(LS); | 361 | save_and_next(L, LS); |
359 | } | 362 | } |
360 | } | 363 | } |
361 | save_and_next(LS); /* skip delimiter */ | 364 | save_and_next(L, LS); /* skip delimiter */ |
362 | LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1), | 365 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), |
363 | L->Mbuffnext-L->Mbuffbase-2); | 366 | L->Mbuffnext-L->Mbuffbase-2); |
364 | return STRING; | 367 | return STRING; |
365 | } | 368 | } |
366 | 369 | ||
367 | case '.': | 370 | case '.': |
368 | save_and_next(LS); | 371 | save_and_next(L, LS); |
369 | if (LS->current == '.') | 372 | if (LS->current == '.') |
370 | { | 373 | { |
371 | save_and_next(LS); | 374 | save_and_next(L, LS); |
372 | if (LS->current == '.') | 375 | if (LS->current == '.') |
373 | { | 376 | { |
374 | save_and_next(LS); | 377 | save_and_next(L, LS); |
375 | return DOTS; /* ... */ | 378 | return DOTS; /* ... */ |
376 | } | 379 | } |
377 | else return CONC; /* .. */ | 380 | else return CONC; /* .. */ |
@@ -382,26 +385,26 @@ int luaX_lex (LexState *LS) { | |||
382 | case '0': case '1': case '2': case '3': case '4': | 385 | case '0': case '1': case '2': case '3': case '4': |
383 | case '5': case '6': case '7': case '8': case '9': | 386 | case '5': case '6': case '7': case '8': case '9': |
384 | do { | 387 | do { |
385 | save_and_next(LS); | 388 | save_and_next(L, LS); |
386 | } while (isdigit(LS->current)); | 389 | } while (isdigit(LS->current)); |
387 | if (LS->current == '.') { | 390 | if (LS->current == '.') { |
388 | save_and_next(LS); | 391 | save_and_next(L, LS); |
389 | if (LS->current == '.') { | 392 | if (LS->current == '.') { |
390 | save('.'); | 393 | save(L, '.'); |
391 | luaX_error(LS, | 394 | luaX_error(LS, |
392 | "ambiguous syntax (decimal point x string concatenation)"); | 395 | "ambiguous syntax (decimal point x string concatenation)"); |
393 | } | 396 | } |
394 | } | 397 | } |
395 | fraction: /* LUA_NUMBER */ | 398 | fraction: /* LUA_NUMBER */ |
396 | while (isdigit(LS->current)) | 399 | while (isdigit(LS->current)) |
397 | save_and_next(LS); | 400 | save_and_next(L, LS); |
398 | if (toupper(LS->current) == 'E') { | 401 | if (toupper(LS->current) == 'E') { |
399 | save_and_next(LS); /* read 'E' */ | 402 | save_and_next(L, LS); /* read 'E' */ |
400 | save_and_next(LS); /* read '+', '-' or first digit */ | 403 | save_and_next(L, LS); /* read '+', '-' or first digit */ |
401 | while (isdigit(LS->current)) | 404 | while (isdigit(LS->current)) |
402 | save_and_next(LS); | 405 | save_and_next(L, LS); |
403 | } | 406 | } |
404 | save('\0'); | 407 | save(L, '\0'); |
405 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) | 408 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) |
406 | luaX_error(LS, "invalid numeric format"); | 409 | luaX_error(LS, "invalid numeric format"); |
407 | return NUMBER; | 410 | return NUMBER; |
@@ -416,16 +419,16 @@ int luaX_lex (LexState *LS) { | |||
416 | int c = LS->current; | 419 | int c = LS->current; |
417 | if (iscntrl(c)) | 420 | if (iscntrl(c)) |
418 | luaX_invalidchar(LS, c); | 421 | luaX_invalidchar(LS, c); |
419 | save_and_next(LS); | 422 | save_and_next(L, LS); |
420 | return c; | 423 | return c; |
421 | } | 424 | } |
422 | else { /* identifier or reserved word */ | 425 | else { /* identifier or reserved word */ |
423 | TaggedString *ts; | 426 | TaggedString *ts; |
424 | do { | 427 | do { |
425 | save_and_next(LS); | 428 | save_and_next(L, LS); |
426 | } while (isalnum(LS->current) || LS->current == '_'); | 429 | } while (isalnum(LS->current) || LS->current == '_'); |
427 | save('\0'); | 430 | save(L, '\0'); |
428 | ts = luaS_new(L->Mbuffer+L->Mbuffbase); | 431 | ts = luaS_new(L, L->Mbuffer+L->Mbuffbase); |
429 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ | 432 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ |
430 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; | 433 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; |
431 | LS->seminfo.ts = ts; | 434 | LS->seminfo.ts = ts; |