diff options
author | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-26 12:27:42 -0300 |
---|---|---|
committer | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-26 12:27:42 -0300 |
commit | e4cc8be34e590dc22f0a25ecfa269624b1569925 (patch) | |
tree | 7d5450bc033e1475a30db15f85ff4e7ab854feb5 | |
parent | f6c68a6313e1700c25a523adde5f92ca1f7f67b6 (diff) | |
download | lpeglabel-e4cc8be34e590dc22f0a25ecfa269624b1569925.tar.gz lpeglabel-e4cc8be34e590dc22f0a25ecfa269624b1569925.tar.bz2 lpeglabel-e4cc8be34e590dc22f0a25ecfa269624b1569925.zip |
Exteding the stack with a field to store the label environment
-rw-r--r-- | lpvm.c | 58 | ||||
-rw-r--r-- | lpvm.h | 1 |
2 files changed, 41 insertions, 18 deletions
@@ -38,6 +38,7 @@ typedef struct Stack { | |||
38 | const char *s; /* saved position (or NULL for calls) */ | 38 | const char *s; /* saved position (or NULL for calls) */ |
39 | const Instruction *p; /* next instruction */ | 39 | const Instruction *p; /* next instruction */ |
40 | int caplevel; | 40 | int caplevel; |
41 | byte labenv; /* labeled failure */ | ||
41 | } Stack; | 42 | } Stack; |
42 | 43 | ||
43 | 44 | ||
@@ -155,7 +156,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
155 | int captop = 0; /* point to first empty slot in captures */ | 156 | int captop = 0; /* point to first empty slot in captures */ |
156 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ | 157 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ |
157 | const Instruction *p = op; /* current instruction */ | 158 | const Instruction *p = op; /* current instruction */ |
158 | stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; /* labeled failure */ | 159 | byte labenv = 1; /* labeled failure: label environment is on */ |
160 | stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack->labenv = 1; stack++; /* labeled failure */ | ||
159 | *sfail = s; /* labeled failure */ | 161 | *sfail = s; /* labeled failure */ |
160 | lua_pushlightuserdata(L, stackbase); | 162 | lua_pushlightuserdata(L, stackbase); |
161 | for (;;) { | 163 | for (;;) { |
@@ -166,7 +168,9 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
166 | s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); | 168 | s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); |
167 | printinst(op, p); | 169 | printinst(op, p); |
168 | #endif | 170 | #endif |
171 | printinst(op, p); | ||
169 | assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); | 172 | assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); |
173 | assert(labenv == 1); | ||
170 | switch ((Opcode)p->i.code) { | 174 | switch ((Opcode)p->i.code) { |
171 | case IEnd: { | 175 | case IEnd: { |
172 | assert(stack == getstackbase(L, ptop) + 1); | 176 | assert(stack == getstackbase(L, ptop) + 1); |
@@ -257,6 +261,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
257 | stack->p = p + getoffset(p); | 261 | stack->p = p + getoffset(p); |
258 | stack->s = s; | 262 | stack->s = s; |
259 | stack->caplevel = captop; | 263 | stack->caplevel = captop; |
264 | stack->labenv = labenv; /* labeled failure */ | ||
260 | stack++; | 265 | stack++; |
261 | p += 2; | 266 | p += 2; |
262 | continue; | 267 | continue; |
@@ -287,6 +292,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
287 | case IBackCommit: { | 292 | case IBackCommit: { |
288 | assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); | 293 | assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); |
289 | s = (--stack)->s; | 294 | s = (--stack)->s; |
295 | labenv = stack->labenv; /* labeled failure */ | ||
296 | assert(labenv == 1); /* labeled failure */ | ||
290 | captop = stack->caplevel; | 297 | captop = stack->caplevel; |
291 | p += getoffset(p); | 298 | p += getoffset(p); |
292 | continue; | 299 | continue; |
@@ -296,12 +303,18 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
296 | lua_rawgeti(L, ktableidx(ptop), (p+1)->i.key); | 303 | lua_rawgeti(L, ktableidx(ptop), (p+1)->i.key); |
297 | printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); | 304 | printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); |
298 | lua_pop(L, 1);*/ | 305 | lua_pop(L, 1);*/ |
299 | *labelf = (p+1)->i.key; | 306 | if (labenv) { |
300 | if (*labelf == LFAIL) | 307 | *labelf = (p+1)->i.key; |
308 | if (*labelf == LFAIL) | ||
301 | luaL_error(L, "labelf is %d", *labelf); | 309 | luaL_error(L, "labelf is %d", *labelf); |
302 | *sfail = s; | 310 | stack = getstackbase(L, ptop); |
303 | stack = getstackbase(L, ptop); | 311 | stack++; |
304 | stack++; | 312 | printf("IThrow stack->labenv = %d\n", stack->labenv); |
313 | } | ||
314 | else { | ||
315 | labelf = LFAIL; | ||
316 | } | ||
317 | *sfail = s; | ||
305 | goto fail; | 318 | goto fail; |
306 | } | 319 | } |
307 | case IThrowRec: { /* labeled failure */ | 320 | case IThrowRec: { /* labeled failure */ |
@@ -309,18 +322,25 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
309 | lua_rawgeti(L, ktableidx(ptop), (p+2)->i.key); | 322 | lua_rawgeti(L, ktableidx(ptop), (p+2)->i.key); |
310 | printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); | 323 | printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); |
311 | lua_pop(L, 1);*/ | 324 | lua_pop(L, 1);*/ |
312 | *labelf = (p+2)->i.key; | 325 | printf("labenv here = %d\n", labenv); |
313 | if (*labelf == LFAIL) | 326 | if (labenv) { |
314 | luaL_error(L, "labelf is %d", *labelf); | 327 | *labelf = (p+2)->i.key; |
315 | *sfail = s; | 328 | if (*labelf == LFAIL) |
316 | if (stack == stacklimit) | 329 | luaL_error(L, "labelf is %d", *labelf); |
317 | stack = doublestack(L, &stacklimit, ptop); | 330 | *sfail = s; |
318 | stack->s = NULL; | 331 | if (stack == stacklimit) |
319 | stack->p = p + 3; | 332 | stack = doublestack(L, &stacklimit, ptop); |
320 | stack->caplevel = captop; | 333 | stack->s = NULL; |
321 | stack++; | 334 | stack->p = p + 3; |
322 | p += getoffset(p); | 335 | stack->caplevel = captop; |
323 | continue; | 336 | stack++; |
337 | p += getoffset(p); | ||
338 | continue; | ||
339 | } else { | ||
340 | labelf = LFAIL; | ||
341 | } | ||
342 | *sfail = s; | ||
343 | goto fail; | ||
324 | } | 344 | } |
325 | case IFailTwice: | 345 | case IFailTwice: |
326 | assert(stack > getstackbase(L, ptop)); | 346 | assert(stack > getstackbase(L, ptop)); |
@@ -337,6 +357,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
337 | if (ndyncap > 0) /* is there matchtime captures? */ | 357 | if (ndyncap > 0) /* is there matchtime captures? */ |
338 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); | 358 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); |
339 | captop = stack->caplevel; | 359 | captop = stack->caplevel; |
360 | labenv = stack->labenv; | ||
361 | assert(labenv == 1); | ||
340 | p = stack->p; | 362 | p = stack->p; |
341 | #if defined(DEBUG) | 363 | #if defined(DEBUG) |
342 | printf("**FAIL**\n"); | 364 | printf("**FAIL**\n"); |
@@ -21,6 +21,7 @@ typedef enum Opcode { | |||
21 | IRet, /* return from a rule */ | 21 | IRet, /* return from a rule */ |
22 | IEnd, /* end of pattern */ | 22 | IEnd, /* end of pattern */ |
23 | IChoice, /* stack a choice; next fail will jump to 'offset' */ | 23 | IChoice, /* stack a choice; next fail will jump to 'offset' */ |
24 | /*IPredChoice,*/ /* labeld failure: stack a choice; changes label env next fail will jump to 'offset' */ | ||
24 | IJmp, /* jump to 'offset' */ | 25 | IJmp, /* jump to 'offset' */ |
25 | ICall, /* call rule at 'offset' */ | 26 | ICall, /* call rule at 'offset' */ |
26 | IOpenCall, /* call rule number 'key' (must be closed to a ICall) */ | 27 | IOpenCall, /* call rule number 'key' (must be closed to a ICall) */ |