aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Medeiros <sqmedeiros@gmail.com>2014-11-13 16:54:52 -0300
committerSergio Medeiros <sqmedeiros@gmail.com>2014-11-13 16:54:52 -0300
commita5a4b257e626847be3be4878c603adb51cbb420f (patch)
tree264346e52b60a17f7d610bca787528920d1f69c5
parent4d9fd92a7fcd124b2dc62e149bf218a6d2f5d711 (diff)
downloadlpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.tar.gz
lpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.tar.bz2
lpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.zip
'match' function now returns the 'nil' plus a list of labels
-rw-r--r--lptree.c14
-rw-r--r--lpvm.c19
-rw-r--r--lpvm.h2
3 files changed, 22 insertions, 13 deletions
diff --git a/lptree.c b/lptree.c
index 5d2933d..0dd5998 100644
--- a/lptree.c
+++ b/lptree.c
@@ -1142,13 +1142,23 @@ static int lp_match (lua_State *L) {
1142 const char *s = luaL_checklstring(L, SUBJIDX, &l); 1142 const char *s = luaL_checklstring(L, SUBJIDX, &l);
1143 size_t i = initposition(L, l); 1143 size_t i = initposition(L, l);
1144 int ptop = lua_gettop(L); 1144 int ptop = lua_gettop(L);
1145 Labelset labelf; /* labeled failure */
1145 lua_pushnil(L); /* initialize subscache */ 1146 lua_pushnil(L); /* initialize subscache */
1146 lua_pushlightuserdata(L, capture); /* initialize caplistidx */ 1147 lua_pushlightuserdata(L, capture); /* initialize caplistidx */
1147 lua_getfenv(L, 1); /* initialize penvidx */ 1148 lua_getfenv(L, 1); /* initialize penvidx */
1148 r = match(L, s, s + i, s + l, code, capture, ptop); 1149 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf);
1149 if (r == NULL) { 1150 if (r == NULL) {
1151 int j = 0;
1152 int n = 1;
1150 lua_pushnil(L); 1153 lua_pushnil(L);
1151 return 1; 1154 while (j < (int) MAXLABELS) {
1155 if (labelf & (1 << j)) {
1156 lua_pushinteger(L, j);
1157 n++;
1158 }
1159 j++;
1160 }
1161 return n;
1152 } 1162 }
1153 return getcaptures(L, s, r, ptop); 1163 return getcaptures(L, s, r, ptop);
1154} 1164}
diff --git a/lpvm.c b/lpvm.c
index 8d2c98e..d8b854a 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -146,7 +146,7 @@ static int removedyncap (lua_State *L, Capture *capture,
146** Opcode interpreter 146** Opcode interpreter
147*/ 147*/
148const char *match (lua_State *L, const char *o, const char *s, const char *e, 148const char *match (lua_State *L, const char *o, const char *s, const char *e,
149 Instruction *op, Capture *capture, int ptop) { 149 Instruction *op, Capture *capture, int ptop, Labelset *labelf) {
150 Stack stackbase[INITBACK]; 150 Stack stackbase[INITBACK];
151 Stack *stacklimit = stackbase + INITBACK; 151 Stack *stacklimit = stackbase + INITBACK;
152 Stack *stack = stackbase; /* point to first empty slot in stack */ 152 Stack *stack = stackbase; /* point to first empty slot in stack */
@@ -154,7 +154,6 @@ 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 */ 154 int captop = 0; /* point to first empty slot in captures */
155 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ 155 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
156 const Instruction *p = op; /* current instruction */ 156 const Instruction *p = op; /* current instruction */
157 Labelset labelf; /* labeled failure */
158 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; 157 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++;
159 lua_pushlightuserdata(L, stackbase); 158 lua_pushlightuserdata(L, stackbase);
160 for (;;) { 159 for (;;) {
@@ -184,7 +183,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
184 case IAny: { 183 case IAny: {
185 if (s < e) { p++; s++; } 184 if (s < e) { p++; s++; }
186 else { 185 else {
187 labelf = LFAIL; /* labeled failure */ 186 *labelf = LFAIL; /* labeled failure */
188 goto fail; 187 goto fail;
189 } 188 }
190 continue; 189 continue;
@@ -197,7 +196,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
197 case IChar: { 196 case IChar: {
198 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 197 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
199 else { 198 else {
200 labelf = LFAIL; /* labeled failure */ 199 *labelf = LFAIL; /* labeled failure */
201 goto fail; 200 goto fail;
202 } 201 }
203 continue; 202 continue;
@@ -212,7 +211,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
212 if (testchar((p+1)->buff, c) && s < e) 211 if (testchar((p+1)->buff, c) && s < e)
213 { p += CHARSETINSTSIZE; s++; } 212 { p += CHARSETINSTSIZE; s++; }
214 else { 213 else {
215 labelf = LFAIL; /* labeled failure */ 214 *labelf = LFAIL; /* labeled failure */
216 goto fail; 215 goto fail;
217 } 216 }
218 continue; 217 continue;
@@ -227,7 +226,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
227 case IBehind: { 226 case IBehind: {
228 int n = p->i.aux; 227 int n = p->i.aux;
229 if (n > s - o) { 228 if (n > s - o) {
230 labelf = LFAIL; /* labeled failure */ 229 *labelf = LFAIL; /* labeled failure */
231 goto fail; 230 goto fail;
232 } 231 }
233 s -= n; p++; 232 s -= n; p++;
@@ -298,7 +297,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
298 continue; 297 continue;
299 } 298 }
300 case IThrow: { /* labeled failure */ 299 case IThrow: { /* labeled failure */
301 labelf = (p+1)->labels; 300 *labelf = (p+1)->labels;
302 goto fail; 301 goto fail;
303 } 302 }
304 case IFailTwice: 303 case IFailTwice:
@@ -306,14 +305,14 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
306 stack--; 305 stack--;
307 /* go through */ 306 /* go through */
308 case IFail: 307 case IFail:
309 labelf = LFAIL; /* labeled failure */ 308 *labelf = LFAIL; /* labeled failure */
310 fail: { /* pattern failed: try to backtrack */ 309 fail: { /* pattern failed: try to backtrack */
311 do { /* remove pending calls */ 310 do { /* remove pending calls */
312 assert(stack > getstackbase(L, ptop)); 311 assert(stack > getstackbase(L, ptop));
313 s = (--stack)->s; 312 s = (--stack)->s;
314 /*printf("fail (s == NULL => %d), labelf=%d stack->ls=%d (stack-> == giveup %d)\n", 313 /*printf("fail (s == NULL => %d), labelf=%d stack->ls=%d (stack-> == giveup %d)\n",
315 s == NULL, labelf, stack->ls, stack->p == &giveup);*/ 314 s == NULL, labelf, stack->ls, stack->p == &giveup);*/
316 } while (s == NULL || (!(stack->ls & labelf) && stack->p != &giveup)); 315 } while (s == NULL || (!(stack->ls & *labelf) && stack->p != &giveup));
317 if (ndyncap > 0) /* is there matchtime captures? */ 316 if (ndyncap > 0) /* is there matchtime captures? */
318 ndyncap -= removedyncap(L, capture, stack->caplevel, captop); 317 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
319 captop = stack->caplevel; 318 captop = stack->caplevel;
@@ -330,7 +329,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
330 fr -= rem; /* 'rem' items were popped from Lua stack */ 329 fr -= rem; /* 'rem' items were popped from Lua stack */
331 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 330 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
332 if (res == -1) { /* fail? */ 331 if (res == -1) { /* fail? */
333 labelf = LFAIL; /* labeled failure */ 332 *labelf = LFAIL; /* labeled failure */
334 goto fail; 333 goto fail;
335 } 334 }
336 s = o + res; /* else update current position */ 335 s = o + res; /* else update current position */
diff --git a/lpvm.h b/lpvm.h
index 8024b45..bb485af 100644
--- a/lpvm.h
+++ b/lpvm.h
@@ -55,7 +55,7 @@ typedef union Instruction {
55int getposition (lua_State *L, int t, int i); 55int getposition (lua_State *L, int t, int i);
56void printpatt (Instruction *p, int n); 56void printpatt (Instruction *p, int n);
57const char *match (lua_State *L, const char *o, const char *s, const char *e, 57const char *match (lua_State *L, const char *o, const char *s, const char *e,
58 Instruction *op, Capture *capture, int ptop); 58 Instruction *op, Capture *capture, int ptop, Labelset *labelf);
59int verify (lua_State *L, Instruction *op, const Instruction *p, 59int verify (lua_State *L, Instruction *op, const Instruction *p,
60 Instruction *e, int postable, int rule); 60 Instruction *e, int postable, int rule);
61void checkrule (lua_State *L, Instruction *op, int from, int to, 61void checkrule (lua_State *L, Instruction *op, int from, int to,