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.c110
1 files changed, 31 insertions, 79 deletions
diff --git a/src/lj_lex.c b/src/lj_lex.c
index 669d2dfe..55e2bea1 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -23,6 +23,7 @@
23#include "lj_lex.h" 23#include "lj_lex.h"
24#include "lj_parse.h" 24#include "lj_parse.h"
25#include "lj_char.h" 25#include "lj_char.h"
26#include "lj_strscan.h"
26 27
27/* Lua lexer token names. */ 28/* Lua lexer token names. */
28static const char *const tokennames[] = { 29static const char *const tokennames[] = {
@@ -84,100 +85,51 @@ static void inclinenumber(LexState *ls)
84 85
85/* -- Scanner for terminals ----------------------------------------------- */ 86/* -- Scanner for terminals ----------------------------------------------- */
86 87
87#if LJ_HASFFI
88/* Load FFI library on-demand. Needed if we create cdata objects. */
89static void lex_loadffi(lua_State *L)
90{
91 ptrdiff_t oldtop = savestack(L, L->top);
92 luaopen_ffi(L);
93 L->top = restorestack(L, oldtop);
94}
95
96/* Parse 64 bit integer. */
97static int lex_number64(LexState *ls, TValue *tv)
98{
99 uint64_t n = 0;
100 uint8_t *p = (uint8_t *)ls->sb.buf;
101 CTypeID id = CTID_INT64;
102 GCcdata *cd;
103 int numl = 0;
104 if (p[0] == '0' && (p[1] & ~0x20) == 'X') { /* Hexadecimal. */
105 p += 2;
106 if (!lj_char_isxdigit(*p)) return 0;
107 do {
108 n = n*16 + (*p & 15);
109 if (!lj_char_isdigit(*p)) n += 9;
110 p++;
111 } while (lj_char_isxdigit(*p));
112 } else { /* Decimal. */
113 if (!lj_char_isdigit(*p)) return 0;
114 do {
115 n = n*10 + (*p - '0');
116 p++;
117 } while (lj_char_isdigit(*p));
118 }
119 for (;;) { /* Parse suffixes. */
120 if ((*p & ~0x20) == 'U')
121 id = CTID_UINT64;
122 else if ((*p & ~0x20) == 'L')
123 numl++;
124 else
125 break;
126 p++;
127 }
128 if (numl != 2 || *p != '\0') return 0;
129 /* Return cdata holding a 64 bit integer. */
130 cd = lj_cdata_new_(ls->L, id, 8);
131 *(uint64_t *)cdataptr(cd) = n;
132 lj_parse_keepcdata(ls, tv, cd);
133 return 1; /* Ok. */
134}
135#endif
136
137/* Parse a number literal. */ 88/* Parse a number literal. */
138static void lex_number(LexState *ls, TValue *tv) 89static void lex_number(LexState *ls, TValue *tv)
139{ 90{
140 int c, xp = 'E'; 91 StrScanFmt fmt;
92 int c, xp = 'e';
141 lua_assert(lj_char_isdigit(ls->current)); 93 lua_assert(lj_char_isdigit(ls->current));
142 if ((c = ls->current) == '0') { 94 if ((c = ls->current) == '0') {
143 save_and_next(ls); 95 save_and_next(ls);
144 if ((ls->current & ~0x20) == 'X') xp = 'P'; 96 if ((ls->current | 0x20) == 'x') xp = 'p';
145 } 97 }
146 while (lj_char_isident(ls->current) || ls->current == '.' || 98 while (lj_char_isident(ls->current) || ls->current == '.' ||
147 ((ls->current == '-' || ls->current == '+') && (c & ~0x20) == xp)) { 99 ((ls->current == '-' || ls->current == '+') && (c | 0x20) == xp)) {
148 c = ls->current; 100 c = ls->current;
149 save_and_next(ls); 101 save_and_next(ls);
150 } 102 }
151#if LJ_HASFFI
152 c &= ~0x20;
153 if ((c == 'I' || c == 'L' || c == 'U') && !ctype_ctsG(G(ls->L)))
154 lex_loadffi(ls->L);
155 if (c == 'I') /* Parse imaginary part of complex number. */
156 ls->sb.n--;
157#endif
158 save(ls, '\0'); 103 save(ls, '\0');
159#if LJ_HASFFI 104 fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv,
160 if ((c == 'L' || c == 'U') && lex_number64(ls, tv)) { /* Parse 64 bit int. */ 105 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
161 return; 106 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
162 } else 107 if (LJ_DUALNUM && fmt == STRSCAN_INT) {
163#endif 108 setitype(tv, LJ_TISNUM);
164 if (lj_str_numconv(ls->sb.buf, tv)) { 109 } else if (fmt == STRSCAN_NUM) {
165#if LJ_HASFFI 110 /* Already in correct format. */
166 if (c == 'I') { /* Return cdata holding a complex number. */ 111 } else if (LJ_HASFFI && fmt != STRSCAN_ERROR) {
167 GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double)); 112 lua_State *L = ls->L;
168 ((double *)cdataptr(cd))[0] = 0; 113 GCcdata *cd;
169 ((double *)cdataptr(cd))[1] = numberVnum(tv); 114 lua_assert(fmt == STRSCAN_I64 || fmt == STRSCAN_U64 || fmt == STRSCAN_IMAG);
170 lj_parse_keepcdata(ls, tv, cd); 115 if (!ctype_ctsG(G(L))) {
116 ptrdiff_t oldtop = savestack(L, L->top);
117 luaopen_ffi(L); /* Load FFI library on-demand. */
118 L->top = restorestack(L, oldtop);
171 } 119 }
172#endif 120 if (fmt == STRSCAN_IMAG) {
173 if (LJ_DUALNUM && tvisnum(tv)) { 121 cd = lj_cdata_new_(L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
174 int32_t k = lj_num2int(numV(tv)); 122 ((double *)cdataptr(cd))[0] = 0;
175 if ((lua_Number)k == numV(tv)) /* -0 cannot end up here. */ 123 ((double *)cdataptr(cd))[1] = numV(tv);
176 setintV(tv, k); 124 } else {
125 cd = lj_cdata_new_(L, fmt==STRSCAN_I64 ? CTID_INT64 : CTID_UINT64, 8);
126 *(uint64_t *)cdataptr(cd) = tv->u64;
177 } 127 }
178 return; 128 lj_parse_keepcdata(ls, tv, cd);
129 } else {
130 lua_assert(fmt == STRSCAN_ERROR);
131 lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
179 } 132 }
180 lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
181} 133}
182 134
183static int skip_sep(LexState *ls) 135static int skip_sep(LexState *ls)