diff options
Diffstat (limited to 'src/lj_cparse.c')
-rw-r--r-- | src/lj_cparse.c | 67 |
1 files changed, 22 insertions, 45 deletions
diff --git a/src/lj_cparse.c b/src/lj_cparse.c index e9826715..ab5903fa 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "lj_frame.h" | 15 | #include "lj_frame.h" |
16 | #include "lj_vm.h" | 16 | #include "lj_vm.h" |
17 | #include "lj_char.h" | 17 | #include "lj_char.h" |
18 | #include "lj_strscan.h" | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | ** Important note: this is NOT a validating C parser! This is a minimal | 21 | ** Important note: this is NOT a validating C parser! This is a minimal |
@@ -156,40 +157,19 @@ LJ_NORET LJ_NOINLINE static void cp_err(CPState *cp, ErrMsg em) | |||
156 | 157 | ||
157 | /* -- Main lexical scanner ------------------------------------------------ */ | 158 | /* -- Main lexical scanner ------------------------------------------------ */ |
158 | 159 | ||
159 | /* Parse integer literal. */ | 160 | /* Parse number literal. Only handles int32_t/uint32_t right now. */ |
160 | static CPToken cp_integer(CPState *cp) | 161 | static CPToken cp_number(CPState *cp) |
161 | { | 162 | { |
162 | uint32_t n = 0; | 163 | StrScanFmt fmt; |
163 | cp->val.id = CTID_INT32; | 164 | TValue o; |
164 | if (cp->c != '0') { /* Decimal. */ | 165 | do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); |
165 | do { | 166 | cp_save(cp, '\0'); |
166 | n = n*10 + (cp->c - '0'); | 167 | fmt = lj_strscan_scan((const uint8_t *)cp->sb.buf, &o, STRSCAN_OPT_C); |
167 | } while (lj_char_isdigit(cp_get(cp))); | 168 | if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; |
168 | } else if ((cp_get(cp)& ~0x20) == 'X') { /* Hexadecimal. */ | 169 | else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; |
169 | if (!lj_char_isxdigit(cp_get(cp))) | 170 | else if (!(cp->mode & CPARSE_MODE_SKIP)) |
170 | cp_err(cp, LJ_ERR_XNUMBER); | 171 | cp_errmsg(cp, CTOK_INTEGER, LJ_ERR_XNUMBER); |
171 | do { | 172 | cp->val.u32 = (uint32_t)o.i; |
172 | n = n*16 + (cp->c & 15); | ||
173 | if (!lj_char_isdigit(cp->c)) n += 9; | ||
174 | } while (lj_char_isxdigit(cp_get(cp))); | ||
175 | if (n >= 0x80000000u) cp->val.id = CTID_UINT32; | ||
176 | } else { /* Octal. */ | ||
177 | while (cp->c >= '0' && cp->c <= '7') { | ||
178 | n = n*8 + (cp->c - '0'); | ||
179 | cp_get(cp); | ||
180 | } | ||
181 | if (n >= 0x80000000u) cp->val.id = CTID_UINT32; | ||
182 | } | ||
183 | cp->val.u32 = n; | ||
184 | for (;;) { /* Parse suffixes. */ | ||
185 | if ((cp->c & ~0x20) == 'U') | ||
186 | cp->val.id = CTID_UINT32; | ||
187 | else if ((cp->c & ~0x20) != 'L') | ||
188 | break; | ||
189 | cp_get(cp); | ||
190 | } | ||
191 | if (lj_char_isident(cp->c) && !(cp->mode & CPARSE_MODE_SKIP)) | ||
192 | cp_errmsg(cp, cp->c, LJ_ERR_XNUMBER); | ||
193 | return CTOK_INTEGER; | 173 | return CTOK_INTEGER; |
194 | } | 174 | } |
195 | 175 | ||
@@ -319,37 +299,34 @@ static CPToken cp_next_(CPState *cp) | |||
319 | lj_str_resetbuf(&cp->sb); | 299 | lj_str_resetbuf(&cp->sb); |
320 | for (;;) { | 300 | for (;;) { |
321 | if (lj_char_isident(cp->c)) | 301 | if (lj_char_isident(cp->c)) |
322 | return lj_char_isdigit(cp->c) ? cp_integer(cp) : cp_ident(cp); | 302 | return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp); |
323 | switch (cp->c) { | 303 | switch (cp->c) { |
324 | case '\n': case '\r': cp_newline(cp); /* fallthrough. */ | 304 | case '\n': case '\r': cp_newline(cp); /* fallthrough. */ |
325 | case ' ': case '\t': case '\v': case '\f': cp_get(cp); break; | 305 | case ' ': case '\t': case '\v': case '\f': cp_get(cp); break; |
326 | case '"': case '\'': return cp_string(cp); | 306 | case '"': case '\'': return cp_string(cp); |
327 | case '/': | 307 | case '/': |
328 | cp_get(cp); | 308 | if (cp_get(cp) == '*') cp_comment_c(cp); |
329 | if (cp->c == '*') cp_comment_c(cp); | ||
330 | else if (cp->c == '/') cp_comment_cpp(cp); | 309 | else if (cp->c == '/') cp_comment_cpp(cp); |
331 | else return '/'; | 310 | else return '/'; |
332 | break; | 311 | break; |
333 | case '|': | 312 | case '|': |
334 | cp_get(cp); if (cp->c != '|') return '|'; cp_get(cp); return CTOK_OROR; | 313 | if (cp_get(cp) != '|') return '|'; cp_get(cp); return CTOK_OROR; |
335 | case '&': | 314 | case '&': |
336 | cp_get(cp); if (cp->c != '&') return '&'; cp_get(cp); return CTOK_ANDAND; | 315 | if (cp_get(cp) != '&') return '&'; cp_get(cp); return CTOK_ANDAND; |
337 | case '=': | 316 | case '=': |
338 | cp_get(cp); if (cp->c != '=') return '='; cp_get(cp); return CTOK_EQ; | 317 | if (cp_get(cp) != '=') return '='; cp_get(cp); return CTOK_EQ; |
339 | case '!': | 318 | case '!': |
340 | cp_get(cp); if (cp->c != '=') return '!'; cp_get(cp); return CTOK_NE; | 319 | if (cp_get(cp) != '=') return '!'; cp_get(cp); return CTOK_NE; |
341 | case '<': | 320 | case '<': |
342 | cp_get(cp); | 321 | if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; } |
343 | if (cp->c == '=') { cp_get(cp); return CTOK_LE; } | ||
344 | else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; } | 322 | else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; } |
345 | return '<'; | 323 | return '<'; |
346 | case '>': | 324 | case '>': |
347 | cp_get(cp); | 325 | if (cp_get(cp) == '=') { cp_get(cp); return CTOK_GE; } |
348 | if (cp->c == '=') { cp_get(cp); return CTOK_GE; } | ||
349 | else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; } | 326 | else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; } |
350 | return '>'; | 327 | return '>'; |
351 | case '-': | 328 | case '-': |
352 | cp_get(cp); if (cp->c != '>') return '-'; cp_get(cp); return CTOK_DEREF; | 329 | if (cp_get(cp) != '>') return '-'; cp_get(cp); return CTOK_DEREF; |
353 | case '$': | 330 | case '$': |
354 | return cp_param(cp); | 331 | return cp_param(cp); |
355 | case '\0': return CTOK_EOF; | 332 | case '\0': return CTOK_EOF; |