aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lpcode.c24
-rw-r--r--lptree.c24
-rw-r--r--lptypes.h2
-rw-r--r--lpvm.c46
-rw-r--r--lpvm.h2
-rw-r--r--makefile4
-rwxr-xr-xtest.lua1
-rw-r--r--testlabel.lua3
8 files changed, 33 insertions, 73 deletions
diff --git a/lpcode.c b/lpcode.c
index 9fa8867..50e6764 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -11,7 +11,7 @@
11 11
12#include "lptypes.h" 12#include "lptypes.h"
13#include "lpcode.h" 13#include "lpcode.h"
14#include "lpprint.h" /* labeled failure */ 14
15 15
16/* signals a "no-instruction */ 16/* signals a "no-instruction */
17#define NOINST -1 17#define NOINST -1
@@ -492,25 +492,10 @@ static int addinstruction (CompileState *compst, Opcode op, int aux) {
492static int addoffsetinst (CompileState *compst, Opcode op) { 492static int addoffsetinst (CompileState *compst, Opcode op) {
493 int i = addinstruction(compst, op, 0); /* instruction */ 493 int i = addinstruction(compst, op, 0); /* instruction */
494 addinstruction(compst, (Opcode)0, 0); /* open space for offset */ 494 addinstruction(compst, (Opcode)0, 0); /* open space for offset */
495 assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2 || op == ILabChoice); /* labeled failure */ 495 assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2);
496 return i; 496 return i;
497} 497}
498 498
499/* labeled failure begin */
500static int addthrowinstruction (CompileState *compst, byte lab) {
501 return addinstruction(compst, IThrow, lab);
502}
503
504/*static int addoffsetlabinst (CompileState *compst, const byte *cs) {
505 int j;
506 int i = addinstruction(compst, ILabChoice, 0);
507 addinstruction(compst, (Opcode)0, 0);
508 j = nextinstruction(compst);
509 getinstr(compst, j).labels = cs;
510
511 return i;
512}*/
513/* labeled failure end */
514 499
515/* 500/*
516** Set the offset of an instruction 501** Set the offset of an instruction
@@ -720,17 +705,14 @@ static void codelabchoice (CompileState *compst, TTree *p1, TTree *p2, int opt,
720 int emptyp2 = (p2->tag == TTrue); 705 int emptyp2 = (p2->tag == TTrue);
721 int pcommit; 706 int pcommit;
722 int test = NOINST; 707 int test = NOINST;
723 /* int pchoice = addoffsetlabinst(compst, cs);*/
724 int pchoice = addoffsetinst(compst, ILabChoice); 708 int pchoice = addoffsetinst(compst, ILabChoice);
725 addcharset(compst, cs); 709 addcharset(compst, cs);
726 codegen(compst, p1, emptyp2, test, fullset); 710 codegen(compst, p1, emptyp2, test, fullset);
727 pcommit = addoffsetinst(compst, ICommit); 711 pcommit = addoffsetinst(compst, ICommit);
728 jumptohere(compst, pchoice); 712 jumptohere(compst, pchoice);
729 jumptohere(compst, test); 713 jumptohere(compst, test);
730 /*printf("vou codificar codelabchoice %d\n", p2->tag);*/
731 codegen(compst, p2, opt, NOINST, fl); 714 codegen(compst, p2, opt, NOINST, fl);
732 jumptohere(compst, pcommit); 715 jumptohere(compst, pcommit);
733 /*printf("fim codelabchoice\n");*/
734} 716}
735/* labeled failure end */ 717/* labeled failure end */
736 718
@@ -962,7 +944,7 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
962 tree = sib2(tree); goto tailcall; 944 tree = sib2(tree); goto tailcall;
963 } 945 }
964 case TThrow: { /* labeled failure */ 946 case TThrow: { /* labeled failure */
965 addthrowinstruction(compst, (byte) tree->u.label); 947 addinstruction(compst, IThrow, (byte) tree->u.label);
966 break; 948 break;
967 } 949 }
968 case TLabChoice: { /* labeled failure */ 950 case TLabChoice: { /* labeled failure */
diff --git a/lptree.c b/lptree.c
index b974bbb..6d0f78c 100644
--- a/lptree.c
+++ b/lptree.c
@@ -34,6 +34,7 @@ const byte numsiblings[] = {
34 34
35static TTree *newgrammar (lua_State *L, int arg); 35static TTree *newgrammar (lua_State *L, int arg);
36 36
37
37/* 38/*
38** returns a reasonable name for value at index 'idx' on the stack 39** returns a reasonable name for value at index 'idx' on the stack
39*/ 40*/
@@ -563,7 +564,7 @@ static int lp_seq (lua_State *L) {
563 else if (tree1->tag == TTrue) 564 else if (tree1->tag == TTrue)
564 lua_pushvalue(L, 2); /* true . x = x */ 565 lua_pushvalue(L, 2); /* true . x = x */
565 else 566 else
566 newroot2sib(L, TSeq); 567 newroot2sib(L, TSeq);
567 return 1; 568 return 1;
568} 569}
569 570
@@ -718,11 +719,11 @@ static int lp_behind (lua_State *L) {
718 719
719/* labeled failure begin */ 720/* labeled failure begin */
720/* 721/*
721** Throws a label 722** Throws a label
722*/ 723*/
723static int lp_throw (lua_State *L) { 724static int lp_throw (lua_State *L) {
724 int label = luaL_checkinteger(L, -1); 725 int label = luaL_checkinteger(L, -1);
725 luaL_argcheck(L, label >= 0 && label < MAXLABELS, -1, "max or min label index exceeded"); 726 luaL_argcheck(L, label >= 0 && label < MAXLABELS, -1, "the number of a label must be between 0 and 255");
726 newthrowleaf(L, label); 727 newthrowleaf(L, label);
727 return 1; 728 return 1;
728} 729}
@@ -736,7 +737,7 @@ static int lp_labchoice (lua_State *L) {
736 int i; 737 int i;
737 for (i = 3; i <= n; i++) { 738 for (i = 3; i <= n; i++) {
738 int d = luaL_checkinteger(L, i); 739 int d = luaL_checkinteger(L, i);
739 luaL_argcheck(L, d >= 0 && d < MAXLABELS, i, "max or min label index exceeded"); 740 luaL_argcheck(L, d >= 0 && d < MAXLABELS, i, "the number of a label must be between 0 and 255");
740 setlabel(treelabelset(tree), (byte)d); 741 setlabel(treelabelset(tree), (byte)d);
741 } 742 }
742 return 1; 743 return 1;
@@ -1209,26 +1210,17 @@ static int lp_match (lua_State *L) {
1209 const char *s = luaL_checklstring(L, SUBJIDX, &l); 1210 const char *s = luaL_checklstring(L, SUBJIDX, &l);
1210 size_t i = initposition(L, l); 1211 size_t i = initposition(L, l);
1211 int ptop = lua_gettop(L); 1212 int ptop = lua_gettop(L);
1212 Labelset labelf; /* labeled failure */ 1213 byte labelf; /* labeled failure */
1213 const char *sfail = NULL; /* labeled failure */ 1214 const char *sfail = NULL; /* labeled failure */
1214 lua_pushnil(L); /* initialize subscache */ 1215 lua_pushnil(L); /* initialize subscache */
1215 lua_pushlightuserdata(L, capture); /* initialize caplistidx */ 1216 lua_pushlightuserdata(L, capture); /* initialize caplistidx */
1216 lua_getuservalue(L, 1); /* initialize penvidx */ 1217 lua_getuservalue(L, 1); /* initialize penvidx */
1217 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf, &sfail); /* labeled failure */ 1218 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf, &sfail); /* labeled failure */
1218 if (r == NULL) { /* labeled failure begin */ 1219 if (r == NULL) { /* labeled failure begin */
1219 long long int j = 0;
1220 int n = 1;
1221 lua_pushnil(L); 1220 lua_pushnil(L);
1222 while (j < MAXLABELS) { 1221 lua_pushinteger(L, labelf);
1223 if (testlabel(labelf.cs, j)) {
1224 lua_pushinteger(L, j);
1225 n++;
1226 break; /* Changing the semantics: only one label */
1227 }
1228 j++;
1229 }
1230 lua_pushstring(L, sfail); /* Pushing the subject where the failure occurred */ 1222 lua_pushstring(L, sfail); /* Pushing the subject where the failure occurred */
1231 return n + 1; 1223 return 3;
1232 } /* labeled failure end */ 1224 } /* labeled failure end */
1233 return getcaptures(L, s, r, ptop); 1225 return getcaptures(L, s, r, ptop);
1234} 1226}
diff --git a/lptypes.h b/lptypes.h
index f61c0ff..dc4ada6 100644
--- a/lptypes.h
+++ b/lptypes.h
@@ -160,7 +160,7 @@ typedef Charset Labelset;
160 160
161#define IDXLFAIL 0 161#define IDXLFAIL 0
162 162
163#define testlabel testchar 163#define LFAIL 0
164/* labeled failure end */ 164/* labeled failure end */
165 165
166#endif 166#endif
diff --git a/lpvm.c b/lpvm.c
index a57c4b3..4d9797c 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -31,17 +31,6 @@ static void setlabelfail(Labelset *ls) {
31 loopset(i, ls->cs[i] = 0); 31 loopset(i, ls->cs[i] = 0);
32 ls->cs[IDXLFAIL] = 1; 32 ls->cs[IDXLFAIL] = 1;
33} 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 */ 34/* labeled failure end */
46 35
47/* 36/*
@@ -54,8 +43,8 @@ static int cs_disjoint (const Charset *cs1, const Charset *cs2) {
54typedef struct Stack { 43typedef struct Stack {
55 const char *s; /* saved position (or NULL for calls) */ 44 const char *s; /* saved position (or NULL for calls) */
56 const Instruction *p; /* next instruction */ 45 const Instruction *p; /* next instruction */
57 int caplevel;
58 const Labelset *ls; /* labeled failure */ 46 const Labelset *ls; /* labeled failure */
47 int caplevel;
59} Stack; 48} Stack;
60 49
61 50
@@ -165,7 +154,7 @@ static int removedyncap (lua_State *L, Capture *capture,
165** Opcode interpreter 154** Opcode interpreter
166*/ 155*/
167const char *match (lua_State *L, const char *o, const char *s, const char *e, 156const char *match (lua_State *L, const char *o, const char *s, const char *e,
168 Instruction *op, Capture *capture, int ptop, Labelset *labelf, const char **sfail) { /* labeled failure */ 157 Instruction *op, Capture *capture, int ptop, byte *labelf, const char **sfail) { /* labeled failure */
169 Stack stackbase[INITBACK]; 158 Stack stackbase[INITBACK];
170 Stack *stacklimit = stackbase + INITBACK; 159 Stack *stacklimit = stackbase + INITBACK;
171 Stack *stack = stackbase; /* point to first empty slot in stack */ 160 Stack *stack = stackbase; /* point to first empty slot in stack */
@@ -177,14 +166,13 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
177 setlabelfail(&lsfail); 166 setlabelfail(&lsfail);
178 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; 167 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++;
179 lua_pushlightuserdata(L, stackbase); 168 lua_pushlightuserdata(L, stackbase);
180 /*printf("match: %s\n", s);*/ 169 for (;;) {
181 for (;;) { 170#if defined(DEBUG)
182/*#if defined(DEBUG)*/ 171 printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
183 /* printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
184 s, stack - getstackbase(L, ptop), ndyncap, captop); 172 s, stack - getstackbase(L, ptop), ndyncap, captop);
185 printinst(op, p);*/ 173 printinst(op, p);
186 /*printcaplist(capture, capture + captop);*/ 174 printcaplist(capture, capture + captop);
187/*#endif*/ 175#endif
188 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); 176 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
189 switch ((Opcode)p->i.code) { 177 switch ((Opcode)p->i.code) {
190 case IEnd: { 178 case IEnd: {
@@ -205,7 +193,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
205 case IAny: { 193 case IAny: {
206 if (s < e) { p++; s++; } 194 if (s < e) { p++; s++; }
207 else { 195 else {
208 setlabelfail(labelf); /* labeled failure */ 196 *labelf = LFAIL; /* labeled failure */
209 *sfail = s; 197 *sfail = s;
210 goto fail; 198 goto fail;
211 } 199 }
@@ -219,7 +207,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
219 case IChar: { 207 case IChar: {
220 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 208 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
221 else { 209 else {
222 setlabelfail(labelf); /* labeled failure */ 210 *labelf = LFAIL; /* labeled failure */
223 *sfail = s; 211 *sfail = s;
224 goto fail; 212 goto fail;
225 } 213 }
@@ -235,7 +223,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
235 if (testchar((p+1)->buff, c) && s < e) 223 if (testchar((p+1)->buff, c) && s < e)
236 { p += CHARSETINSTSIZE; s++; } 224 { p += CHARSETINSTSIZE; s++; }
237 else { 225 else {
238 setlabelfail(labelf); /* labeled failure */ 226 *labelf = LFAIL; /* labeled failure */
239 *sfail = s; 227 *sfail = s;
240 goto fail; 228 goto fail;
241 } 229 }
@@ -251,7 +239,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
251 case IBehind: { 239 case IBehind: {
252 int n = p->i.aux; 240 int n = p->i.aux;
253 if (n > s - o) { 241 if (n > s - o) {
254 setlabelfail(labelf); /* labeled failure */ 242 *labelf = LFAIL; /* labeled failure */
255 *sfail = s; 243 *sfail = s;
256 goto fail; 244 goto fail;
257 } 245 }
@@ -322,9 +310,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
322 continue; 310 continue;
323 } 311 }
324 case IThrow: { /* labeled failure */ 312 case IThrow: { /* labeled failure */
325 clearandsetlabel(labelf, p->i.aux); 313 *labelf = p->i.aux;
326 *sfail = s; 314 *sfail = s;
327 /*printf("s = %s, sfail = %s\n", s, *sfail);*/
328 goto fail; 315 goto fail;
329 } 316 }
330 case IFailTwice: 317 case IFailTwice:
@@ -332,14 +319,13 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
332 stack--; 319 stack--;
333 /* go through */ 320 /* go through */
334 case IFail: 321 case IFail:
335 setlabelfail(labelf); /* labeled failure */ 322 *labelf = LFAIL; /* labeled failure */
336 *sfail = s; 323 *sfail = s;
337 fail: { /* pattern failed: try to backtrack */ 324 fail: { /* pattern failed: try to backtrack */
338 do { /* remove pending calls */ 325 do { /* remove pending calls */
339 assert(stack > getstackbase(L, ptop)); 326 assert(stack > getstackbase(L, ptop));
340 s = (--stack)->s; 327 s = (--stack)->s;
341 /*printf("s = %s, disj = %d\n", s, cs_disjoint(stack->ls, labelf));*/ 328 } while (s == NULL || (stack->p != &giveup && !testlabel(stack->ls->cs, *labelf)));
342 } while (s == NULL || (stack->p != &giveup && cs_disjoint(stack->ls, labelf)));
343 if (ndyncap > 0) /* is there matchtime captures? */ 329 if (ndyncap > 0) /* is there matchtime captures? */
344 ndyncap -= removedyncap(L, capture, stack->caplevel, captop); 330 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
345 captop = stack->caplevel; 331 captop = stack->caplevel;
@@ -356,7 +342,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
356 fr -= rem; /* 'rem' items were popped from Lua stack */ 342 fr -= rem; /* 'rem' items were popped from Lua stack */
357 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 343 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
358 if (res == -1) { /* fail? */ 344 if (res == -1) { /* fail? */
359 setlabelfail(labelf); /* labeled failure */ 345 *labelf = LFAIL; /* labeled failure */
360 *sfail = (const char *) s; /* TODO: ??? */ 346 *sfail = (const char *) s; /* TODO: ??? */
361 goto fail; 347 goto fail;
362 } 348 }
diff --git a/lpvm.h b/lpvm.h
index 3e006d3..4b4dda5 100644
--- a/lpvm.h
+++ b/lpvm.h
@@ -53,7 +53,7 @@ typedef union Instruction {
53 53
54void printpatt (Instruction *p, int n); 54void printpatt (Instruction *p, int n);
55const char *match (lua_State *L, const char *o, const char *s, const char *e, 55const char *match (lua_State *L, const char *o, const char *s, const char *e,
56 Instruction *op, Capture *capture, int ptop, Labelset *labelf, const char **sfail); /* labeled failure */ 56 Instruction *op, Capture *capture, int ptop, byte *labelf, const char **sfail); /* labeled failure */
57 57
58 58
59#endif 59#endif
diff --git a/makefile b/makefile
index ce53890..5728b38 100644
--- a/makefile
+++ b/makefile
@@ -1,8 +1,8 @@
1LIBNAME = lpeglabel 1LIBNAME = lpeglabel
2LUADIR = ../lua/ 2LUADIR = ../lua/
3 3
4#COPT = -O2 4COPT = -O2
5COPT = -DLPEG_DEBUG -g 5# COPT = -DLPEG_DEBUG -g
6 6
7CWARNS = -Wall -Wextra -pedantic \ 7CWARNS = -Wall -Wextra -pedantic \
8 -Waggregate-return \ 8 -Waggregate-return \
diff --git a/test.lua b/test.lua
index 3f94edc..d5922ac 100755
--- a/test.lua
+++ b/test.lua
@@ -1115,6 +1115,7 @@ local re = require "relabel"
1115local match, compile = re.match, re.compile 1115local match, compile = re.match, re.compile
1116 1116
1117 1117
1118
1118assert(match("a", ".") == 2) 1119assert(match("a", ".") == 2)
1119assert(match("a", "''") == 1) 1120assert(match("a", "''") == 1)
1120assert(match("", " ! . ") == 1) 1121assert(match("", " ! . ") == 1)
diff --git a/testlabel.lua b/testlabel.lua
index 67dc36b..f7180a7 100644
--- a/testlabel.lua
+++ b/testlabel.lua
@@ -1,7 +1,5 @@
1local m = require 'lpeglabel' 1local m = require 'lpeglabel'
2 2
3p = m.Lc(true, true, 1, 3)
4
5local p, r, l, s, serror 3local p, r, l, s, serror
6 4
7-- throws a label 5-- throws a label
@@ -135,6 +133,7 @@ assert(p:match("B") == 2)
135p = m.Lc(m.P"A", m.P(false), 1) + m.P("B") 133p = m.Lc(m.P"A", m.P(false), 1) + m.P("B")
136assert(p:match("B") == 2) 134assert(p:match("B") == 2)
137 135
136
138--[[ 137--[[
139S -> A /{1} 'a' 138S -> A /{1} 'a'
140A -> B 139A -> B