aboutsummaryrefslogtreecommitdiff
path: root/lpvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpvm.c')
-rw-r--r--lpvm.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/lpvm.c b/lpvm.c
index c15d543..a57c4b3 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -26,6 +26,23 @@
26 26
27static const Instruction giveup = {{IGiveup, 0, 0}}; 27static const Instruction giveup = {{IGiveup, 0, 0}};
28 28
29/* labeled failure */
30static void setlabelfail(Labelset *ls) {
31 loopset(i, ls->cs[i] = 0);
32 ls->cs[IDXLFAIL] = 1;
33}
34
35static void clearandsetlabel(Labelset *ls, byte b) {
36 loopset(i, ls->cs[i] = 0);
37 setlabel(ls->cs, b);
38}
39
40
41static int cs_disjoint (const Charset *cs1, const Charset *cs2) {
42 loopset(i, if ((cs1->cs[i] & cs2->cs[i]) != 0) return 0;)
43 return 1;
44}
45/* labeled failure end */
29 46
30/* 47/*
31** {====================================================== 48** {======================================================
@@ -38,7 +55,7 @@ typedef struct Stack {
38 const char *s; /* saved position (or NULL for calls) */ 55 const char *s; /* saved position (or NULL for calls) */
39 const Instruction *p; /* next instruction */ 56 const Instruction *p; /* next instruction */
40 int caplevel; 57 int caplevel;
41 Labelset ls; /* labeled failure */ 58 const Labelset *ls; /* labeled failure */
42} Stack; 59} Stack;
43 60
44 61
@@ -142,6 +159,8 @@ static int removedyncap (lua_State *L, Capture *capture,
142} 159}
143 160
144 161
162
163
145/* 164/*
146** Opcode interpreter 165** Opcode interpreter
147*/ 166*/
@@ -154,15 +173,18 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
154 int captop = 0; /* point to first empty slot in captures */ 173 int captop = 0; /* point to first empty slot in captures */
155 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ 174 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
156 const Instruction *p = op; /* current instruction */ 175 const Instruction *p = op; /* current instruction */
176 Labelset lsfail;
177 setlabelfail(&lsfail);
157 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; 178 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++;
158 lua_pushlightuserdata(L, stackbase); 179 lua_pushlightuserdata(L, stackbase);
159 for (;;) { 180 /*printf("match: %s\n", s);*/
160#if defined(DEBUG) 181 for (;;) {
161 printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", 182/*#if defined(DEBUG)*/
183 /* printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
162 s, stack - getstackbase(L, ptop), ndyncap, captop); 184 s, stack - getstackbase(L, ptop), ndyncap, captop);
163 printinst(op, p); 185 printinst(op, p);*/
164 printcaplist(capture, capture + captop); 186 /*printcaplist(capture, capture + captop);*/
165#endif 187/*#endif*/
166 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); 188 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
167 switch ((Opcode)p->i.code) { 189 switch ((Opcode)p->i.code) {
168 case IEnd: { 190 case IEnd: {
@@ -183,7 +205,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
183 case IAny: { 205 case IAny: {
184 if (s < e) { p++; s++; } 206 if (s < e) { p++; s++; }
185 else { 207 else {
186 *labelf = LFAIL; /* labeled failure */ 208 setlabelfail(labelf); /* labeled failure */
187 *sfail = s; 209 *sfail = s;
188 goto fail; 210 goto fail;
189 } 211 }
@@ -197,7 +219,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
197 case IChar: { 219 case IChar: {
198 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 220 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
199 else { 221 else {
200 *labelf = LFAIL; /* labeled failure */ 222 setlabelfail(labelf); /* labeled failure */
201 *sfail = s; 223 *sfail = s;
202 goto fail; 224 goto fail;
203 } 225 }
@@ -213,7 +235,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
213 if (testchar((p+1)->buff, c) && s < e) 235 if (testchar((p+1)->buff, c) && s < e)
214 { p += CHARSETINSTSIZE; s++; } 236 { p += CHARSETINSTSIZE; s++; }
215 else { 237 else {
216 *labelf = LFAIL; /* labeled failure */ 238 setlabelfail(labelf); /* labeled failure */
217 *sfail = s; 239 *sfail = s;
218 goto fail; 240 goto fail;
219 } 241 }
@@ -229,7 +251,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
229 case IBehind: { 251 case IBehind: {
230 int n = p->i.aux; 252 int n = p->i.aux;
231 if (n > s - o) { 253 if (n > s - o) {
232 *labelf = LFAIL; /* labeled failure */ 254 setlabelfail(labelf); /* labeled failure */
233 *sfail = s; 255 *sfail = s;
234 goto fail; 256 goto fail;
235 } 257 }
@@ -253,7 +275,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
253 stack = doublestack(L, &stacklimit, ptop); 275 stack = doublestack(L, &stacklimit, ptop);
254 stack->p = p + getoffset(p); 276 stack->p = p + getoffset(p);
255 stack->s = s; 277 stack->s = s;
256 stack->ls = LFAIL; /* labeled failure */ 278 stack->ls = &lsfail; /* labeled failure */
257 stack->caplevel = captop; 279 stack->caplevel = captop;
258 stack++; 280 stack++;
259 p += 2; 281 p += 2;
@@ -264,10 +286,10 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
264 stack = doublestack(L, &stacklimit, ptop); 286 stack = doublestack(L, &stacklimit, ptop);
265 stack->p = p + getoffset(p); 287 stack->p = p + getoffset(p);
266 stack->s = s; 288 stack->s = s;
267 stack->ls = (p + 2)->labels; 289 stack->ls = (const Labelset *) ((p + 2)->buff);
268 stack->caplevel = captop; 290 stack->caplevel = captop;
269 stack++; 291 stack++;
270 p += 3; 292 p += (CHARSETINSTSIZE - 1) + 2;
271 continue; 293 continue;
272 } 294 }
273 case ICall: { 295 case ICall: {
@@ -300,7 +322,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
300 continue; 322 continue;
301 } 323 }
302 case IThrow: { /* labeled failure */ 324 case IThrow: { /* labeled failure */
303 *labelf = (p+1)->labels; 325 clearandsetlabel(labelf, p->i.aux);
304 *sfail = s; 326 *sfail = s;
305 /*printf("s = %s, sfail = %s\n", s, *sfail);*/ 327 /*printf("s = %s, sfail = %s\n", s, *sfail);*/
306 goto fail; 328 goto fail;
@@ -310,13 +332,14 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
310 stack--; 332 stack--;
311 /* go through */ 333 /* go through */
312 case IFail: 334 case IFail:
313 *labelf = LFAIL; /* labeled failure */ 335 setlabelfail(labelf); /* labeled failure */
314 *sfail = s; 336 *sfail = s;
315 fail: { /* pattern failed: try to backtrack */ 337 fail: { /* pattern failed: try to backtrack */
316 do { /* remove pending calls */ 338 do { /* remove pending calls */
317 assert(stack > getstackbase(L, ptop)); 339 assert(stack > getstackbase(L, ptop));
318 s = (--stack)->s; 340 s = (--stack)->s;
319 } while (s == NULL || (!(stack->ls & *labelf) && stack->p != &giveup)); 341 /*printf("s = %s, disj = %d\n", s, cs_disjoint(stack->ls, labelf));*/
342 } while (s == NULL || (stack->p != &giveup && cs_disjoint(stack->ls, labelf)));
320 if (ndyncap > 0) /* is there matchtime captures? */ 343 if (ndyncap > 0) /* is there matchtime captures? */
321 ndyncap -= removedyncap(L, capture, stack->caplevel, captop); 344 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
322 captop = stack->caplevel; 345 captop = stack->caplevel;
@@ -333,7 +356,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
333 fr -= rem; /* 'rem' items were popped from Lua stack */ 356 fr -= rem; /* 'rem' items were popped from Lua stack */
334 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 357 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
335 if (res == -1) { /* fail? */ 358 if (res == -1) { /* fail? */
336 *labelf = LFAIL; /* labeled failure */ 359 setlabelfail(labelf); /* labeled failure */
337 *sfail = (const char *) s; /* TODO: ??? */ 360 *sfail = (const char *) s; /* TODO: ??? */
338 goto fail; 361 goto fail;
339 } 362 }