aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSérgio Queiroz <sqmedeiros@gmail.com>2017-12-12 11:42:14 -0300
committerSérgio Queiroz <sqmedeiros@gmail.com>2017-12-12 11:42:14 -0300
commit26c1b9aa78e10b2ed2d36d151033fe94254fa8c5 (patch)
tree743f8cca325a2788cd0aa9e98de79ab275884d01
parent5ffef3da93ad53069d2510a75b11ecbb1b6e8aa7 (diff)
downloadlpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.tar.gz
lpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.tar.bz2
lpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.zip
Using field 'key' to allow strings as labels (partial)
-rw-r--r--lpcode.c14
-rw-r--r--lptree.c18
-rw-r--r--lpvm.c6
-rw-r--r--testlabel.lua18
4 files changed, 42 insertions, 14 deletions
diff --git a/lpcode.c b/lpcode.c
index f335dcb..d67d42f 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -519,6 +519,15 @@ static int addinstruction (CompileState *compst, Opcode op, int aux) {
519 return i; 519 return i;
520} 520}
521 521
522/* labeled failure */
523static int addthrowinstruction (CompileState *compst, int aux, int key) {
524 int i = addinstruction(compst, IThrow, aux);
525 getinstr(compst, i).i.key = key;
526 return i;
527}
528
529/* labeled failure */
530
522 531
523/* 532/*
524** Add an instruction followed by space for an offset (to be set later) 533** Add an instruction followed by space for an offset (to be set later)
@@ -996,7 +1005,10 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
996 tree = sib2(tree); goto tailcall; 1005 tree = sib2(tree); goto tailcall;
997 } 1006 }
998 case TThrow: { /* labeled failure */ 1007 case TThrow: { /* labeled failure */
999 addinstruction(compst, IThrow, (byte) tree->u.label); 1008 /*printf("TThrow %s top %d\n", lua_typename(compst->L, -1), lua_gettop(compst->L));*/
1009 /*lua_rawgeti(compst->L, -1, tree->key);*/
1010 /*printf("Throw2 lab = %s\n", lua_tostring(compst->L, -1));*/
1011 addthrowinstruction(compst, (byte) tree->u.label, tree->key);
1000 break; 1012 break;
1001 } 1013 }
1002 case TRecov: { /* labeled failure */ 1014 case TRecov: { /* labeled failure */
diff --git a/lptree.c b/lptree.c
index 810e267..fea2ecf 100644
--- a/lptree.c
+++ b/lptree.c
@@ -216,7 +216,7 @@ static void correctkeys (TTree *tree, int n) {
216 if (n == 0) return; /* no correction? */ 216 if (n == 0) return; /* no correction? */
217 tailcall: 217 tailcall:
218 switch (tree->tag) { 218 switch (tree->tag) {
219 case TOpenCall: case TCall: case TRunTime: case TRule: { 219 case TOpenCall: case TCall: case TRunTime: case TRule: case TThrow: { /* labeled failure */
220 if (tree->key > 0) 220 if (tree->key > 0)
221 tree->key += n; 221 tree->key += n;
222 break; 222 break;
@@ -721,9 +721,14 @@ static int lp_behind (lua_State *L) {
721** Throws a label 721** Throws a label
722*/ 722*/
723static int lp_throw (lua_State *L) { 723static int lp_throw (lua_State *L) {
724 int label = luaL_checkinteger(L, -1); 724 /*int label = luaL_checkinteger(L, -1);*/
725 luaL_argcheck(L, label >= 1 && label < MAXLABELS, -1, "the number of a label must be between 1 and 255"); 725 /*luaL_argcheck(L, label >= 1 && label < MAXLABELS, -1, "the number of a label must be between 1 and 255");*/
726 newthrowleaf(L, label); 726 TTree * tree;
727 luaL_checkstring(L, -1);
728 tree = newthrowleaf(L, 0);
729 tree->u.label = addtonewktable(L, 0, 1);
730 tree->key = tree->u.label;
731 /*printf("lp_throw %d %s\n", tree->key, lua_tostring(L, 1));*/
727 return 1; 732 return 1;
728} 733}
729 734
@@ -1242,7 +1247,10 @@ static int lp_match (lua_State *L) {
1242 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf, &sfail); /* labeled failure */ 1247 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf, &sfail); /* labeled failure */
1243 if (r == NULL) { /* labeled failure begin */ 1248 if (r == NULL) { /* labeled failure begin */
1244 lua_pushnil(L); 1249 lua_pushnil(L);
1245 lua_pushinteger(L, labelf); 1250 if (labelf)
1251 lua_rawgeti(L, ktableidx(ptop), labelf);
1252 else
1253 lua_pushstring(L, "fail");
1246 lua_pushinteger(L, sfail - (s + i) + 1); /* subject position related to the error */ 1254 lua_pushinteger(L, sfail - (s + i) + 1); /* subject position related to the error */
1247 return 3; 1255 return 3;
1248 } /* labeled failure end */ 1256 } /* labeled failure end */
diff --git a/lpvm.c b/lpvm.c
index d2b1f55..61d609a 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -331,7 +331,11 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
331 continue; 331 continue;
332 } 332 }
333 case IThrow: { /* labeled failure */ 333 case IThrow: { /* labeled failure */
334 *labelf = p->i.aux; 334 printf("IThrow here: key=%d aux = %d top = %d\n", p->i.key, p->i.aux, lua_gettop(L));
335 lua_rawgeti(L, ktableidx(ptop), p->i.key);
336 printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L));
337 lua_pop(L, 1);
338 *labelf = p->i.key;
335 pk = p + 1; 339 pk = p + 1;
336 *sfail = s; 340 *sfail = s;
337 goto fail; 341 goto fail;
diff --git a/testlabel.lua b/testlabel.lua
index 1be1343..72eb9aa 100644
--- a/testlabel.lua
+++ b/testlabel.lua
@@ -6,6 +6,9 @@ local function checklabeq (x, ...)
6 y = { ... } 6 y = { ... }
7 assert(type(x) == "table") 7 assert(type(x) == "table")
8 assert(#x == #y) 8 assert(#x == #y)
9 if x[2] == 0 then -- 0 -> 'fail'
10 x[2] = 'fail'
11 end
9 for i = 1, 3 do 12 for i = 1, 3 do
10 assert(x[i] == y[i]) 13 assert(x[i] == y[i])
11 end 14 end
@@ -81,12 +84,12 @@ print"+"
81p = m.T(1) 84p = m.T(1)
82s = "abc" 85s = "abc"
83r, l, poserr = p:match(s) 86r, l, poserr = p:match(s)
84assert(r == nil and l == 1 and poserr == 1) 87assert(r == nil and l == '1' and poserr == 1)
85 88
86-- throws a label, choice does not catch labels 89-- throws a label, choice does not catch labels
87p = m.T(1) + m.P"a" 90p = m.T(1) + m.P"a"
88r, l, poserr = p:match(s) 91r, l, poserr = p:match(s)
89assert(r == nil and l == 1 and poserr == 1) 92assert(r == nil and l == '1' and poserr == 1)
90 93
91-- again throws a label that is not caught by choice 94-- again throws a label that is not caught by choice
92local g = m.P{ 95local g = m.P{
@@ -96,21 +99,22 @@ local g = m.P{
96 B = m.P"a" 99 B = m.P"a"
97} 100}
98r, l, poserr = g:match(s) 101r, l, poserr = g:match(s)
99assert(r == nil and l == 1 and poserr == 1) 102assert(r == nil and l == '1' and poserr == 1)
100 103
101-- throws a label in a position that is not the farthest one 104-- throws a label in a position that is not the farthest one
102-- but it is the position that should be reported 105-- but it is the position that should be reported
103p = m.P(1) * m.P"a" + m.T(11) 106p = m.P(1) * m.P"a" + m.T(11)
104checklabeq({3, nil, nil}, p:match("bac")) 107checklabeq({3, nil, nil}, p:match("bac"))
105checklabeq({nil, 11, 1}, p:match("c")) 108checklabeq({nil, '11', 1}, p:match("c"))
106checklabeq({nil, 11, 1}, p:match("x")) 109checklabeq({nil, '11', 1}, p:match("x"))
107checklabeq({nil, 11, 1}, p:match("kx")) 110checklabeq({nil, '11', 1}, p:match("kx"))
108 111
109 112
110-- throws a label that is not caught by the recovery operator 113-- throws a label that is not caught by the recovery operator
111p = m.Rec(m.T(2), m.P"a", 1, 3) 114p = m.Rec(m.T(2), m.P"a", 1, 3)
112r, l, poserr = p:match(s) 115r, l, poserr = p:match(s)
113assert(r == nil and l == 2 and poserr == 1) 116print(r, l, poserr)
117assert(r == nil and l == '2' and poserr == 1)
114 118
115-- wraps the previous pattern with a recovery that catches label "2" 119-- wraps the previous pattern with a recovery that catches label "2"
116p = m.Rec(p, m.P"a", 2) 120p = m.Rec(p, m.P"a", 2)