aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
commitd83c2a84550221c30a48647fde9c433c65af1802 (patch)
treeea525b29eaabb7cacd54bf7d42ab9e57533e4b5a
parentd11e5adf55b11a446671775a6c7803e066fc94e8 (diff)
downloadlua-d83c2a84550221c30a48647fde9c433c65af1802.tar.gz
lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.bz2
lua-d83c2a84550221c30a48647fde9c433c65af1802.zip
performance details.
-rw-r--r--llex.c171
-rw-r--r--llex.h4
-rw-r--r--lobject.c17
-rw-r--r--lparser.c87
4 files changed, 146 insertions, 133 deletions
diff --git a/llex.c b/llex.c
index 49f22860..cd67103e 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.47 1999/12/22 16:58:36 roberto Exp roberto $ 2** $Id: llex.c,v 1.48 1999/12/30 12:40:29 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*/
@@ -33,7 +33,7 @@
33/* ORDER RESERVED */ 33/* ORDER RESERVED */
34static const char *const reserved [] = {"and", "do", "else", "elseif", "end", 34static const char *const reserved [] = {"and", "do", "else", "elseif", "end",
35 "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", 35 "function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
36 "until", "while"}; 36 "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", ""};
37 37
38 38
39void luaX_init (lua_State *L) { 39void luaX_init (lua_State *L) {
@@ -57,9 +57,15 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
57} 57}
58 58
59 59
60void luaX_error (LexState *ls, const char *s) { 60void luaX_error (LexState *ls, const char *s, int token) {
61 save(ls->L, '\0'); 61 char buff[TOKEN_LEN];
62 luaX_syntaxerror(ls, s, luaL_buffer(ls->L)); 62 luaX_token2str(token, buff);
63 if (buff[0] == '\0') {
64 save(ls->L, '\0');
65 luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
66 }
67 else
68 luaX_syntaxerror(ls, s, buff);
63} 69}
64 70
65 71
@@ -156,7 +162,7 @@ static void ifskip (lua_State *L, LexState *LS) {
156 if (LS->current == '\n') 162 if (LS->current == '\n')
157 inclinenumber(L, LS); 163 inclinenumber(L, LS);
158 else if (LS->current == EOZ) 164 else if (LS->current == EOZ)
159 luaX_error(LS, "input ends inside a $if"); 165 luaX_error(LS, "input ends inside a $if", EOS);
160 else next(LS); 166 else next(LS);
161 } 167 }
162} 168}
@@ -231,13 +237,13 @@ static void inclinenumber (lua_State *L, LexState *LS) {
231 237
232 238
233 239
234static int read_long_string (lua_State *L, LexState *LS) { 240static void read_long_string (lua_State *L, LexState *LS) {
235 int cont = 0; 241 int cont = 0;
236 for (;;) { 242 for (;;) {
237 switch (LS->current) { 243 switch (LS->current) {
238 case EOZ: 244 case EOZ:
239 luaX_error(LS, "unfinished long string"); 245 luaX_error(LS, "unfinished long string", STRING);
240 return EOS; /* to avoid warnings */ 246 break; /* to avoid warnings */
241 case '[': 247 case '[':
242 save_and_next(L, LS); 248 save_and_next(L, LS);
243 if (LS->current == '[') { 249 if (LS->current == '[') {
@@ -264,7 +270,52 @@ static int read_long_string (lua_State *L, LexState *LS) {
264 save_and_next(L, LS); /* skip the second ']' */ 270 save_and_next(L, LS); /* skip the second ']' */
265 LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), 271 LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2),
266 L->Mbuffnext-L->Mbuffbase-4); 272 L->Mbuffnext-L->Mbuffbase-4);
267 return STRING; 273}
274
275
276static void read_string (lua_State *L, LexState *LS, int del) {
277 save_and_next(L, LS);
278 while (LS->current != del) {
279 switch (LS->current) {
280 case EOZ: case '\n':
281 luaX_error(LS, "unfinished string", STRING);
282 break; /* to avoid warnings */
283 case '\\':
284 next(LS); /* do not save the '\' */
285 switch (LS->current) {
286 case 'a': save(L, '\a'); next(LS); break;
287 case 'b': save(L, '\b'); next(LS); break;
288 case 'f': save(L, '\f'); next(LS); break;
289 case 'n': save(L, '\n'); next(LS); break;
290 case 'r': save(L, '\r'); next(LS); break;
291 case 't': save(L, '\t'); next(LS); break;
292 case 'v': save(L, '\v'); next(LS); break;
293 case '\n': save(L, '\n'); inclinenumber(L, LS); break;
294 case '0': case '1': case '2': case '3': case '4':
295 case '5': case '6': case '7': case '8': case '9': {
296 int c = 0;
297 int i = 0;
298 do {
299 c = 10*c + (LS->current-'0');
300 next(LS);
301 } while (++i<3 && isdigit(LS->current));
302 if (c != (unsigned char)c)
303 luaX_error(LS, "escape sequence too large", STRING);
304 save(L, c);
305 break;
306 }
307 default: /* handles \\, \", \', and \? */
308 save(L, LS->current);
309 next(LS);
310 }
311 break;
312 default:
313 save_and_next(L, LS);
314 }
315 }
316 save_and_next(L, LS); /* skip delimiter */
317 LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
318 L->Mbuffnext-L->Mbuffbase-2);
268} 319}
269 320
270 321
@@ -283,10 +334,9 @@ int luaX_lex (LexState *LS) {
283 continue; 334 continue;
284 335
285 case '-': 336 case '-':
286 save_and_next(L, LS); 337 next(LS);
287 if (LS->current != '-') return '-'; 338 if (LS->current != '-') return '-';
288 do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); 339 do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
289 luaL_resetbuffer(L);
290 continue; 340 continue;
291 341
292 case '[': 342 case '[':
@@ -294,88 +344,41 @@ int luaX_lex (LexState *LS) {
294 if (LS->current != '[') return '['; 344 if (LS->current != '[') return '[';
295 else { 345 else {
296 save_and_next(L, LS); /* pass the second '[' */ 346 save_and_next(L, LS); /* pass the second '[' */
297 return read_long_string(L, LS); 347 read_long_string(L, LS);
348 return STRING;
298 } 349 }
299 350
300 case '=': 351 case '=':
301 save_and_next(L, LS); 352 next(LS);
302 if (LS->current != '=') return '='; 353 if (LS->current != '=') return '=';
303 else { save_and_next(L, LS); return EQ; } 354 else { next(LS); return EQ; }
304 355
305 case '<': 356 case '<':
306 save_and_next(L, LS); 357 next(LS);
307 if (LS->current != '=') return '<'; 358 if (LS->current != '=') return '<';
308 else { save_and_next(L, LS); return LE; } 359 else { next(LS); return LE; }
309 360
310 case '>': 361 case '>':
311 save_and_next(L, LS); 362 next(LS);
312 if (LS->current != '=') return '>'; 363 if (LS->current != '=') return '>';
313 else { save_and_next(L, LS); return GE; } 364 else { next(LS); return GE; }
314 365
315 case '~': 366 case '~':
316 save_and_next(L, LS); 367 next(LS);
317 if (LS->current != '=') return '~'; 368 if (LS->current != '=') return '~';
318 else { save_and_next(L, LS); return NE; } 369 else { next(LS); return NE; }
319 370
320 case '"': 371 case '"':
321 case '\'': { 372 case '\'':
322 int del = LS->current; 373 read_string(L, LS, LS->current);
323 save_and_next(L, LS);
324 while (LS->current != del) {
325 switch (LS->current) {
326 case EOZ:
327 case '\n':
328 luaX_error(LS, "unfinished string");
329 return EOS; /* to avoid warnings */
330 case '\\':
331 next(LS); /* do not save the '\' */
332 switch (LS->current) {
333 case 'a': save(L, '\a'); next(LS); break;
334 case 'b': save(L, '\b'); next(LS); break;
335 case 'f': save(L, '\f'); next(LS); break;
336 case 'n': save(L, '\n'); next(LS); break;
337 case 'r': save(L, '\r'); next(LS); break;
338 case 't': save(L, '\t'); next(LS); break;
339 case 'v': save(L, '\v'); next(LS); break;
340 case '\n': save(L, '\n'); inclinenumber(L, LS); break;
341 default : {
342 if (isdigit(LS->current)) {
343 int c = 0;
344 int i = 0;
345 do {
346 c = 10*c + (LS->current-'0');
347 next(LS);
348 } while (++i<3 && isdigit(LS->current));
349 if (c != (unsigned char)c)
350 luaX_error(LS, "escape sequence too large");
351 save(L, c);
352 }
353 else { /* handles \, ", ', and ? */
354 save(L, LS->current);
355 next(LS);
356 }
357 break;
358 }
359 }
360 break;
361 default:
362 save_and_next(L, LS);
363 }
364 }
365 save_and_next(L, LS); /* skip delimiter */
366 LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
367 L->Mbuffnext-L->Mbuffbase-2);
368 return STRING; 374 return STRING;
369 }
370 375
371 case '.': 376 case '.':
372 save_and_next(L, LS); 377 save_and_next(L, LS);
373 if (LS->current == '.') 378 if (LS->current == '.') {
374 { 379 next(LS);
375 save_and_next(L, LS); 380 if (LS->current == '.') {
376 if (LS->current == '.') 381 next(LS);
377 {
378 save_and_next(L, LS);
379 return DOTS; /* ... */ 382 return DOTS; /* ... */
380 } 383 }
381 else return CONC; /* .. */ 384 else return CONC; /* .. */
@@ -392,14 +395,14 @@ int luaX_lex (LexState *LS) {
392 save_and_next(L, LS); 395 save_and_next(L, LS);
393 if (LS->current == '.') { 396 if (LS->current == '.') {
394 save(L, '.'); 397 save(L, '.');
395 luaX_error(LS, 398 luaX_error(LS, "ambiguous syntax"
396 "ambiguous syntax (decimal point x string concatenation)"); 399 " (decimal point x string concatenation)", NUMBER);
397 } 400 }
398 } 401 }
399 fraction: /* LUA_NUMBER */ 402 fraction: /* LUA_NUMBER */
400 while (isdigit(LS->current)) 403 while (isdigit(LS->current))
401 save_and_next(L, LS); 404 save_and_next(L, LS);
402 if (toupper(LS->current) == 'E') { 405 if (LS->current == 'e' || LS->current == 'E') {
403 save_and_next(L, LS); /* read 'E' */ 406 save_and_next(L, LS); /* read 'E' */
404 if (LS->current == '+' || LS->current == '-') 407 if (LS->current == '+' || LS->current == '-')
405 save_and_next(L, LS); /* optional exponent sign */ 408 save_and_next(L, LS); /* optional exponent sign */
@@ -408,23 +411,25 @@ int luaX_lex (LexState *LS) {
408 } 411 }
409 save(L, '\0'); 412 save(L, '\0');
410 if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) 413 if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r))
411 luaX_error(LS, "malformed number"); 414 luaX_error(LS, "malformed number", NUMBER);
412 return NUMBER; 415 return NUMBER;
413 416
414 case EOZ: 417 case EOZ:
415 if (LS->iflevel > 0) 418 if (LS->iflevel > 0)
416 luaX_error(LS, "input ends inside a $if"); 419 luaX_error(LS, "input ends inside a $if", EOS);
417 return EOS; 420 return EOS;
418 421
422 case '_': goto tname;
423
419 default: 424 default:
420 if (LS->current != '_' && !isalpha(LS->current)) { 425 if (!isalpha(LS->current)) {
421 int c = LS->current; 426 int c = LS->current;
422 if (iscntrl(c)) 427 if (iscntrl(c))
423 luaX_invalidchar(LS, c); 428 luaX_invalidchar(LS, c);
424 save_and_next(L, LS); 429 next(LS);
425 return c; 430 return c;
426 } 431 }
427 else { /* identifier or reserved word */ 432 tname: { /* identifier or reserved word */
428 TaggedString *ts; 433 TaggedString *ts;
429 do { 434 do {
430 save_and_next(L, LS); 435 save_and_next(L, LS);
diff --git a/llex.h b/llex.h
index ffa53aa5..918b4125 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.15 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: llex.h,v 1.16 1999/12/27 17:33:22 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*/
@@ -63,7 +63,7 @@ void luaX_init (lua_State *L);
63void luaX_setinput (lua_State *L, LexState *LS, ZIO *z); 63void luaX_setinput (lua_State *L, LexState *LS, ZIO *z);
64int luaX_lex (LexState *LS); 64int luaX_lex (LexState *LS);
65void luaX_syntaxerror (LexState *ls, const char *s, const char *token); 65void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
66void luaX_error (LexState *ls, const char *s); 66void luaX_error (LexState *ls, const char *s, int token);
67void luaX_token2str (int token, char *s); 67void luaX_token2str (int token, char *s);
68 68
69 69
diff --git a/lobject.c b/lobject.c
index 6aa92d0a..d89e2211 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 1.28 1999/12/23 18:19:57 roberto Exp roberto $ 2** $Id: lobject.c,v 1.29 1999/12/30 18:28:40 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -87,9 +87,9 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */
87 int point = 0; /* number of decimal digits */ 87 int point = 0; /* number of decimal digits */
88 int sig; 88 int sig;
89 while (isspace((unsigned char)*s)) s++; 89 while (isspace((unsigned char)*s)) s++;
90 sig = 1; 90 sig = 0;
91 switch (*s) { 91 switch (*s) {
92 case '-': sig = -1; /* go through */ 92 case '-': sig = 1; /* go through */
93 case '+': s++; 93 case '+': s++;
94 } 94 }
95 if (! (isdigit((unsigned char)*s) || 95 if (! (isdigit((unsigned char)*s) ||
@@ -104,20 +104,21 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */
104 point++; 104 point++;
105 } 105 }
106 } 106 }
107 a *= sig; 107 if (sig) a = -a;
108 if (toupper((unsigned char)*s) == 'E') { 108 if (*s == 'e' || *s == 'E') {
109 int e = 0; 109 int e = 0;
110 s++; 110 s++;
111 sig = 1; 111 sig = 0;
112 switch (*s) { 112 switch (*s) {
113 case '-': sig = -1; /* go through */ 113 case '-': sig = 1; /* go through */
114 case '+': s++; 114 case '+': s++;
115 } 115 }
116 if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */ 116 if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */
117 do { 117 do {
118 e = 10*e + (*(s++)-'0'); 118 e = 10*e + (*(s++)-'0');
119 } while (isdigit((unsigned char)*s)); 119 } while (isdigit((unsigned char)*s));
120 point -= sig*e; 120 if (sig) e = -e;
121 point -= e;
121 } 122 }
122 while (isspace((unsigned char)*s)) s++; 123 while (isspace((unsigned char)*s)) s++;
123 if (*s != '\0') return 0; /* invalid trailing characters? */ 124 if (*s != '\0') return 0; /* invalid trailing characters? */
diff --git a/lparser.c b/lparser.c
index 664795c6..ec655a99 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.54 2000/01/12 16:24:39 roberto Exp roberto $ 2** $Id: lparser.c,v 1.55 2000/01/25 13:57:18 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -119,11 +119,16 @@ static void exp1 (LexState *ls);
119 119
120 120
121 121
122static void luaY_error (LexState *ls, const char *msg) {
123 luaX_error(ls, msg, ls->token);
124}
125
126
122static void checklimit (LexState *ls, int val, int limit, const char *msg) { 127static void checklimit (LexState *ls, int val, int limit, const char *msg) {
123 if (val > limit) { 128 if (val > limit) {
124 char buff[100]; 129 char buff[100];
125 sprintf(buff, "too many %.50s (limit=%d)", msg, limit); 130 sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
126 luaX_error(ls, buff); 131 luaY_error(ls, buff);
127 } 132 }
128} 133}
129 134
@@ -145,7 +150,7 @@ static void deltastack (LexState *ls, int delta) {
145 fs->stacksize += delta; 150 fs->stacksize += delta;
146 if (fs->stacksize > fs->maxstacksize) { 151 if (fs->stacksize > fs->maxstacksize) {
147 if (fs->stacksize > MAX_BYTE) 152 if (fs->stacksize > MAX_BYTE)
148 luaX_error(ls, "function/expression too complex"); 153 luaY_error(ls, "function/expression too complex");
149 fs->maxstacksize = fs->stacksize; 154 fs->maxstacksize = fs->stacksize;
150 } 155 }
151} 156}
@@ -160,7 +165,7 @@ static void code_oparg_at (LexState *ls, int pc, OpCode op,
160 code[pc+1] = (Byte)arg; 165 code[pc+1] = (Byte)arg;
161 } 166 }
162 else if (arg > MAX_ARG) 167 else if (arg > MAX_ARG)
163 luaX_error(ls, "code too long"); 168 luaY_error(ls, "code too long");
164 else { /* MAX_BYTE < arg < MAX_ARG */ 169 else { /* MAX_BYTE < arg < MAX_ARG */
165 if (arg > MAX_WORD) { 170 if (arg > MAX_WORD) {
166 code[pc] = (Byte)LONGARG; 171 code[pc] = (Byte)LONGARG;
@@ -599,20 +604,6 @@ static void close_func (LexState *ls) {
599} 604}
600 605
601 606
602
603static const int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT,
604 DO, NAME, LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';',
605 EOS, ',', 0};
606
607
608static int is_in (int tok, const int *toks) {
609 const int *t;
610 for (t=toks; *t; t++)
611 if (*t == tok) return t-toks;
612 return -1;
613}
614
615
616static void next (LexState *ls) { 607static void next (LexState *ls) {
617 ls->token = luaX_lex(ls); 608 ls->token = luaX_lex(ls);
618} 609}
@@ -622,12 +613,12 @@ static void error_expected (LexState *ls, int token) {
622 char buff[100], t[TOKEN_LEN]; 613 char buff[100], t[TOKEN_LEN];
623 luaX_token2str(token, t); 614 luaX_token2str(token, t);
624 sprintf(buff, "`%.20s' expected", t); 615 sprintf(buff, "`%.20s' expected", t);
625 luaX_error(ls, buff); 616 luaY_error(ls, buff);
626} 617}
627 618
628 619
629static void error_unexpected (LexState *ls) { 620static void error_unexpected (LexState *ls) {
630 luaX_error(ls, "unexpected token"); 621 luaY_error(ls, "unexpected token");
631} 622}
632 623
633 624
@@ -641,7 +632,7 @@ static void error_unmatched (LexState *ls, int what, int who, int where) {
641 luaX_token2str(who, t_who); 632 luaX_token2str(who, t_who);
642 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", 633 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
643 t_what, t_who, where); 634 t_what, t_who, where);
644 luaX_error(ls, buff); 635 luaY_error(ls, buff);
645 } 636 }
646} 637}
647 638
@@ -661,7 +652,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
661static int checkname (LexState *ls) { 652static int checkname (LexState *ls) {
662 int sc; 653 int sc;
663 if (ls->token != NAME) 654 if (ls->token != NAME)
664 luaX_error(ls, "<name> expected"); 655 luaY_error(ls, "<name> expected");
665 sc = string_constant(ls, ls->fs, ls->seminfo.ts); 656 sc = string_constant(ls, ls->fs, ls->seminfo.ts);
666 next(ls); 657 next(ls);
667 return sc; 658 return sc;
@@ -691,7 +682,7 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
691 next(&lexstate); /* read first token */ 682 next(&lexstate); /* read first token */
692 chunk(&lexstate); 683 chunk(&lexstate);
693 if (lexstate.token != EOS) 684 if (lexstate.token != EOS)
694 luaX_error(&lexstate, "<eof> expected"); 685 luaY_error(&lexstate, "<eof> expected");
695 close_func(&lexstate); 686 close_func(&lexstate);
696 return funcstate.f; 687 return funcstate.f;
697} 688}
@@ -782,7 +773,7 @@ static int funcparams (LexState *ls, int slf, vardesc *v) {
782 break; 773 break;
783 774
784 default: 775 default:
785 luaX_error(ls, "function arguments expected"); 776 luaY_error(ls, "function arguments expected");
786 break; 777 break;
787 } 778 }
788 code_setname(ls, v); 779 code_setname(ls, v);
@@ -871,7 +862,7 @@ static void recfield (LexState *ls) {
871 check(ls, ']'); 862 check(ls, ']');
872 break; 863 break;
873 864
874 default: luaX_error(ls, "<name> or `[' expected"); 865 default: luaY_error(ls, "<name> or `[' expected");
875 } 866 }
876 check(ls, '='); 867 check(ls, '=');
877 exp1(ls); 868 exp1(ls);
@@ -977,7 +968,7 @@ static void constructor (LexState *ls) {
977 next(ls); 968 next(ls);
978 constructor_part(ls, &other_cd); 969 constructor_part(ls, &other_cd);
979 if (cd.k == other_cd.k) /* repeated parts? */ 970 if (cd.k == other_cd.k) /* repeated parts? */
980 luaX_error(ls, "invalid constructor syntax"); 971 luaY_error(ls, "invalid constructor syntax");
981 nelems += other_cd.n; 972 nelems += other_cd.n;
982 } 973 }
983 check_match(ls, '}', '{', line); 974 check_match(ls, '}', '{', line);
@@ -992,8 +983,8 @@ static void constructor (LexState *ls) {
992/* 983/*
993** {====================================================================== 984** {======================================================================
994** For parsing expressions, we use a classic stack with priorities. 985** For parsing expressions, we use a classic stack with priorities.
995** Each binary operator is represented by its index in `binop' + FIRSTBIN 986** Each binary operator is represented by an index: EQ=2, NE=3, ... '^'=13.
996** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. 987** The unary NOT is 0 and UNMINUS is 1.
997** ======================================================================= 988** =======================================================================
998*/ 989*/
999 990
@@ -1008,8 +999,6 @@ static void constructor (LexState *ls) {
1008*/ 999*/
1009#define POW 13 1000#define POW 13
1010 1001
1011static const int binop [] = {EQ, NE, '>', '<', LE, GE, CONC,
1012 '+', '-', '*', '/', '^', 0};
1013 1002
1014static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; 1003static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
1015 1004
@@ -1024,10 +1013,31 @@ typedef struct stack_op {
1024} stack_op; 1013} stack_op;
1025 1014
1026 1015
1016/*
1017** returns the index of a binary operator
1018*/
1019static int binop (int op) {
1020 switch (op) {
1021 case EQ: return FIRSTBIN;
1022 case NE: return FIRSTBIN+1;
1023 case '>': return FIRSTBIN+2;
1024 case '<': return FIRSTBIN+3;
1025 case LE: return FIRSTBIN+4;
1026 case GE: return FIRSTBIN+5;
1027 case CONC: return FIRSTBIN+6;
1028 case '+': return FIRSTBIN+7;
1029 case '-': return FIRSTBIN+8;
1030 case '*': return FIRSTBIN+9;
1031 case '/': return FIRSTBIN+10;
1032 case '^': return FIRSTBIN+11;
1033 default: return -1;
1034 }
1035}
1036
1027 1037
1028static void push (LexState *ls, stack_op *s, int op) { 1038static void push (LexState *ls, stack_op *s, int op) {
1029 if (s->top >= MAXOPS) 1039 if (s->top >= MAXOPS)
1030 luaX_error(ls, "expression too complex"); 1040 luaY_error(ls, "expression too complex");
1031 s->ops[s->top++] = op; 1041 s->ops[s->top++] = op;
1032} 1042}
1033 1043
@@ -1086,7 +1096,7 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1086 return; 1096 return;
1087 1097
1088 default: 1098 default:
1089 luaX_error(ls, "<expression> expected"); 1099 luaY_error(ls, "<expression> expected");
1090 return; 1100 return;
1091 } 1101 }
1092 v->k = VEXP; v->info = 0; 1102 v->k = VEXP; v->info = 0;
@@ -1108,8 +1118,7 @@ static void arith_exp (LexState *ls, vardesc *v) {
1108 int op; 1118 int op;
1109 s.top = 0; 1119 s.top = 0;
1110 prefixexp(ls, v, &s); 1120 prefixexp(ls, v, &s);
1111 while ((op = is_in(ls->token, binop)) >= 0) { 1121 while ((op = binop(ls->token)) >= 0) {
1112 op += FIRSTBIN;
1113 lua_pushvar(ls, v); 1122 lua_pushvar(ls, v);
1114 /* '^' is right associative, so must 'simulate' a higher priority */ 1123 /* '^' is right associative, so must 'simulate' a higher priority */
1115 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); 1124 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
@@ -1129,8 +1138,6 @@ static void exp1 (LexState *ls) {
1129 vardesc v; 1138 vardesc v;
1130 expr(ls, &v); 1139 expr(ls, &v);
1131 lua_pushvar(ls, &v); 1140 lua_pushvar(ls, &v);
1132 if (is_in(ls->token, expfollow) < 0)
1133 luaX_error(ls, "malformed expression");
1134} 1141}
1135 1142
1136 1143
@@ -1180,7 +1187,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
1180 next(ls); 1187 next(ls);
1181 var_or_func(ls, &nv); 1188 var_or_func(ls, &nv);
1182 if (nv.k == VEXP) 1189 if (nv.k == VEXP)
1183 luaX_error(ls, "syntax error"); 1190 luaY_error(ls, "syntax error");
1184 left = assignment(ls, &nv, nvars+1); 1191 left = assignment(ls, &nv, nvars+1);
1185 } 1192 }
1186 else { /* assignment -> '=' explist1 */ 1193 else { /* assignment -> '=' explist1 */
@@ -1313,7 +1320,7 @@ static void namestat (LexState *ls) {
1313 var_or_func(ls, &v); 1320 var_or_func(ls, &v);
1314 if (v.k == VEXP) { /* stat -> func */ 1321 if (v.k == VEXP) { /* stat -> func */
1315 if (v.info == 0) /* is just an upper value? */ 1322 if (v.info == 0) /* is just an upper value? */
1316 luaX_error(ls, "syntax error"); 1323 luaY_error(ls, "syntax error");
1317 close_exp(ls, v.info, 0); 1324 close_exp(ls, v.info, 0);
1318 } 1325 }
1319 else { /* stat -> ['%'] NAME assignment */ 1326 else { /* stat -> ['%'] NAME assignment */
@@ -1410,14 +1417,14 @@ static void parlist (LexState *ls) {
1410 case NAME: /* tailparlist -> NAME [',' tailparlist] */ 1417 case NAME: /* tailparlist -> NAME [',' tailparlist] */
1411 goto init; 1418 goto init;
1412 1419
1413 default: luaX_error(ls, "<name> or `...' expected"); 1420 default: luaY_error(ls, "<name> or `...' expected");
1414 } 1421 }
1415 } 1422 }
1416 break; 1423 break;
1417 1424
1418 case ')': break; /* parlist -> empty */ 1425 case ')': break; /* parlist -> empty */
1419 1426
1420 default: luaX_error(ls, "<name> or `...' expected"); 1427 default: luaY_error(ls, "<name> or `...' expected");
1421 } 1428 }
1422 code_args(ls, nparams, dots); 1429 code_args(ls, nparams, dots);
1423} 1430}