diff options
author | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-12 11:42:14 -0300 |
---|---|---|
committer | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-12 11:42:14 -0300 |
commit | 26c1b9aa78e10b2ed2d36d151033fe94254fa8c5 (patch) | |
tree | 743f8cca325a2788cd0aa9e98de79ab275884d01 | |
parent | 5ffef3da93ad53069d2510a75b11ecbb1b6e8aa7 (diff) | |
download | lpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.tar.gz lpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.tar.bz2 lpeglabel-26c1b9aa78e10b2ed2d36d151033fe94254fa8c5.zip |
Using field 'key' to allow strings as labels (partial)
-rw-r--r-- | lpcode.c | 14 | ||||
-rw-r--r-- | lptree.c | 18 | ||||
-rw-r--r-- | lpvm.c | 6 | ||||
-rw-r--r-- | testlabel.lua | 18 |
4 files changed, 42 insertions, 14 deletions
@@ -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 */ | ||
523 | static 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 */ |
@@ -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 | */ |
723 | static int lp_throw (lua_State *L) { | 723 | static 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 */ |
@@ -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"+" | |||
81 | p = m.T(1) | 84 | p = m.T(1) |
82 | s = "abc" | 85 | s = "abc" |
83 | r, l, poserr = p:match(s) | 86 | r, l, poserr = p:match(s) |
84 | assert(r == nil and l == 1 and poserr == 1) | 87 | assert(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 |
87 | p = m.T(1) + m.P"a" | 90 | p = m.T(1) + m.P"a" |
88 | r, l, poserr = p:match(s) | 91 | r, l, poserr = p:match(s) |
89 | assert(r == nil and l == 1 and poserr == 1) | 92 | assert(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 |
92 | local g = m.P{ | 95 | local g = m.P{ |
@@ -96,21 +99,22 @@ local g = m.P{ | |||
96 | B = m.P"a" | 99 | B = m.P"a" |
97 | } | 100 | } |
98 | r, l, poserr = g:match(s) | 101 | r, l, poserr = g:match(s) |
99 | assert(r == nil and l == 1 and poserr == 1) | 102 | assert(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 |
103 | p = m.P(1) * m.P"a" + m.T(11) | 106 | p = m.P(1) * m.P"a" + m.T(11) |
104 | checklabeq({3, nil, nil}, p:match("bac")) | 107 | checklabeq({3, nil, nil}, p:match("bac")) |
105 | checklabeq({nil, 11, 1}, p:match("c")) | 108 | checklabeq({nil, '11', 1}, p:match("c")) |
106 | checklabeq({nil, 11, 1}, p:match("x")) | 109 | checklabeq({nil, '11', 1}, p:match("x")) |
107 | checklabeq({nil, 11, 1}, p:match("kx")) | 110 | checklabeq({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 |
111 | p = m.Rec(m.T(2), m.P"a", 1, 3) | 114 | p = m.Rec(m.T(2), m.P"a", 1, 3) |
112 | r, l, poserr = p:match(s) | 115 | r, l, poserr = p:match(s) |
113 | assert(r == nil and l == 2 and poserr == 1) | 116 | print(r, l, poserr) |
117 | assert(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" |
116 | p = m.Rec(p, m.P"a", 2) | 120 | p = m.Rec(p, m.P"a", 2) |