aboutsummaryrefslogtreecommitdiff
path: root/llex.c
diff options
context:
space:
mode:
Diffstat (limited to 'llex.c')
-rw-r--r--llex.c138
1 files changed, 74 insertions, 64 deletions
diff --git a/llex.c b/llex.c
index d1301463..7a19eb7e 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.17 1998/03/09 17:22:49 roberto Exp roberto $ 2** $Id: llex.c,v 1.18 1998/03/20 14:18:18 roberto Exp roberto $
3** Lexical Analizer 3** Lexical Analizer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,7 +15,6 @@
15#include "lparser.h" 15#include "lparser.h"
16#include "lstate.h" 16#include "lstate.h"
17#include "lstring.h" 17#include "lstring.h"
18#include "lstx.h"
19#include "luadebug.h" 18#include "luadebug.h"
20#include "lzio.h" 19#include "lzio.h"
21 20
@@ -27,23 +26,53 @@ int lua_debug=0;
27#define next(LS) (LS->current = zgetc(LS->lex_z)) 26#define next(LS) (LS->current = zgetc(LS->lex_z))
28 27
29 28
30static struct { 29#define save(c) luaL_addchar(c)
31 char *name; 30#define save_and_next(LS) (save(LS->current), next(LS))
32 int token; 31
33} reserved [] = { 32
34 {"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF}, 33char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
35 {"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL}, 34 "if", "local", "nil", "not", "or", "repeat", "return", "then",
36 {"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT}, 35 "until", "while"};
37 {"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE} 36
38};
39 37
40void luaX_init (void) 38void luaX_init (void)
41{ 39{
42 int i; 40 int i;
43 for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { 41 for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
44 TaggedString *ts = luaS_new(reserved[i].name); 42 TaggedString *ts = luaS_new(reserved[i]);
45 ts->head.marked = reserved[i].token; /* reserved word (always > 255) */ 43 ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
44 }
45}
46
47
48void luaX_syntaxerror (LexState *ls, char *s, char *token) {
49 if (token[0] == 0)
50 token = "<eof>";
51 luaL_verror("%.100s;\n last token read: `%.50s' at line %d in file %.50s",
52 s, token, ls->linenumber, zname(ls->lex_z));
53}
54
55
56void luaX_error (LexState *ls, char *s) {
57 save(0);
58 luaX_syntaxerror(ls, s, luaL_buffer());
59}
60
61
62void luaX_token2str (LexState *ls, int token, char *s) {
63 if (token < 255) {
64 s[0] = token;
65 s[1] = 0;
46 } 66 }
67 else
68 strcpy(s, reserved[token-FIRST_RESERVED]);
69}
70
71
72static void luaX_invalidchar (LexState *ls, int c) {
73 char buff[10];
74 sprintf(buff, "0x%X", c);
75 luaX_syntaxerror(ls, "invalid control char", buff);
47} 76}
48 77
49 78
@@ -56,16 +85,15 @@ static void firstline (LexState *LS)
56} 85}
57 86
58 87
59void luaX_setinput (ZIO *z) 88void luaX_setinput (LexState *LS, ZIO *z)
60{ 89{
61 LexState *LS = L->lexstate;
62 LS->current = '\n'; 90 LS->current = '\n';
63 LS->linelasttoken = 0;
64 LS->linenumber = 0; 91 LS->linenumber = 0;
65 LS->iflevel = 0; 92 LS->iflevel = 0;
66 LS->ifstate[0].skip = 0; 93 LS->ifstate[0].skip = 0;
67 LS->ifstate[0].elsepart = 1; /* to avoid a free $else */ 94 LS->ifstate[0].elsepart = 1; /* to avoid a free $else */
68 LS->lex_z = z; 95 LS->lex_z = z;
96 LS->fs = NULL;
69 firstline(LS); 97 firstline(LS);
70 luaL_resetbuffer(); 98 luaL_resetbuffer();
71} 99}
@@ -87,7 +115,7 @@ static void skipspace (LexState *LS)
87} 115}
88 116
89 117
90static int checkcond (char *buff) 118static int checkcond (LexState *LS, char *buff)
91{ 119{
92 static char *opts[] = {"nil", "1", NULL}; 120 static char *opts[] = {"nil", "1", NULL};
93 int i = luaO_findstring(buff, opts); 121 int i = luaO_findstring(buff, opts);
@@ -95,7 +123,7 @@ static int checkcond (char *buff)
95 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') 123 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
96 return luaS_globaldefined(buff); 124 return luaS_globaldefined(buff);
97 else { 125 else {
98 luaY_syntaxerror("invalid $if condition", buff); 126 luaX_syntaxerror(LS, "invalid $if condition", buff);
99 return 0; /* to avoid warnings */ 127 return 0; /* to avoid warnings */
100 } 128 }
101} 129}
@@ -108,7 +136,7 @@ static void readname (LexState *LS, char *buff)
108 while (isalnum(LS->current) || LS->current == '_') { 136 while (isalnum(LS->current) || LS->current == '_') {
109 if (i >= PRAGMASIZE) { 137 if (i >= PRAGMASIZE) {
110 buff[PRAGMASIZE] = 0; 138 buff[PRAGMASIZE] = 0;
111 luaY_syntaxerror("pragma too long", buff); 139 luaX_syntaxerror(LS, "pragma too long", buff);
112 } 140 }
113 buff[i++] = LS->current; 141 buff[i++] = LS->current;
114 next(LS); 142 next(LS);
@@ -126,7 +154,7 @@ static void ifskip (LexState *LS)
126 if (LS->current == '\n') 154 if (LS->current == '\n')
127 inclinenumber(LS); 155 inclinenumber(LS);
128 else if (LS->current == EOZ) 156 else if (LS->current == EOZ)
129 luaY_error("input ends inside a $if"); 157 luaX_error(LS, "input ends inside a $if");
130 else next(LS); 158 else next(LS);
131 } 159 }
132} 160}
@@ -159,35 +187,35 @@ static void inclinenumber (LexState *LS)
159 break; 187 break;
160 case 3: /* end */ 188 case 3: /* end */
161 if (LS->iflevel-- == 0) 189 if (LS->iflevel-- == 0)
162 luaY_syntaxerror("unmatched $end", "$end"); 190 luaX_syntaxerror(LS, "unmatched $end", "$end");
163 break; 191 break;
164 case 4: /* ifnot */ 192 case 4: /* ifnot */
165 ifnot = 1; 193 ifnot = 1;
166 /* go through */ 194 /* go through */
167 case 5: /* if */ 195 case 5: /* if */
168 if (LS->iflevel == MAX_IFS-1) 196 if (LS->iflevel == MAX_IFS-1)
169 luaY_syntaxerror("too many nested $ifs", "$if"); 197 luaX_syntaxerror(LS, "too many nested $ifs", "$if");
170 readname(LS, buff); 198 readname(LS, buff);
171 LS->iflevel++; 199 LS->iflevel++;
172 LS->ifstate[LS->iflevel].elsepart = 0; 200 LS->ifstate[LS->iflevel].elsepart = 0;
173 LS->ifstate[LS->iflevel].condition = checkcond(buff) ? !ifnot : ifnot; 201 LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot;
174 LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; 202 LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition;
175 break; 203 break;
176 case 6: /* else */ 204 case 6: /* else */
177 if (LS->ifstate[LS->iflevel].elsepart) 205 if (LS->ifstate[LS->iflevel].elsepart)
178 luaY_syntaxerror("unmatched $else", "$else"); 206 luaX_syntaxerror(LS, "unmatched $else", "$else");
179 LS->ifstate[LS->iflevel].elsepart = 1; 207 LS->ifstate[LS->iflevel].elsepart = 1;
180 LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip || 208 LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip ||
181 LS->ifstate[LS->iflevel].condition; 209 LS->ifstate[LS->iflevel].condition;
182 break; 210 break;
183 default: 211 default:
184 luaY_syntaxerror("unknown pragma", buff); 212 luaX_syntaxerror(LS, "unknown pragma", buff);
185 } 213 }
186 skipspace(LS); 214 skipspace(LS);
187 if (LS->current == '\n') /* pragma must end with a '\n' ... */ 215 if (LS->current == '\n') /* pragma must end with a '\n' ... */
188 inclinenumber(LS); 216 inclinenumber(LS);
189 else if (LS->current != EOZ) /* or eof */ 217 else if (LS->current != EOZ) /* or eof */
190 luaY_syntaxerror("invalid pragma format", buff); 218 luaX_syntaxerror(LS, "invalid pragma format", buff);
191 ifskip(LS); 219 ifskip(LS);
192 } 220 }
193} 221}
@@ -201,25 +229,16 @@ static void inclinenumber (LexState *LS)
201 229
202 230
203 231
204#define save(c) luaL_addchar(c)
205#define save_and_next(LS) (save(LS->current), next(LS))
206
207
208char *luaX_lasttoken (void)
209{
210 save(0);
211 return luaL_buffer();
212}
213 232
214 233
215static int read_long_string (LexState *LS, YYSTYPE *l) 234static int read_long_string (LexState *LS)
216{ 235{
217 int cont = 0; 236 int cont = 0;
218 while (1) { 237 while (1) {
219 switch (LS->current) { 238 switch (LS->current) {
220 case EOZ: 239 case EOZ:
221 luaY_error("unfinished long string"); 240 luaX_error(LS, "unfinished long string");
222 return 0; /* to avoid warnings */ 241 return EOS; /* to avoid warnings */
223 case '[': 242 case '[':
224 save_and_next(LS); 243 save_and_next(LS);
225 if (LS->current == '[') { 244 if (LS->current == '[') {
@@ -244,25 +263,15 @@ static int read_long_string (LexState *LS, YYSTYPE *l)
244 } 263 }
245 } endloop: 264 } endloop:
246 save_and_next(LS); /* pass the second ']' */ 265 save_and_next(LS); /* pass the second ']' */
247 l->pTStr = luaS_newlstr(L->Mbuffbase+2, 266 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
248 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4); 267 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
249 return STRING; 268 return STRING;
250} 269}
251 270
252 271
253/* to avoid warnings; this declaration cannot be public since YYSTYPE 272int luaX_lex (LexState *LS) {
254** cannot be visible in llex.h (otherwise there is an error, since
255** the parser body redefines it!)
256*/
257int luaY_lex (YYSTYPE *l);
258int luaY_lex (YYSTYPE *l)
259{
260 LexState *LS = L->lexstate;
261 double a; 273 double a;
262 luaL_resetbuffer(); 274 luaL_resetbuffer();
263 if (lua_debug)
264 luaY_codedebugline(LS->linelasttoken);
265 LS->linelasttoken = LS->linenumber;
266 while (1) { 275 while (1) {
267 switch (LS->current) { 276 switch (LS->current) {
268 277
@@ -272,7 +281,6 @@ int luaY_lex (YYSTYPE *l)
272 281
273 case '\n': 282 case '\n':
274 inclinenumber(LS); 283 inclinenumber(LS);
275 LS->linelasttoken = LS->linenumber;
276 continue; 284 continue;
277 285
278 case '-': 286 case '-':
@@ -287,7 +295,7 @@ int luaY_lex (YYSTYPE *l)
287 if (LS->current != '[') return '['; 295 if (LS->current != '[') return '[';
288 else { 296 else {
289 save_and_next(LS); /* pass the second '[' */ 297 save_and_next(LS); /* pass the second '[' */
290 return read_long_string(LS, l); 298 return read_long_string(LS);
291 } 299 }
292 300
293 case '=': 301 case '=':
@@ -318,8 +326,8 @@ int luaY_lex (YYSTYPE *l)
318 switch (LS->current) { 326 switch (LS->current) {
319 case EOZ: 327 case EOZ:
320 case '\n': 328 case '\n':
321 luaY_error("unfinished string"); 329 luaX_error(LS, "unfinished string");
322 return 0; /* to avoid warnings */ 330 return EOS; /* to avoid warnings */
323 case '\\': 331 case '\\':
324 next(LS); /* do not save the '\' */ 332 next(LS); /* do not save the '\' */
325 switch (LS->current) { 333 switch (LS->current) {
@@ -345,13 +353,13 @@ int luaY_lex (YYSTYPE *l)
345 next(LS); 353 next(LS);
346 } while (++i<3 && isdigit(LS->current)); 354 } while (++i<3 && isdigit(LS->current));
347 if (c >= 256) 355 if (c >= 256)
348 luaY_error("escape sequence too large"); 356 luaX_error(LS, "escape sequence too large");
349 save(c); 357 save(c);
350 } 358 }
351 else { 359 else {
352 save('\\'); 360 save('\\');
353 save(LS->current); 361 save(LS->current);
354 luaY_error("invalid escape sequence"); 362 luaX_error(LS, "invalid escape sequence");
355 } 363 }
356 break; 364 break;
357 } 365 }
@@ -362,7 +370,7 @@ int luaY_lex (YYSTYPE *l)
362 } 370 }
363 } 371 }
364 save_and_next(LS); /* skip delimiter */ 372 save_and_next(LS); /* skip delimiter */
365 l->pTStr = luaS_newlstr(L->Mbuffbase+1, 373 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1,
366 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2); 374 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2);
367 return STRING; 375 return STRING;
368 } 376 }
@@ -395,7 +403,7 @@ int luaY_lex (YYSTYPE *l)
395 save_and_next(LS); 403 save_and_next(LS);
396 if (LS->current == '.') { 404 if (LS->current == '.') {
397 save('.'); 405 save('.');
398 luaY_error( 406 luaX_error(LS,
399 "ambiguous syntax (decimal point x string concatenation)"); 407 "ambiguous syntax (decimal point x string concatenation)");
400 } 408 }
401 } 409 }
@@ -415,7 +423,7 @@ int luaY_lex (YYSTYPE *l)
415 neg = (LS->current=='-'); 423 neg = (LS->current=='-');
416 if (LS->current == '+' || LS->current == '-') save_and_next(LS); 424 if (LS->current == '+' || LS->current == '-') save_and_next(LS);
417 if (!isdigit(LS->current)) 425 if (!isdigit(LS->current))
418 luaY_error("invalid numeral format"); 426 luaX_error(LS, "invalid numeral format");
419 do { 427 do {
420 e = 10.0*e + (LS->current-'0'); 428 e = 10.0*e + (LS->current-'0');
421 save_and_next(LS); 429 save_and_next(LS);
@@ -426,18 +434,20 @@ int luaY_lex (YYSTYPE *l)
426 ea *= ea; 434 ea *= ea;
427 } 435 }
428 } 436 }
429 l->vReal = a; 437 LS->seminfo.r = a;
430 return NUMBER; 438 return NUMBER;
431 } 439 }
432 440
433 case EOZ: 441 case EOZ:
434 if (LS->iflevel > 0) 442 if (LS->iflevel > 0)
435 luaY_error("input ends inside a $if"); 443 luaX_error(LS, "input ends inside a $if");
436 return 0; 444 return EOS;
437 445
438 default: 446 default:
439 if (LS->current != '_' && !isalpha(LS->current)) { 447 if (LS->current != '_' && !isalpha(LS->current)) {
440 int c = LS->current; 448 int c = LS->current;
449 if (iscntrl(c))
450 luaX_invalidchar(LS, c);
441 save_and_next(LS); 451 save_and_next(LS);
442 return c; 452 return c;
443 } 453 }
@@ -448,9 +458,9 @@ int luaY_lex (YYSTYPE *l)
448 } while (isalnum(LS->current) || LS->current == '_'); 458 } while (isalnum(LS->current) || LS->current == '_');
449 save(0); 459 save(0);
450 ts = luaS_new(L->Mbuffbase); 460 ts = luaS_new(L->Mbuffbase);
451 if (ts->head.marked > 255) 461 if (ts->head.marked >= 'A')
452 return ts->head.marked; /* reserved word */ 462 return ts->head.marked; /* reserved word */
453 l->pTStr = ts; 463 LS->seminfo.ts = ts;
454 return NAME; 464 return NAME;
455 } 465 }
456 } 466 }