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) */ |
