aboutsummaryrefslogtreecommitdiff
path: root/llex.c
diff options
context:
space:
mode:
Diffstat (limited to 'llex.c')
-rw-r--r--llex.c196
1 files changed, 114 insertions, 82 deletions
diff --git a/llex.c b/llex.c
index 6a9039d1..d16cb99f 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.67 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: llex.c,v 1.68 2000/08/22 20:07:56 roberto Exp $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,9 +27,6 @@
27#define next(LS) (LS->current = zgetc(LS->z)) 27#define next(LS) (LS->current = zgetc(LS->z))
28 28
29 29
30#define save(L, c) luaL_addchar(L, c)
31#define save_and_next(L, LS) (save(L, LS->current), next(LS))
32
33 30
34/* ORDER RESERVED */ 31/* ORDER RESERVED */
35static const char *const token2string [] = { 32static const char *const token2string [] = {
@@ -70,10 +67,8 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
70void luaX_error (LexState *ls, const char *s, int token) { 67void luaX_error (LexState *ls, const char *s, int token) {
71 char buff[TOKEN_LEN]; 68 char buff[TOKEN_LEN];
72 luaX_token2str(token, buff); 69 luaX_token2str(token, buff);
73 if (buff[0] == '\0') { 70 if (buff[0] == '\0')
74 save(ls->L, '\0'); 71 luaX_syntaxerror(ls, s, ls->L->Mbuffer);
75 luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
76 }
77 else 72 else
78 luaX_syntaxerror(ls, s, buff); 73 luaX_syntaxerror(ls, s, buff);
79} 74}
@@ -96,16 +91,6 @@ static void luaX_invalidchar (LexState *ls, int c) {
96} 91}
97 92
98 93
99static const char *readname (lua_State *L, LexState *LS) {
100 luaL_resetbuffer(L);
101 do {
102 save_and_next(L, LS);
103 } while (isalnum(LS->current) || LS->current == '_');
104 save(L, '\0');
105 return L->Mbuffer+L->Mbuffbase;
106}
107
108
109static void inclinenumber (LexState *LS) { 94static void inclinenumber (LexState *LS) {
110 next(LS); /* skip '\n' */ 95 next(LS); /* skip '\n' */
111 ++LS->linenumber; 96 ++LS->linenumber;
@@ -138,61 +123,133 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
138*/ 123*/
139 124
140 125
126/* use Mbuffer to store names, literal strings and numbers */
127
128#define EXTRABUFF 128
129#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
130 luaO_openspace(L, (len)+(n)+EXTRABUFF)
131
132#define save(L, c, l) (L->Mbuffer[l++] = (char)c)
133#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS))
134
141 135
142static void read_long_string (lua_State *L, LexState *LS) { 136static const char *readname (LexState *LS) {
137 lua_State *L = LS->L;
138 size_t l = 0;
139 checkbuffer(L, 10, l);
140 do {
141 checkbuffer(L, 10, l);
142 save_and_next(L, LS, l);
143 } while (isalnum(LS->current) || LS->current == '_');
144 save(L, '\0', l);
145 return L->Mbuffer;
146}
147
148
149/* LUA_NUMBER */
150static void read_number (LexState *LS, int comma) {
151 lua_State *L = LS->L;
152 size_t l = 0;
153 checkbuffer(L, 10, l);
154 if (comma) save(L, '.', l);
155 while (isdigit(LS->current)) {
156 checkbuffer(L, 10, l);
157 save_and_next(L, LS, l);
158 }
159 if (LS->current == '.') {
160 save_and_next(L, LS, l);
161 if (LS->current == '.') {
162 save_and_next(L, LS, l);
163 save(L, '\0', l);
164 luaX_error(LS, "ambiguous syntax"
165 " (decimal point x string concatenation)", TK_NUMBER);
166 }
167 }
168 while (isdigit(LS->current)) {
169 checkbuffer(L, 10, l);
170 save_and_next(L, LS, l);
171 }
172 if (LS->current == 'e' || LS->current == 'E') {
173 save_and_next(L, LS, l); /* read 'E' */
174 if (LS->current == '+' || LS->current == '-')
175 save_and_next(L, LS, l); /* optional exponent sign */
176 while (isdigit(LS->current)) {
177 checkbuffer(L, 10, l);
178 save_and_next(L, LS, l);
179 }
180 }
181 save(L, '\0', l);
182 if (!luaO_str2d(L->Mbuffer, &LS->t.seminfo.r))
183 luaX_error(LS, "malformed number", TK_NUMBER);
184}
185
186
187static void read_long_string (LexState *LS) {
188 lua_State *L = LS->L;
143 int cont = 0; 189 int cont = 0;
190 size_t l = 0;
191 checkbuffer(L, 10, l);
192 save(L, '[', l); /* save first '[' */
193 save_and_next(L, LS, l); /* pass the second '[' */
144 for (;;) { 194 for (;;) {
195 checkbuffer(L, 10, l);
145 switch (LS->current) { 196 switch (LS->current) {
146 case EOZ: 197 case EOZ:
198 save(L, '\0', l);
147 luaX_error(LS, "unfinished long string", TK_STRING); 199 luaX_error(LS, "unfinished long string", TK_STRING);
148 break; /* to avoid warnings */ 200 break; /* to avoid warnings */
149 case '[': 201 case '[':
150 save_and_next(L, LS); 202 save_and_next(L, LS, l);
151 if (LS->current == '[') { 203 if (LS->current == '[') {
152 cont++; 204 cont++;
153 save_and_next(L, LS); 205 save_and_next(L, LS, l);
154 } 206 }
155 continue; 207 continue;
156 case ']': 208 case ']':
157 save_and_next(L, LS); 209 save_and_next(L, LS, l);
158 if (LS->current == ']') { 210 if (LS->current == ']') {
159 if (cont == 0) goto endloop; 211 if (cont == 0) goto endloop;
160 cont--; 212 cont--;
161 save_and_next(L, LS); 213 save_and_next(L, LS, l);
162 } 214 }
163 continue; 215 continue;
164 case '\n': 216 case '\n':
165 save(L, '\n'); 217 save(L, '\n', l);
166 inclinenumber(LS); 218 inclinenumber(LS);
167 continue; 219 continue;
168 default: 220 default:
169 save_and_next(L, LS); 221 save_and_next(L, LS, l);
170 } 222 }
171 } endloop: 223 } endloop:
172 save_and_next(L, LS); /* skip the second ']' */ 224 save_and_next(L, LS, l); /* skip the second ']' */
173 LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), 225 save(L, '\0', l);
174 L->Mbuffnext-L->Mbuffbase-4); 226 LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
175} 227}
176 228
177 229
178static void read_string (lua_State *L, LexState *LS, int del) { 230static void read_string (LexState *LS, int del) {
179 save_and_next(L, LS); 231 lua_State *L = LS->L;
232 size_t l = 0;
233 checkbuffer(L, 10, l);
234 save_and_next(L, LS, l);
180 while (LS->current != del) { 235 while (LS->current != del) {
236 checkbuffer(L, 10, l);
181 switch (LS->current) { 237 switch (LS->current) {
182 case EOZ: case '\n': 238 case EOZ: case '\n':
239 save(L, '\0', l);
183 luaX_error(LS, "unfinished string", TK_STRING); 240 luaX_error(LS, "unfinished string", TK_STRING);
184 break; /* to avoid warnings */ 241 break; /* to avoid warnings */
185 case '\\': 242 case '\\':
186 next(LS); /* do not save the '\' */ 243 next(LS); /* do not save the '\' */
187 switch (LS->current) { 244 switch (LS->current) {
188 case 'a': save(L, '\a'); next(LS); break; 245 case 'a': save(L, '\a', l); next(LS); break;
189 case 'b': save(L, '\b'); next(LS); break; 246 case 'b': save(L, '\b', l); next(LS); break;
190 case 'f': save(L, '\f'); next(LS); break; 247 case 'f': save(L, '\f', l); next(LS); break;
191 case 'n': save(L, '\n'); next(LS); break; 248 case 'n': save(L, '\n', l); next(LS); break;
192 case 'r': save(L, '\r'); next(LS); break; 249 case 'r': save(L, '\r', l); next(LS); break;
193 case 't': save(L, '\t'); next(LS); break; 250 case 't': save(L, '\t', l); next(LS); break;
194 case 'v': save(L, '\v'); next(LS); break; 251 case 'v': save(L, '\v', l); next(LS); break;
195 case '\n': save(L, '\n'); inclinenumber(LS); break; 252 case '\n': save(L, '\n', l); inclinenumber(LS); break;
196 case '0': case '1': case '2': case '3': case '4': 253 case '0': case '1': case '2': case '3': case '4':
197 case '5': case '6': case '7': case '8': case '9': { 254 case '5': case '6': case '7': case '8': case '9': {
198 int c = 0; 255 int c = 0;
@@ -201,28 +258,28 @@ static void read_string (lua_State *L, LexState *LS, int del) {
201 c = 10*c + (LS->current-'0'); 258 c = 10*c + (LS->current-'0');
202 next(LS); 259 next(LS);
203 } while (++i<3 && isdigit(LS->current)); 260 } while (++i<3 && isdigit(LS->current));
204 if (c != (unsigned char)c) 261 if (c != (unsigned char)c) {
262 save(L, '\0', l);
205 luaX_error(LS, "escape sequence too large", TK_STRING); 263 luaX_error(LS, "escape sequence too large", TK_STRING);
206 save(L, c); 264 }
265 save(L, c, l);
207 break; 266 break;
208 } 267 }
209 default: /* handles \\, \", \', and \? */ 268 default: /* handles \\, \", \', and \? */
210 save(L, LS->current); 269 save_and_next(L, LS, l);
211 next(LS);
212 } 270 }
213 break; 271 break;
214 default: 272 default:
215 save_and_next(L, LS); 273 save_and_next(L, LS, l);
216 } 274 }
217 } 275 }
218 save_and_next(L, LS); /* skip delimiter */ 276 save_and_next(L, LS, l); /* skip delimiter */
219 LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), 277 save(L, '\0', l);
220 L->Mbuffnext-L->Mbuffbase-2); 278 LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
221} 279}
222 280
223 281
224int luaX_lex (LexState *LS) { 282int luaX_lex (LexState *LS) {
225 lua_State *L = LS->L;
226 for (;;) { 283 for (;;) {
227 switch (LS->current) { 284 switch (LS->current) {
228 285
@@ -245,12 +302,10 @@ int luaX_lex (LexState *LS) {
245 continue; 302 continue;
246 303
247 case '[': 304 case '[':
248 luaL_resetbuffer(L); 305 next(LS);
249 save_and_next(L, LS);
250 if (LS->current != '[') return '['; 306 if (LS->current != '[') return '[';
251 else { 307 else {
252 save_and_next(L, LS); /* pass the second '[' */ 308 read_long_string(LS);
253 read_long_string(L, LS);
254 return TK_STRING; 309 return TK_STRING;
255 } 310 }
256 311
@@ -276,13 +331,11 @@ int luaX_lex (LexState *LS) {
276 331
277 case '"': 332 case '"':
278 case '\'': 333 case '\'':
279 luaL_resetbuffer(L); 334 read_string(LS, LS->current);
280 read_string(L, LS, LS->current);
281 return TK_STRING; 335 return TK_STRING;
282 336
283 case '.': 337 case '.':
284 luaL_resetbuffer(L); 338 next(LS);
285 save_and_next(L, LS);
286 if (LS->current == '.') { 339 if (LS->current == '.') {
287 next(LS); 340 next(LS);
288 if (LS->current == '.') { 341 if (LS->current == '.') {
@@ -292,35 +345,14 @@ int luaX_lex (LexState *LS) {
292 else return TK_CONCAT; /* .. */ 345 else return TK_CONCAT; /* .. */
293 } 346 }
294 else if (!isdigit(LS->current)) return '.'; 347 else if (!isdigit(LS->current)) return '.';
295 else goto fraction; /* LS->current is a digit */ 348 else {
349 read_number(LS, 1);
350 return TK_NUMBER;
351 }
296 352
297 case '0': case '1': case '2': case '3': case '4': 353 case '0': case '1': case '2': case '3': case '4':
298 case '5': case '6': case '7': case '8': case '9': 354 case '5': case '6': case '7': case '8': case '9':
299 luaL_resetbuffer(L); 355 read_number(LS, 0);
300 do {
301 save_and_next(L, LS);
302 } while (isdigit(LS->current));
303 if (LS->current == '.') {
304 save_and_next(L, LS);
305 if (LS->current == '.') {
306 save(L, '.');
307 luaX_error(LS, "ambiguous syntax"
308 " (decimal point x string concatenation)", TK_NUMBER);
309 }
310 }
311 fraction: /* LUA_NUMBER */
312 while (isdigit(LS->current))
313 save_and_next(L, LS);
314 if (LS->current == 'e' || LS->current == 'E') {
315 save_and_next(L, LS); /* read 'E' */
316 if (LS->current == '+' || LS->current == '-')
317 save_and_next(L, LS); /* optional exponent sign */
318 while (isdigit(LS->current))
319 save_and_next(L, LS);
320 }
321 save(L, '\0');
322 if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->t.seminfo.r))
323 luaX_error(LS, "malformed number", TK_NUMBER);
324 return TK_NUMBER; 356 return TK_NUMBER;
325 357
326 case EOZ: 358 case EOZ:
@@ -337,7 +369,7 @@ int luaX_lex (LexState *LS) {
337 return c; 369 return c;
338 } 370 }
339 tname: { /* identifier or reserved word */ 371 tname: { /* identifier or reserved word */
340 TString *ts = luaS_new(L, readname(L, LS)); 372 TString *ts = luaS_new(LS->L, readname(LS));
341 if (ts->marked >= RESERVEDMARK) /* reserved word? */ 373 if (ts->marked >= RESERVEDMARK) /* reserved word? */
342 return ts->marked-RESERVEDMARK+FIRST_RESERVED; 374 return ts->marked-RESERVEDMARK+FIRST_RESERVED;
343 LS->t.seminfo.ts = ts; 375 LS->t.seminfo.ts = ts;