diff options
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 129 |
1 files changed, 63 insertions, 66 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.111 2002/09/05 19:45:42 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.112 2002/09/19 13:03:53 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -100,7 +100,7 @@ static void luaX_lexerror (LexState *ls, const char *s, int token) { | |||
100 | if (token == TK_EOS) | 100 | if (token == TK_EOS) |
101 | luaX_error(ls, s, luaX_token2str(ls, token)); | 101 | luaX_error(ls, s, luaX_token2str(ls, token)); |
102 | else | 102 | else |
103 | luaX_error(ls, s, cast(char *, G(ls->L)->Mbuffer)); | 103 | luaX_error(ls, s, luaZ_buffer(ls->buff)); |
104 | } | 104 | } |
105 | 105 | ||
106 | 106 | ||
@@ -138,146 +138,143 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { | |||
138 | 138 | ||
139 | /* use Mbuffer to store names, literal strings and numbers */ | 139 | /* use Mbuffer to store names, literal strings and numbers */ |
140 | 140 | ||
141 | #define EXTRABUFF 128 | 141 | #define EXTRABUFF 32 |
142 | #define checkbuffer(L, len) \ | 142 | #define checkbuffer(LS, len) \ |
143 | if (((len)+10)*sizeof(char) > G(L)->Mbuffsize) \ | 143 | if (((len)+3)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \ |
144 | luaO_openspace(L, (len)+EXTRABUFF) | 144 | luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF) |
145 | 145 | ||
146 | #define save(L, c, l) (cast(char *, G(L)->Mbuffer)[l++] = cast(char, c)) | 146 | #define save(LS, c, l) \ |
147 | #define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) | 147 | (cast(char *, luaZ_buffer((LS)->buff))[l++] = cast(char, c)) |
148 | #define save_and_next(LS, l) (save(LS, LS->current, l), next(LS)) | ||
148 | 149 | ||
149 | 150 | ||
150 | static size_t readname (LexState *LS) { | 151 | static size_t readname (LexState *LS) { |
151 | lua_State *L = LS->L; | ||
152 | size_t l = 0; | 152 | size_t l = 0; |
153 | checkbuffer(L, l); | 153 | checkbuffer(LS, l); |
154 | do { | 154 | do { |
155 | checkbuffer(L, l); | 155 | checkbuffer(LS, l); |
156 | save_and_next(L, LS, l); | 156 | save_and_next(LS, l); |
157 | } while (isalnum(LS->current) || LS->current == '_'); | 157 | } while (isalnum(LS->current) || LS->current == '_'); |
158 | save(L, '\0', l); | 158 | save(LS, '\0', l); |
159 | return l-1; | 159 | return l-1; |
160 | } | 160 | } |
161 | 161 | ||
162 | 162 | ||
163 | /* LUA_NUMBER */ | 163 | /* LUA_NUMBER */ |
164 | static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { | 164 | static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { |
165 | lua_State *L = LS->L; | ||
166 | size_t l = 0; | 165 | size_t l = 0; |
167 | checkbuffer(L, l); | 166 | checkbuffer(LS, l); |
168 | if (comma) save(L, '.', l); | 167 | if (comma) save(LS, '.', l); |
169 | while (isdigit(LS->current)) { | 168 | while (isdigit(LS->current)) { |
170 | checkbuffer(L, l); | 169 | checkbuffer(LS, l); |
171 | save_and_next(L, LS, l); | 170 | save_and_next(LS, l); |
172 | } | 171 | } |
173 | if (LS->current == '.') { | 172 | if (LS->current == '.') { |
174 | save_and_next(L, LS, l); | 173 | save_and_next(LS, l); |
175 | if (LS->current == '.') { | 174 | if (LS->current == '.') { |
176 | save_and_next(L, LS, l); | 175 | save_and_next(LS, l); |
177 | save(L, '\0', l); | 176 | save(LS, '\0', l); |
178 | luaX_lexerror(LS, | 177 | luaX_lexerror(LS, |
179 | "ambiguous syntax (decimal point x string concatenation)", | 178 | "ambiguous syntax (decimal point x string concatenation)", |
180 | TK_NUMBER); | 179 | TK_NUMBER); |
181 | } | 180 | } |
182 | } | 181 | } |
183 | while (isdigit(LS->current)) { | 182 | while (isdigit(LS->current)) { |
184 | checkbuffer(L, l); | 183 | checkbuffer(LS, l); |
185 | save_and_next(L, LS, l); | 184 | save_and_next(LS, l); |
186 | } | 185 | } |
187 | if (LS->current == 'e' || LS->current == 'E') { | 186 | if (LS->current == 'e' || LS->current == 'E') { |
188 | save_and_next(L, LS, l); /* read `E' */ | 187 | save_and_next(LS, l); /* read `E' */ |
189 | if (LS->current == '+' || LS->current == '-') | 188 | if (LS->current == '+' || LS->current == '-') |
190 | save_and_next(L, LS, l); /* optional exponent sign */ | 189 | save_and_next(LS, l); /* optional exponent sign */ |
191 | while (isdigit(LS->current)) { | 190 | while (isdigit(LS->current)) { |
192 | checkbuffer(L, l); | 191 | checkbuffer(LS, l); |
193 | save_and_next(L, LS, l); | 192 | save_and_next(LS, l); |
194 | } | 193 | } |
195 | } | 194 | } |
196 | save(L, '\0', l); | 195 | save(LS, '\0', l); |
197 | if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r)) | 196 | if (!luaO_str2d(cast(char *, luaZ_buffer(LS->buff)), &seminfo->r)) |
198 | luaX_lexerror(LS, "malformed number", TK_NUMBER); | 197 | luaX_lexerror(LS, "malformed number", TK_NUMBER); |
199 | } | 198 | } |
200 | 199 | ||
201 | 200 | ||
202 | static void read_long_string (LexState *LS, SemInfo *seminfo) { | 201 | static void read_long_string (LexState *LS, SemInfo *seminfo) { |
203 | lua_State *L = LS->L; | ||
204 | int cont = 0; | 202 | int cont = 0; |
205 | size_t l = 0; | 203 | size_t l = 0; |
206 | checkbuffer(L, l); | 204 | checkbuffer(LS, l); |
207 | save(L, '[', l); /* save first `[' */ | 205 | save(LS, '[', l); /* save first `[' */ |
208 | save_and_next(L, LS, l); /* pass the second `[' */ | 206 | save_and_next(LS, l); /* pass the second `[' */ |
209 | if (LS->current == '\n') /* string starts with a newline? */ | 207 | if (LS->current == '\n') /* string starts with a newline? */ |
210 | inclinenumber(LS); /* skip it */ | 208 | inclinenumber(LS); /* skip it */ |
211 | for (;;) { | 209 | for (;;) { |
212 | checkbuffer(L, l); | 210 | checkbuffer(LS, l); |
213 | switch (LS->current) { | 211 | switch (LS->current) { |
214 | case EOZ: | 212 | case EOZ: |
215 | save(L, '\0', l); | 213 | save(LS, '\0', l); |
216 | luaX_lexerror(LS, (seminfo) ? "unfinished long string" : | 214 | luaX_lexerror(LS, (seminfo) ? "unfinished long string" : |
217 | "unfinished long comment", TK_EOS); | 215 | "unfinished long comment", TK_EOS); |
218 | break; /* to avoid warnings */ | 216 | break; /* to avoid warnings */ |
219 | case '[': | 217 | case '[': |
220 | save_and_next(L, LS, l); | 218 | save_and_next(LS, l); |
221 | if (LS->current == '[') { | 219 | if (LS->current == '[') { |
222 | cont++; | 220 | cont++; |
223 | save_and_next(L, LS, l); | 221 | save_and_next(LS, l); |
224 | } | 222 | } |
225 | continue; | 223 | continue; |
226 | case ']': | 224 | case ']': |
227 | save_and_next(L, LS, l); | 225 | save_and_next(LS, l); |
228 | if (LS->current == ']') { | 226 | if (LS->current == ']') { |
229 | if (cont == 0) goto endloop; | 227 | if (cont == 0) goto endloop; |
230 | cont--; | 228 | cont--; |
231 | save_and_next(L, LS, l); | 229 | save_and_next(LS, l); |
232 | } | 230 | } |
233 | continue; | 231 | continue; |
234 | case '\n': | 232 | case '\n': |
235 | save(L, '\n', l); | 233 | save(LS, '\n', l); |
236 | inclinenumber(LS); | 234 | inclinenumber(LS); |
237 | if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ | 235 | if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ |
238 | continue; | 236 | continue; |
239 | default: | 237 | default: |
240 | save_and_next(L, LS, l); | 238 | save_and_next(LS, l); |
241 | } | 239 | } |
242 | } endloop: | 240 | } endloop: |
243 | save_and_next(L, LS, l); /* skip the second `]' */ | 241 | save_and_next(LS, l); /* skip the second `]' */ |
244 | save(L, '\0', l); | 242 | save(LS, '\0', l); |
245 | if (seminfo) | 243 | if (seminfo) |
246 | seminfo->ts = luaS_newlstr(L, cast(char *, G(L)->Mbuffer)+2, l-5); | 244 | seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); |
247 | } | 245 | } |
248 | 246 | ||
249 | 247 | ||
250 | static void read_string (LexState *LS, int del, SemInfo *seminfo) { | 248 | static void read_string (LexState *LS, int del, SemInfo *seminfo) { |
251 | lua_State *L = LS->L; | ||
252 | size_t l = 0; | 249 | size_t l = 0; |
253 | checkbuffer(L, l); | 250 | checkbuffer(LS, l); |
254 | save_and_next(L, LS, l); | 251 | save_and_next(LS, l); |
255 | while (LS->current != del) { | 252 | while (LS->current != del) { |
256 | checkbuffer(L, l); | 253 | checkbuffer(LS, l); |
257 | switch (LS->current) { | 254 | switch (LS->current) { |
258 | case EOZ: | 255 | case EOZ: |
259 | save(L, '\0', l); | 256 | save(LS, '\0', l); |
260 | luaX_lexerror(LS, "unfinished string", TK_EOS); | 257 | luaX_lexerror(LS, "unfinished string", TK_EOS); |
261 | break; /* to avoid warnings */ | 258 | break; /* to avoid warnings */ |
262 | case '\n': | 259 | case '\n': |
263 | save(L, '\0', l); | 260 | save(LS, '\0', l); |
264 | luaX_lexerror(LS, "unfinished string", TK_STRING); | 261 | luaX_lexerror(LS, "unfinished string", TK_STRING); |
265 | break; /* to avoid warnings */ | 262 | break; /* to avoid warnings */ |
266 | case '\\': | 263 | case '\\': |
267 | next(LS); /* do not save the `\' */ | 264 | next(LS); /* do not save the `\' */ |
268 | switch (LS->current) { | 265 | switch (LS->current) { |
269 | case 'a': save(L, '\a', l); next(LS); break; | 266 | case 'a': save(LS, '\a', l); next(LS); break; |
270 | case 'b': save(L, '\b', l); next(LS); break; | 267 | case 'b': save(LS, '\b', l); next(LS); break; |
271 | case 'f': save(L, '\f', l); next(LS); break; | 268 | case 'f': save(LS, '\f', l); next(LS); break; |
272 | case 'n': save(L, '\n', l); next(LS); break; | 269 | case 'n': save(LS, '\n', l); next(LS); break; |
273 | case 'r': save(L, '\r', l); next(LS); break; | 270 | case 'r': save(LS, '\r', l); next(LS); break; |
274 | case 't': save(L, '\t', l); next(LS); break; | 271 | case 't': save(LS, '\t', l); next(LS); break; |
275 | case 'v': save(L, '\v', l); next(LS); break; | 272 | case 'v': save(LS, '\v', l); next(LS); break; |
276 | case '\n': save(L, '\n', l); inclinenumber(LS); break; | 273 | case '\n': save(LS, '\n', l); inclinenumber(LS); break; |
277 | case EOZ: break; /* will raise an error next loop */ | 274 | case EOZ: break; /* will raise an error next loop */ |
278 | default: { | 275 | default: { |
279 | if (!isdigit(LS->current)) | 276 | if (!isdigit(LS->current)) |
280 | save_and_next(L, LS, l); /* handles \\, \", \', and \? */ | 277 | save_and_next(LS, l); /* handles \\, \", \', and \? */ |
281 | else { /* \xxx */ | 278 | else { /* \xxx */ |
282 | int c = 0; | 279 | int c = 0; |
283 | int i = 0; | 280 | int i = 0; |
@@ -286,21 +283,21 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) { | |||
286 | next(LS); | 283 | next(LS); |
287 | } while (++i<3 && isdigit(LS->current)); | 284 | } while (++i<3 && isdigit(LS->current)); |
288 | if (c > UCHAR_MAX) { | 285 | if (c > UCHAR_MAX) { |
289 | save(L, '\0', l); | 286 | save(LS, '\0', l); |
290 | luaX_lexerror(LS, "escape sequence too large", TK_STRING); | 287 | luaX_lexerror(LS, "escape sequence too large", TK_STRING); |
291 | } | 288 | } |
292 | save(L, c, l); | 289 | save(LS, c, l); |
293 | } | 290 | } |
294 | } | 291 | } |
295 | } | 292 | } |
296 | break; | 293 | break; |
297 | default: | 294 | default: |
298 | save_and_next(L, LS, l); | 295 | save_and_next(LS, l); |
299 | } | 296 | } |
300 | } | 297 | } |
301 | save_and_next(L, LS, l); /* skip delimiter */ | 298 | save_and_next(LS, l); /* skip delimiter */ |
302 | save(L, '\0', l); | 299 | save(LS, '\0', l); |
303 | seminfo->ts = luaS_newlstr(L, cast(char *, G(L)->Mbuffer)+1, l-3); | 300 | seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); |
304 | } | 301 | } |
305 | 302 | ||
306 | 303 | ||
@@ -388,7 +385,7 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { | |||
388 | else if (isalpha(LS->current) || LS->current == '_') { | 385 | else if (isalpha(LS->current) || LS->current == '_') { |
389 | /* identifier or reserved word */ | 386 | /* identifier or reserved word */ |
390 | size_t l = readname(LS); | 387 | size_t l = readname(LS); |
391 | TString *ts = luaS_newlstr(LS->L, cast(char *, G(LS->L)->Mbuffer), l); | 388 | TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); |
392 | if (ts->tsv.reserved > 0) /* reserved word? */ | 389 | if (ts->tsv.reserved > 0) /* reserved word? */ |
393 | return ts->tsv.reserved - 1 + FIRST_RESERVED; | 390 | return ts->tsv.reserved - 1 + FIRST_RESERVED; |
394 | seminfo->ts = ts; | 391 | seminfo->ts = ts; |