diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-08 15:46:08 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-08 15:46:08 -0300 |
| commit | b3d0682fb94f56a438dbb4fdb2b3440ccc10cfb4 (patch) | |
| tree | 746fc9900768dfaf1ddffca35cb4f6fd55903bbf /llex.c | |
| parent | 02afc892d5ce5d85e88faac443d7294589ee697a (diff) | |
| download | lua-b3d0682fb94f56a438dbb4fdb2b3440ccc10cfb4.tar.gz lua-b3d0682fb94f56a438dbb4fdb2b3440ccc10cfb4.tar.bz2 lua-b3d0682fb94f56a438dbb4fdb2b3440ccc10cfb4.zip | |
use of different buffers for scanner and concatenation
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; |
