aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-02-28 01:11:49 +0100
committerMike Pall <mike>2013-02-28 01:11:49 +0100
commit87c51e7f57ec9277a02e7e21c8a28b4cb9d08914 (patch)
treeda3a7ac7babe8fe86d68df7472faa753dd70f682
parent116cdd7e9a578efffa5a9ca38167d059d12296d7 (diff)
downloadluajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.tar.gz
luajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.tar.bz2
luajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.zip
Cleanup lexer source code.
-rw-r--r--src/lj_bcread.c6
-rw-r--r--src/lj_lex.c301
-rw-r--r--src/lj_lex.h13
-rw-r--r--src/lj_lib.c2
-rw-r--r--src/lj_parse.c100
5 files changed, 218 insertions, 204 deletions
diff --git a/src/lj_bcread.c b/src/lj_bcread.c
index eda121e0..5be34757 100644
--- a/src/lj_bcread.c
+++ b/src/lj_bcread.c
@@ -47,7 +47,7 @@ static LJ_NOINLINE void bcread_error(LexState *ls, ErrMsg em)
47static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need) 47static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
48{ 48{
49 lua_assert(len != 0); 49 lua_assert(len != 0);
50 if (len > LJ_MAX_MEM || ls->current < 0) 50 if (len > LJ_MAX_MEM || ls->c < 0)
51 bcread_error(ls, LJ_ERR_BCBAD); 51 bcread_error(ls, LJ_ERR_BCBAD);
52 do { 52 do {
53 const char *buf; 53 const char *buf;
@@ -66,7 +66,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
66 buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */ 66 buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */
67 if (buf == NULL || size == 0) { /* EOF? */ 67 if (buf == NULL || size == 0) { /* EOF? */
68 if (need) bcread_error(ls, LJ_ERR_BCBAD); 68 if (need) bcread_error(ls, LJ_ERR_BCBAD);
69 ls->current = -1; /* Only bad if we get called again. */ 69 ls->c = -1; /* Only bad if we get called again. */
70 break; 70 break;
71 } 71 }
72 if (sbuflen(&ls->sb)) { /* Append to buffer. */ 72 if (sbuflen(&ls->sb)) { /* Append to buffer. */
@@ -430,7 +430,7 @@ static int bcread_header(LexState *ls)
430GCproto *lj_bcread(LexState *ls) 430GCproto *lj_bcread(LexState *ls)
431{ 431{
432 lua_State *L = ls->L; 432 lua_State *L = ls->L;
433 lua_assert(ls->current == BCDUMP_HEAD1); 433 lua_assert(ls->c == BCDUMP_HEAD1);
434 bcread_savetop(L, ls, L->top); 434 bcread_savetop(L, ls, L->top);
435 lj_buf_reset(&ls->sb); 435 lj_buf_reset(&ls->sb);
436 /* Check for a valid bytecode dump header. */ 436 /* Check for a valid bytecode dump header. */
diff --git a/src/lj_lex.c b/src/lj_lex.c
index c4d52da2..2c5128e7 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -38,37 +38,48 @@ TKDEF(TKSTR1, TKSTR2)
38 38
39/* -- Buffer handling ----------------------------------------------------- */ 39/* -- Buffer handling ----------------------------------------------------- */
40 40
41#define char2int(c) ((int)(uint8_t)(c)) 41#define LEX_EOF (-1)
42#define next(ls) \ 42#define lex_iseol(ls) (ls->c == '\n' || ls->c == '\r')
43 (ls->current = (ls->n--) > 0 ? char2int(*ls->p++) : fillbuf(ls))
44#define save_and_next(ls) (save(ls, ls->current), next(ls))
45#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
46#define END_OF_STREAM (-1)
47 43
48static int fillbuf(LexState *ls) 44/* Get more input from reader. */
45static LJ_NOINLINE LexChar lex_more(LexState *ls)
49{ 46{
50 size_t sz; 47 size_t sz;
51 const char *buf = ls->rfunc(ls->L, ls->rdata, &sz); 48 const char *buf = ls->rfunc(ls->L, ls->rdata, &sz);
52 if (buf == NULL || sz == 0) return END_OF_STREAM; 49 if (buf == NULL || sz == 0) return LEX_EOF;
53 ls->n = (MSize)sz - 1; 50 ls->n = (MSize)sz - 1;
54 ls->p = buf; 51 ls->p = buf;
55 return char2int(*(ls->p++)); 52 return (LexChar)(uint8_t)*ls->p++;
56} 53}
57 54
58static LJ_AINLINE void save(LexState *ls, int c) 55/* Get next character. */
56static LJ_AINLINE LexChar lex_next(LexState *ls)
57{
58 return (ls->c = ls->n ? (ls->n--,(LexChar)(uint8_t)*ls->p++) : lex_more(ls));
59}
60
61/* Save character. */
62static LJ_AINLINE void lex_save(LexState *ls, LexChar c)
59{ 63{
60 lj_buf_putb(ls->L, &ls->sb, c); 64 lj_buf_putb(ls->L, &ls->sb, c);
61} 65}
62 66
63static void inclinenumber(LexState *ls) 67/* Save previous character and get next character. */
68static LJ_AINLINE LexChar lex_savenext(LexState *ls)
69{
70 lex_save(ls, ls->c);
71 return lex_next(ls);
72}
73
74/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
75static void lex_newline(LexState *ls)
64{ 76{
65 int old = ls->current; 77 LexChar old = ls->c;
66 lua_assert(currIsNewline(ls)); 78 lua_assert(lex_iseol(ls));
67 next(ls); /* skip `\n' or `\r' */ 79 lex_next(ls); /* Skip "\n" or "\r". */
68 if (currIsNewline(ls) && ls->current != old) 80 if (lex_iseol(ls) && ls->c != old) lex_next(ls); /* Skip "\n\r" or "\r\n". */
69 next(ls); /* skip `\n\r' or `\r\n' */
70 if (++ls->linenumber >= LJ_MAX_LINE) 81 if (++ls->linenumber >= LJ_MAX_LINE)
71 lj_lex_error(ls, ls->token, LJ_ERR_XLINES); 82 lj_lex_error(ls, ls->tok, LJ_ERR_XLINES);
72} 83}
73 84
74/* -- Scanner for terminals ----------------------------------------------- */ 85/* -- Scanner for terminals ----------------------------------------------- */
@@ -77,18 +88,16 @@ static void inclinenumber(LexState *ls)
77static void lex_number(LexState *ls, TValue *tv) 88static void lex_number(LexState *ls, TValue *tv)
78{ 89{
79 StrScanFmt fmt; 90 StrScanFmt fmt;
80 int c, xp = 'e'; 91 LexChar c, xp = 'e';
81 lua_assert(lj_char_isdigit(ls->current)); 92 lua_assert(lj_char_isdigit(ls->c));
82 if ((c = ls->current) == '0') { 93 if ((c = ls->c) == '0' && (lex_savenext(ls) | 0x20) == 'x')
83 save_and_next(ls); 94 xp = 'p';
84 if ((ls->current | 0x20) == 'x') xp = 'p'; 95 while (lj_char_isident(ls->c) || ls->c == '.' ||
96 ((ls->c == '-' || ls->c == '+') && (c | 0x20) == xp)) {
97 c = ls->c;
98 lex_savenext(ls);
85 } 99 }
86 while (lj_char_isident(ls->current) || ls->current == '.' || 100 lex_save(ls, '\0');
87 ((ls->current == '-' || ls->current == '+') && (c | 0x20) == xp)) {
88 c = ls->current;
89 save_and_next(ls);
90 }
91 save(ls, '\0');
92 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv, 101 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv,
93 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | 102 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
94 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); 103 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
@@ -122,44 +131,42 @@ static void lex_number(LexState *ls, TValue *tv)
122 } 131 }
123} 132}
124 133
125static int skip_sep(LexState *ls) 134/* Skip equal signs for "[=...=[" and "]=...=]" and return their count. */
135static int lex_skipeq(LexState *ls)
126{ 136{
127 int count = 0; 137 int count = 0;
128 int s = ls->current; 138 LexChar s = ls->c;
129 lua_assert(s == '[' || s == ']'); 139 lua_assert(s == '[' || s == ']');
130 save_and_next(ls); 140 while (lex_savenext(ls) == '=')
131 while (ls->current == '=') {
132 save_and_next(ls);
133 count++; 141 count++;
134 } 142 return (ls->c == s) ? count : (-count) - 1;
135 return (ls->current == s) ? count : (-count) - 1;
136} 143}
137 144
138static void read_long_string(LexState *ls, TValue *tv, int sep) 145/* Parse a long string or long comment (tv set to NULL). */
146static void lex_longstring(LexState *ls, TValue *tv, int sep)
139{ 147{
140 save_and_next(ls); /* skip 2nd `[' */ 148 lex_savenext(ls); /* Skip second '['. */
141 if (currIsNewline(ls)) /* string starts with a newline? */ 149 if (lex_iseol(ls)) /* Skip initial newline. */
142 inclinenumber(ls); /* skip it */ 150 lex_newline(ls);
143 for (;;) { 151 for (;;) {
144 switch (ls->current) { 152 switch (ls->c) {
145 case END_OF_STREAM: 153 case LEX_EOF:
146 lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM); 154 lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM);
147 break; 155 break;
148 case ']': 156 case ']':
149 if (skip_sep(ls) == sep) { 157 if (lex_skipeq(ls) == sep) {
150 save_and_next(ls); /* skip 2nd `]' */ 158 lex_savenext(ls); /* Skip second ']'. */
151 goto endloop; 159 goto endloop;
152 } 160 }
153 break; 161 break;
154 case '\n': 162 case '\n':
155 case '\r': 163 case '\r':
156 save(ls, '\n'); 164 lex_save(ls, '\n');
157 inclinenumber(ls); 165 lex_newline(ls);
158 if (!tv) lj_buf_reset(&ls->sb); /* Don't waste space for comments. */ 166 if (!tv) lj_buf_reset(&ls->sb); /* Don't waste space for comments. */
159 break; 167 break;
160 default: 168 default:
161 if (tv) save_and_next(ls); 169 lex_savenext(ls);
162 else next(ls);
163 break; 170 break;
164 } 171 }
165 } endloop: 172 } endloop:
@@ -170,12 +177,14 @@ static void read_long_string(LexState *ls, TValue *tv, int sep)
170 } 177 }
171} 178}
172 179
173static void read_string(LexState *ls, int delim, TValue *tv) 180/* Parse a string. */
181static void lex_string(LexState *ls, TValue *tv)
174{ 182{
175 save_and_next(ls); 183 LexChar delim = ls->c; /* Delimiter is '\'' or '"'. */
176 while (ls->current != delim) { 184 lex_savenext(ls);
177 switch (ls->current) { 185 while (ls->c != delim) {
178 case END_OF_STREAM: 186 switch (ls->c) {
187 case LEX_EOF:
179 lj_lex_error(ls, TK_eof, LJ_ERR_XSTR); 188 lj_lex_error(ls, TK_eof, LJ_ERR_XSTR);
180 continue; 189 continue;
181 case '\n': 190 case '\n':
@@ -183,7 +192,7 @@ static void read_string(LexState *ls, int delim, TValue *tv)
183 lj_lex_error(ls, TK_string, LJ_ERR_XSTR); 192 lj_lex_error(ls, TK_string, LJ_ERR_XSTR);
184 continue; 193 continue;
185 case '\\': { 194 case '\\': {
186 int c = next(ls); /* Skip the '\\'. */ 195 LexChar c = lex_next(ls); /* Skip the '\\'. */
187 switch (c) { 196 switch (c) {
188 case 'a': c = '\a'; break; 197 case 'a': c = '\a'; break;
189 case 'b': c = '\b'; break; 198 case 'b': c = '\b'; break;
@@ -193,112 +202,112 @@ static void read_string(LexState *ls, int delim, TValue *tv)
193 case 't': c = '\t'; break; 202 case 't': c = '\t'; break;
194 case 'v': c = '\v'; break; 203 case 'v': c = '\v'; break;
195 case 'x': /* Hexadecimal escape '\xXX'. */ 204 case 'x': /* Hexadecimal escape '\xXX'. */
196 c = (next(ls) & 15u) << 4; 205 c = (lex_next(ls) & 15u) << 4;
197 if (!lj_char_isdigit(ls->current)) { 206 if (!lj_char_isdigit(ls->c)) {
198 if (!lj_char_isxdigit(ls->current)) goto err_xesc; 207 if (!lj_char_isxdigit(ls->c)) goto err_xesc;
199 c += 9 << 4; 208 c += 9 << 4;
200 } 209 }
201 c += (next(ls) & 15u); 210 c += (lex_next(ls) & 15u);
202 if (!lj_char_isdigit(ls->current)) { 211 if (!lj_char_isdigit(ls->c)) {
203 if (!lj_char_isxdigit(ls->current)) goto err_xesc; 212 if (!lj_char_isxdigit(ls->c)) goto err_xesc;
204 c += 9; 213 c += 9;
205 } 214 }
206 break; 215 break;
207 case 'z': /* Skip whitespace. */ 216 case 'z': /* Skip whitespace. */
208 next(ls); 217 lex_next(ls);
209 while (lj_char_isspace(ls->current)) 218 while (lj_char_isspace(ls->c))
210 if (currIsNewline(ls)) inclinenumber(ls); else next(ls); 219 if (lex_iseol(ls)) lex_newline(ls); else lex_next(ls);
211 continue; 220 continue;
212 case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue; 221 case '\n': case '\r': lex_save(ls, '\n'); lex_newline(ls); continue;
213 case '\\': case '\"': case '\'': break; 222 case '\\': case '\"': case '\'': break;
214 case END_OF_STREAM: continue; 223 case LEX_EOF: continue;
215 default: 224 default:
216 if (!lj_char_isdigit(c)) 225 if (!lj_char_isdigit(c))
217 goto err_xesc; 226 goto err_xesc;
218 c -= '0'; /* Decimal escape '\ddd'. */ 227 c -= '0'; /* Decimal escape '\ddd'. */
219 if (lj_char_isdigit(next(ls))) { 228 if (lj_char_isdigit(lex_next(ls))) {
220 c = c*10 + (ls->current - '0'); 229 c = c*10 + (ls->c - '0');
221 if (lj_char_isdigit(next(ls))) { 230 if (lj_char_isdigit(lex_next(ls))) {
222 c = c*10 + (ls->current - '0'); 231 c = c*10 + (ls->c - '0');
223 if (c > 255) { 232 if (c > 255) {
224 err_xesc: 233 err_xesc:
225 lj_lex_error(ls, TK_string, LJ_ERR_XESC); 234 lj_lex_error(ls, TK_string, LJ_ERR_XESC);
226 } 235 }
227 next(ls); 236 lex_next(ls);
228 } 237 }
229 } 238 }
230 save(ls, c); 239 lex_save(ls, c);
231 continue; 240 continue;
232 } 241 }
233 save(ls, c); 242 lex_save(ls, c);
234 next(ls); 243 lex_next(ls);
235 continue; 244 continue;
236 } 245 }
237 default: 246 default:
238 save_and_next(ls); 247 lex_savenext(ls);
239 break; 248 break;
240 } 249 }
241 } 250 }
242 save_and_next(ls); /* skip delimiter */ 251 lex_savenext(ls); /* Skip trailing delimiter. */
243 setstrV(ls->L, tv, 252 setstrV(ls->L, tv,
244 lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2)); 253 lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2));
245} 254}
246 255
247/* -- Main lexical scanner ------------------------------------------------ */ 256/* -- Main lexical scanner ------------------------------------------------ */
248 257
249static int llex(LexState *ls, TValue *tv) 258/* Get next lexical token. */
259static LexToken lex_scan(LexState *ls, TValue *tv)
250{ 260{
251 lj_buf_reset(&ls->sb); 261 lj_buf_reset(&ls->sb);
252 for (;;) { 262 for (;;) {
253 if (lj_char_isident(ls->current)) { 263 if (lj_char_isident(ls->c)) {
254 GCstr *s; 264 GCstr *s;
255 if (lj_char_isdigit(ls->current)) { /* Numeric literal. */ 265 if (lj_char_isdigit(ls->c)) { /* Numeric literal. */
256 lex_number(ls, tv); 266 lex_number(ls, tv);
257 return TK_number; 267 return TK_number;
258 } 268 }
259 /* Identifier or reserved word. */ 269 /* Identifier or reserved word. */
260 do { 270 do {
261 save_and_next(ls); 271 lex_savenext(ls);
262 } while (lj_char_isident(ls->current)); 272 } while (lj_char_isident(ls->c));
263 s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb)); 273 s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb));
264 setstrV(ls->L, tv, s); 274 setstrV(ls->L, tv, s);
265 if (s->reserved > 0) /* Reserved word? */ 275 if (s->reserved > 0) /* Reserved word? */
266 return TK_OFS + s->reserved; 276 return TK_OFS + s->reserved;
267 return TK_name; 277 return TK_name;
268 } 278 }
269 switch (ls->current) { 279 switch (ls->c) {
270 case '\n': 280 case '\n':
271 case '\r': 281 case '\r':
272 inclinenumber(ls); 282 lex_newline(ls);
273 continue; 283 continue;
274 case ' ': 284 case ' ':
275 case '\t': 285 case '\t':
276 case '\v': 286 case '\v':
277 case '\f': 287 case '\f':
278 next(ls); 288 lex_next(ls);
279 continue; 289 continue;
280 case '-': 290 case '-':
281 next(ls); 291 lex_next(ls);
282 if (ls->current != '-') return '-'; 292 if (ls->c != '-') return '-';
283 /* else is a comment */ 293 lex_next(ls);
284 next(ls); 294 if (ls->c == '[') { /* Long comment "--[=*[...]=*]". */
285 if (ls->current == '[') { 295 int sep = lex_skipeq(ls);
286 int sep = skip_sep(ls); 296 lj_buf_reset(&ls->sb); /* `lex_skipeq' may dirty the buffer */
287 lj_buf_reset(&ls->sb); /* `skip_sep' may dirty the buffer */
288 if (sep >= 0) { 297 if (sep >= 0) {
289 read_long_string(ls, NULL, sep); /* long comment */ 298 lex_longstring(ls, NULL, sep);
290 lj_buf_reset(&ls->sb); 299 lj_buf_reset(&ls->sb);
291 continue; 300 continue;
292 } 301 }
293 } 302 }
294 /* else short comment */ 303 /* Short comment "--.*\n". */
295 while (!currIsNewline(ls) && ls->current != END_OF_STREAM) 304 while (!lex_iseol(ls) && ls->c != LEX_EOF)
296 next(ls); 305 lex_next(ls);
297 continue; 306 continue;
298 case '[': { 307 case '[': {
299 int sep = skip_sep(ls); 308 int sep = lex_skipeq(ls);
300 if (sep >= 0) { 309 if (sep >= 0) {
301 read_long_string(ls, tv, sep); 310 lex_longstring(ls, tv, sep);
302 return TK_string; 311 return TK_string;
303 } else if (sep == -1) { 312 } else if (sep == -1) {
304 return '['; 313 return '[';
@@ -308,44 +317,43 @@ static int llex(LexState *ls, TValue *tv)
308 } 317 }
309 } 318 }
310 case '=': 319 case '=':
311 next(ls); 320 lex_next(ls);
312 if (ls->current != '=') return '='; else { next(ls); return TK_eq; } 321 if (ls->c != '=') return '='; else { lex_next(ls); return TK_eq; }
313 case '<': 322 case '<':
314 next(ls); 323 lex_next(ls);
315 if (ls->current != '=') return '<'; else { next(ls); return TK_le; } 324 if (ls->c != '=') return '<'; else { lex_next(ls); return TK_le; }
316 case '>': 325 case '>':
317 next(ls); 326 lex_next(ls);
318 if (ls->current != '=') return '>'; else { next(ls); return TK_ge; } 327 if (ls->c != '=') return '>'; else { lex_next(ls); return TK_ge; }
319 case '~': 328 case '~':
320 next(ls); 329 lex_next(ls);
321 if (ls->current != '=') return '~'; else { next(ls); return TK_ne; } 330 if (ls->c != '=') return '~'; else { lex_next(ls); return TK_ne; }
322 case ':': 331 case ':':
323 next(ls); 332 lex_next(ls);
324 if (ls->current != ':') return ':'; else { next(ls); return TK_label; } 333 if (ls->c != ':') return ':'; else { lex_next(ls); return TK_label; }
325 case '"': 334 case '"':
326 case '\'': 335 case '\'':
327 read_string(ls, ls->current, tv); 336 lex_string(ls, tv);
328 return TK_string; 337 return TK_string;
329 case '.': 338 case '.':
330 save_and_next(ls); 339 if (lex_savenext(ls) == '.') {
331 if (ls->current == '.') { 340 lex_next(ls);
332 next(ls); 341 if (ls->c == '.') {
333 if (ls->current == '.') { 342 lex_next(ls);
334 next(ls);
335 return TK_dots; /* ... */ 343 return TK_dots; /* ... */
336 } 344 }
337 return TK_concat; /* .. */ 345 return TK_concat; /* .. */
338 } else if (!lj_char_isdigit(ls->current)) { 346 } else if (!lj_char_isdigit(ls->c)) {
339 return '.'; 347 return '.';
340 } else { 348 } else {
341 lex_number(ls, tv); 349 lex_number(ls, tv);
342 return TK_number; 350 return TK_number;
343 } 351 }
344 case END_OF_STREAM: 352 case LEX_EOF:
345 return TK_eof; 353 return TK_eof;
346 default: { 354 default: {
347 int c = ls->current; 355 LexChar c = ls->c;
348 next(ls); 356 lex_next(ls);
349 return c; /* Single-char tokens (+ - / ...). */ 357 return c; /* Single-char tokens (+ - / ...). */
350 } 358 }
351 } 359 }
@@ -370,23 +378,23 @@ int lj_lex_setup(lua_State *L, LexState *ls)
370 ls->lookahead = TK_eof; /* No look-ahead token. */ 378 ls->lookahead = TK_eof; /* No look-ahead token. */
371 ls->linenumber = 1; 379 ls->linenumber = 1;
372 ls->lastline = 1; 380 ls->lastline = 1;
373 next(ls); /* Read-ahead first char. */ 381 lex_next(ls); /* Read-ahead first char. */
374 if (ls->current == 0xef && ls->n >= 2 && char2int(ls->p[0]) == 0xbb && 382 if (ls->c == 0xef && ls->n >= 2 && (uint8_t)ls->p[0] == 0xbb &&
375 char2int(ls->p[1]) == 0xbf) { /* Skip UTF-8 BOM (if buffered). */ 383 (uint8_t)ls->p[1] == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
376 ls->n -= 2; 384 ls->n -= 2;
377 ls->p += 2; 385 ls->p += 2;
378 next(ls); 386 lex_next(ls);
379 header = 1; 387 header = 1;
380 } 388 }
381 if (ls->current == '#') { /* Skip POSIX #! header line. */ 389 if (ls->c == '#') { /* Skip POSIX #! header line. */
382 do { 390 do {
383 next(ls); 391 lex_next(ls);
384 if (ls->current == END_OF_STREAM) return 0; 392 if (ls->c == LEX_EOF) return 0;
385 } while (!currIsNewline(ls)); 393 } while (!lex_iseol(ls));
386 inclinenumber(ls); 394 lex_newline(ls);
387 header = 1; 395 header = 1;
388 } 396 }
389 if (ls->current == LUA_SIGNATURE[0]) { /* Bytecode dump. */ 397 if (ls->c == LUA_SIGNATURE[0]) { /* Bytecode dump. */
390 if (header) { 398 if (header) {
391 /* 399 /*
392 ** Loading bytecode with an extra header is disabled for security 400 ** Loading bytecode with an extra header is disabled for security
@@ -411,52 +419,57 @@ void lj_lex_cleanup(lua_State *L, LexState *ls)
411 lj_buf_free(g, &ls->sb); 419 lj_buf_free(g, &ls->sb);
412} 420}
413 421
422/* Return next lexical token. */
414void lj_lex_next(LexState *ls) 423void lj_lex_next(LexState *ls)
415{ 424{
416 ls->lastline = ls->linenumber; 425 ls->lastline = ls->linenumber;
417 if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */ 426 if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */
418 ls->token = llex(ls, &ls->tokenval); /* Get next token. */ 427 ls->tok = lex_scan(ls, &ls->tokval); /* Get next token. */
419 } else { /* Otherwise return lookahead token. */ 428 } else { /* Otherwise return lookahead token. */
420 ls->token = ls->lookahead; 429 ls->tok = ls->lookahead;
421 ls->lookahead = TK_eof; 430 ls->lookahead = TK_eof;
422 ls->tokenval = ls->lookaheadval; 431 ls->tokval = ls->lookaheadval;
423 } 432 }
424} 433}
425 434
435/* Look ahead for the next token. */
426LexToken lj_lex_lookahead(LexState *ls) 436LexToken lj_lex_lookahead(LexState *ls)
427{ 437{
428 lua_assert(ls->lookahead == TK_eof); 438 lua_assert(ls->lookahead == TK_eof);
429 ls->lookahead = llex(ls, &ls->lookaheadval); 439 ls->lookahead = lex_scan(ls, &ls->lookaheadval);
430 return ls->lookahead; 440 return ls->lookahead;
431} 441}
432 442
433const char *lj_lex_token2str(LexState *ls, LexToken token) 443/* Convert token to string. */
444const char *lj_lex_token2str(LexState *ls, LexToken tok)
434{ 445{
435 if (token > TK_OFS) 446 if (tok > TK_OFS)
436 return tokennames[token-TK_OFS-1]; 447 return tokennames[tok-TK_OFS-1];
437 else if (!lj_char_iscntrl(token)) 448 else if (!lj_char_iscntrl(tok))
438 return lj_str_pushf(ls->L, "%c", token); 449 return lj_str_pushf(ls->L, "%c", tok);
439 else 450 else
440 return lj_str_pushf(ls->L, "char(%d)", token); 451 return lj_str_pushf(ls->L, "char(%d)", tok);
441} 452}
442 453
443void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...) 454/* Lexer error. */
455void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...)
444{ 456{
445 const char *tok; 457 const char *tokstr;
446 va_list argp; 458 va_list argp;
447 if (token == 0) { 459 if (tok == 0) {
448 tok = NULL; 460 tokstr = NULL;
449 } else if (token == TK_name || token == TK_string || token == TK_number) { 461 } else if (tok == TK_name || tok == TK_string || tok == TK_number) {
450 save(ls, '\0'); 462 lex_save(ls, '\0');
451 tok = sbufB(&ls->sb); 463 tokstr = sbufB(&ls->sb);
452 } else { 464 } else {
453 tok = lj_lex_token2str(ls, token); 465 tokstr = lj_lex_token2str(ls, tok);
454 } 466 }
455 va_start(argp, em); 467 va_start(argp, em);
456 lj_err_lex(ls->L, ls->chunkname, tok, ls->linenumber, em, argp); 468 lj_err_lex(ls->L, ls->chunkname, tokstr, ls->linenumber, em, argp);
457 va_end(argp); 469 va_end(argp);
458} 470}
459 471
472/* Initialize strings for reserved words. */
460void lj_lex_init(lua_State *L) 473void lj_lex_init(lua_State *L)
461{ 474{
462 uint32_t i; 475 uint32_t i;
diff --git a/src/lj_lex.h b/src/lj_lex.h
index 6e18e4b0..71a7c1de 100644
--- a/src/lj_lex.h
+++ b/src/lj_lex.h
@@ -30,7 +30,8 @@ TKDEF(TKENUM1, TKENUM2)
30 TK_RESERVED = TK_while - TK_OFS 30 TK_RESERVED = TK_while - TK_OFS
31}; 31};
32 32
33typedef int LexToken; 33typedef int LexChar; /* Lexical character. Unsigned ext. from char. */
34typedef int LexToken; /* Lexical token. */
34 35
35/* Combined bytecode ins/line. Only used during bytecode generation. */ 36/* Combined bytecode ins/line. Only used during bytecode generation. */
36typedef struct BCInsLine { 37typedef struct BCInsLine {
@@ -51,10 +52,10 @@ typedef struct VarInfo {
51typedef struct LexState { 52typedef struct LexState {
52 struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */ 53 struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */
53 struct lua_State *L; /* Lua state. */ 54 struct lua_State *L; /* Lua state. */
54 TValue tokenval; /* Current token value. */ 55 TValue tokval; /* Current token value. */
55 TValue lookaheadval; /* Lookahead token value. */ 56 TValue lookaheadval; /* Lookahead token value. */
56 int current; /* Current character (charint). */ 57 LexChar c; /* Current character. */
57 LexToken token; /* Current token. */ 58 LexToken tok; /* Current token. */
58 LexToken lookahead; /* Lookahead token. */ 59 LexToken lookahead; /* Lookahead token. */
59 MSize n; /* Bytes left in input buffer. */ 60 MSize n; /* Bytes left in input buffer. */
60 const char *p; /* Current position in input buffer. */ 61 const char *p; /* Current position in input buffer. */
@@ -78,8 +79,8 @@ LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
78LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls); 79LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls);
79LJ_FUNC void lj_lex_next(LexState *ls); 80LJ_FUNC void lj_lex_next(LexState *ls);
80LJ_FUNC LexToken lj_lex_lookahead(LexState *ls); 81LJ_FUNC LexToken lj_lex_lookahead(LexState *ls);
81LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken token); 82LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken tok);
82LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...); 83LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...);
83LJ_FUNC void lj_lex_init(lua_State *L); 84LJ_FUNC void lj_lex_init(lua_State *L);
84 85
85#endif 86#endif
diff --git a/src/lj_lib.c b/src/lj_lib.c
index be3ee004..79c2c99a 100644
--- a/src/lj_lib.c
+++ b/src/lj_lib.c
@@ -56,7 +56,7 @@ static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
56 ls.L = L; 56 ls.L = L;
57 ls.p = (const char *)(p+len); 57 ls.p = (const char *)(p+len);
58 ls.n = ~(MSize)0; 58 ls.n = ~(MSize)0;
59 ls.current = -1; 59 ls.c = -1;
60 ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE)); 60 ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
61 ls.chunkname = name; 61 ls.chunkname = name;
62 pt = lj_bcread_proto(&ls); 62 pt = lj_bcread_proto(&ls);
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 64652ed2..39a01e6f 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -166,12 +166,12 @@ LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD);
166 166
167LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) 167LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em)
168{ 168{
169 lj_lex_error(ls, ls->token, em); 169 lj_lex_error(ls, ls->tok, em);
170} 170}
171 171
172LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token) 172LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok)
173{ 173{
174 lj_lex_error(ls, ls->token, LJ_ERR_XTOKEN, lj_lex_token2str(ls, token)); 174 lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok));
175} 175}
176 176
177LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) 177LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what)
@@ -982,7 +982,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
982/* Check and consume optional token. */ 982/* Check and consume optional token. */
983static int lex_opt(LexState *ls, LexToken tok) 983static int lex_opt(LexState *ls, LexToken tok)
984{ 984{
985 if (ls->token == tok) { 985 if (ls->tok == tok) {
986 lj_lex_next(ls); 986 lj_lex_next(ls);
987 return 1; 987 return 1;
988 } 988 }
@@ -992,7 +992,7 @@ static int lex_opt(LexState *ls, LexToken tok)
992/* Check and consume token. */ 992/* Check and consume token. */
993static void lex_check(LexState *ls, LexToken tok) 993static void lex_check(LexState *ls, LexToken tok)
994{ 994{
995 if (ls->token != tok) 995 if (ls->tok != tok)
996 err_token(ls, tok); 996 err_token(ls, tok);
997 lj_lex_next(ls); 997 lj_lex_next(ls);
998} 998}
@@ -1006,7 +1006,7 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
1006 } else { 1006 } else {
1007 const char *swhat = lj_lex_token2str(ls, what); 1007 const char *swhat = lj_lex_token2str(ls, what);
1008 const char *swho = lj_lex_token2str(ls, who); 1008 const char *swho = lj_lex_token2str(ls, who);
1009 lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line); 1009 lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line);
1010 } 1010 }
1011 } 1011 }
1012} 1012}
@@ -1015,9 +1015,9 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
1015static GCstr *lex_str(LexState *ls) 1015static GCstr *lex_str(LexState *ls)
1016{ 1016{
1017 GCstr *s; 1017 GCstr *s;
1018 if (ls->token != TK_name && (LJ_52 || ls->token != TK_goto)) 1018 if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto))
1019 err_token(ls, TK_name); 1019 err_token(ls, TK_name);
1020 s = strV(&ls->tokenval); 1020 s = strV(&ls->tokval);
1021 lj_lex_next(ls); 1021 lj_lex_next(ls);
1022 return s; 1022 return s;
1023} 1023}
@@ -1584,7 +1584,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
1584 L->top--; /* Pop table of constants. */ 1584 L->top--; /* Pop table of constants. */
1585 ls->vtop = fs->vbase; /* Reset variable stack. */ 1585 ls->vtop = fs->vbase; /* Reset variable stack. */
1586 ls->fs = fs->prev; 1586 ls->fs = fs->prev;
1587 lua_assert(ls->fs != NULL || ls->token == TK_eof); 1587 lua_assert(ls->fs != NULL || ls->tok == TK_eof);
1588 return pt; 1588 return pt;
1589} 1589}
1590 1590
@@ -1706,15 +1706,15 @@ static void expr_table(LexState *ls, ExpDesc *e)
1706 bcreg_reserve(fs, 1); 1706 bcreg_reserve(fs, 1);
1707 freg++; 1707 freg++;
1708 lex_check(ls, '{'); 1708 lex_check(ls, '{');
1709 while (ls->token != '}') { 1709 while (ls->tok != '}') {
1710 ExpDesc key, val; 1710 ExpDesc key, val;
1711 vcall = 0; 1711 vcall = 0;
1712 if (ls->token == '[') { 1712 if (ls->tok == '[') {
1713 expr_bracket(ls, &key); /* Already calls expr_toval. */ 1713 expr_bracket(ls, &key); /* Already calls expr_toval. */
1714 if (!expr_isk(&key)) expr_index(fs, e, &key); 1714 if (!expr_isk(&key)) expr_index(fs, e, &key);
1715 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; 1715 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
1716 lex_check(ls, '='); 1716 lex_check(ls, '=');
1717 } else if ((ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) && 1717 } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) &&
1718 lj_lex_lookahead(ls) == '=') { 1718 lj_lex_lookahead(ls) == '=') {
1719 expr_str(ls, &key); 1719 expr_str(ls, &key);
1720 lex_check(ls, '='); 1720 lex_check(ls, '=');
@@ -1807,11 +1807,11 @@ static BCReg parse_params(LexState *ls, int needself)
1807 lex_check(ls, '('); 1807 lex_check(ls, '(');
1808 if (needself) 1808 if (needself)
1809 var_new_lit(ls, nparams++, "self"); 1809 var_new_lit(ls, nparams++, "self");
1810 if (ls->token != ')') { 1810 if (ls->tok != ')') {
1811 do { 1811 do {
1812 if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { 1812 if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
1813 var_new(ls, nparams++, lex_str(ls)); 1813 var_new(ls, nparams++, lex_str(ls));
1814 } else if (ls->token == TK_dots) { 1814 } else if (ls->tok == TK_dots) {
1815 lj_lex_next(ls); 1815 lj_lex_next(ls);
1816 fs->flags |= PROTO_VARARG; 1816 fs->flags |= PROTO_VARARG;
1817 break; 1817 break;
@@ -1845,7 +1845,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1845 fs.bclim = pfs->bclim - pfs->pc; 1845 fs.bclim = pfs->bclim - pfs->pc;
1846 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ 1846 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */
1847 parse_chunk(ls); 1847 parse_chunk(ls);
1848 if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line); 1848 if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line);
1849 pt = fs_finish(ls, (ls->lastline = ls->linenumber)); 1849 pt = fs_finish(ls, (ls->lastline = ls->linenumber));
1850 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ 1850 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
1851 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); 1851 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
@@ -1884,13 +1884,13 @@ static void parse_args(LexState *ls, ExpDesc *e)
1884 BCIns ins; 1884 BCIns ins;
1885 BCReg base; 1885 BCReg base;
1886 BCLine line = ls->linenumber; 1886 BCLine line = ls->linenumber;
1887 if (ls->token == '(') { 1887 if (ls->tok == '(') {
1888#if !LJ_52 1888#if !LJ_52
1889 if (line != ls->lastline) 1889 if (line != ls->lastline)
1890 err_syntax(ls, LJ_ERR_XAMBIG); 1890 err_syntax(ls, LJ_ERR_XAMBIG);
1891#endif 1891#endif
1892 lj_lex_next(ls); 1892 lj_lex_next(ls);
1893 if (ls->token == ')') { /* f(). */ 1893 if (ls->tok == ')') { /* f(). */
1894 args.k = VVOID; 1894 args.k = VVOID;
1895 } else { 1895 } else {
1896 expr_list(ls, &args); 1896 expr_list(ls, &args);
@@ -1898,11 +1898,11 @@ static void parse_args(LexState *ls, ExpDesc *e)
1898 setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ 1898 setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */
1899 } 1899 }
1900 lex_match(ls, ')', '(', line); 1900 lex_match(ls, ')', '(', line);
1901 } else if (ls->token == '{') { 1901 } else if (ls->tok == '{') {
1902 expr_table(ls, &args); 1902 expr_table(ls, &args);
1903 } else if (ls->token == TK_string) { 1903 } else if (ls->tok == TK_string) {
1904 expr_init(&args, VKSTR, 0); 1904 expr_init(&args, VKSTR, 0);
1905 args.u.sval = strV(&ls->tokenval); 1905 args.u.sval = strV(&ls->tokval);
1906 lj_lex_next(ls); 1906 lj_lex_next(ls);
1907 } else { 1907 } else {
1908 err_syntax(ls, LJ_ERR_XFUNARG); 1908 err_syntax(ls, LJ_ERR_XFUNARG);
@@ -1928,32 +1928,32 @@ static void expr_primary(LexState *ls, ExpDesc *v)
1928{ 1928{
1929 FuncState *fs = ls->fs; 1929 FuncState *fs = ls->fs;
1930 /* Parse prefix expression. */ 1930 /* Parse prefix expression. */
1931 if (ls->token == '(') { 1931 if (ls->tok == '(') {
1932 BCLine line = ls->linenumber; 1932 BCLine line = ls->linenumber;
1933 lj_lex_next(ls); 1933 lj_lex_next(ls);
1934 expr(ls, v); 1934 expr(ls, v);
1935 lex_match(ls, ')', '(', line); 1935 lex_match(ls, ')', '(', line);
1936 expr_discharge(ls->fs, v); 1936 expr_discharge(ls->fs, v);
1937 } else if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { 1937 } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
1938 var_lookup(ls, v); 1938 var_lookup(ls, v);
1939 } else { 1939 } else {
1940 err_syntax(ls, LJ_ERR_XSYMBOL); 1940 err_syntax(ls, LJ_ERR_XSYMBOL);
1941 } 1941 }
1942 for (;;) { /* Parse multiple expression suffixes. */ 1942 for (;;) { /* Parse multiple expression suffixes. */
1943 if (ls->token == '.') { 1943 if (ls->tok == '.') {
1944 expr_field(ls, v); 1944 expr_field(ls, v);
1945 } else if (ls->token == '[') { 1945 } else if (ls->tok == '[') {
1946 ExpDesc key; 1946 ExpDesc key;
1947 expr_toanyreg(fs, v); 1947 expr_toanyreg(fs, v);
1948 expr_bracket(ls, &key); 1948 expr_bracket(ls, &key);
1949 expr_index(fs, v, &key); 1949 expr_index(fs, v, &key);
1950 } else if (ls->token == ':') { 1950 } else if (ls->tok == ':') {
1951 ExpDesc key; 1951 ExpDesc key;
1952 lj_lex_next(ls); 1952 lj_lex_next(ls);
1953 expr_str(ls, &key); 1953 expr_str(ls, &key);
1954 bcemit_method(fs, v, &key); 1954 bcemit_method(fs, v, &key);
1955 parse_args(ls, v); 1955 parse_args(ls, v);
1956 } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { 1956 } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
1957 expr_tonextreg(fs, v); 1957 expr_tonextreg(fs, v);
1958 parse_args(ls, v); 1958 parse_args(ls, v);
1959 } else { 1959 } else {
@@ -1965,14 +1965,14 @@ static void expr_primary(LexState *ls, ExpDesc *v)
1965/* Parse simple expression. */ 1965/* Parse simple expression. */
1966static void expr_simple(LexState *ls, ExpDesc *v) 1966static void expr_simple(LexState *ls, ExpDesc *v)
1967{ 1967{
1968 switch (ls->token) { 1968 switch (ls->tok) {
1969 case TK_number: 1969 case TK_number:
1970 expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0); 1970 expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0);
1971 copyTV(ls->L, &v->u.nval, &ls->tokenval); 1971 copyTV(ls->L, &v->u.nval, &ls->tokval);
1972 break; 1972 break;
1973 case TK_string: 1973 case TK_string:
1974 expr_init(v, VKSTR, 0); 1974 expr_init(v, VKSTR, 0);
1975 v->u.sval = strV(&ls->tokenval); 1975 v->u.sval = strV(&ls->tokval);
1976 break; 1976 break;
1977 case TK_nil: 1977 case TK_nil:
1978 expr_init(v, VKNIL, 0); 1978 expr_init(v, VKNIL, 0);
@@ -2060,11 +2060,11 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit);
2060static void expr_unop(LexState *ls, ExpDesc *v) 2060static void expr_unop(LexState *ls, ExpDesc *v)
2061{ 2061{
2062 BCOp op; 2062 BCOp op;
2063 if (ls->token == TK_not) { 2063 if (ls->tok == TK_not) {
2064 op = BC_NOT; 2064 op = BC_NOT;
2065 } else if (ls->token == '-') { 2065 } else if (ls->tok == '-') {
2066 op = BC_UNM; 2066 op = BC_UNM;
2067 } else if (ls->token == '#') { 2067 } else if (ls->tok == '#') {
2068 op = BC_LEN; 2068 op = BC_LEN;
2069 } else { 2069 } else {
2070 expr_simple(ls, v); 2070 expr_simple(ls, v);
@@ -2081,7 +2081,7 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit)
2081 BinOpr op; 2081 BinOpr op;
2082 synlevel_begin(ls); 2082 synlevel_begin(ls);
2083 expr_unop(ls, v); 2083 expr_unop(ls, v);
2084 op = token2binop(ls->token); 2084 op = token2binop(ls->tok);
2085 while (op != OPR_NOBINOPR && priority[op].left > limit) { 2085 while (op != OPR_NOBINOPR && priority[op].left > limit) {
2086 ExpDesc v2; 2086 ExpDesc v2;
2087 BinOpr nextop; 2087 BinOpr nextop;
@@ -2270,9 +2270,9 @@ static void parse_func(LexState *ls, BCLine line)
2270 lj_lex_next(ls); /* Skip 'function'. */ 2270 lj_lex_next(ls); /* Skip 'function'. */
2271 /* Parse function name. */ 2271 /* Parse function name. */
2272 var_lookup(ls, &v); 2272 var_lookup(ls, &v);
2273 while (ls->token == '.') /* Multiple dot-separated fields. */ 2273 while (ls->tok == '.') /* Multiple dot-separated fields. */
2274 expr_field(ls, &v); 2274 expr_field(ls, &v);
2275 if (ls->token == ':') { /* Optional colon to signify method call. */ 2275 if (ls->tok == ':') { /* Optional colon to signify method call. */
2276 needself = 1; 2276 needself = 1;
2277 expr_field(ls, &v); 2277 expr_field(ls, &v);
2278 } 2278 }
@@ -2285,9 +2285,9 @@ static void parse_func(LexState *ls, BCLine line)
2285/* -- Control transfer statements ----------------------------------------- */ 2285/* -- Control transfer statements ----------------------------------------- */
2286 2286
2287/* Check for end of block. */ 2287/* Check for end of block. */
2288static int endofblock(LexToken token) 2288static int parse_isend(LexToken tok)
2289{ 2289{
2290 switch (token) { 2290 switch (tok) {
2291 case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: 2291 case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof:
2292 return 1; 2292 return 1;
2293 default: 2293 default:
@@ -2302,7 +2302,7 @@ static void parse_return(LexState *ls)
2302 FuncState *fs = ls->fs; 2302 FuncState *fs = ls->fs;
2303 lj_lex_next(ls); /* Skip 'return'. */ 2303 lj_lex_next(ls); /* Skip 'return'. */
2304 fs->flags |= PROTO_HAS_RETURN; 2304 fs->flags |= PROTO_HAS_RETURN;
2305 if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ 2305 if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */
2306 ins = BCINS_AD(BC_RET0, 0, 1); 2306 ins = BCINS_AD(BC_RET0, 0, 1);
2307 } else { /* Return with one or more values. */ 2307 } else { /* Return with one or more values. */
2308 ExpDesc e; /* Receives the _last_ expression in the list. */ 2308 ExpDesc e; /* Receives the _last_ expression in the list. */
@@ -2368,18 +2368,18 @@ static void parse_label(LexState *ls)
2368 lex_check(ls, TK_label); 2368 lex_check(ls, TK_label);
2369 /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ 2369 /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */
2370 for (;;) { 2370 for (;;) {
2371 if (ls->token == TK_label) { 2371 if (ls->tok == TK_label) {
2372 synlevel_begin(ls); 2372 synlevel_begin(ls);
2373 parse_label(ls); 2373 parse_label(ls);
2374 synlevel_end(ls); 2374 synlevel_end(ls);
2375 } else if (LJ_52 && ls->token == ';') { 2375 } else if (LJ_52 && ls->tok == ';') {
2376 lj_lex_next(ls); 2376 lj_lex_next(ls);
2377 } else { 2377 } else {
2378 break; 2378 break;
2379 } 2379 }
2380 } 2380 }
2381 /* Trailing label is considered to be outside of scope. */ 2381 /* Trailing label is considered to be outside of scope. */
2382 if (endofblock(ls->token) && ls->token != TK_until) 2382 if (parse_isend(ls->tok) && ls->tok != TK_until)
2383 ls->vstack[idx].slot = fs->bl->nactvar; 2383 ls->vstack[idx].slot = fs->bl->nactvar;
2384 gola_resolve(ls, fs->bl, idx); 2384 gola_resolve(ls, fs->bl, idx);
2385} 2385}
@@ -2563,9 +2563,9 @@ static void parse_for(LexState *ls, BCLine line)
2563 fscope_begin(fs, &bl, FSCOPE_LOOP); 2563 fscope_begin(fs, &bl, FSCOPE_LOOP);
2564 lj_lex_next(ls); /* Skip 'for'. */ 2564 lj_lex_next(ls); /* Skip 'for'. */
2565 varname = lex_str(ls); /* Get first variable name. */ 2565 varname = lex_str(ls); /* Get first variable name. */
2566 if (ls->token == '=') 2566 if (ls->tok == '=')
2567 parse_for_num(ls, varname, line); 2567 parse_for_num(ls, varname, line);
2568 else if (ls->token == ',' || ls->token == TK_in) 2568 else if (ls->tok == ',' || ls->tok == TK_in)
2569 parse_for_iter(ls, varname); 2569 parse_for_iter(ls, varname);
2570 else 2570 else
2571 err_syntax(ls, LJ_ERR_XFOR); 2571 err_syntax(ls, LJ_ERR_XFOR);
@@ -2591,12 +2591,12 @@ static void parse_if(LexState *ls, BCLine line)
2591 BCPos flist; 2591 BCPos flist;
2592 BCPos escapelist = NO_JMP; 2592 BCPos escapelist = NO_JMP;
2593 flist = parse_then(ls); 2593 flist = parse_then(ls);
2594 while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ 2594 while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */
2595 jmp_append(fs, &escapelist, bcemit_jmp(fs)); 2595 jmp_append(fs, &escapelist, bcemit_jmp(fs));
2596 jmp_tohere(fs, flist); 2596 jmp_tohere(fs, flist);
2597 flist = parse_then(ls); 2597 flist = parse_then(ls);
2598 } 2598 }
2599 if (ls->token == TK_else) { /* Parse optional 'else' block. */ 2599 if (ls->tok == TK_else) { /* Parse optional 'else' block. */
2600 jmp_append(fs, &escapelist, bcemit_jmp(fs)); 2600 jmp_append(fs, &escapelist, bcemit_jmp(fs));
2601 jmp_tohere(fs, flist); 2601 jmp_tohere(fs, flist);
2602 lj_lex_next(ls); /* Skip 'else'. */ 2602 lj_lex_next(ls); /* Skip 'else'. */
@@ -2614,7 +2614,7 @@ static void parse_if(LexState *ls, BCLine line)
2614static int parse_stmt(LexState *ls) 2614static int parse_stmt(LexState *ls)
2615{ 2615{
2616 BCLine line = ls->linenumber; 2616 BCLine line = ls->linenumber;
2617 switch (ls->token) { 2617 switch (ls->tok) {
2618 case TK_if: 2618 case TK_if:
2619 parse_if(ls, line); 2619 parse_if(ls, line);
2620 break; 2620 break;
@@ -2672,7 +2672,7 @@ static void parse_chunk(LexState *ls)
2672{ 2672{
2673 int islast = 0; 2673 int islast = 0;
2674 synlevel_begin(ls); 2674 synlevel_begin(ls);
2675 while (!islast && !endofblock(ls->token)) { 2675 while (!islast && !parse_isend(ls->tok)) {
2676 islast = parse_stmt(ls); 2676 islast = parse_stmt(ls);
2677 lex_opt(ls, ';'); 2677 lex_opt(ls, ';');
2678 lua_assert(ls->fs->framesize >= ls->fs->freereg && 2678 lua_assert(ls->fs->framesize >= ls->fs->freereg &&
@@ -2707,7 +2707,7 @@ GCproto *lj_parse(LexState *ls)
2707 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ 2707 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */
2708 lj_lex_next(ls); /* Read-ahead first token. */ 2708 lj_lex_next(ls); /* Read-ahead first token. */
2709 parse_chunk(ls); 2709 parse_chunk(ls);
2710 if (ls->token != TK_eof) 2710 if (ls->tok != TK_eof)
2711 err_token(ls, TK_eof); 2711 err_token(ls, TK_eof);
2712 pt = fs_finish(ls, ls->linenumber); 2712 pt = fs_finish(ls, ls->linenumber);
2713 L->top--; /* Drop chunkname. */ 2713 L->top--; /* Drop chunkname. */