optimize trivial recursion
This commit is contained in:
69
pike.c
69
pike.c
@@ -117,12 +117,6 @@ rsub* newsub(int n)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsub* incref(rsub *s)
|
|
||||||
{
|
|
||||||
s->ref++;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
rsub* update(rsub *s, int i, const char *p)
|
rsub* update(rsub *s, int i, const char *p)
|
||||||
{
|
{
|
||||||
rsub *s1;
|
rsub *s1;
|
||||||
@@ -526,54 +520,49 @@ void cleanmarks(rcode *prog)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rthread thread(int *pc, rsub *sub)
|
static void addthread(rthreadlist *l, int *pc, rsub *sub, const char *beg, const char *sp)
|
||||||
{
|
|
||||||
rthread t = {pc, sub};
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addthread(rthreadlist *l, rthread t, const char *beg, const char *sp)
|
|
||||||
{
|
{
|
||||||
int off;
|
int off;
|
||||||
if(*t.pc & 0x80) {
|
rec:
|
||||||
decref(t.sub);
|
if(*pc & 0x80) {
|
||||||
|
decref(sub);
|
||||||
return; // already on list
|
return; // already on list
|
||||||
}
|
}
|
||||||
*t.pc |= 0x80;
|
*pc |= 0x80;
|
||||||
|
|
||||||
switch(*t.pc & 0x7f) {
|
switch(*pc & 0x7f) {
|
||||||
default:
|
default:
|
||||||
l->t[l->n++] = t;
|
l->t[l->n].sub = sub;
|
||||||
|
l->t[l->n++].pc = pc;
|
||||||
break;
|
break;
|
||||||
case JMP:
|
case JMP:
|
||||||
off = t.pc[1];
|
off = pc[1];
|
||||||
t.pc += 2;
|
pc += 2 + off;
|
||||||
addthread(l, thread(t.pc + off, t.sub), beg, sp);
|
goto rec;
|
||||||
break;
|
|
||||||
case SPLIT:
|
case SPLIT:
|
||||||
off = t.pc[1];
|
off = pc[1];
|
||||||
t.pc += 2;
|
sub->ref++;
|
||||||
addthread(l, thread(t.pc, incref(t.sub)), beg, sp);
|
addthread(l, pc+2, sub, beg, sp);
|
||||||
addthread(l, thread(t.pc + off, t.sub), beg, sp);
|
pc += 2 + off;
|
||||||
break;
|
goto rec;
|
||||||
case RSPLIT:
|
case RSPLIT:
|
||||||
off = t.pc[1];
|
off = pc[1];
|
||||||
t.pc += 2;
|
pc += 2;
|
||||||
addthread(l, thread(t.pc + off, incref(t.sub)), beg, sp);
|
sub->ref++;
|
||||||
addthread(l, thread(t.pc, t.sub), beg, sp);
|
addthread(l, pc + off, sub, beg, sp);
|
||||||
break;
|
goto rec;
|
||||||
case SAVE:
|
case SAVE:
|
||||||
off = t.pc[1];
|
off = pc[1];
|
||||||
t.pc += 2;
|
pc += 2;
|
||||||
addthread(l, thread(t.pc, update(t.sub, off, sp)), beg, sp);
|
sub = update(sub, off, sp);
|
||||||
break;
|
goto rec;
|
||||||
case BOL:
|
case BOL:
|
||||||
if(sp == beg)
|
if(sp == beg)
|
||||||
addthread(l, thread(t.pc + 1, t.sub), beg, sp);
|
{ pc++; goto rec; }
|
||||||
break;
|
break;
|
||||||
case EOL:
|
case EOL:
|
||||||
if(!*sp)
|
if(!*sp)
|
||||||
addthread(l, thread(t.pc + 1, t.sub), beg, sp);
|
{ pc++; goto rec; }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -598,7 +587,7 @@ int re_pikevm(rcode *prog, const char *s, const char **subp, int nsubp)
|
|||||||
sub->sub[i] = NULL;
|
sub->sub[i] = NULL;
|
||||||
|
|
||||||
cleanmarks(prog);
|
cleanmarks(prog);
|
||||||
addthread(clist, thread(prog->insts, sub), s, s);
|
addthread(clist, prog->insts, sub, s, s);
|
||||||
for(sp=s;; sp++) {
|
for(sp=s;; sp++) {
|
||||||
if(clist->n == 0)
|
if(clist->n == 0)
|
||||||
break;
|
break;
|
||||||
@@ -620,7 +609,7 @@ int re_pikevm(rcode *prog, const char *s, const char **subp, int nsubp)
|
|||||||
}
|
}
|
||||||
case ANY:
|
case ANY:
|
||||||
addthread:
|
addthread:
|
||||||
addthread(nlist, thread(pc, sub), s, sp+1);
|
addthread(nlist, pc, sub, s, sp+1);
|
||||||
break;
|
break;
|
||||||
case CLASS:
|
case CLASS:
|
||||||
case CLASSNOT:
|
case CLASSNOT:
|
||||||
|
|||||||
Reference in New Issue
Block a user