diff options
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 196 |
1 files changed, 114 insertions, 82 deletions
@@ -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 */ |
35 | static const char *const token2string [] = { | 32 | static const char *const token2string [] = { |
@@ -70,10 +67,8 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { | |||
70 | void luaX_error (LexState *ls, const char *s, int token) { | 67 | void 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 | ||
99 | static 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 | |||
109 | static void inclinenumber (LexState *LS) { | 94 | static 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 | ||
142 | static void read_long_string (lua_State *L, LexState *LS) { | 136 | static 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 */ | ||
150 | static 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 | |||
187 | static 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 | ||
178 | static void read_string (lua_State *L, LexState *LS, int del) { | 230 | static 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 | ||
224 | int luaX_lex (LexState *LS) { | 282 | int 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; |