aboutsummaryrefslogtreecommitdiff
path: root/src/lj_lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_lex.c')
-rw-r--r--src/lj_lex.c342
1 files changed, 171 insertions, 171 deletions
diff --git a/src/lj_lex.c b/src/lj_lex.c
index 9f2b06f8..7c2c6677 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -12,6 +12,7 @@
12#include "lj_obj.h" 12#include "lj_obj.h"
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_buf.h"
15#include "lj_str.h" 16#include "lj_str.h"
16#if LJ_HASFFI 17#if LJ_HASFFI
17#include "lj_tab.h" 18#include "lj_tab.h"
@@ -24,6 +25,7 @@
24#include "lj_parse.h" 25#include "lj_parse.h"
25#include "lj_char.h" 26#include "lj_char.h"
26#include "lj_strscan.h" 27#include "lj_strscan.h"
28#include "lj_strfmt.h"
27 29
28/* Lua lexer token names. */ 30/* Lua lexer token names. */
29static const char *const tokennames[] = { 31static const char *const tokennames[] = {
@@ -37,50 +39,48 @@ TKDEF(TKSTR1, TKSTR2)
37 39
38/* -- Buffer handling ----------------------------------------------------- */ 40/* -- Buffer handling ----------------------------------------------------- */
39 41
40#define char2int(c) ((int)(uint8_t)(c)) 42#define LEX_EOF (-1)
41#define next(ls) \ 43#define lex_iseol(ls) (ls->c == '\n' || ls->c == '\r')
42 (ls->current = (ls->n--) > 0 ? char2int(*ls->p++) : fillbuf(ls))
43#define save_and_next(ls) (save(ls, ls->current), next(ls))
44#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
45#define END_OF_STREAM (-1)
46 44
47static int fillbuf(LexState *ls) 45/* Get more input from reader. */
46static LJ_NOINLINE LexChar lex_more(LexState *ls)
48{ 47{
49 size_t sz; 48 size_t sz;
50 const char *buf = ls->rfunc(ls->L, ls->rdata, &sz); 49 const char *p = ls->rfunc(ls->L, ls->rdata, &sz);
51 if (buf == NULL || sz == 0) return END_OF_STREAM; 50 if (p == NULL || sz == 0) return LEX_EOF;
52 ls->n = (MSize)sz - 1; 51 ls->pe = p + sz;
53 ls->p = buf; 52 ls->p = p + 1;
54 return char2int(*(ls->p++)); 53 return (LexChar)(uint8_t)p[0];
55} 54}
56 55
57static LJ_NOINLINE void save_grow(LexState *ls, int c) 56/* Get next character. */
57static LJ_AINLINE LexChar lex_next(LexState *ls)
58{ 58{
59 MSize newsize; 59 return (ls->c = ls->p < ls->pe ? (LexChar)(uint8_t)*ls->p++ : lex_more(ls));
60 if (ls->sb.sz >= LJ_MAX_STR/2)
61 lj_lex_error(ls, 0, LJ_ERR_XELEM);
62 newsize = ls->sb.sz * 2;
63 lj_str_resizebuf(ls->L, &ls->sb, newsize);
64 ls->sb.buf[ls->sb.n++] = (char)c;
65} 60}
66 61
67static LJ_AINLINE void save(LexState *ls, int c) 62/* Save character. */
63static LJ_AINLINE void lex_save(LexState *ls, LexChar c)
68{ 64{
69 if (LJ_UNLIKELY(ls->sb.n + 1 > ls->sb.sz)) 65 lj_buf_putb(&ls->sb, c);
70 save_grow(ls, c); 66}
71 else 67
72 ls->sb.buf[ls->sb.n++] = (char)c; 68/* Save previous character and get next character. */
69static LJ_AINLINE LexChar lex_savenext(LexState *ls)
70{
71 lex_save(ls, ls->c);
72 return lex_next(ls);
73} 73}
74 74
75static void inclinenumber(LexState *ls) 75/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
76static void lex_newline(LexState *ls)
76{ 77{
77 int old = ls->current; 78 LexChar old = ls->c;
78 lua_assert(currIsNewline(ls)); 79 lua_assert(lex_iseol(ls));
79 next(ls); /* skip `\n' or `\r' */ 80 lex_next(ls); /* Skip "\n" or "\r". */
80 if (currIsNewline(ls) && ls->current != old) 81 if (lex_iseol(ls) && ls->c != old) lex_next(ls); /* Skip "\n\r" or "\r\n". */
81 next(ls); /* skip `\n\r' or `\r\n' */
82 if (++ls->linenumber >= LJ_MAX_LINE) 82 if (++ls->linenumber >= LJ_MAX_LINE)
83 lj_lex_error(ls, ls->token, LJ_ERR_XLINES); 83 lj_lex_error(ls, ls->tok, LJ_ERR_XLINES);
84} 84}
85 85
86/* -- Scanner for terminals ----------------------------------------------- */ 86/* -- Scanner for terminals ----------------------------------------------- */
@@ -89,19 +89,17 @@ static void inclinenumber(LexState *ls)
89static void lex_number(LexState *ls, TValue *tv) 89static void lex_number(LexState *ls, TValue *tv)
90{ 90{
91 StrScanFmt fmt; 91 StrScanFmt fmt;
92 int c, xp = 'e'; 92 LexChar c, xp = 'e';
93 lua_assert(lj_char_isdigit(ls->current)); 93 lua_assert(lj_char_isdigit(ls->c));
94 if ((c = ls->current) == '0') { 94 if ((c = ls->c) == '0' && (lex_savenext(ls) | 0x20) == 'x')
95 save_and_next(ls); 95 xp = 'p';
96 if ((ls->current | 0x20) == 'x') xp = 'p'; 96 while (lj_char_isident(ls->c) || ls->c == '.' ||
97 } 97 ((ls->c == '-' || ls->c == '+') && (c | 0x20) == xp)) {
98 while (lj_char_isident(ls->current) || ls->current == '.' || 98 c = ls->c;
99 ((ls->current == '-' || ls->current == '+') && (c | 0x20) == xp)) { 99 lex_savenext(ls);
100 c = ls->current;
101 save_and_next(ls);
102 } 100 }
103 save(ls, '\0'); 101 lex_save(ls, '\0');
104 fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv, 102 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), tv,
105 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | 103 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
106 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); 104 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
107 if (LJ_DUALNUM && fmt == STRSCAN_INT) { 105 if (LJ_DUALNUM && fmt == STRSCAN_INT) {
@@ -134,60 +132,60 @@ static void lex_number(LexState *ls, TValue *tv)
134 } 132 }
135} 133}
136 134
137static int skip_sep(LexState *ls) 135/* Skip equal signs for "[=...=[" and "]=...=]" and return their count. */
136static int lex_skipeq(LexState *ls)
138{ 137{
139 int count = 0; 138 int count = 0;
140 int s = ls->current; 139 LexChar s = ls->c;
141 lua_assert(s == '[' || s == ']'); 140 lua_assert(s == '[' || s == ']');
142 save_and_next(ls); 141 while (lex_savenext(ls) == '=')
143 while (ls->current == '=') {
144 save_and_next(ls);
145 count++; 142 count++;
146 } 143 return (ls->c == s) ? count : (-count) - 1;
147 return (ls->current == s) ? count : (-count) - 1;
148} 144}
149 145
150static void read_long_string(LexState *ls, TValue *tv, int sep) 146/* Parse a long string or long comment (tv set to NULL). */
147static void lex_longstring(LexState *ls, TValue *tv, int sep)
151{ 148{
152 save_and_next(ls); /* skip 2nd `[' */ 149 lex_savenext(ls); /* Skip second '['. */
153 if (currIsNewline(ls)) /* string starts with a newline? */ 150 if (lex_iseol(ls)) /* Skip initial newline. */
154 inclinenumber(ls); /* skip it */ 151 lex_newline(ls);
155 for (;;) { 152 for (;;) {
156 switch (ls->current) { 153 switch (ls->c) {
157 case END_OF_STREAM: 154 case LEX_EOF:
158 lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM); 155 lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM);
159 break; 156 break;
160 case ']': 157 case ']':
161 if (skip_sep(ls) == sep) { 158 if (lex_skipeq(ls) == sep) {
162 save_and_next(ls); /* skip 2nd `]' */ 159 lex_savenext(ls); /* Skip second ']'. */
163 goto endloop; 160 goto endloop;
164 } 161 }
165 break; 162 break;
166 case '\n': 163 case '\n':
167 case '\r': 164 case '\r':
168 save(ls, '\n'); 165 lex_save(ls, '\n');
169 inclinenumber(ls); 166 lex_newline(ls);
170 if (!tv) lj_str_resetbuf(&ls->sb); /* avoid wasting space */ 167 if (!tv) lj_buf_reset(&ls->sb); /* Don't waste space for comments. */
171 break; 168 break;
172 default: 169 default:
173 if (tv) save_and_next(ls); 170 lex_savenext(ls);
174 else next(ls);
175 break; 171 break;
176 } 172 }
177 } endloop: 173 } endloop:
178 if (tv) { 174 if (tv) {
179 GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep), 175 GCstr *str = lj_parse_keepstr(ls, sbufB(&ls->sb) + (2 + (MSize)sep),
180 ls->sb.n - 2*(2 + (MSize)sep)); 176 sbuflen(&ls->sb) - 2*(2 + (MSize)sep));
181 setstrV(ls->L, tv, str); 177 setstrV(ls->L, tv, str);
182 } 178 }
183} 179}
184 180
185static void read_string(LexState *ls, int delim, TValue *tv) 181/* Parse a string. */
182static void lex_string(LexState *ls, TValue *tv)
186{ 183{
187 save_and_next(ls); 184 LexChar delim = ls->c; /* Delimiter is '\'' or '"'. */
188 while (ls->current != delim) { 185 lex_savenext(ls);
189 switch (ls->current) { 186 while (ls->c != delim) {
190 case END_OF_STREAM: 187 switch (ls->c) {
188 case LEX_EOF:
191 lj_lex_error(ls, TK_eof, LJ_ERR_XSTR); 189 lj_lex_error(ls, TK_eof, LJ_ERR_XSTR);
192 continue; 190 continue;
193 case '\n': 191 case '\n':
@@ -195,7 +193,7 @@ static void read_string(LexState *ls, int delim, TValue *tv)
195 lj_lex_error(ls, TK_string, LJ_ERR_XSTR); 193 lj_lex_error(ls, TK_string, LJ_ERR_XSTR);
196 continue; 194 continue;
197 case '\\': { 195 case '\\': {
198 int c = next(ls); /* Skip the '\\'. */ 196 LexChar c = lex_next(ls); /* Skip the '\\'. */
199 switch (c) { 197 switch (c) {
200 case 'a': c = '\a'; break; 198 case 'a': c = '\a'; break;
201 case 'b': c = '\b'; break; 199 case 'b': c = '\b'; break;
@@ -205,111 +203,112 @@ static void read_string(LexState *ls, int delim, TValue *tv)
205 case 't': c = '\t'; break; 203 case 't': c = '\t'; break;
206 case 'v': c = '\v'; break; 204 case 'v': c = '\v'; break;
207 case 'x': /* Hexadecimal escape '\xXX'. */ 205 case 'x': /* Hexadecimal escape '\xXX'. */
208 c = (next(ls) & 15u) << 4; 206 c = (lex_next(ls) & 15u) << 4;
209 if (!lj_char_isdigit(ls->current)) { 207 if (!lj_char_isdigit(ls->c)) {
210 if (!lj_char_isxdigit(ls->current)) goto err_xesc; 208 if (!lj_char_isxdigit(ls->c)) goto err_xesc;
211 c += 9 << 4; 209 c += 9 << 4;
212 } 210 }
213 c += (next(ls) & 15u); 211 c += (lex_next(ls) & 15u);
214 if (!lj_char_isdigit(ls->current)) { 212 if (!lj_char_isdigit(ls->c)) {
215 if (!lj_char_isxdigit(ls->current)) goto err_xesc; 213 if (!lj_char_isxdigit(ls->c)) goto err_xesc;
216 c += 9; 214 c += 9;
217 } 215 }
218 break; 216 break;
219 case 'z': /* Skip whitespace. */ 217 case 'z': /* Skip whitespace. */
220 next(ls); 218 lex_next(ls);
221 while (lj_char_isspace(ls->current)) 219 while (lj_char_isspace(ls->c))
222 if (currIsNewline(ls)) inclinenumber(ls); else next(ls); 220 if (lex_iseol(ls)) lex_newline(ls); else lex_next(ls);
223 continue; 221 continue;
224 case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue; 222 case '\n': case '\r': lex_save(ls, '\n'); lex_newline(ls); continue;
225 case '\\': case '\"': case '\'': break; 223 case '\\': case '\"': case '\'': break;
226 case END_OF_STREAM: continue; 224 case LEX_EOF: continue;
227 default: 225 default:
228 if (!lj_char_isdigit(c)) 226 if (!lj_char_isdigit(c))
229 goto err_xesc; 227 goto err_xesc;
230 c -= '0'; /* Decimal escape '\ddd'. */ 228 c -= '0'; /* Decimal escape '\ddd'. */
231 if (lj_char_isdigit(next(ls))) { 229 if (lj_char_isdigit(lex_next(ls))) {
232 c = c*10 + (ls->current - '0'); 230 c = c*10 + (ls->c - '0');
233 if (lj_char_isdigit(next(ls))) { 231 if (lj_char_isdigit(lex_next(ls))) {
234 c = c*10 + (ls->current - '0'); 232 c = c*10 + (ls->c - '0');
235 if (c > 255) { 233 if (c > 255) {
236 err_xesc: 234 err_xesc:
237 lj_lex_error(ls, TK_string, LJ_ERR_XESC); 235 lj_lex_error(ls, TK_string, LJ_ERR_XESC);
238 } 236 }
239 next(ls); 237 lex_next(ls);
240 } 238 }
241 } 239 }
242 save(ls, c); 240 lex_save(ls, c);
243 continue; 241 continue;
244 } 242 }
245 save(ls, c); 243 lex_save(ls, c);
246 next(ls); 244 lex_next(ls);
247 continue; 245 continue;
248 } 246 }
249 default: 247 default:
250 save_and_next(ls); 248 lex_savenext(ls);
251 break; 249 break;
252 } 250 }
253 } 251 }
254 save_and_next(ls); /* skip delimiter */ 252 lex_savenext(ls); /* Skip trailing delimiter. */
255 setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2)); 253 setstrV(ls->L, tv,
254 lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2));
256} 255}
257 256
258/* -- Main lexical scanner ------------------------------------------------ */ 257/* -- Main lexical scanner ------------------------------------------------ */
259 258
260static int llex(LexState *ls, TValue *tv) 259/* Get next lexical token. */
260static LexToken lex_scan(LexState *ls, TValue *tv)
261{ 261{
262 lj_str_resetbuf(&ls->sb); 262 lj_buf_reset(&ls->sb);
263 for (;;) { 263 for (;;) {
264 if (lj_char_isident(ls->current)) { 264 if (lj_char_isident(ls->c)) {
265 GCstr *s; 265 GCstr *s;
266 if (lj_char_isdigit(ls->current)) { /* Numeric literal. */ 266 if (lj_char_isdigit(ls->c)) { /* Numeric literal. */
267 lex_number(ls, tv); 267 lex_number(ls, tv);
268 return TK_number; 268 return TK_number;
269 } 269 }
270 /* Identifier or reserved word. */ 270 /* Identifier or reserved word. */
271 do { 271 do {
272 save_and_next(ls); 272 lex_savenext(ls);
273 } while (lj_char_isident(ls->current)); 273 } while (lj_char_isident(ls->c));
274 s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n); 274 s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb));
275 setstrV(ls->L, tv, s); 275 setstrV(ls->L, tv, s);
276 if (s->reserved > 0) /* Reserved word? */ 276 if (s->reserved > 0) /* Reserved word? */
277 return TK_OFS + s->reserved; 277 return TK_OFS + s->reserved;
278 return TK_name; 278 return TK_name;
279 } 279 }
280 switch (ls->current) { 280 switch (ls->c) {
281 case '\n': 281 case '\n':
282 case '\r': 282 case '\r':
283 inclinenumber(ls); 283 lex_newline(ls);
284 continue; 284 continue;
285 case ' ': 285 case ' ':
286 case '\t': 286 case '\t':
287 case '\v': 287 case '\v':
288 case '\f': 288 case '\f':
289 next(ls); 289 lex_next(ls);
290 continue; 290 continue;
291 case '-': 291 case '-':
292 next(ls); 292 lex_next(ls);
293 if (ls->current != '-') return '-'; 293 if (ls->c != '-') return '-';
294 /* else is a comment */ 294 lex_next(ls);
295 next(ls); 295 if (ls->c == '[') { /* Long comment "--[=*[...]=*]". */
296 if (ls->current == '[') { 296 int sep = lex_skipeq(ls);
297 int sep = skip_sep(ls); 297 lj_buf_reset(&ls->sb); /* `lex_skipeq' may dirty the buffer */
298 lj_str_resetbuf(&ls->sb); /* `skip_sep' may dirty the buffer */
299 if (sep >= 0) { 298 if (sep >= 0) {
300 read_long_string(ls, NULL, sep); /* long comment */ 299 lex_longstring(ls, NULL, sep);
301 lj_str_resetbuf(&ls->sb); 300 lj_buf_reset(&ls->sb);
302 continue; 301 continue;
303 } 302 }
304 } 303 }
305 /* else short comment */ 304 /* Short comment "--.*\n". */
306 while (!currIsNewline(ls) && ls->current != END_OF_STREAM) 305 while (!lex_iseol(ls) && ls->c != LEX_EOF)
307 next(ls); 306 lex_next(ls);
308 continue; 307 continue;
309 case '[': { 308 case '[': {
310 int sep = skip_sep(ls); 309 int sep = lex_skipeq(ls);
311 if (sep >= 0) { 310 if (sep >= 0) {
312 read_long_string(ls, tv, sep); 311 lex_longstring(ls, tv, sep);
313 return TK_string; 312 return TK_string;
314 } else if (sep == -1) { 313 } else if (sep == -1) {
315 return '['; 314 return '[';
@@ -319,44 +318,43 @@ static int llex(LexState *ls, TValue *tv)
319 } 318 }
320 } 319 }
321 case '=': 320 case '=':
322 next(ls); 321 lex_next(ls);
323 if (ls->current != '=') return '='; else { next(ls); return TK_eq; } 322 if (ls->c != '=') return '='; else { lex_next(ls); return TK_eq; }
324 case '<': 323 case '<':
325 next(ls); 324 lex_next(ls);
326 if (ls->current != '=') return '<'; else { next(ls); return TK_le; } 325 if (ls->c != '=') return '<'; else { lex_next(ls); return TK_le; }
327 case '>': 326 case '>':
328 next(ls); 327 lex_next(ls);
329 if (ls->current != '=') return '>'; else { next(ls); return TK_ge; } 328 if (ls->c != '=') return '>'; else { lex_next(ls); return TK_ge; }
330 case '~': 329 case '~':
331 next(ls); 330 lex_next(ls);
332 if (ls->current != '=') return '~'; else { next(ls); return TK_ne; } 331 if (ls->c != '=') return '~'; else { lex_next(ls); return TK_ne; }
333 case ':': 332 case ':':
334 next(ls); 333 lex_next(ls);
335 if (ls->current != ':') return ':'; else { next(ls); return TK_label; } 334 if (ls->c != ':') return ':'; else { lex_next(ls); return TK_label; }
336 case '"': 335 case '"':
337 case '\'': 336 case '\'':
338 read_string(ls, ls->current, tv); 337 lex_string(ls, tv);
339 return TK_string; 338 return TK_string;
340 case '.': 339 case '.':
341 save_and_next(ls); 340 if (lex_savenext(ls) == '.') {
342 if (ls->current == '.') { 341 lex_next(ls);
343 next(ls); 342 if (ls->c == '.') {
344 if (ls->current == '.') { 343 lex_next(ls);
345 next(ls);
346 return TK_dots; /* ... */ 344 return TK_dots; /* ... */
347 } 345 }
348 return TK_concat; /* .. */ 346 return TK_concat; /* .. */
349 } else if (!lj_char_isdigit(ls->current)) { 347 } else if (!lj_char_isdigit(ls->c)) {
350 return '.'; 348 return '.';
351 } else { 349 } else {
352 lex_number(ls, tv); 350 lex_number(ls, tv);
353 return TK_number; 351 return TK_number;
354 } 352 }
355 case END_OF_STREAM: 353 case LEX_EOF:
356 return TK_eof; 354 return TK_eof;
357 default: { 355 default: {
358 int c = ls->current; 356 LexChar c = ls->c;
359 next(ls); 357 lex_next(ls);
360 return c; /* Single-char tokens (+ - / ...). */ 358 return c; /* Single-char tokens (+ - / ...). */
361 } 359 }
362 } 360 }
@@ -371,8 +369,7 @@ int lj_lex_setup(lua_State *L, LexState *ls)
371 int header = 0; 369 int header = 0;
372 ls->L = L; 370 ls->L = L;
373 ls->fs = NULL; 371 ls->fs = NULL;
374 ls->n = 0; 372 ls->pe = ls->p = NULL;
375 ls->p = NULL;
376 ls->vstack = NULL; 373 ls->vstack = NULL;
377 ls->sizevstack = 0; 374 ls->sizevstack = 0;
378 ls->vtop = 0; 375 ls->vtop = 0;
@@ -381,24 +378,22 @@ int lj_lex_setup(lua_State *L, LexState *ls)
381 ls->lookahead = TK_eof; /* No look-ahead token. */ 378 ls->lookahead = TK_eof; /* No look-ahead token. */
382 ls->linenumber = 1; 379 ls->linenumber = 1;
383 ls->lastline = 1; 380 ls->lastline = 1;
384 lj_str_resizebuf(ls->L, &ls->sb, LJ_MIN_SBUF); 381 lex_next(ls); /* Read-ahead first char. */
385 next(ls); /* Read-ahead first char. */ 382 if (ls->c == 0xef && ls->p + 2 <= ls->pe && (uint8_t)ls->p[0] == 0xbb &&
386 if (ls->current == 0xef && ls->n >= 2 && char2int(ls->p[0]) == 0xbb && 383 (uint8_t)ls->p[1] == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
387 char2int(ls->p[1]) == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
388 ls->n -= 2;
389 ls->p += 2; 384 ls->p += 2;
390 next(ls); 385 lex_next(ls);
391 header = 1; 386 header = 1;
392 } 387 }
393 if (ls->current == '#') { /* Skip POSIX #! header line. */ 388 if (ls->c == '#') { /* Skip POSIX #! header line. */
394 do { 389 do {
395 next(ls); 390 lex_next(ls);
396 if (ls->current == END_OF_STREAM) return 0; 391 if (ls->c == LEX_EOF) return 0;
397 } while (!currIsNewline(ls)); 392 } while (!lex_iseol(ls));
398 inclinenumber(ls); 393 lex_newline(ls);
399 header = 1; 394 header = 1;
400 } 395 }
401 if (ls->current == LUA_SIGNATURE[0]) { /* Bytecode dump. */ 396 if (ls->c == LUA_SIGNATURE[0]) { /* Bytecode dump. */
402 if (header) { 397 if (header) {
403 /* 398 /*
404 ** Loading bytecode with an extra header is disabled for security 399 ** Loading bytecode with an extra header is disabled for security
@@ -420,55 +415,60 @@ void lj_lex_cleanup(lua_State *L, LexState *ls)
420 global_State *g = G(L); 415 global_State *g = G(L);
421 lj_mem_freevec(g, ls->bcstack, ls->sizebcstack, BCInsLine); 416 lj_mem_freevec(g, ls->bcstack, ls->sizebcstack, BCInsLine);
422 lj_mem_freevec(g, ls->vstack, ls->sizevstack, VarInfo); 417 lj_mem_freevec(g, ls->vstack, ls->sizevstack, VarInfo);
423 lj_str_freebuf(g, &ls->sb); 418 lj_buf_free(g, &ls->sb);
424} 419}
425 420
421/* Return next lexical token. */
426void lj_lex_next(LexState *ls) 422void lj_lex_next(LexState *ls)
427{ 423{
428 ls->lastline = ls->linenumber; 424 ls->lastline = ls->linenumber;
429 if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */ 425 if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */
430 ls->token = llex(ls, &ls->tokenval); /* Get next token. */ 426 ls->tok = lex_scan(ls, &ls->tokval); /* Get next token. */
431 } else { /* Otherwise return lookahead token. */ 427 } else { /* Otherwise return lookahead token. */
432 ls->token = ls->lookahead; 428 ls->tok = ls->lookahead;
433 ls->lookahead = TK_eof; 429 ls->lookahead = TK_eof;
434 ls->tokenval = ls->lookaheadval; 430 ls->tokval = ls->lookaheadval;
435 } 431 }
436} 432}
437 433
434/* Look ahead for the next token. */
438LexToken lj_lex_lookahead(LexState *ls) 435LexToken lj_lex_lookahead(LexState *ls)
439{ 436{
440 lua_assert(ls->lookahead == TK_eof); 437 lua_assert(ls->lookahead == TK_eof);
441 ls->lookahead = llex(ls, &ls->lookaheadval); 438 ls->lookahead = lex_scan(ls, &ls->lookaheadval);
442 return ls->lookahead; 439 return ls->lookahead;
443} 440}
444 441
445const char *lj_lex_token2str(LexState *ls, LexToken token) 442/* Convert token to string. */
443const char *lj_lex_token2str(LexState *ls, LexToken tok)
446{ 444{
447 if (token > TK_OFS) 445 if (tok > TK_OFS)
448 return tokennames[token-TK_OFS-1]; 446 return tokennames[tok-TK_OFS-1];
449 else if (!lj_char_iscntrl(token)) 447 else if (!lj_char_iscntrl(tok))
450 return lj_str_pushf(ls->L, "%c", token); 448 return lj_strfmt_pushf(ls->L, "%c", tok);
451 else 449 else
452 return lj_str_pushf(ls->L, "char(%d)", token); 450 return lj_strfmt_pushf(ls->L, "char(%d)", tok);
453} 451}
454 452
455void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...) 453/* Lexer error. */
454void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...)
456{ 455{
457 const char *tok; 456 const char *tokstr;
458 va_list argp; 457 va_list argp;
459 if (token == 0) { 458 if (tok == 0) {
460 tok = NULL; 459 tokstr = NULL;
461 } else if (token == TK_name || token == TK_string || token == TK_number) { 460 } else if (tok == TK_name || tok == TK_string || tok == TK_number) {
462 save(ls, '\0'); 461 lex_save(ls, '\0');
463 tok = ls->sb.buf; 462 tokstr = sbufB(&ls->sb);
464 } else { 463 } else {
465 tok = lj_lex_token2str(ls, token); 464 tokstr = lj_lex_token2str(ls, tok);
466 } 465 }
467 va_start(argp, em); 466 va_start(argp, em);
468 lj_err_lex(ls->L, ls->chunkname, tok, ls->linenumber, em, argp); 467 lj_err_lex(ls->L, ls->chunkname, tokstr, ls->linenumber, em, argp);
469 va_end(argp); 468 va_end(argp);
470} 469}
471 470
471/* Initialize strings for reserved words. */
472void lj_lex_init(lua_State *L) 472void lj_lex_init(lua_State *L)
473{ 473{
474 uint32_t i; 474 uint32_t i;