diff options
author | Sergio Queiroz <sqmedeiros@gmail.com> | 2017-07-06 16:01:44 -0300 |
---|---|---|
committer | Sergio Queiroz <sqmedeiros@gmail.com> | 2017-07-06 16:01:44 -0300 |
commit | e2a8e1c789a7a769c83a66d6fd2f191b0e465cba (patch) | |
tree | e2aecc3d439e44db98439c26cf23625da1bedb3f /lpcode.c | |
parent | a36fe71ac0271d9013f76d9342f9a2fca40f64fc (diff) | |
download | lpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.tar.gz lpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.tar.bz2 lpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.zip |
Reintroducing the labeled ordered choice (tests without it passed)
Diffstat (limited to 'lpcode.c')
-rw-r--r-- | lpcode.c | 35 |
1 files changed, 27 insertions, 8 deletions
@@ -220,7 +220,7 @@ int checkaux (TTree *tree, int pred) { | |||
220 | if (checkaux(sib2(tree), pred)) return 1; | 220 | if (checkaux(sib2(tree), pred)) return 1; |
221 | /* else return checkaux(sib1(tree), pred); */ | 221 | /* else return checkaux(sib1(tree), pred); */ |
222 | tree = sib1(tree); goto tailcall; | 222 | tree = sib1(tree); goto tailcall; |
223 | case TRecov: /* labeled failure */ | 223 | case TRecov: case TLabChoice: /* labeled failure */ |
224 | /* we do not know whether sib2 will be evaluated */ | 224 | /* we do not know whether sib2 will be evaluated */ |
225 | tree = sib1(tree); goto tailcall; | 225 | tree = sib1(tree); goto tailcall; |
226 | case TCapture: case TGrammar: case TRule: | 226 | case TCapture: case TGrammar: case TRule: |
@@ -264,7 +264,7 @@ int fixedlen (TTree *tree) { | |||
264 | /* else return fixedlen(sib2(tree)) + len; */ | 264 | /* else return fixedlen(sib2(tree)) + len; */ |
265 | len += n1; tree = sib2(tree); goto tailcall; | 265 | len += n1; tree = sib2(tree); goto tailcall; |
266 | } | 266 | } |
267 | case TChoice: { | 267 | case TChoice: case TLabChoice: { /* labeled failure */ |
268 | int n1 = fixedlen(sib1(tree)); | 268 | int n1 = fixedlen(sib1(tree)); |
269 | int n2 = fixedlen(sib2(tree)); | 269 | int n2 = fixedlen(sib2(tree)); |
270 | if (n1 != n2 || n1 < 0) | 270 | if (n1 != n2 || n1 < 0) |
@@ -314,7 +314,7 @@ static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) { | |||
314 | loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */ | 314 | loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */ |
315 | return 1; | 315 | return 1; |
316 | } | 316 | } |
317 | case TChoice: { | 317 | case TChoice: case TLabChoice: { /*(?) labeled failure */ |
318 | Charset csaux; | 318 | Charset csaux; |
319 | int e1 = getfirst(sib1(tree), follow, firstset); | 319 | int e1 = getfirst(sib1(tree), follow, firstset); |
320 | int e2 = getfirst(sib2(tree), follow, &csaux); | 320 | int e2 = getfirst(sib2(tree), follow, &csaux); |
@@ -405,7 +405,7 @@ static int headfail (TTree *tree) { | |||
405 | if (!nofail(sib2(tree))) return 0; | 405 | if (!nofail(sib2(tree))) return 0; |
406 | /* else return headfail(sib1(tree)); */ | 406 | /* else return headfail(sib1(tree)); */ |
407 | tree = sib1(tree); goto tailcall; | 407 | tree = sib1(tree); goto tailcall; |
408 | case TChoice: case TRecov: /* labeled failure */ | 408 | case TChoice: case TRecov: case TLabChoice: /* labeled failure */ |
409 | if (!headfail(sib1(tree))) return 0; | 409 | if (!headfail(sib1(tree))) return 0; |
410 | /* else return headfail(sib2(tree)); */ | 410 | /* else return headfail(sib2(tree)); */ |
411 | tree = sib2(tree); goto tailcall; | 411 | tree = sib2(tree); goto tailcall; |
@@ -425,7 +425,7 @@ static int needfollow (TTree *tree) { | |||
425 | case TChar: case TSet: case TAny: | 425 | case TChar: case TSet: case TAny: |
426 | case TFalse: case TTrue: case TAnd: case TNot: | 426 | case TFalse: case TTrue: case TAnd: case TNot: |
427 | case TRunTime: case TGrammar: case TCall: case TBehind: | 427 | case TRunTime: case TGrammar: case TCall: case TBehind: |
428 | case TThrow: case TRecov: /* (?)labeled failure */ | 428 | case TThrow: case TRecov: case TLabChoice: /* (?)labeled failure */ |
429 | return 0; | 429 | return 0; |
430 | case TChoice: case TRep: | 430 | case TChoice: case TRep: |
431 | return 1; | 431 | return 1; |
@@ -460,7 +460,7 @@ int sizei (const Instruction *i) { | |||
460 | return 2; | 460 | return 2; |
461 | case IThrow: /* labeled failure */ | 461 | case IThrow: /* labeled failure */ |
462 | return 1; | 462 | return 1; |
463 | case IRecov: | 463 | case IRecov: case ILabChoice: |
464 | return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ | 464 | return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ |
465 | 465 | ||
466 | default: return 1; | 466 | default: return 1; |
@@ -527,7 +527,7 @@ static int addoffsetinst (CompileState *compst, Opcode op) { | |||
527 | int i = addinstruction(compst, op, 0); /* instruction */ | 527 | int i = addinstruction(compst, op, 0); /* instruction */ |
528 | addinstruction(compst, (Opcode)0, 0); /* open space for offset */ | 528 | addinstruction(compst, (Opcode)0, 0); /* open space for offset */ |
529 | assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2 || | 529 | assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2 || |
530 | op == IRecov); /* labeled failure */ | 530 | op == IRecov || op == ILabChoice); /* labeled failure */ |
531 | return i; | 531 | return i; |
532 | } | 532 | } |
533 | 533 | ||
@@ -750,6 +750,21 @@ static void coderecovery (CompileState *compst, TTree *p1, TTree *p2, int opt, | |||
750 | addinstruction(compst, IRet, 0); | 750 | addinstruction(compst, IRet, 0); |
751 | jumptohere(compst, pcommit); | 751 | jumptohere(compst, pcommit); |
752 | } | 752 | } |
753 | |||
754 | static void codelabchoice (CompileState *compst, TTree *p1, TTree *p2, int opt, | ||
755 | const Charset *fl, const byte *cs) { | ||
756 | int emptyp2 = (p2->tag == TTrue); | ||
757 | int pcommit; | ||
758 | int test = NOINST; | ||
759 | int pchoice = addoffsetinst(compst, ILabChoice); | ||
760 | addcharset(compst, cs); | ||
761 | codegen(compst, p1, emptyp2, test, fullset); | ||
762 | pcommit = addoffsetinst(compst, ICommit); | ||
763 | jumptohere(compst, pchoice); | ||
764 | jumptohere(compst, test); | ||
765 | codegen(compst, p2, opt, NOINST, fl); | ||
766 | jumptohere(compst, pcommit); | ||
767 | } | ||
753 | /* labeled failure end */ | 768 | /* labeled failure end */ |
754 | 769 | ||
755 | 770 | ||
@@ -988,6 +1003,10 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt, | |||
988 | coderecovery(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree)); | 1003 | coderecovery(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree)); |
989 | break; | 1004 | break; |
990 | } | 1005 | } |
1006 | case TLabChoice: { /* labeled failure */ | ||
1007 | codelabchoice(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree)); | ||
1008 | break; | ||
1009 | } | ||
991 | default: assert(0); | 1010 | default: assert(0); |
992 | } | 1011 | } |
993 | } | 1012 | } |
@@ -1010,7 +1029,7 @@ static void peephole (CompileState *compst) { | |||
1010 | switch (code[i].i.code) { | 1029 | switch (code[i].i.code) { |
1011 | case IChoice: case ICall: case ICommit: case IPartialCommit: | 1030 | case IChoice: case ICall: case ICommit: case IPartialCommit: |
1012 | case IBackCommit: case ITestChar: case ITestSet: | 1031 | case IBackCommit: case ITestChar: case ITestSet: |
1013 | case IRecov: /* labeled failure */ | 1032 | case IRecov: case ILabChoice: /* labeled failure */ |
1014 | case ITestAny: { /* instructions with labels */ | 1033 | case ITestAny: { /* instructions with labels */ |
1015 | jumptothere(compst, i, finallabel(code, i)); /* optimize label */ | 1034 | jumptothere(compst, i, finallabel(code, i)); /* optimize label */ |
1016 | break; | 1035 | break; |