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.c95
1 files changed, 90 insertions, 5 deletions
diff --git a/src/lj_lex.c b/src/lj_lex.c
index a115b79a..01e5ce57 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -13,6 +13,12 @@
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_str.h" 15#include "lj_str.h"
16#if LJ_HASFFI
17#include "lj_tab.h"
18#include "lj_ctype.h"
19#include "lj_cdata.h"
20#include "lualib.h"
21#endif
16#include "lj_lex.h" 22#include "lj_lex.h"
17#include "lj_parse.h" 23#include "lj_parse.h"
18#include "lj_char.h" 24#include "lj_char.h"
@@ -77,7 +83,64 @@ static void inclinenumber(LexState *ls)
77 83
78/* -- Scanner for terminals ----------------------------------------------- */ 84/* -- Scanner for terminals ----------------------------------------------- */
79 85
80static void read_numeral(LexState *ls, TValue *tv) 86#if LJ_HASFFI
87/* Load FFI library on-demand. Needed if we create cdata objects. */
88static void lex_loadffi(lua_State *L)
89{
90 cTValue *tmp;
91 luaopen_ffi(L);
92 tmp = lj_tab_getstr(tabV(registry(L)), lj_str_newlit(L, "_LOADED"));
93 if (tmp && tvistab(tmp)) {
94 GCtab *t = tabV(tmp);
95 copyTV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "ffi")), L->top-1);
96 lj_gc_anybarriert(L, t);
97 }
98 L->top--;
99}
100
101/* Parse 64 bit integer. */
102static int lex_number64(LexState *ls, TValue *tv)
103{
104 uint64_t n = 0;
105 uint8_t *p = (uint8_t *)ls->sb.buf;
106 CTypeID id = CTID_INT64;
107 GCcdata *cd;
108 int numl = 0;
109 if (p[0] == '0' && (p[1] & ~0x20) == 'X') { /* Hexadecimal. */
110 p += 2;
111 if (!lj_char_isxdigit(*p)) return 0;
112 do {
113 n = n*16 + (*p & 15);
114 if (!lj_char_isdigit(*p)) n += 9;
115 p++;
116 } while (lj_char_isxdigit(*p));
117 } else { /* Decimal. */
118 if (!lj_char_isdigit(*p)) return 0;
119 do {
120 n = n*10 + (*p - '0');
121 p++;
122 } while (lj_char_isdigit(*p));
123 }
124 for (;;) { /* Parse suffixes. */
125 if ((*p & ~0x20) == 'U')
126 id = CTID_UINT64;
127 else if ((*p & ~0x20) == 'L')
128 numl++;
129 else
130 break;
131 p++;
132 }
133 if (numl != 2 || *p != '\0') return 0;
134 /* Return cdata holding a 64 bit integer. */
135 cd = lj_cdata_new_(ls->L, id, 8);
136 *(uint64_t *)cdataptr(cd) = n;
137 lj_parse_keepcdata(ls, tv, cd);
138 return 1; /* Ok. */
139}
140#endif
141
142/* Parse a number literal. */
143static void lex_number(LexState *ls, TValue *tv)
81{ 144{
82 int c; 145 int c;
83 lua_assert(lj_char_isdigit(ls->current)); 146 lua_assert(lj_char_isdigit(ls->current));
@@ -87,9 +150,31 @@ static void read_numeral(LexState *ls, TValue *tv)
87 } while (lj_char_isident(ls->current) || ls->current == '.' || 150 } while (lj_char_isident(ls->current) || ls->current == '.' ||
88 ((ls->current == '-' || ls->current == '+') && 151 ((ls->current == '-' || ls->current == '+') &&
89 ((c & ~0x20) == 'E' || (c & ~0x20) == 'P'))); 152 ((c & ~0x20) == 'E' || (c & ~0x20) == 'P')));
153#if LJ_HASFFI
154 c &= ~0x20;
155 if ((c == 'I' || c == 'L' || c == 'U') && !ctype_ctsG(G(ls->L)))
156 lex_loadffi(ls->L);
157 if (c == 'I') /* Parse imaginary part of complex number. */
158 ls->sb.n--;
159#endif
90 save(ls, '\0'); 160 save(ls, '\0');
91 if (!lj_str_numconv(ls->sb.buf, tv)) 161#if LJ_HASFFI
92 lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER); 162 if ((c == 'L' || c == 'U') && lex_number64(ls, tv)) { /* Parse 64 bit int. */
163 return;
164 } else
165#endif
166 if (lj_str_numconv(ls->sb.buf, tv)) {
167#if LJ_HASFFI
168 if (c == 'I') { /* Return cdata holding a complex number. */
169 GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
170 ((double *)cdataptr(cd))[0] = 0;
171 ((double *)cdataptr(cd))[1] = tv->n;
172 lj_parse_keepcdata(ls, tv, cd);
173 }
174#endif
175 return;
176 }
177 lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
93} 178}
94 179
95static int skip_sep(LexState *ls) 180static int skip_sep(LexState *ls)
@@ -224,7 +309,7 @@ static int llex(LexState *ls, TValue *tv)
224 if (lj_char_isident(ls->current)) { 309 if (lj_char_isident(ls->current)) {
225 GCstr *s; 310 GCstr *s;
226 if (lj_char_isdigit(ls->current)) { /* Numeric literal. */ 311 if (lj_char_isdigit(ls->current)) { /* Numeric literal. */
227 read_numeral(ls, tv); 312 lex_number(ls, tv);
228 return TK_number; 313 return TK_number;
229 } 314 }
230 /* Identifier or reserved word. */ 315 /* Identifier or reserved word. */
@@ -306,7 +391,7 @@ static int llex(LexState *ls, TValue *tv)
306 } else if (!lj_char_isdigit(ls->current)) { 391 } else if (!lj_char_isdigit(ls->current)) {
307 return '.'; 392 return '.';
308 } else { 393 } else {
309 read_numeral(ls, tv); 394 lex_number(ls, tv);
310 return TK_number; 395 return TK_number;
311 } 396 }
312 case END_OF_STREAM: 397 case END_OF_STREAM: