diff options
Diffstat (limited to 'lpvm.c')
-rw-r--r-- | lpvm.c | 69 |
1 files changed, 14 insertions, 55 deletions
@@ -26,13 +26,6 @@ | |||
26 | 26 | ||
27 | static const Instruction giveup = {{IGiveup, 0, 0}}; | 27 | static const Instruction giveup = {{IGiveup, 0, 0}}; |
28 | 28 | ||
29 | /* labeled failure */ | ||
30 | static void setlabelfail(Labelset *ls) { | ||
31 | loopset(i, ls->cs[i] = 0); | ||
32 | ls->cs[IDXLFAIL] = 1; | ||
33 | } | ||
34 | /* labeled failure end */ | ||
35 | |||
36 | 29 | ||
37 | /* | 30 | /* |
38 | ** {====================================================== | 31 | ** {====================================================== |
@@ -44,7 +37,6 @@ static void setlabelfail(Labelset *ls) { | |||
44 | typedef struct Stack { | 37 | typedef struct Stack { |
45 | const char *s; /* saved position (or NULL for calls) */ | 38 | const char *s; /* saved position (or NULL for calls) */ |
46 | const Instruction *p; /* next instruction */ | 39 | const Instruction *p; /* next instruction */ |
47 | const Labelset *ls; /* labeled failure */ | ||
48 | int caplevel; | 40 | int caplevel; |
49 | } Stack; | 41 | } Stack; |
50 | 42 | ||
@@ -163,10 +155,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
163 | int captop = 0; /* point to first empty slot in captures */ | 155 | int captop = 0; /* point to first empty slot in captures */ |
164 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ | 156 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ |
165 | const Instruction *p = op; /* current instruction */ | 157 | const Instruction *p = op; /* current instruction */ |
166 | const Instruction *pk = NULL; /* resume instruction */ | 158 | stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; /* labeled failure */ |
167 | Labelset lsfail; | ||
168 | setlabelfail(&lsfail); | ||
169 | stack->p = &giveup; stack->s = s; stack->ls = &lsfail; stack->caplevel = 0; stack++; /* labeled failure */ | ||
170 | *sfail = s; /* labeled failure */ | 159 | *sfail = s; /* labeled failure */ |
171 | lua_pushlightuserdata(L, stackbase); | 160 | lua_pushlightuserdata(L, stackbase); |
172 | for (;;) { | 161 | for (;;) { |
@@ -198,7 +187,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
198 | if (s < e) { p++; s++; } | 187 | if (s < e) { p++; s++; } |
199 | else { | 188 | else { |
200 | *labelf = LFAIL; /* labeled failure */ | 189 | *labelf = LFAIL; /* labeled failure */ |
201 | pk = p + 1; | ||
202 | updatefarthest(*sfail, s); /*labeled failure */ | 190 | updatefarthest(*sfail, s); /*labeled failure */ |
203 | goto fail; | 191 | goto fail; |
204 | } | 192 | } |
@@ -213,7 +201,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
213 | if ((byte)*s == p->i.aux && s < e) { p++; s++; } | 201 | if ((byte)*s == p->i.aux && s < e) { p++; s++; } |
214 | else { | 202 | else { |
215 | *labelf = LFAIL; /* labeled failure */ | 203 | *labelf = LFAIL; /* labeled failure */ |
216 | pk = p + 1; | ||
217 | updatefarthest(*sfail, s); /*labeled failure */ | 204 | updatefarthest(*sfail, s); /*labeled failure */ |
218 | goto fail; | 205 | goto fail; |
219 | } | 206 | } |
@@ -230,7 +217,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
230 | { p += CHARSETINSTSIZE; s++; } | 217 | { p += CHARSETINSTSIZE; s++; } |
231 | else { | 218 | else { |
232 | *labelf = LFAIL; /* labeled failure */ | 219 | *labelf = LFAIL; /* labeled failure */ |
233 | pk = p + CHARSETINSTSIZE; | ||
234 | updatefarthest(*sfail, s); /*labeled failure */ | 220 | updatefarthest(*sfail, s); /*labeled failure */ |
235 | goto fail; | 221 | goto fail; |
236 | } | 222 | } |
@@ -247,7 +233,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
247 | int n = p->i.aux; | 233 | int n = p->i.aux; |
248 | if (n > s - o) { | 234 | if (n > s - o) { |
249 | *labelf = LFAIL; /* labeled failure */ | 235 | *labelf = LFAIL; /* labeled failure */ |
250 | pk = p + 1; | ||
251 | updatefarthest(*sfail, s); /*labeled failure */ | 236 | updatefarthest(*sfail, s); /*labeled failure */ |
252 | goto fail; | 237 | goto fail; |
253 | } | 238 | } |
@@ -271,35 +256,22 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
271 | stack = doublestack(L, &stacklimit, ptop); | 256 | stack = doublestack(L, &stacklimit, ptop); |
272 | stack->p = p + getoffset(p); | 257 | stack->p = p + getoffset(p); |
273 | stack->s = s; | 258 | stack->s = s; |
274 | stack->ls = &lsfail; /* labeled failure */ | ||
275 | stack->caplevel = captop; | 259 | stack->caplevel = captop; |
276 | stack++; | 260 | stack++; |
277 | p += 2; | 261 | p += 2; |
278 | continue; | 262 | continue; |
279 | } | 263 | } |
280 | case ILabChoice: { /* labeled failure */ | ||
281 | if (stack == stacklimit) | ||
282 | stack = doublestack(L, &stacklimit, ptop); | ||
283 | stack->p = p + getoffset(p); | ||
284 | stack->s = s; | ||
285 | stack->ls = (const Labelset *) ((p + 2)->buff); | ||
286 | stack->caplevel = captop; | ||
287 | stack++; | ||
288 | p += (CHARSETINSTSIZE - 1) + 2; | ||
289 | continue; | ||
290 | } | ||
291 | case ICall: { | 264 | case ICall: { |
292 | if (stack == stacklimit) | 265 | if (stack == stacklimit) |
293 | stack = doublestack(L, &stacklimit, ptop); | 266 | stack = doublestack(L, &stacklimit, ptop); |
294 | stack->s = NULL; | 267 | stack->s = NULL; |
295 | stack->p = p + 2; /* save return address */ | 268 | stack->p = p + 2; /* save return address */ |
296 | stack->ls = NULL; | ||
297 | stack++; | 269 | stack++; |
298 | p += getoffset(p); | 270 | p += getoffset(p); |
299 | continue; | 271 | continue; |
300 | } | 272 | } |
301 | case ICommit: { | 273 | case ICommit: { |
302 | assert(stack > getstackbase(L, ptop) && (stack - 1)->ls != NULL); /* labeled failure */ | 274 | assert(stack > getstackbase(L, ptop)); |
303 | assert((stack - 1)->s != NULL); | 275 | assert((stack - 1)->s != NULL); |
304 | stack--; | 276 | stack--; |
305 | p += getoffset(p); | 277 | p += getoffset(p); |
@@ -325,8 +297,10 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
325 | printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); | 297 | printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); |
326 | lua_pop(L, 1);*/ | 298 | lua_pop(L, 1);*/ |
327 | *labelf = (p+1)->i.key; | 299 | *labelf = (p+1)->i.key; |
328 | pk = p + 1; | 300 | if (*labelf == LFAIL) |
301 | luaL_error(L, "labelf is %d", *labelf); | ||
329 | *sfail = s; | 302 | *sfail = s; |
303 | stack = getstackbase(L, ptop); | ||
330 | goto fail; | 304 | goto fail; |
331 | } | 305 | } |
332 | case IThrowRec: { /* labeled failure */ | 306 | case IThrowRec: { /* labeled failure */ |
@@ -335,12 +309,13 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
335 | printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); | 309 | printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); |
336 | lua_pop(L, 1);*/ | 310 | lua_pop(L, 1);*/ |
337 | *labelf = (p+2)->i.key; | 311 | *labelf = (p+2)->i.key; |
312 | if (*labelf == LFAIL) | ||
313 | luaL_error(L, "labelf is %d", *labelf); | ||
338 | *sfail = s; | 314 | *sfail = s; |
339 | if (stack == stacklimit) | 315 | if (stack == stacklimit) |
340 | stack = doublestack(L, &stacklimit, ptop); | 316 | stack = doublestack(L, &stacklimit, ptop); |
341 | stack->s = NULL; | 317 | stack->s = NULL; |
342 | stack->p = p + 3; | 318 | stack->p = p + 3; |
343 | stack->ls = NULL; | ||
344 | stack->caplevel = captop; | 319 | stack->caplevel = captop; |
345 | stack++; | 320 | stack++; |
346 | p += getoffset(p); | 321 | p += getoffset(p); |
@@ -352,31 +327,16 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
352 | /* go through */ | 327 | /* go through */ |
353 | case IFail: | 328 | case IFail: |
354 | *labelf = LFAIL; /* labeled failure */ | 329 | *labelf = LFAIL; /* labeled failure */ |
355 | pk = NULL; | ||
356 | updatefarthest(*sfail, s); /*labeled failure */ | 330 | updatefarthest(*sfail, s); /*labeled failure */ |
357 | fail: { /* pattern failed: try to backtrack */ | 331 | fail: { /* pattern failed: try to backtrack */ |
358 | const Labelset *auxlab = NULL; | ||
359 | Stack *pstack = stack; | ||
360 | do { /* remove pending calls */ | 332 | do { /* remove pending calls */ |
361 | assert(pstack > getstackbase(L, ptop)); | 333 | assert(stack > getstackbase(L, ptop)); |
362 | auxlab = (--pstack)->ls; | 334 | s = (--stack)->s; |
363 | } while (auxlab == NULL || !(pstack->p == &giveup || testlabel(pstack->ls->cs, *labelf))); | 335 | } while (s == NULL); |
364 | if (pstack->s != NULL) { /* labeled failure: giveup or backtrack frame */ | 336 | if (ndyncap > 0) /* is there matchtime captures? */ |
365 | stack = pstack; | 337 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); |
366 | s = stack->s; | 338 | captop = stack->caplevel; |
367 | if (ndyncap > 0) /* is there matchtime captures? */ | 339 | p = stack->p; |
368 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); | ||
369 | captop = stack->caplevel; | ||
370 | } else { /* labeled failure: recovery frame */ | ||
371 | if (stack == stacklimit) | ||
372 | stack = doublestack(L, &stacklimit, ptop); | ||
373 | stack->s = NULL; | ||
374 | stack->p = pk; /* save return address */ | ||
375 | stack->ls = NULL; | ||
376 | stack->caplevel = captop; /* TODO: really necessary?? */ | ||
377 | stack++; | ||
378 | } | ||
379 | p = pstack->p; | ||
380 | #if defined(DEBUG) | 340 | #if defined(DEBUG) |
381 | printf("**FAIL**\n"); | 341 | printf("**FAIL**\n"); |
382 | #endif | 342 | #endif |
@@ -394,7 +354,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
394 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ | 354 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ |
395 | if (res == -1) { /* fail? */ | 355 | if (res == -1) { /* fail? */ |
396 | *labelf = LFAIL; /* labeled failure */ | 356 | *labelf = LFAIL; /* labeled failure */ |
397 | pk = NULL; | ||
398 | updatefarthest(*sfail, s); /*labeled failure */ | 357 | updatefarthest(*sfail, s); /*labeled failure */ |
399 | goto fail; | 358 | goto fail; |
400 | } | 359 | } |