diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-08-29 13:48:14 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-08-29 13:48:14 -0300 |
commit | 0ff1596476f7e3f65cd5505d148d43baf58fbaac (patch) | |
tree | 34d219d0e33c70131d01353095d916678f96120f /llex.c | |
parent | b27664e0db93f513fe43fa582a9950b8ad701905 (diff) | |
download | lua-0ff1596476f7e3f65cd5505d148d43baf58fbaac.tar.gz lua-0ff1596476f7e3f65cd5505d148d43baf58fbaac.tar.bz2 lua-0ff1596476f7e3f65cd5505d148d43baf58fbaac.zip |
new form of long strings: `[***[...]***]'
Diffstat (limited to 'llex.c')
-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); |