aboutsummaryrefslogtreecommitdiff
path: root/src/lj_lex.c
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 /src/lj_lex.c
parent116cdd7e9a578efffa5a9ca38167d059d12296d7 (diff)
downloadluajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.tar.gz
luajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.tar.bz2
luajit-87c51e7f57ec9277a02e7e21c8a28b4cb9d08914.zip
Cleanup lexer source code.
Diffstat (limited to 'src/lj_lex.c')
-rw-r--r--src/lj_lex.c301
1 files changed, 157 insertions, 144 deletions
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;