diff options
Diffstat (limited to 'lptree.c')
-rw-r--r-- | lptree.c | 413 |
1 files changed, 234 insertions, 179 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lptree.c,v 1.10 2013/04/12 16:30:33 roberto Exp $ | 2 | ** $Id: lptree.c,v 1.15 2015/03/04 17:23:00 roberto Exp $ |
3 | ** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license) | 3 | ** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license) |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -127,6 +127,189 @@ static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) { | |||
127 | } | 127 | } |
128 | 128 | ||
129 | 129 | ||
130 | |||
131 | /* | ||
132 | ** {=================================================================== | ||
133 | ** KTable manipulation | ||
134 | ** | ||
135 | ** - The ktable of a pattern 'p' can be shared by other patterns that | ||
136 | ** contain 'p' and no other constants. Because of this sharing, we | ||
137 | ** should not add elements to a 'ktable' unless it was freshly created | ||
138 | ** for the new pattern. | ||
139 | ** | ||
140 | ** - The maximum index in a ktable is USHRT_MAX, because trees and | ||
141 | ** patterns use unsigned shorts to store those indices. | ||
142 | ** ==================================================================== | ||
143 | */ | ||
144 | |||
145 | /* | ||
146 | ** Create a new 'ktable' to the pattern at the top of the stack. | ||
147 | */ | ||
148 | static void newktable (lua_State *L, int n) { | ||
149 | lua_createtable(L, n, 0); /* create a fresh table */ | ||
150 | lua_setfenv(L, -2); /* set it as 'ktable' for pattern */ | ||
151 | } | ||
152 | |||
153 | |||
154 | /* | ||
155 | ** Add element 'idx' to 'ktable' of pattern at the top of the stack; | ||
156 | ** Return index of new element. | ||
157 | ** If new element is nil, does not add it to table (as it would be | ||
158 | ** useless) and returns 0, as ktable[0] is always nil. | ||
159 | */ | ||
160 | static int addtoktable (lua_State *L, int idx) { | ||
161 | if (lua_isnil(L, idx)) /* nil value? */ | ||
162 | return 0; | ||
163 | else { | ||
164 | int n; | ||
165 | lua_getfenv(L, -1); /* get ktable from pattern */ | ||
166 | n = lua_objlen(L, -1); | ||
167 | if (n >= USHRT_MAX) | ||
168 | luaL_error(L, "too many Lua values in pattern"); | ||
169 | lua_pushvalue(L, idx); /* element to be added */ | ||
170 | lua_rawseti(L, -2, ++n); | ||
171 | lua_pop(L, 1); /* remove 'ktable' */ | ||
172 | return n; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | |||
177 | /* | ||
178 | ** Return the number of elements in the ktable at 'idx'. | ||
179 | ** In Lua 5.2/5.3, default "environment" for patterns is nil, not | ||
180 | ** a table. Treat it as an empty table. In Lua 5.1, assumes that | ||
181 | ** the environment has no numeric indices (len == 0) | ||
182 | */ | ||
183 | static int ktablelen (lua_State *L, int idx) { | ||
184 | if (!lua_istable(L, idx)) return 0; | ||
185 | else return lua_objlen(L, idx); | ||
186 | } | ||
187 | |||
188 | |||
189 | /* | ||
190 | ** Concatentate the contents of table 'idx1' into table 'idx2'. | ||
191 | ** (Assume that both indices are negative.) | ||
192 | ** Return the original length of table 'idx2' (or 0, if no | ||
193 | ** element was added, as there is no need to correct any index). | ||
194 | */ | ||
195 | static int concattable (lua_State *L, int idx1, int idx2) { | ||
196 | int i; | ||
197 | int n1 = ktablelen(L, idx1); | ||
198 | int n2 = ktablelen(L, idx2); | ||
199 | if (n1 + n2 > USHRT_MAX) | ||
200 | luaL_error(L, "too many Lua values in pattern"); | ||
201 | if (n1 == 0) return 0; /* nothing to correct */ | ||
202 | for (i = 1; i <= n1; i++) { | ||
203 | lua_rawgeti(L, idx1, i); | ||
204 | lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ | ||
205 | } | ||
206 | return n2; | ||
207 | } | ||
208 | |||
209 | |||
210 | /* | ||
211 | ** When joining 'ktables', constants from one of the subpatterns must | ||
212 | ** be renumbered; 'correctkeys' corrects their indices (adding 'n' | ||
213 | ** to each of them) | ||
214 | */ | ||
215 | static void correctkeys (TTree *tree, int n) { | ||
216 | if (n == 0) return; /* no correction? */ | ||
217 | tailcall: | ||
218 | switch (tree->tag) { | ||
219 | case TOpenCall: case TCall: case TRunTime: case TRule: { | ||
220 | if (tree->key > 0) | ||
221 | tree->key += n; | ||
222 | break; | ||
223 | } | ||
224 | case TCapture: { | ||
225 | if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum) | ||
226 | tree->key += n; | ||
227 | break; | ||
228 | } | ||
229 | default: break; | ||
230 | } | ||
231 | switch (numsiblings[tree->tag]) { | ||
232 | case 1: /* correctkeys(sib1(tree), n); */ | ||
233 | tree = sib1(tree); goto tailcall; | ||
234 | case 2: | ||
235 | correctkeys(sib1(tree), n); | ||
236 | tree = sib2(tree); goto tailcall; /* correctkeys(sib2(tree), n); */ | ||
237 | default: assert(numsiblings[tree->tag] == 0); break; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | |||
242 | /* | ||
243 | ** Join the ktables from p1 and p2 the ktable for the new pattern at the | ||
244 | ** top of the stack, reusing them when possible. | ||
245 | */ | ||
246 | static void joinktables (lua_State *L, int p1, TTree *t2, int p2) { | ||
247 | int n1, n2; | ||
248 | lua_getfenv(L, p1); /* get ktables */ | ||
249 | lua_getfenv(L, p2); | ||
250 | n1 = ktablelen(L, -2); | ||
251 | n2 = ktablelen(L, -1); | ||
252 | if (n1 == 0 && n2 == 0) /* are both tables empty? */ | ||
253 | lua_pop(L, 2); /* nothing to be done; pop tables */ | ||
254 | else if (n2 == 0 || lua_equal(L, -2, -1)) { /* 2nd table empty or equal? */ | ||
255 | lua_pop(L, 1); /* pop 2nd table */ | ||
256 | lua_setfenv(L, -2); /* set 1st ktable into new pattern */ | ||
257 | } | ||
258 | else if (n1 == 0) { /* first table is empty? */ | ||
259 | lua_setfenv(L, -3); /* set 2nd table into new pattern */ | ||
260 | lua_pop(L, 1); /* pop 1st table */ | ||
261 | } | ||
262 | else { | ||
263 | lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ | ||
264 | /* stack: new p; ktable p1; ktable p2; new ktable */ | ||
265 | concattable(L, -3, -1); /* from p1 into new ktable */ | ||
266 | concattable(L, -2, -1); /* from p2 into new ktable */ | ||
267 | lua_setfenv(L, -4); /* new ktable becomes 'p' environment */ | ||
268 | lua_pop(L, 2); /* pop other ktables */ | ||
269 | correctkeys(t2, n1); /* correction for indices from p2 */ | ||
270 | } | ||
271 | } | ||
272 | |||
273 | |||
274 | /* | ||
275 | ** copy 'ktable' of element 'idx' to new tree (on top of stack) | ||
276 | */ | ||
277 | static void copyktable (lua_State *L, int idx) { | ||
278 | lua_getfenv(L, idx); | ||
279 | lua_setfenv(L, -2); | ||
280 | } | ||
281 | |||
282 | |||
283 | /* | ||
284 | ** merge 'ktable' from 'stree' at stack index 'idx' into 'ktable' | ||
285 | ** from tree at the top of the stack, and correct corresponding | ||
286 | ** tree. | ||
287 | */ | ||
288 | static void mergektable (lua_State *L, int idx, TTree *stree) { | ||
289 | int n; | ||
290 | lua_getfenv(L, -1); /* get ktables */ | ||
291 | lua_getfenv(L, idx); | ||
292 | n = concattable(L, -1, -2); | ||
293 | lua_pop(L, 2); /* remove both ktables */ | ||
294 | correctkeys(stree, n); | ||
295 | } | ||
296 | |||
297 | |||
298 | /* | ||
299 | ** Create a new 'ktable' to the pattern at the top of the stack, adding | ||
300 | ** all elements from pattern 'p' (if not 0) plus element 'idx' to it. | ||
301 | ** Return index of new element. | ||
302 | */ | ||
303 | static int addtonewktable (lua_State *L, int p, int idx) { | ||
304 | newktable(L, 1); | ||
305 | if (p) | ||
306 | mergektable(L, p, NULL); | ||
307 | return addtoktable(L, idx); | ||
308 | } | ||
309 | |||
310 | /* }====================================================== */ | ||
311 | |||
312 | |||
130 | /* | 313 | /* |
131 | ** {====================================================== | 314 | ** {====================================================== |
132 | ** Tree generation | 315 | ** Tree generation |
@@ -218,29 +401,6 @@ static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { | |||
218 | 401 | ||
219 | 402 | ||
220 | /* | 403 | /* |
221 | ** Add element 'idx' to 'ktable' of pattern at the top of the stack; | ||
222 | ** create new 'ktable' if necessary. Return index of new element. | ||
223 | */ | ||
224 | static int addtoktable (lua_State *L, int idx) { | ||
225 | if (idx == 0 || lua_isnil(L, idx)) /* no actual value to insert? */ | ||
226 | return 0; | ||
227 | else { | ||
228 | int n; | ||
229 | lua_getfenv(L, -1); /* get ktable from pattern */ | ||
230 | n = lua_objlen(L, -1); | ||
231 | if (n == 0) { /* is it empty/non-existent? */ | ||
232 | lua_pop(L, 1); /* remove it */ | ||
233 | lua_createtable(L, 1, 0); /* create a fresh table */ | ||
234 | } | ||
235 | lua_pushvalue(L, idx); /* element to be added */ | ||
236 | lua_rawseti(L, -2, n + 1); | ||
237 | lua_setfenv(L, -2); /* set it as ktable for pattern */ | ||
238 | return n + 1; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | |||
243 | /* | ||
244 | ** Build a sequence of 'n' nodes, each with tag 'tag' and 'u.n' got | 404 | ** Build a sequence of 'n' nodes, each with tag 'tag' and 'u.n' got |
245 | ** from the array 's' (or 0 if array is NULL). (TSeq is binary, so it | 405 | ** from the array 's' (or 0 if array is NULL). (TSeq is binary, so it |
246 | ** must build a sequence of sequence of sequence...) | 406 | ** must build a sequence of sequence of sequence...) |
@@ -315,7 +475,7 @@ static TTree *getpatt (lua_State *L, int idx, int *len) { | |||
315 | case LUA_TFUNCTION: { | 475 | case LUA_TFUNCTION: { |
316 | tree = newtree(L, 2); | 476 | tree = newtree(L, 2); |
317 | tree->tag = TRunTime; | 477 | tree->tag = TRunTime; |
318 | tree->key = addtoktable(L, idx); | 478 | tree->key = addtonewktable(L, 0, idx); |
319 | sib1(tree)->tag = TTrue; | 479 | sib1(tree)->tag = TTrue; |
320 | break; | 480 | break; |
321 | } | 481 | } |
@@ -331,123 +491,6 @@ static TTree *getpatt (lua_State *L, int idx, int *len) { | |||
331 | 491 | ||
332 | 492 | ||
333 | /* | 493 | /* |
334 | ** Return the number of elements in the ktable of pattern at 'idx'. | ||
335 | ** In Lua 5.2, default "environment" for patterns is nil, not | ||
336 | ** a table. Treat it as an empty table. In Lua 5.1, assumes that | ||
337 | ** the environment has no numeric indices (len == 0) | ||
338 | */ | ||
339 | static int ktablelen (lua_State *L, int idx) { | ||
340 | if (!lua_istable(L, idx)) return 0; | ||
341 | else return lua_objlen(L, idx); | ||
342 | } | ||
343 | |||
344 | |||
345 | /* | ||
346 | ** Concatentate the contents of table 'idx1' into table 'idx2'. | ||
347 | ** (Assume that both indices are negative.) | ||
348 | ** Return the original length of table 'idx2' | ||
349 | */ | ||
350 | static int concattable (lua_State *L, int idx1, int idx2) { | ||
351 | int i; | ||
352 | int n1 = ktablelen(L, idx1); | ||
353 | int n2 = ktablelen(L, idx2); | ||
354 | if (n1 == 0) return 0; /* nothing to correct */ | ||
355 | for (i = 1; i <= n1; i++) { | ||
356 | lua_rawgeti(L, idx1, i); | ||
357 | lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ | ||
358 | } | ||
359 | return n2; | ||
360 | } | ||
361 | |||
362 | |||
363 | /* | ||
364 | ** Make a merge of ktables from p1 and p2 the ktable for the new | ||
365 | ** pattern at the top of the stack. | ||
366 | */ | ||
367 | static int joinktables (lua_State *L, int p1, int p2) { | ||
368 | int n1, n2; | ||
369 | lua_getfenv(L, p1); /* get ktables */ | ||
370 | lua_getfenv(L, p2); | ||
371 | n1 = ktablelen(L, -2); | ||
372 | n2 = ktablelen(L, -1); | ||
373 | if (n1 == 0 && n2 == 0) { /* are both tables empty? */ | ||
374 | lua_pop(L, 2); /* nothing to be done; pop tables */ | ||
375 | return 0; /* nothing to correct */ | ||
376 | } | ||
377 | if (n2 == 0 || lua_equal(L, -2, -1)) { /* second table is empty or equal? */ | ||
378 | lua_pop(L, 1); /* pop 2nd table */ | ||
379 | lua_setfenv(L, -2); /* set 1st ktable into new pattern */ | ||
380 | return 0; /* nothing to correct */ | ||
381 | } | ||
382 | if (n1 == 0) { /* first table is empty? */ | ||
383 | lua_setfenv(L, -3); /* set 2nd table into new pattern */ | ||
384 | lua_pop(L, 1); /* pop 1st table */ | ||
385 | return 0; /* nothing to correct */ | ||
386 | } | ||
387 | else { | ||
388 | lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ | ||
389 | /* stack: new p; ktable p1; ktable p2; new ktable */ | ||
390 | concattable(L, -3, -1); /* from p1 into new ktable */ | ||
391 | concattable(L, -2, -1); /* from p2 into new ktable */ | ||
392 | lua_setfenv(L, -4); /* new ktable becomes p env */ | ||
393 | lua_pop(L, 2); /* pop other ktables */ | ||
394 | return n1; /* correction for indices from p2 */ | ||
395 | } | ||
396 | } | ||
397 | |||
398 | |||
399 | static void correctkeys (TTree *tree, int n) { | ||
400 | if (n == 0) return; /* no correction? */ | ||
401 | tailcall: | ||
402 | switch (tree->tag) { | ||
403 | case TOpenCall: case TCall: case TRunTime: case TRule: { | ||
404 | if (tree->key > 0) | ||
405 | tree->key += n; | ||
406 | break; | ||
407 | } | ||
408 | case TCapture: { | ||
409 | if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum) | ||
410 | tree->key += n; | ||
411 | break; | ||
412 | } | ||
413 | default: break; | ||
414 | } | ||
415 | switch (numsiblings[tree->tag]) { | ||
416 | case 1: /* correctkeys(sib1(tree), n); */ | ||
417 | tree = sib1(tree); goto tailcall; | ||
418 | case 2: | ||
419 | correctkeys(sib1(tree), n); | ||
420 | tree = sib2(tree); goto tailcall; /* correctkeys(sib2(tree), n); */ | ||
421 | default: assert(numsiblings[tree->tag] == 0); break; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | |||
426 | /* | ||
427 | ** copy 'ktable' of element 'idx' to new tree (on top of stack) | ||
428 | */ | ||
429 | static void copyktable (lua_State *L, int idx) { | ||
430 | lua_getfenv(L, idx); | ||
431 | lua_setfenv(L, -2); | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | ** merge 'ktable' from rule at stack index 'idx' into 'ktable' | ||
437 | ** from tree at the top of the stack, and correct corresponding | ||
438 | ** tree. | ||
439 | */ | ||
440 | static void mergektable (lua_State *L, int idx, TTree *rule) { | ||
441 | int n; | ||
442 | lua_getfenv(L, -1); /* get ktables */ | ||
443 | lua_getfenv(L, idx); | ||
444 | n = concattable(L, -1, -2); | ||
445 | lua_pop(L, 2); /* remove both ktables */ | ||
446 | correctkeys(rule, n); | ||
447 | } | ||
448 | |||
449 | |||
450 | /* | ||
451 | ** create a new tree, whith a new root and one sibling. | 494 | ** create a new tree, whith a new root and one sibling. |
452 | ** Sibling must be on the Lua stack, at index 1. | 495 | ** Sibling must be on the Lua stack, at index 1. |
453 | */ | 496 | */ |
@@ -475,7 +518,7 @@ static TTree *newroot2sib (lua_State *L, int tag) { | |||
475 | tree->u.ps = 1 + s1; | 518 | tree->u.ps = 1 + s1; |
476 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); | 519 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); |
477 | memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); | 520 | memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); |
478 | correctkeys(sib2(tree), joinktables(L, 1, 2)); | 521 | joinktables(L, 1, sib2(tree), 2); |
479 | return tree; | 522 | return tree; |
480 | } | 523 | } |
481 | 524 | ||
@@ -535,8 +578,8 @@ static int lp_choice (lua_State *L) { | |||
535 | */ | 578 | */ |
536 | static int lp_star (lua_State *L) { | 579 | static int lp_star (lua_State *L) { |
537 | int size1; | 580 | int size1; |
538 | int n = luaL_checkint(L, 2); | 581 | int n = (int)luaL_checkinteger(L, 2); |
539 | TTree *tree1 = gettree(L, 1, &size1); | 582 | TTree *tree1 = getpatt(L, 1, &size1); |
540 | if (n >= 0) { /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */ | 583 | if (n >= 0) { /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */ |
541 | TTree *tree = newtree(L, (n + 1) * (size1 + 1)); | 584 | TTree *tree = newtree(L, (n + 1) * (size1 + 1)); |
542 | if (nullable(tree1)) | 585 | if (nullable(tree1)) |
@@ -604,7 +647,7 @@ static int lp_sub (lua_State *L) { | |||
604 | sib1(tree)->tag = TNot; /* ...not... */ | 647 | sib1(tree)->tag = TNot; /* ...not... */ |
605 | memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ | 648 | memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ |
606 | memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ | 649 | memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ |
607 | correctkeys(sib1(tree), joinktables(L, 1, 2)); | 650 | joinktables(L, 1, sib1(tree), 2); |
608 | } | 651 | } |
609 | return 1; | 652 | return 1; |
610 | } | 653 | } |
@@ -645,8 +688,8 @@ static int lp_behind (lua_State *L) { | |||
645 | TTree *tree; | 688 | TTree *tree; |
646 | TTree *tree1 = getpatt(L, 1, NULL); | 689 | TTree *tree1 = getpatt(L, 1, NULL); |
647 | int n = fixedlen(tree1); | 690 | int n = fixedlen(tree1); |
648 | luaL_argcheck(L, !hascaptures(tree1), 1, "pattern have captures"); | ||
649 | luaL_argcheck(L, n > 0, 1, "pattern may not have fixed length"); | 691 | luaL_argcheck(L, n > 0, 1, "pattern may not have fixed length"); |
692 | luaL_argcheck(L, !hascaptures(tree1), 1, "pattern have captures"); | ||
650 | luaL_argcheck(L, n <= MAXBEHIND, 1, "pattern too long to look behind"); | 693 | luaL_argcheck(L, n <= MAXBEHIND, 1, "pattern too long to look behind"); |
651 | tree = newroot1sib(L, TBehind); | 694 | tree = newroot1sib(L, TBehind); |
652 | tree->u.n = n; | 695 | tree->u.n = n; |
@@ -697,7 +740,7 @@ static int lp_labchoice (lua_State *L) { | |||
697 | static int lp_V (lua_State *L) { | 740 | static int lp_V (lua_State *L) { |
698 | TTree *tree = newleaf(L, TOpenCall); | 741 | TTree *tree = newleaf(L, TOpenCall); |
699 | luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); | 742 | luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); |
700 | tree->key = addtoktable(L, 1); | 743 | tree->key = addtonewktable(L, 0, 1); |
701 | return 1; | 744 | return 1; |
702 | } | 745 | } |
703 | 746 | ||
@@ -710,7 +753,7 @@ static int lp_V (lua_State *L) { | |||
710 | static int capture_aux (lua_State *L, int cap, int labelidx) { | 753 | static int capture_aux (lua_State *L, int cap, int labelidx) { |
711 | TTree *tree = newroot1sib(L, TCapture); | 754 | TTree *tree = newroot1sib(L, TCapture); |
712 | tree->cap = cap; | 755 | tree->cap = cap; |
713 | tree->key = addtoktable(L, labelidx); | 756 | tree->key = (labelidx == 0) ? 0 : addtonewktable(L, 1, labelidx); |
714 | return 1; | 757 | return 1; |
715 | } | 758 | } |
716 | 759 | ||
@@ -718,10 +761,9 @@ static int capture_aux (lua_State *L, int cap, int labelidx) { | |||
718 | /* | 761 | /* |
719 | ** Fill a tree with an empty capture, using an empty (TTrue) sibling. | 762 | ** Fill a tree with an empty capture, using an empty (TTrue) sibling. |
720 | */ | 763 | */ |
721 | static TTree *auxemptycap (lua_State *L, TTree *tree, int cap, int idx) { | 764 | static TTree *auxemptycap (TTree *tree, int cap) { |
722 | tree->tag = TCapture; | 765 | tree->tag = TCapture; |
723 | tree->cap = cap; | 766 | tree->cap = cap; |
724 | tree->key = addtoktable(L, idx); | ||
725 | sib1(tree)->tag = TTrue; | 767 | sib1(tree)->tag = TTrue; |
726 | return tree; | 768 | return tree; |
727 | } | 769 | } |
@@ -730,8 +772,18 @@ static TTree *auxemptycap (lua_State *L, TTree *tree, int cap, int idx) { | |||
730 | /* | 772 | /* |
731 | ** Create a tree for an empty capture | 773 | ** Create a tree for an empty capture |
732 | */ | 774 | */ |
733 | static TTree *newemptycap (lua_State *L, int cap, int idx) { | 775 | static TTree *newemptycap (lua_State *L, int cap) { |
734 | return auxemptycap(L, newtree(L, 2), cap, idx); | 776 | return auxemptycap(newtree(L, 2), cap); |
777 | } | ||
778 | |||
779 | |||
780 | /* | ||
781 | ** Create a tree for an empty capture with an associated Lua value | ||
782 | */ | ||
783 | static TTree *newemptycapkey (lua_State *L, int cap, int idx) { | ||
784 | TTree *tree = auxemptycap(newtree(L, 2), cap); | ||
785 | tree->key = addtonewktable(L, 0, idx); | ||
786 | return tree; | ||
735 | } | 787 | } |
736 | 788 | ||
737 | 789 | ||
@@ -789,14 +841,14 @@ static int lp_simplecapture (lua_State *L) { | |||
789 | 841 | ||
790 | 842 | ||
791 | static int lp_poscapture (lua_State *L) { | 843 | static int lp_poscapture (lua_State *L) { |
792 | newemptycap(L, Cposition, 0); | 844 | newemptycap(L, Cposition); |
793 | return 1; | 845 | return 1; |
794 | } | 846 | } |
795 | 847 | ||
796 | 848 | ||
797 | static int lp_argcapture (lua_State *L) { | 849 | static int lp_argcapture (lua_State *L) { |
798 | int n = luaL_checkint(L, 1); | 850 | int n = (int)luaL_checkinteger(L, 1); |
799 | TTree *tree = newemptycap(L, Carg, 0); | 851 | TTree *tree = newemptycap(L, Carg); |
800 | tree->key = n; | 852 | tree->key = n; |
801 | luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); | 853 | luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); |
802 | return 1; | 854 | return 1; |
@@ -805,7 +857,7 @@ static int lp_argcapture (lua_State *L) { | |||
805 | 857 | ||
806 | static int lp_backref (lua_State *L) { | 858 | static int lp_backref (lua_State *L) { |
807 | luaL_checkstring(L, 1); | 859 | luaL_checkstring(L, 1); |
808 | newemptycap(L, Cbackref, 1); | 860 | newemptycapkey(L, Cbackref, 1); |
809 | return 1; | 861 | return 1; |
810 | } | 862 | } |
811 | 863 | ||
@@ -819,9 +871,10 @@ static int lp_constcapture (lua_State *L) { | |||
819 | if (n == 0) /* no values? */ | 871 | if (n == 0) /* no values? */ |
820 | newleaf(L, TTrue); /* no capture */ | 872 | newleaf(L, TTrue); /* no capture */ |
821 | else if (n == 1) | 873 | else if (n == 1) |
822 | newemptycap(L, Cconst, 1); /* single constant capture */ | 874 | newemptycapkey(L, Cconst, 1); /* single constant capture */ |
823 | else { /* create a group capture with all values */ | 875 | else { /* create a group capture with all values */ |
824 | TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); | 876 | TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); |
877 | newktable(L, n); /* create a 'ktable' for new tree */ | ||
825 | tree->tag = TCapture; | 878 | tree->tag = TCapture; |
826 | tree->cap = Cgroup; | 879 | tree->cap = Cgroup; |
827 | tree->key = 0; | 880 | tree->key = 0; |
@@ -829,10 +882,12 @@ static int lp_constcapture (lua_State *L) { | |||
829 | for (i = 1; i <= n - 1; i++) { | 882 | for (i = 1; i <= n - 1; i++) { |
830 | tree->tag = TSeq; | 883 | tree->tag = TSeq; |
831 | tree->u.ps = 3; /* skip TCapture and its sibling */ | 884 | tree->u.ps = 3; /* skip TCapture and its sibling */ |
832 | auxemptycap(L, sib1(tree), Cconst, i); | 885 | auxemptycap(sib1(tree), Cconst); |
886 | sib1(tree)->key = addtoktable(L, i); | ||
833 | tree = sib2(tree); | 887 | tree = sib2(tree); |
834 | } | 888 | } |
835 | auxemptycap(L, tree, Cconst, i); | 889 | auxemptycap(tree, Cconst); |
890 | tree->key = addtoktable(L, i); | ||
836 | } | 891 | } |
837 | return 1; | 892 | return 1; |
838 | } | 893 | } |
@@ -842,7 +897,7 @@ static int lp_matchtime (lua_State *L) { | |||
842 | TTree *tree; | 897 | TTree *tree; |
843 | luaL_checktype(L, 2, LUA_TFUNCTION); | 898 | luaL_checktype(L, 2, LUA_TFUNCTION); |
844 | tree = newroot1sib(L, TRunTime); | 899 | tree = newroot1sib(L, TRunTime); |
845 | tree->key = addtoktable(L, 2); | 900 | tree->key = addtonewktable(L, 1, 2); |
846 | return 1; | 901 | return 1; |
847 | } | 902 | } |
848 | 903 | ||
@@ -1146,20 +1201,20 @@ static int lp_match (lua_State *L) { | |||
1146 | lua_pushnil(L); /* initialize subscache */ | 1201 | lua_pushnil(L); /* initialize subscache */ |
1147 | lua_pushlightuserdata(L, capture); /* initialize caplistidx */ | 1202 | lua_pushlightuserdata(L, capture); /* initialize caplistidx */ |
1148 | lua_getfenv(L, 1); /* initialize penvidx */ | 1203 | lua_getfenv(L, 1); /* initialize penvidx */ |
1149 | r = match(L, s, s + i, s + l, code, capture, ptop, &labelf); | 1204 | r = match(L, s, s + i, s + l, code, capture, ptop, &labelf); /* labeled failure */ |
1150 | if (r == NULL) { | 1205 | if (r == NULL) { /* labeled failure begin */ |
1151 | int j = 0; | 1206 | int j = 0; |
1152 | int n = 1; | 1207 | int n = 1; |
1153 | lua_pushnil(L); | 1208 | lua_pushnil(L); |
1154 | while (j < (int) MAXLABELS) { | 1209 | while (j < (int) MAXLABELS) { |
1155 | if (labelf & (1 << j)) { | 1210 | if (labelf & (1 << j)) { |
1156 | lua_pushinteger(L, j); | 1211 | lua_pushinteger(L, j); |
1157 | n++; | 1212 | n++; |
1158 | } | 1213 | } |
1159 | j++; | 1214 | j++; |
1160 | } | 1215 | } |
1161 | return n; | 1216 | return n; |
1162 | } | 1217 | } /* labeled failure end */ |
1163 | return getcaptures(L, s, r, ptop); | 1218 | return getcaptures(L, s, r, ptop); |
1164 | } | 1219 | } |
1165 | 1220 | ||
@@ -1197,7 +1252,7 @@ static int lp_type (lua_State *L) { | |||
1197 | int lp_gc (lua_State *L) { | 1252 | int lp_gc (lua_State *L) { |
1198 | Pattern *p = getpattern(L, 1); | 1253 | Pattern *p = getpattern(L, 1); |
1199 | if (p->codesize > 0) | 1254 | if (p->codesize > 0) |
1200 | reallocprog(L, p, 0); | 1255 | realloccode(L, p, 0); |
1201 | return 0; | 1256 | return 0; |
1202 | } | 1257 | } |
1203 | 1258 | ||
@@ -1258,8 +1313,8 @@ static struct luaL_Reg pattreg[] = { | |||
1258 | {"version", lp_version}, | 1313 | {"version", lp_version}, |
1259 | {"setmaxstack", lp_setmax}, | 1314 | {"setmaxstack", lp_setmax}, |
1260 | {"type", lp_type}, | 1315 | {"type", lp_type}, |
1261 | {"T", lp_throw}, /* labeled failure throw */ | 1316 | {"T", lp_throw}, /* labeled failure throw */ |
1262 | {"Lc", lp_labchoice}, /* labeled failure choice */ | 1317 | {"Lc", lp_labchoice}, /* labeled failure choice */ |
1263 | {NULL, NULL} | 1318 | {NULL, NULL} |
1264 | }; | 1319 | }; |
1265 | 1320 | ||
@@ -1277,13 +1332,13 @@ static struct luaL_Reg metareg[] = { | |||
1277 | }; | 1332 | }; |
1278 | 1333 | ||
1279 | 1334 | ||
1280 | int luaopen_lpeglabel (lua_State *L); | 1335 | int luaopen_lpeglabel (lua_State *L); /* labeld failure */ |
1281 | int luaopen_lpeglabel (lua_State *L) { | 1336 | int luaopen_lpeglabel (lua_State *L) { /* labeled failure */ |
1282 | luaL_newmetatable(L, PATTERN_T); | 1337 | luaL_newmetatable(L, PATTERN_T); |
1283 | lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ | 1338 | lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ |
1284 | lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); | 1339 | lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); |
1285 | luaL_register(L, NULL, metareg); | 1340 | luaL_register(L, NULL, metareg); |
1286 | luaL_register(L, "lpeglabel", pattreg); | 1341 | luaL_register(L, "lpeglabel", pattreg); /* labeled failure */ |
1287 | lua_pushvalue(L, -1); | 1342 | lua_pushvalue(L, -1); |
1288 | lua_setfield(L, -3, "__index"); | 1343 | lua_setfield(L, -3, "__index"); |
1289 | return 1; | 1344 | return 1; |