aboutsummaryrefslogtreecommitdiff
path: root/src/lj_cparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_cparse.c')
-rw-r--r--src/lj_cparse.c67
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. */
160static CPToken cp_integer(CPState *cp) 161static 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;