diff options
| -rw-r--r-- | llex.c | 63 |
1 files changed, 39 insertions, 24 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 1.122 2003/08/27 21:01:44 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.123 2003/08/28 14:38:46 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 | */ |
| @@ -196,9 +196,22 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | 198 | ||
| 199 | static void read_long_string (LexState *ls, SemInfo *seminfo) { | 199 | static int skip_ast (LexState *ls) { |
| 200 | int count = 0; | ||
| 201 | int s = ls->current; | ||
| 202 | lua_assert(s == '[' || s == ']'); | ||
| 203 | save_and_next(ls); | ||
| 204 | while (ls->current == '*') { | ||
| 205 | save_and_next(ls); | ||
| 206 | count++; | ||
| 207 | } | ||
| 208 | return (ls->current == s) ? count : (-count) - 1; | ||
| 209 | } | ||
| 210 | |||
| 211 | |||
| 212 | static void read_long_string (LexState *ls, SemInfo *seminfo, int ast) { | ||
| 200 | int cont = 0; | 213 | int cont = 0; |
| 201 | save_and_next(ls); /* pass the second `[' */ | 214 | save_and_next(ls); /* skip 2nd `[' */ |
| 202 | if (currIsNewline(ls)) /* string starts with a newline? */ | 215 | if (currIsNewline(ls)) /* string starts with a newline? */ |
| 203 | inclinenumber(ls); /* skip it */ | 216 | inclinenumber(ls); /* skip it */ |
| 204 | for (;;) { | 217 | for (;;) { |
| @@ -208,18 +221,15 @@ static void read_long_string (LexState *ls, SemInfo *seminfo) { | |||
| 208 | "unfinished long comment", TK_EOS); | 221 | "unfinished long comment", TK_EOS); |
| 209 | break; /* to avoid warnings */ | 222 | break; /* to avoid warnings */ |
| 210 | case '[': | 223 | case '[': |
| 211 | save_and_next(ls); | 224 | if (skip_ast(ls) == ast) { |
| 212 | if (ls->current == '[') { | 225 | save_and_next(ls); /* skip 2nd `[' */ |
| 213 | cont++; | 226 | cont++; |
| 214 | save_and_next(ls); | ||
| 215 | } | 227 | } |
| 216 | continue; | 228 | continue; |
| 217 | case ']': | 229 | case ']': |
| 218 | save_and_next(ls); | 230 | if (skip_ast(ls) == ast) { |
| 219 | if (ls->current == ']') { | 231 | save_and_next(ls); /* skip 2nd `]' */ |
| 220 | if (cont == 0) goto endloop; | 232 | if (cont-- == 0) goto endloop; |
| 221 | cont--; | ||
| 222 | save_and_next(ls); | ||
| 223 | } | 233 | } |
| 224 | continue; | 234 | continue; |
| 225 | case '\n': | 235 | case '\n': |
| @@ -233,10 +243,9 @@ static void read_long_string (LexState *ls, SemInfo *seminfo) { | |||
| 233 | else next(ls); | 243 | else next(ls); |
| 234 | } | 244 | } |
| 235 | } endloop: | 245 | } endloop: |
| 236 | save_and_next(ls); /* skip the second `]' */ | ||
| 237 | if (seminfo) | 246 | if (seminfo) |
| 238 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 2, | 247 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + ast), |
| 239 | luaZ_bufflen(ls->buff) - 4); | 248 | luaZ_bufflen(ls->buff) - 2*(2 + ast)); |
| 240 | } | 249 | } |
| 241 | 250 | ||
| 242 | 251 | ||
| @@ -310,22 +319,28 @@ int luaX_lex (LexState *ls, SemInfo *seminfo) { | |||
| 310 | if (ls->current != '-') return '-'; | 319 | if (ls->current != '-') return '-'; |
| 311 | /* else is a comment */ | 320 | /* else is a comment */ |
| 312 | next(ls); | 321 | next(ls); |
| 313 | if (ls->current == '[' && (next(ls), ls->current == '[')) { | 322 | if (ls->current == '[') { |
| 314 | read_long_string(ls, NULL); /* long comment */ | 323 | int ast = skip_ast(ls); |
| 315 | luaZ_resetbuffer(ls->buff); | 324 | luaZ_resetbuffer(ls->buff); /* `skip_ast' may dirty the buffer */ |
| 325 | if (ast >= 0) { | ||
| 326 | read_long_string(ls, NULL, ast); /* long comment */ | ||
| 327 | luaZ_resetbuffer(ls->buff); | ||
| 328 | continue; | ||
| 329 | } | ||
| 316 | } | 330 | } |
| 317 | else /* short comment */ | 331 | /* else short comment */ |
| 318 | while (!currIsNewline(ls) && ls->current != EOZ) | 332 | while (!currIsNewline(ls) && ls->current != EOZ) |
| 319 | next(ls); | 333 | next(ls); |
| 320 | continue; | 334 | continue; |
| 321 | } | 335 | } |
| 322 | case '[': { | 336 | case '[': { |
| 323 | save_and_next(ls); | 337 | int ast = skip_ast(ls); |
| 324 | if (ls->current != '[') return '['; | 338 | if (ast >= 0) { |
| 325 | else { | 339 | read_long_string(ls, seminfo, ast); |
| 326 | read_long_string(ls, seminfo); | ||
| 327 | return TK_STRING; | 340 | return TK_STRING; |
| 328 | } | 341 | } |
| 342 | else if (ast == -1) return '['; | ||
| 343 | else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); | ||
| 329 | } | 344 | } |
| 330 | case '=': { | 345 | case '=': { |
| 331 | next(ls); | 346 | next(ls); |
