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