decompiled_code:
int __fastcall md5_4_humans(__int64 a1, char *a2)
{
char *v3; // rbx
int result; // eax
_BYTE v5[16]; // [rsp+0h] [rbp-28h] BYREF
char v6; // [rsp+10h] [rbp-18h] BYREF

MD5_Final(v5, a1);
v3 = v5;
do
{
result = sprintf(a2, "%02x", (unsigned __int8)*v3++);
a2 += 2;
}
while ( v3 != &v6 );
return result;
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1, char *a2)
{
char *v3; // rbx
int result; // eax
_BYTE v5[16]; // [rsp+0h] [rbp-28h] BYREF
char v6; // [rsp+10h] [rbp-18h] BYREF

MD5_Final(v5, a1);
v3 = v5;
do
{
result = sprintf(a2, "%02x", (unsigned __int8)*v3++);
a2 += 2;
}
while ( v3 != &v6 );
return result;
}

original_code:
void md5_4_humans(MD5_CTX *c, char* stringa)
{
    unsigned char digest[16];
    int i;
    MD5_Final(digest,c);
    for(i = 0; i < 16; ++i)
        sprintf(&stringa[i*2], "%02x", (unsigned int)digest[i]);
}

canonical_original_code:
void md5_4_humans(struct MD5state_st *c, char *stringa)
{
    unsigned char digest[16];
    int i;
    MD5_Final(digest,c);
    for(i = 0; i < 16; ++i)
        sprintf(&stringa[i*2], "%02x", (unsigned int)digest[i]);
}

variable_types: struct MD5state_st { unsigned int A; unsigned int Nl; unsigned int data[-1]; unsigned int num; } *

variable_types:
stringa
char *

variable_types:
digest
unsigned char [16]

variable_types: i int


printgameflags

original_code:
void printgameflags(vars *varia, char *str)
{
    switch (varia->gamemode&0b1111)
        {
        case 0b01: sprintf(str,"s");
        break;
        case 0b10: sprintf(str,"d");
        break;
        case 0b100: sprintf(str,"e");
        break;
        case 0b1000: sprintf(str,"r");
        break;
        }
    if ((varia->gamemode&0b10000)!=0)
        {
        sprintf(&(str[strlen(str)]),"p");
        }
    if (varia->gioco.serpente.ai&0b1)
        {
        sprintf(&(str[strlen(str)]),"l");
        }
    sprintf(&(str[strlen(str)]),"%d",varia->speed);
    if (varia->gameover==2)
        {
        sprintf(&(str[strlen(str)]),"k");
        }
}

canonical_original_code:
void printgameflags(struct vars *varia, char *str)
{
    switch (varia->gamemode&0b1111)
        {
        case 0b01: sprintf(str,"s");
        break;
        case 0b10: sprintf(str,"d");
        break;
        case 0b100: sprintf(str,"e");
        break;
        case 0b1000: sprintf(str,"r");
        break;
        }
    if ((varia->gamemode&0b10000)!=0)
        {
        sprintf(&(str[strlen(str)]),"p");
        }
    if (varia->gioco.serpente.ai&0b1)
        {
        sprintf(&(str[strlen(str)]),"l");
        }
    sprintf(&(str[strlen(str)]),"%d",varia->speed);
    if (varia->gameover==2)
        {
        sprintf(&(str[strlen(str)]),"k");
        }
}

variable_types: struct vars { struct campo { struct snake { struct punto { int x; int y; } *sezioni; int numsezioni; int direz; int scheduledir; int ciclo_anim; int ate; int keepexp; int portalcross; int ai; char **cache; } serpente; struct punto portale[2]; int numportals; int nextportime; struct punto *powerup; int numpowerups; int larg; int alt; struct punto *toblast; int blastlung; } gioco; struct leaderboard { struct punteggio { int score; char nome[10]; char flags[6]; } *entry; int numentry; int curr; } board; int score; int speed; int quit; int paused; int gameover; int gamemode; int colori; int safe_graph; int game_insane; char playername[10]; } *

variable_types:
str
char *

return_type: void

user_defined_types: struct vars { struct campo gioco; struct leaderboard board; int score; int speed; int quit; int paused; int gameover; int gamemode; int colori; int safe_graph; int game_insane; char playername[10]; }

user_defined_types: struct campo { struct snake serpente; struct punto portale[2]; int numportals; int nextportime; struct punto *powerup; int numpowerups; int larg; int alt; struct punto *toblast; int blastlung; }

user_defined_types: struct leaderboard { struct punteggio *entry; int numentry; int curr; }

user_defined_types: struct snake { struct punto *sezioni; int numsezioni; int direz; int scheduledir; int ciclo_anim; int ate; int keepexp; int portalcross; int ai; char **cache; }


decompiled_code:
void __fastcall sort_punteggi(__int64 a1)
{
qsort(*(void **)a1, *(int *)(a1 + 8), 0x14uLL, (__compar_fn_t)comparaz);
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1)
{
qsort(*(void **)a1, *(int *)(a1 + 8), 0x14uLL, (__compar_fn_t)comparaz);
}

original_code:
void sort_punteggi(leaderboard *board)
{
    qsort(board->entry,board->numentry,sizeof(punteggio),comparaz);
}

canonical_original_code:
void sort_punteggi(struct leaderboard *board)
{
    qsort(board->entry,board->numentry,sizeof(punteggio),comparaz);
}

variable_types: struct leaderboard { struct punteggio { int score; char nome[10]; char flags[6]; } *entry; int numentry; int curr; } *


decompiled_code:
__int64 __fastcall scrivi_punteggi(int a1, int a2, int a3, __int64 a4)
{
__int64 result; // rax
__int64 v7; // r12
int v8; // ebx

wmove(stdscr, a1, a2);
printw("Punteggi migliori:");
result = *(unsigned int *)(a4 + 124);
if ( a3 > 0 )
{
v7 = 20LL * (int)result;
v8 = *(_DWORD *)(a4 + 124);
do
{
if ( *(_DWORD *)(a4 + 120) <= v8 )
break;
wmove(stdscr, a1 + 1 + v8++ - result, a2);
printw(
"%3d)%11s %5d %6s",
(unsigned int)v8,
(const char *)(*(_QWORD *)(a4 + 112) + v7 + 4),
*(unsigned int *)(*(_QWORD *)(a4 + 112) + v7),
(const char *)(*(_QWORD *)(a4 + 112) + v7 + 14));
result = *(unsigned int *)(a4 + 124);
v7 += 20LL;
}
while ( v8 < (int)result + a3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(int a1, int a2, int a3, __int64 a4)
{
__int64 result; // rax
__int64 v7; // r12
int v8; // ebx

wmove(stdscr, a1, a2);
printw("Punteggi migliori:");
result = *(unsigned int *)(a4 + 124);
if ( a3 > 0 )
{
v7 = 20LL * (int)result;
v8 = *(_DWORD *)(a4 + 124);
do
{
if ( *(_DWORD *)(a4 + 120) <= v8 )
break;
wmove(stdscr, a1 + 1 + v8++ - result, a2);
printw(
"%3d)%11s %5d %6s",
(unsigned int)v8,
(const char *)(*(_QWORD *)(a4 + 112) + v7 + 4),
*(unsigned int *)(*(_QWORD *)(a4 + 112) + v7),
(const char *)(*(_QWORD *)(a4 + 112) + v7 + 14));
result = *(unsigned int *)(a4 + 124);
v7 += 20LL;
}
while ( v8 < (int)result + a3 );
}
return result;
}

original_code:
void scrivi_punteggi(int top, int left, int num, vars *varia)
{
    int cont;
    wmove(stdscr,(top+cont),(left));
    printw("Punteggi migliori:");
    for (cont=varia->board.curr; cont<varia->board.curr+num && cont<varia->board.numentry; cont++)
        {
        wmove(stdscr,(top+cont+1-varia->board.curr),(left));
        printw("%3d)%11s %5d %6s",cont+1,varia->board.entry[cont].nome,varia->board.entry[cont].score,varia->board.entry[cont].flags);
        }
}

canonical_original_code:
void scrivi_punteggi(int top, int left, int num, struct vars *varia)
{
    int cont;
    wmove(stdscr,(top+cont),(left));
    printw("Punteggi migliori:");
    for (cont=varia->board.curr; cont<varia->board.curr+num && cont<varia->board.numentry; cont++)
        {
        wmove(stdscr,(top+cont+1-varia->board.curr),(left));
        printw("%3d)%11s %5d %6s",cont+1,varia->board.entry[cont].nome,varia->board.entry[cont].score,varia->board.entry[cont].flags);
        }
}

variable_types: top int

variable_types: left int

variable_types: num int

variable_types: cont int

user_defined_types: struct punteggio { int score; char nome[10]; char flags[6]; }


decompiled_code:
int __fastcall just_print(__int64 a1, int a2)
{
int result; // eax
int v3; // ebx
__int64 v4; // r12

result = puts("Punteggi migliori:");
v3 = *(_DWORD *)(a1 + 124);
if ( a2 > 0 )
{
result = *(_DWORD *)(a1 + 124);
v4 = 20LL * v3;
do
{
if ( *(_DWORD *)(a1 + 120) <= v3 )
break;
printf(
"%3d)\t%11s\t%5d\t%6s\n",
(unsigned int)++v3,
(const char *)(*(_QWORD *)(a1 + 112) + v4 + 4),
*(unsigned int *)(*(_QWORD *)(a1 + 112) + v4),
(const char *)(*(_QWORD *)(a1 + 112) + v4 + 14));
v4 += 20LL;
result = *(_DWORD *)(a1 + 124) + a2;
}
while ( v3 < result );
}
return result;
}

canonical_decompiled_code:
int __fastcall func9(__int64 a1, int a2)
{
int result; // eax
int v3; // ebx
__int64 v4; // r12

result = puts("Punteggi migliori:");
v3 = *(_DWORD *)(a1 + 124);
if ( a2 > 0 )
{
result = *(_DWORD *)(a1 + 124);
v4 = 20LL * v3;
do
{
if ( *(_DWORD *)(a1 + 120) <= v3 )
break;
printf(
"%3d)\t%11s\t%5d\t%6s\n",
(unsigned int)++v3,
(const char *)(*(_QWORD *)(a1 + 112) + v4 + 4),
*(unsigned int *)(*(_QWORD *)(a1 + 112) + v4),
(const char *)(*(_QWORD *)(a1 + 112) + v4 + 14));
v4 += 20LL;
result = *(_DWORD *)(a1 + 124) + a2;
}
while ( v3 < result );
}
return result;
}

original_code:
void just_print(vars *varia, int num)
{
    int cont;
    printf("Punteggi migliori:\n");
    for (cont=varia->board.curr; cont<varia->board.curr+num && cont<varia->board.numentry; cont++)
        {
        printf("%3d)\t%11s\t%5d\t%6s\n",cont+1,varia->board.entry[cont].nome,varia->board.entry[cont].score,varia->board.entry[cont].flags);
        }
}

canonical_original_code:
void just_print(struct vars *varia, int num)
{
    int cont;
    printf("Punteggi migliori:\n");
    for (cont=varia->board.curr; cont<varia->board.curr+num && cont<varia->board.numentry; cont++)
        {
        printf("%3d)\t%11s\t%5d\t%6s\n",cont+1,varia->board.entry[cont].nome,varia->board.entry[cont].score,varia->board.entry[cont].flags);
        }
}


printNexit

decompiled_code:
void __fastcall __noreturn printNexit(__int64 a1, int a2)
{
int v2; // eax

end_gioco();
endNcurses();
v2 = open_savefile(a1 + 112, "scoreboard.txt");
if ( v2 == -3 )
{
puts("File salvataggi corrotto!");
}
else if ( v2 )
{
just_print(a1, a2);
}
else
{
puts("Errore.");
}
free(*(void **)(a1 + 112));
exit(0);
}

canonical_decompiled_code:
void __fastcall __noreturn func11(__int64 a1, int a2)
{
int v2; // eax

end_gioco();
endNcurses();
v2 = func10(a1 + 112, "scoreboard.txt");
if ( v2 == -3 )
{
puts("File salvataggi corrotto!");
}
else if ( v2 )
{
func9(a1, a2);
}
else
{
puts("Errore.");
}
free(*(void **)(a1 + 112));
exit(0);
}

original_code:
void printNexit(vars *varia, int num)
{
    int ret;
    end_gioco(varia);
    endNcurses();
    ret=open_savefile(&(varia->board),"scoreboard.txt");
    if (ret==-3)
        {
        printf("File salvataggi corrotto!\n");
        }
    else if (ret)
        {
        just_print(varia,num);
        }
    else
        {
        printf("Errore.\n");
        }
    free(varia->board.entry);
    exit(0);
}

canonical_original_code:
void printNexit(struct vars *varia, int num)
{
    int ret;
    end_gioco(varia);
    endNcurses();
    ret=open_savefile(&(varia->board),"scoreboard.txt");
    if (ret==-3)
        {
        printf("File salvataggi corrotto!\n");
        }
    else if (ret)
        {
        just_print(varia,num);
        }
    else
        {
        printf("Errore.\n");
        }
    free(varia->board.entry);
    exit(0);
}

variable_types: ret int


decompiled_code:
__int64 __fastcall snake_direz(__int64 a1, int a2)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 12);
if ( (a2 != 3 || (_DWORD)result != 1)
&& (a2 != 2 || (_DWORD)result)
&& (a2 != 1 || (_DWORD)result != 3)
&& (a2 || (_DWORD)result != 2) )
{
*(_DWORD *)(a1 + 16) = a2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, int a2)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 12);
if ( (a2 != 3 || (_DWORD)result != 1)
&& (a2 != 2 || (_DWORD)result)
&& (a2 != 1 || (_DWORD)result != 3)
&& (a2 || (_DWORD)result != 2) )
{
*(_DWORD *)(a1 + 16) = a2;
}
return result;
}

original_code:
void snake_direz(snake *chi, int facing)
{
    if (chi->direz==1 && facing==3) return;
    if (chi->direz==0 && facing==2) return;
    if (chi->direz==3 && facing==1) return;
    if (chi->direz==2 && facing==0) return;
    chi->scheduledir=facing;
}

canonical_original_code:
void snake_direz(struct snake *chi, int facing)
{
    if (chi->direz==1 && facing==3) return;
    if (chi->direz==0 && facing==2) return;
    if (chi->direz==3 && facing==1) return;
    if (chi->direz==2 && facing==0) return;
    chi->scheduledir=facing;
}

variable_types: struct snake { struct punto { int x; int y; } *sezioni; int numsezioni; int direz; int scheduledir; int ciclo_anim; int ate; int keepexp; int portalcross; int ai; char **cache; } *

variable_types: facing int


comandi

decompiled_code:
wint_t __fastcall comandi(__int64 a1)
{
wint_t result; // eax
wint_t v2[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = wget_wch(stdscr, v2);
if ( result != -1 )
{
result = v2[0];
if ( (int)v2[0] > 119 )
{
if ( v2[0] == 260 )
{
result = snake_direz(a1, 3);
}
else if ( (int)v2[0] <= 260 )
{
if ( v2[0] == 258 )
{
LABEL_14:
result = snake_direz(a1, 2);
}
else if ( v2[0] == 259 )
{
LABEL_11:
result = snake_direz(a1, 0);
}
}
else if ( v2[0] == 261 )
{
LABEL_8:
result = snake_direz(a1, 1);
}
}
else if ( (int)v2[0] > 96 )
{
result = v2[0] - 97;
switch ( v2[0] )
{
case 'a':
result = snake_direz(a1, 3);
break;
case 'd':
goto LABEL_8;
case 'p':
result = *(_DWORD *)(a1 + 140) == 0;
*(_DWORD *)(a1 + 140) = result;
break;
case 'q':
*(_DWORD *)(a1 + 136) = 1;
break;
case 's':
goto LABEL_14;
case 'w':
goto LABEL_11;
default:
return result;
}
}
}
return result;
}

canonical_decompiled_code:
wint_t __fastcall func1(__int64 a1)
{
wint_t result; // eax
wint_t v2[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = wget_wch(stdscr, v2);
if ( result != -1 )
{
result = v2[0];
if ( (int)v2[0] > 119 )
{
if ( v2[0] == 260 )
{
result = func0(a1, 3);
}
else if ( (int)v2[0] <= 260 )
{
if ( v2[0] == 258 )
{
LABEL_14:
result = func0(a1, 2);
}
else if ( v2[0] == 259 )
{
LABEL_11:
result = func0(a1, 0);
}
}
else if ( v2[0] == 261 )
{
LABEL_8:
result = func0(a1, 1);
}
}
else if ( (int)v2[0] > 96 )
{
result = v2[0] - 97;
switch ( v2[0] )
{
case 'a':
result = func0(a1, 3);
break;
case 'd':
goto LABEL_8;
case 'p':
result = *(_DWORD *)(a1 + 140) == 0;
*(_DWORD *)(a1 + 140) = result;
break;
case 'q':
*(_DWORD *)(a1 + 136) = 1;
break;
case 's':
goto LABEL_14;
case 'w':
goto LABEL_11;
default:
return result;
}
}
}
return result;
}

original_code:
void comandi(vars *varia)
{
    wchar_t ch;
    int esit;
    esit=wget_wch(stdscr,((wint_t*)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 0404: snake_direz(&(varia->gioco.serpente),3); break;
            case 0405: snake_direz(&(varia->gioco.serpente),1); break;
            case 0403: snake_direz(&(varia->gioco.serpente),0); break;
            case 0402: snake_direz(&(varia->gioco.serpente),2); break;
            case 'a': snake_direz(&(varia->gioco.serpente),3); break;
            case 'd': snake_direz(&(varia->gioco.serpente),1); break;
            case 'w': snake_direz(&(varia->gioco.serpente),0); break;
            case 's': snake_direz(&(varia->gioco.serpente),2); break;
            case 'q': varia->quit=1; break;
            case 'p': if (varia->paused)varia->paused=0; else varia->paused=1; break;
            default:
            break;
            }
        }
}

canonical_original_code:
void comandi(struct vars *varia)
{
    int ch;
    int esit;
    esit=wget_wch(stdscr,((unsigned int *)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 0404: snake_direz(&(varia->gioco.serpente),3); break;
            case 0405: snake_direz(&(varia->gioco.serpente),1); break;
            case 0403: snake_direz(&(varia->gioco.serpente),0); break;
            case 0402: snake_direz(&(varia->gioco.serpente),2); break;
            case 'a': snake_direz(&(varia->gioco.serpente),3); break;
            case 'd': snake_direz(&(varia->gioco.serpente),1); break;
            case 'w': snake_direz(&(varia->gioco.serpente),0); break;
            case 's': snake_direz(&(varia->gioco.serpente),2); break;
            case 'q': varia->quit=1; break;
            case 'p': if (varia->paused)varia->paused=0; else varia->paused=1; break;
            default:
            break;
            }
        }
}

variable_types: ch int

variable_types: esit int


decompiled_code:
int __fastcall comandi_pausa(_DWORD *a1)
{
int result; // eax
wint_t v2[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = wget_wch(stdscr, v2);
if ( result != -1 )
{
result = v2[0];
if ( v2[0] == 114 )
{
if ( (int)a1[36] < 0 )
result = riprova(a1);
}
else if ( (int)v2[0] <= 114 )
{
if ( v2[0] == 112 )
{
if ( (int)a1[36] >= 0 )
{
result = a1[35] == 0;
a1[35] = result;
}
}
else if ( v2[0] == 113 )
{
a1[34] = 1;
}
}
else if ( v2[0] == 258 )
{
result = a1[31];
if ( result + 8 < a1[30] )
a1[31] = ++result;
}
else if ( v2[0] == 259 )
{
result = a1[31];
if ( result > 0 )
a1[31] = --result;
}
}
return result;
}

original_code:
void comandi_pausa(vars *varia)
{
    wchar_t ch;
    int esit;
    esit=wget_wch(stdscr,((wint_t*)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 0403:
                if (varia->board.curr>0) varia->board.curr--;
            break;
            case 0402:
                if (varia->board.curr+8<(varia->board.numentry)) varia->board.curr++;
            break;
            case 'q': varia->quit=1; break;
            case 'p':
                if (varia->gameover>=0)
                    {
                    if (varia->paused)varia->paused=0;
                    else varia->paused=1;
                    }
            break;
            case 'r':
                if (varia->gameover<0)
                    {
                    riprova(varia);
                    }
            break;
            default:
            break;
            }
        }
}

canonical_original_code:
void comandi_pausa(struct vars *varia)
{
    int ch;
    int esit;
    esit=wget_wch(stdscr,((unsigned int *)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 0403:
                if (varia->board.curr>0) varia->board.curr--;
            break;
            case 0402:
                if (varia->board.curr+8<(varia->board.numentry)) varia->board.curr++;
            break;
            case 'q': varia->quit=1; break;
            case 'p':
                if (varia->gameover>=0)
                    {
                    if (varia->paused)varia->paused=0;
                    else varia->paused=1;
                    }
            break;
            case 'r':
                if (varia->gameover<0)
                    {
                    riprova(varia);
                    }
            break;
            default:
            break;
            }
        }
}


decompiled_code:
int __fastcall comandi_titolo(_DWORD *a1)
{
int result; // eax
int v2; // edx
wint_t v3[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = wget_wch(stdscr, v3);
if ( result != -1 )
{
result = v3[0] - 99;
switch ( v3[0] )
{
case 'c':
result = a1[33] + 1;
if ( result > 4 )
result = 0;
a1[33] = result;
break;
case 'd':
a1[37] += 2;
a1[35] = 0;
break;
case 'e':
a1[37] += 4;
a1[35] = 0;
break;
case 'l':
result = a1[9];
if ( result )
{
if ( result == 1 )
a1[9] = 0;
}
else
{
a1[9] = 1;
}
break;
case 'p':
v2 = a1[37];
result = v2 - 16;
if ( (v2 & 0x10) == 0 )
result = v2 + 16;
a1[37] = result;
break;
case 'q':
a1[34] = 1;
break;
case 'r':
a1[37] += 8;
a1[35] = 0;
break;
case 's':
++a1[37];
a1[35] = 0;
break;
default:
return result;
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(_DWORD *a1)
{
int result; // eax
int v2; // edx
wint_t v3[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = wget_wch(stdscr, v3);
if ( result != -1 )
{
result = v3[0] - 99;
switch ( v3[0] )
{
case 'c':
result = a1[33] + 1;
if ( result > 4 )
result = 0;
a1[33] = result;
break;
case 'd':
a1[37] += 2;
a1[35] = 0;
break;
case 'e':
a1[37] += 4;
a1[35] = 0;
break;
case 'l':
result = a1[9];
if ( result )
{
if ( result == 1 )
a1[9] = 0;
}
else
{
a1[9] = 1;
}
break;
case 'p':
v2 = a1[37];
result = v2 - 16;
if ( (v2 & 0x10) == 0 )
result = v2 + 16;
a1[37] = result;
break;
case 'q':
a1[34] = 1;
break;
case 'r':
a1[37] += 8;
a1[35] = 0;
break;
case 's':
++a1[37];
a1[35] = 0;
break;
default:
return result;
}
}
return result;
}

original_code:
void comandi_titolo(vars *varia)
{
    wchar_t ch;
    int esit;
    esit=wget_wch(stdscr,((wint_t*)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 'q': varia->quit=1; break;
            case 's':
                varia->gamemode+=0b01;
                varia->paused=0;
            break;
            case 'd':
                varia->gamemode+=0b10;
                varia->paused=0;
            break;
            case 'e':
                varia->gamemode+=0b100;
                varia->paused=0;
            break;
            case 'r':
                varia->gamemode+=0b1000;
                varia->paused=0;
            break;
            case 'p':
                if ((varia->gamemode&0b10000)!=0)varia->gamemode-=0b10000;
                else varia->gamemode+=0b10000;
            break;
            case 'l':
                if ((varia->gioco.serpente.ai==0b0))varia->gioco.serpente.ai=0b1;
                else if ((varia->gioco.serpente.ai==0b1))varia->gioco.serpente.ai=0b0;
            break;
            case 'c':
                varia->speed++;
                if (varia->speed>=5)varia->speed=0;
            break;
            default:
            break;
            }
        }
}

canonical_original_code:
void comandi_titolo(struct vars *varia)
{
    int ch;
    int esit;
    esit=wget_wch(stdscr,((unsigned int *)&ch));
    if (esit==(-1))
        {
        }
    else
        {
        switch (ch)
            {
            case 'q': varia->quit=1; break;
            case 's':
                varia->gamemode+=0b01;
                varia->paused=0;
            break;
            case 'd':
                varia->gamemode+=0b10;
                varia->paused=0;
            break;
            case 'e':
                varia->gamemode+=0b100;
                varia->paused=0;
            break;
            case 'r':
                varia->gamemode+=0b1000;
                varia->paused=0;
            break;
            case 'p':
                if ((varia->gamemode&0b10000)!=0)varia->gamemode-=0b10000;
                else varia->gamemode+=0b10000;
            break;
            case 'l':
                if ((varia->gioco.serpente.ai==0b0))varia->gioco.serpente.ai=0b1;
                else if ((varia->gioco.serpente.ai==0b1))varia->gioco.serpente.ai=0b0;
            break;
            case 'c':
                varia->speed++;
                if (varia->speed>=5)varia->speed=0;
            break;
            default:
            break;
            }
        }
}


timerPortal

decompiled_code:
__int64 __fastcall timerPortal(__int64 a1)
{
int v1; // edx
__int64 result; // rax

v1 = rand();
result = (unsigned int)(35 * (v1 / 35));
*(_DWORD *)(a1 + 68) = v1 % 35 + 10;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
int v1; // edx
__int64 result; // rax

v1 = rand();
result = (unsigned int)(35 * (v1 / 35));
*(_DWORD *)(a1 + 68) = v1 % 35 + 10;
return result;
}

original_code:
void timerPortal(vars *varia)
{
    varia->gioco.nextportime=10 +(rand()%(45 -10));
}

canonical_original_code:
void timerPortal(struct vars *varia)
{
    varia->gioco.nextportime=10 +(rand()%(45 -10));
}


removepup

decompiled_code:
__int64 __fastcall removepup(__int64 a1, int a2)
{
int v2; // ebp
_DWORD *v3; // rax
__int64 result; // rax
__int64 v5; // rdx

v2 = a2;
v3 = (_DWORD *)(*(_QWORD *)(a1 + 72) + 8LL * a2);
wmove(stdscr, v3[1] + 1, 2 * *v3 + 1);
wprintw(stdscr, " ");
result = (unsigned int)(*(_DWORD *)(a1 + 80) - 1);
if ( a2 < (int)result )
{
v5 = 8LL * a2 + 8;
do
{
*(_QWORD *)(*(_QWORD *)(a1 + 72) + v5 - 8) = *(_QWORD *)(*(_QWORD *)(a1 + 72) + v5);
++v2;
result = (unsigned int)(*(_DWORD *)(a1 + 80) - 1);
v5 += 8LL;
}
while ( (int)result > v2 );
}
*(_DWORD *)(a1 + 80) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2)
{
int v2; // ebp
_DWORD *v3; // rax
__int64 result; // rax
__int64 v5; // rdx

v2 = a2;
v3 = (_DWORD *)(*(_QWORD *)(a1 + 72) + 8LL * a2);
wmove(stdscr, v3[1] + 1, 2 * *v3 + 1);
wprintw(stdscr, " ");
result = (unsigned int)(*(_DWORD *)(a1 + 80) - 1);
if ( a2 < (int)result )
{
v5 = 8LL * a2 + 8;
do
{
*(_QWORD *)(*(_QWORD *)(a1 + 72) + v5 - 8) = *(_QWORD *)(*(_QWORD *)(a1 + 72) + v5);
++v2;
result = (unsigned int)(*(_DWORD *)(a1 + 80) - 1);
v5 += 8LL;
}
while ( (int)result > v2 );
}
*(_DWORD *)(a1 + 80) = result;
return result;
}

original_code:
void removepup(campo *dove, int indice)
{
    int cont;
    wmove(stdscr,(dove->powerup[indice].y+1),((dove->powerup[indice].x*2)+1));
    wprintw(stdscr,"  ");
    for (cont=indice; cont<dove->numpowerups-1; cont++)
        {
        dove->powerup[cont]=dove->powerup[cont+1];
        }
    dove->numpowerups--;
}

canonical_original_code:
void removepup(struct campo *dove, int indice)
{
    int cont;
    wmove(stdscr,(dove->powerup[indice].y+1),((dove->powerup[indice].x*2)+1));
    wprintw(stdscr,"  ");
    for (cont=indice; cont<dove->numpowerups-1; cont++)
        {
        dove->powerup[cont]=dove->powerup[cont+1];
        }
    dove->numpowerups--;
}

variable_types: struct campo { struct snake { struct punto { int x; int y; } *sezioni; int numsezioni; int direz; int scheduledir; int ciclo_anim; int ate; int keepexp; int portalcross; int ai; char **cache; } serpente; struct punto portale[2]; int numportals; int nextportime; struct punto *powerup; int numpowerups; int larg; int alt; struct punto *toblast; int blastlung; } *

variable_types: indice int


droppup

original_code:
void droppup(vars *varia)
{
    int x,y,safe=0;
    if (varia->gioco.numpowerups<2)
        {
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && safe<2500);
        varia->gioco.powerup[varia->gioco.numpowerups].x=x;
        varia->gioco.powerup[varia->gioco.numpowerups].y=y;
        varia->gioco.numpowerups++;
        }
}

canonical_original_code:
void droppup(struct vars *varia)
{
    int x; int y; int safe = 0;
    if (varia->gioco.numpowerups<2)
        {
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && safe<2500);
        varia->gioco.powerup[varia->gioco.numpowerups].x=x;
        varia->gioco.powerup[varia->gioco.numpowerups].y=y;
        varia->gioco.numpowerups++;
        }
}

variable_types: x int

variable_types: y int

variable_types: safe int


mangiacibo

decompiled_code:
__int64 __fastcall mangiacibo(__int64 a1)
{
__int64 result; // rax
int v2; // edx

result = *(_DWORD *)(a1 + 148) & 0xF;
if ( (_DWORD)result == 4 )
{
result = (unsigned int)(int)pow(2.0, (double)*(int *)(a1 + 28));
*(_DWORD *)(a1 + 24) += result;
++*(_DWORD *)(a1 + 28);
}
else if ( (*(_DWORD *)(a1 + 148) & 0xFu) > 4 )
{
if ( (_DWORD)result == 8 )
{
v2 = rand();
result = (unsigned int)(6 * (v2 / 6));
if ( v2 == (_DWORD)result )
{
nuovoblast(a1, *(_QWORD *)a1 + 8LL, (unsigned int)(*(_DWORD *)(a1 + 8) - 1));
*(_DWORD *)(a1 + 8) = 1;
result = regen_snacache(a1, *(unsigned int *)(a1 + 84), *(unsigned int *)(a1 + 88));
}
else
{
++*(_DWORD *)(a1 + 24);
}
}
}
else if ( (_DWORD)result == 1 )
{
++*(_DWORD *)(a1 + 24);
}
else if ( (_DWORD)result == 2 )
{
*(_DWORD *)(a1 + 24) += 2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
__int64 result; // rax
int v2; // edx

result = *(_DWORD *)(a1 + 148) & 0xF;
if ( (_DWORD)result == 4 )
{
result = (unsigned int)(int)pow(2.0, (double)*(int *)(a1 + 28));
*(_DWORD *)(a1 + 24) += result;
++*(_DWORD *)(a1 + 28);
}
else if ( (*(_DWORD *)(a1 + 148) & 0xFu) > 4 )
{
if ( (_DWORD)result == 8 )
{
v2 = rand();
result = (unsigned int)(6 * (v2 / 6));
if ( v2 == (_DWORD)result )
{
nuovoblast(a1, *(_QWORD *)a1 + 8LL, (unsigned int)(*(_DWORD *)(a1 + 8) - 1));
*(_DWORD *)(a1 + 8) = 1;
result = regen_snacache(a1, *(unsigned int *)(a1 + 84), *(unsigned int *)(a1 + 88));
}
else
{
++*(_DWORD *)(a1 + 24);
}
}
}
else if ( (_DWORD)result == 1 )
{
++*(_DWORD *)(a1 + 24);
}
else if ( (_DWORD)result == 2 )
{
*(_DWORD *)(a1 + 24) += 2;
}
return result;
}

original_code:
void mangiacibo(vars *varia)
{
    switch (varia->gamemode&0b1111)
        {
        case 0b01:
            varia->gioco.serpente.ate+=1;
        break;
        case 0b10:
            varia->gioco.serpente.ate+=2;
        break;
        case 0b100:
            varia->gioco.serpente.ate+=abs(pow(2,varia->gioco.serpente.keepexp));
            varia->gioco.serpente.keepexp++;
        break;
        case 0b1000:
            if (rand()%6 == 0)
                {
                nuovoblast(varia,&(varia->gioco.serpente.sezioni[1]),varia->gioco.serpente.numsezioni-1);
                varia->gioco.serpente.numsezioni=1;
                regen_snacache(&(varia->gioco.serpente),varia->gioco.larg,varia->gioco.alt);
                }
            else varia->gioco.serpente.ate+=1;
        break;
        }
}

canonical_original_code:
void mangiacibo(struct vars *varia)
{
    switch (varia->gamemode&0b1111)
        {
        case 0b01:
            varia->gioco.serpente.ate+=1;
        break;
        case 0b10:
            varia->gioco.serpente.ate+=2;
        break;
        case 0b100:
            varia->gioco.serpente.ate+=abs(pow(2,varia->gioco.serpente.keepexp));
            varia->gioco.serpente.keepexp++;
        break;
        case 0b1000:
            if (rand()%6 == 0)
                {
                nuovoblast(varia,&(varia->gioco.serpente.sezioni[1]),varia->gioco.serpente.numsezioni-1);
                varia->gioco.serpente.numsezioni=1;
                regen_snacache(&(varia->gioco.serpente),varia->gioco.larg,varia->gioco.alt);
                }
            else varia->gioco.serpente.ate+=1;
        break;
        }
}

variable_types: struct vars { struct campo { struct snake { struct punto { int x; int y; } *sezioni; int numsezioni; int direz; int scheduledir; int ciclo_anim; int ate; int keepexp; int portalcross; int ai; char **cache; } serpente; struct punto portale[2]; int numportals; int nextportime; struct punto *powerup; int numpowerups; int larg; int alt; struct punto *toblast; int blastlung; } gioco; struct leaderboard { struct punteggio { int score; char nome[10]; char flags[6]; } *entry; int numentry; int curr; } board; int score; int speed; int quit; int paused; int gameover; int gamemode; int colori; int safe_graph; int game_insane; char playername[10]; } *


decompiled_code:
__int64 __fastcall drop_portal(__int64 a1)
{
int v1; // er12
int v2; // ebp
unsigned int v3; // er13
unsigned int v4; // er14
int v5; // eax
unsigned int v6; // er13
unsigned int v7; // ebp
int v8; // eax
__int64 result; // rax
int v10; // eax
int v11; // er14
__int64 v12; // r15
int v13; // er13
unsigned int v14; // er12
unsigned int v15; // ebp
int v16; // eax

v1 = *(_DWORD *)(a1 + 64);
if ( v1 )
{
v10 = rand();
v11 = 2 - (v10 & 1);
v12 = a1 + 8LL * (v10 % 2);
wmove(stdscr, *(_DWORD *)(v12 + 52) + 1, 2 * *(_DWORD *)(v12 + 48) + 1);
printw(" ");
v13 = 0;
do
{
v14 = rand() % *(_DWORD *)(a1 + 84);
v15 = rand() % *(_DWORD *)(a1 + 88);
++v13;
if ( !(unsigned int)morsocoda(a1, v14) )
break;
if ( !(unsigned int)presopup(a1, v14, v15) )
break;
v16 = presoportal(a1, v14, v15);
if ( v13 > 2499 )
break;
}
while ( v16 == v11 );
*(_DWORD *)(v12 + 48) = v14;
*(_DWORD *)(v12 + 52) = v15;
}
else
{
v2 = 0;
do
{
v3 = rand() % *(_DWORD *)(a1 + 84);
v4 = rand() % *(_DWORD *)(a1 + 88);
++v2;
if ( !(unsigned int)morsocoda(a1, v3) )
break;
v5 = presopup(a1, v3, v4);
if ( v2 > 2499 )
break;
}
while ( v5 );
*(_DWORD *)(a1 + 48) = v3;
*(_DWORD *)(a1 + 52) = v4;
do
{
v6 = rand() % *(_DWORD *)(a1 + 84);
v7 = rand() % *(_DWORD *)(a1 + 88);
++v1;
if ( !(unsigned int)morsocoda(a1, v6) )
break;
if ( !(unsigned int)presopup(a1, v6, v7) )
break;
v8 = presoportal(a1, v6, v7);
if ( v1 > 2499 )
break;
}
while ( v8 == 1 );
*(_DWORD *)(a1 + 56) = v6;
*(_DWORD *)(a1 + 60) = v7;
*(_DWORD *)(a1 + 64) = 2;
}
result = *(unsigned int *)(a1 + 32);
if ( (_DWORD)result )
{
nuovoblast(a1, *(_QWORD *)a1 + 8LL * (int)result, (unsigned int)(*(_DWORD *)(a1 + 8) - result));
*(_DWORD *)(a1 + 8) = *(_DWORD *)(a1 + 32);
*(_DWORD *)(a1 + 32) = 0;
*(_DWORD *)(a1 + 24) = 0;
result = regen_snacache(a1, *(unsigned int *)(a1 + 84), *(unsigned int *)(a1 + 88));
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
int v1; // er12
int v2; // ebp
unsigned int v3; // er13
unsigned int v4; // er14
int v5; // eax
unsigned int v6; // er13
unsigned int v7; // ebp
int v8; // eax
__int64 result; // rax
int v10; // eax
int v11; // er14
__int64 v12; // r15
int v13; // er13
unsigned int v14; // er12
unsigned int v15; // ebp
int v16; // eax

v1 = *(_DWORD *)(a1 + 64);
if ( v1 )
{
v10 = rand();
v11 = 2 - (v10 & 1);
v12 = a1 + 8LL * (v10 % 2);
wmove(stdscr, *(_DWORD *)(v12 + 52) + 1, 2 * *(_DWORD *)(v12 + 48) + 1);
printw(" ");
v13 = 0;
do
{
v14 = rand() % *(_DWORD *)(a1 + 84);
v15 = rand() % *(_DWORD *)(a1 + 88);
++v13;
if ( !(unsigned int)morsocoda(a1, v14) )
break;
if ( !(unsigned int)presopup(a1, v14, v15) )
break;
v16 = presoportal(a1, v14, v15);
if ( v13 > 2499 )
break;
}
while ( v16 == v11 );
*(_DWORD *)(v12 + 48) = v14;
*(_DWORD *)(v12 + 52) = v15;
}
else
{
v2 = 0;
do
{
v3 = rand() % *(_DWORD *)(a1 + 84);
v4 = rand() % *(_DWORD *)(a1 + 88);
++v2;
if ( !(unsigned int)morsocoda(a1, v3) )
break;
v5 = presopup(a1, v3, v4);
if ( v2 > 2499 )
break;
}
while ( v5 );
*(_DWORD *)(a1 + 48) = v3;
*(_DWORD *)(a1 + 52) = v4;
do
{
v6 = rand() % *(_DWORD *)(a1 + 84);
v7 = rand() % *(_DWORD *)(a1 + 88);
++v1;
if ( !(unsigned int)morsocoda(a1, v6) )
break;
if ( !(unsigned int)presopup(a1, v6, v7) )
break;
v8 = presoportal(a1, v6, v7);
if ( v1 > 2499 )
break;
}
while ( v8 == 1 );
*(_DWORD *)(a1 + 56) = v6;
*(_DWORD *)(a1 + 60) = v7;
*(_DWORD *)(a1 + 64) = 2;
}
result = *(unsigned int *)(a1 + 32);
if ( (_DWORD)result )
{
nuovoblast(a1, *(_QWORD *)a1 + 8LL * (int)result, (unsigned int)(*(_DWORD *)(a1 + 8) - result));
*(_DWORD *)(a1 + 8) = *(_DWORD *)(a1 + 32);
*(_DWORD *)(a1 + 32) = 0;
*(_DWORD *)(a1 + 24) = 0;
result = regen_snacache(a1, *(unsigned int *)(a1 + 84), *(unsigned int *)(a1 + 88));
}
return result;
}

original_code:
void drop_portal(vars *varia)
{
    int x,y,safe=0,nuovo,altro;
    if (varia->gioco.numportals==0)
        {
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && safe<2500);
        varia->gioco.portale[0].x=x;
        varia->gioco.portale[0].y=y;
        safe=0;
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && (presoportal(varia,x,y)==1) && safe<2500);
        varia->gioco.portale[1].x=x;
        varia->gioco.portale[1].y=y;
        varia->gioco.numportals=2;
        }
    else
        {
        nuovo=rand()%2;
        if (nuovo==0)altro=2;
        else altro=1;
        wmove(stdscr,(varia->gioco.portale[nuovo].y+1),((varia->gioco.portale[nuovo].x*2)+1));
        printw("  ");
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && (presoportal(varia,x,y)==altro) && safe<2500);
        varia->gioco.portale[nuovo].x=x;
        varia->gioco.portale[nuovo].y=y;
        }
    if (varia->gioco.serpente.portalcross!=0)
        {
        nuovoblast(varia,&(varia->gioco.serpente.sezioni[varia->gioco.serpente.portalcross]),varia->gioco.serpente.numsezioni-varia->gioco.serpente.portalcross);
        varia->gioco.serpente.numsezioni=varia->gioco.serpente.portalcross;
        varia->gioco.serpente.portalcross=0;
        varia->gioco.serpente.ate=0;
        regen_snacache(&(varia->gioco.serpente),varia->gioco.larg,varia->gioco.alt);
        }
}

canonical_original_code:
void drop_portal(struct vars *varia)
{
    int x; int y; int safe = 0; int nuovo; int altro;
    if (varia->gioco.numportals==0)
        {
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && safe<2500);
        varia->gioco.portale[0].x=x;
        varia->gioco.portale[0].y=y;
        safe=0;
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && (presoportal(varia,x,y)==1) && safe<2500);
        varia->gioco.portale[1].x=x;
        varia->gioco.portale[1].y=y;
        varia->gioco.numportals=2;
        }
    else
        {
        nuovo=rand()%2;
        if (nuovo==0)altro=2;
        else altro=1;
        wmove(stdscr,(varia->gioco.portale[nuovo].y+1),((varia->gioco.portale[nuovo].x*2)+1));
        printw("  ");
        do {
            x=rand()%varia->gioco.larg;
            y=rand()%varia->gioco.alt;
            safe++;
            } while (morsocoda(varia,x,y) && presopup(varia,x,y) && (presoportal(varia,x,y)==altro) && safe<2500);
        varia->gioco.portale[nuovo].x=x;
        varia->gioco.portale[nuovo].y=y;
        }
    if (varia->gioco.serpente.portalcross!=0)
        {
        nuovoblast(varia,&(varia->gioco.serpente.sezioni[varia->gioco.serpente.portalcross]),varia->gioco.serpente.numsezioni-varia->gioco.serpente.portalcross);
        varia->gioco.serpente.numsezioni=varia->gioco.serpente.portalcross;
        varia->gioco.serpente.portalcross=0;
        varia->gioco.serpente.ate=0;
        regen_snacache(&(varia->gioco.serpente),varia->gioco.larg,varia->gioco.alt);
        }
}

variable_types: nuovo int

variable_types: altro int


nuovoblast

decompiled_code:
int __fastcall nuovoblast(__int64 a1, __int64 a2, int a3)
{
int result; // eax

if ( *(_QWORD *)(a1 + 96) )
{
result = wclear(stdscr);
*(_QWORD *)(a1 + 96) = a2;
*(_DWORD *)(a1 + 104) = a3;
}
else
{
*(_QWORD *)(a1 + 96) = a2;
*(_DWORD *)(a1 + 104) = a3;
}
return result;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1, __int64 a2, int a3)
{
int result; // eax

if ( *(_QWORD *)(a1 + 96) )
{
result = wclear(stdscr);
*(_QWORD *)(a1 + 96) = a2;
*(_DWORD *)(a1 + 104) = a3;
}
else
{
*(_QWORD *)(a1 + 96) = a2;
*(_DWORD *)(a1 + 104) = a3;
}
return result;
}

original_code:
void nuovoblast(vars *varia,punto *dove, int lung)
{
    if (varia->gioco.toblast!=((void *)0))
        {
        wclear(stdscr);
        varia->gioco.toblast=dove;
        varia->gioco.blastlung=lung;
        }
    else
        {
        varia->gioco.toblast=dove;
        varia->gioco.blastlung=lung;
        }
}

canonical_original_code:
void nuovoblast(struct vars *varia, struct punto *dove, int lung)
{
    if (varia->gioco.toblast!=((void *)0))
        {
        wclear(stdscr);
        varia->gioco.toblast=dove;
        varia->gioco.blastlung=lung;
        }
    else
        {
        varia->gioco.toblast=dove;
        varia->gioco.blastlung=lung;
        }
}

variable_types:
dove
struct punto *

variable_types: lung int


usage

decompiled_code:
void __noreturn usage()
{
fwrite("usage: re regexp string...\n", 1uLL, 0x1BuLL, stderr);
exit(2);
}

canonical_decompiled_code:
void __noreturn func0()
{
fwrite("usage: re regexp string...\n", 1uLL, 0x1BuLL, stderr);
exit(2);
}

original_code:
void
usage(void)
{
 fprintf(stderr, "usage: re regexp string...\n");
 exit(2);
}

canonical_original_code:
void usage()
{
 fprintf(stderr, "usage: re regexp string...\n");
 exit(2);
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbx
const char *v4; // rdx
int v5; // ecx
const char **v6; // r15
__int64 v7; // rax
int v8; // er12
__int64 i; // r14
__int64 v10; // rbx
__int64 v11; // rsi
__int64 v12; // rsi
char *v14; // [rsp+0h] [rbp-E8h]
unsigned int v15; // [rsp+8h] [rbp-E0h]
int v16; // [rsp+Ch] [rbp-DCh]
_QWORD v17[27]; // [rsp+10h] [rbp-D8h] BYREF

v16 = argc;
if ( argc <= 1 )
usage(argc, argv, envp);
v3 = (char *)parse(argv[1]);
printre(v3);
putchar(10);
v14 = compile(v3, (char *)argv, v4, v5);
printprog(v14);
if ( v16 > 2 )
{
v6 = argv + 2;
v15 = 2;
do
{
printf("#%d %s\n", v15, *v6);
for ( i = 0LL; i != 10; i += 2LL )
{
printf("%s ", (&tab)[i]);
memset(v17, 0, 0xA0uLL);
if ( ((unsigned int (__fastcall *)(char *, const char *, _QWORD *, __int64))(&tab)[i + 1])(v14, *v6, v17, 20LL) )
{
printf("match");
v7 = 20LL;
while ( 1 )
{
v8 = v7;
if ( *((_QWORD *)&v15 + v7) )
break;
if ( !--v7 )
goto LABEL_8;
}
v10 = 0LL;
do
{
printf(" (");
v11 = v17[v10];
if ( v11 )
printf("%d", v11 - (_QWORD)*v6);
else
putchar(63);
putchar(44);
v12 = v17[v10 + 1];
if ( v12 )
printf("%d", v12 - (_QWORD)*v6);
else
putchar(63);
putchar(41);
v10 += 2LL;
}
while ( v8 > (int)v10 );
LABEL_8:
putchar(10);
}
else
{
puts("-no match-");
}
}
++v15;
++v6;
}
while ( v16 != v15 );
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbx
const char *v4; // rdx
int v5; // ecx
const char **v6; // r15
__int64 v7; // rax
int v8; // er12
__int64 i; // r14
__int64 v10; // rbx
__int64 v11; // rsi
__int64 v12; // rsi
char *v14; // [rsp+0h] [rbp-E8h]
unsigned int v15; // [rsp+8h] [rbp-E0h]
int v16; // [rsp+Ch] [rbp-DCh]
_QWORD v17[27]; // [rsp+10h] [rbp-D8h] BYREF

v16 = argc;
if ( argc <= 1 )
func0(argc, argv, envp);
v3 = (char *)parse(argv[1]);
printre(v3);
putchar(10);
v14 = compile(v3, (char *)argv, v4, v5);
printprog(v14);
if ( v16 > 2 )
{
v6 = argv + 2;
v15 = 2;
do
{
printf("#%d %s\n", v15, *v6);
for ( i = 0LL; i != 10; i += 2LL )
{
printf("%s ", (&tab)[i]);
memset(v17, 0, 0xA0uLL);
if ( ((unsigned int (__fastcall *)(char *, const char *, _QWORD *, __int64))(&tab)[i + 1])(v14, *v6, v17, 20LL) )
{
printf("match");
v7 = 20LL;
while ( 1 )
{
v8 = v7;
if ( *((_QWORD *)&v15 + v7) )
break;
if ( !--v7 )
goto LABEL_8;
}
v10 = 0LL;
do
{
printf(" (");
v11 = v17[v10];
if ( v11 )
printf("%d", v11 - (_QWORD)*v6);
else
putchar(63);
putchar(44);
v12 = v17[v10 + 1];
if ( v12 )
printf("%d", v12 - (_QWORD)*v6);
else
putchar(63);
putchar(41);
v10 += 2LL;
}
while ( v8 > (int)v10 );
LABEL_8:
putchar(10);
}
else
{
puts("-no match-");
}
}
++v15;
++v6;
}
while ( v16 != v15 );
}
return 0;
}

original_code:
int
main(int argc, char **argv)
{
 int i, j, k, l;
 Regexp *re;
 Prog *prog;
 char *sub[MAXSUB];
 if(argc < 2)
  usage();
 re = parse(argv[1]);
 printre(re);
 printf("\n");
 prog = compile(re);
 printprog(prog);
 for(i=2; i<argc; i++) {
  printf("#%d %s\n", i, argv[i]);
  for(j=0; j<(sizeof(tab)/sizeof((tab)[0])); j++) {
   printf("%s ", tab[j].name);
   memset(sub, 0, sizeof sub);
   if(!tab[j].fn(prog, argv[i], sub, (sizeof(sub)/sizeof((sub)[0])))) {
    printf("-no match-\n");
    continue;
   }
   printf("match");
   for(k=MAXSUB; k>0; k--)
    if(sub[k-1])
     break;
   for(l=0; l<k; l+=2) {
    printf(" (");
    if(sub[l] == ((void*)0))
     printf("?");
    else
     printf("%d", (int)(sub[l] - argv[i]));
    printf(",");
    if(sub[l+1] == ((void*)0))
     printf("?");
    else
     printf("%d", (int)(sub[l+1] - argv[i]));
    printf(")");
   }
   printf("\n");
  }
 }
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 int i; int j; int k; int l;
 struct Regexp *re;
 struct Prog *prog;
 char *sub[-1];
 if(argc < 2)
  usage();
 re = parse(argv[1]);
 printre(re);
 printf("\n");
 prog = compile(re);
 printprog(prog);
 for(i=2; i<argc; i++) {
  printf("#%d %s\n", i, argv[i]);
  for(j=0; j<(sizeof(tab)/sizeof((tab)[0])); j++) {
   printf("%s ", tab[j].name);
   memset(sub, 0, sizeof sub);
   if(!tab[j].fn(prog, argv[i], sub, (sizeof(sub)/sizeof((sub)[0])))) {
    printf("-no match-\n");
    continue;
   }
   printf("match");
   for(k=MAXSUB; k>0; k--)
    if(sub[k-1])
     break;
   for(l=0; l<k; l+=2) {
    printf(" (");
    if(sub[l] == ((void *)0))
     printf("?");
    else
     printf("%d", (int)(sub[l] - argv[i]));
    printf(",");
    if(sub[l+1] == ((void *)0))
     printf("?");
    else
     printf("%d", (int)(sub[l+1] - argv[i]));
    printf(")");
   }
   printf("\n");
  }
 }
 return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int

variable_types: j int

variable_types: k int

variable_types: l int

variable_types: struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; } *

variable_types: struct Prog { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *start; int len; } *

variable_types:
sub
char *[-1]

return_type: int

user_defined_types: struct Prog { struct Inst *start; int len; }


fatal

decompiled_code:
void __noreturn fatal(const char *a1, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, a1);
fwrite("fatal error: ", 1uLL, 0xDuLL, stderr);
vfprintf(stderr, a1, arg);
fputc(10, stderr);
exit(2);
}

canonical_decompiled_code:
void __noreturn func1(const char *a1, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, a1);
fwrite("fatal error: ", 1uLL, 0xDuLL, stderr);
vfprintf(stderr, a1, arg);
fputc(10, stderr);
exit(2);
}

original_code:
void
fatal(char *fmt, ...)
{
 va_list arg;
 __builtin_va_start(arg,fmt);
 fprintf(stderr, "fatal error: ");
 vfprintf(stderr, fmt, arg);
 fprintf(stderr, "\n");
 __builtin_va_end(arg);
 exit(2);
}

canonical_original_code:
void fatal(char *fmt, ...)
{
 __builtin_va_list arg;
 __builtin_va_start(arg,fmt);
 fprintf(stderr, "fatal error: ");
 vfprintf(stderr, fmt, arg);
 fprintf(stderr, "\n");
 __builtin_va_end(arg);
 exit(2);
}

variable_types:
fmt
char *


yyparse

decompiled_code:
__int64 yyparse()
{
int v0; // ebp
unsigned __int64 v1; // r12
__int64 *v2; // r14
__int16 *v3; // rbx
__int16 *v4; // r15
int v5; // edx
unsigned int v6; // er13
__int16 *v7; // rcx
unsigned __int64 v8; // rdx
int v9; // eax
unsigned __int8 v10; // bp
int v11; // eax
int v12; // esi
unsigned int v13; // edx
unsigned __int64 v14; // rax
__int64 v15; // rbx
__int16 *v16; // rax
__int16 *v17; // r13
size_t v18; // r14
int v19; // er13
unsigned __int8 v20; // cl
unsigned int v21; // ebp
char *v23; // [rsp+8h] [rbp-820h]
unsigned __int64 v24; // [rsp+10h] [rbp-818h]
char *v25; // [rsp+18h] [rbp-810h]
char v26[1600]; // [rsp+20h] [rbp-808h] BYREF
__int16 src[228]; // [rsp+660h] [rbp-1C8h] BYREF

yynerrs = 0;
yychar = -2;
src[0] = 0;
v0 = 0;
v1 = 200LL;
v2 = (__int64 *)v26;
v23 = v26;
v3 = src;
v4 = src;
do
{
v19 = yypact[v0];
if ( v19 == -8 )
goto LABEL_27;
if ( yychar == -2 )
yychar = yylex();
if ( yychar <= 0 )
{
yychar = 0;
v5 = 0;
}
else
{
v5 = 2;
if ( (unsigned int)yychar <= 0x103 )
v5 = (unsigned __int8)yytranslate[yychar];
}
v6 = v5 + v19;
if ( v6 > 0x16 || (unsigned __int8)yycheck[v6] != v5 )
{
LABEL_27:
v20 = yydefact[v0];
v9 = v20;
if ( v20 )
{
v10 = yyr2[v20];
v8 = v2[1 - v10];
switch ( v20 )
{
case 2u:
parsed_regexp = *(v2 - 1);
return 1;
case 4u:
v8 = (unsigned __int64)reg(1, *(v2 - 2), *v2);
v9 = 4;
goto LABEL_8;
case 6u:
v8 = (unsigned __int64)reg(2, *(v2 - 1), *v2);
v9 = 6;
goto LABEL_8;
case 8u:
v8 = (unsigned __int64)reg(7, *(v2 - 1), 0LL);
v9 = 8;
goto LABEL_8;
case 9u:
v8 = (unsigned __int64)reg(7, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 9;
goto LABEL_8;
case 0xAu:
v8 = (unsigned __int64)reg(8, *(v2 - 1), 0LL);
v9 = 10;
goto LABEL_8;
case 0xBu:
v8 = (unsigned __int64)reg(8, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 11;
goto LABEL_8;
case 0xCu:
v8 = (unsigned __int64)reg(6, *(v2 - 1), 0LL);
v9 = 12;
goto LABEL_8;
case 0xDu:
v8 = (unsigned __int64)reg(6, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 13;
goto LABEL_8;
case 0xEu:
v8 = (unsigned int)++nparen | v8 & 0xFFFFFFFF00000000LL;
v9 = 14;
goto LABEL_8;
case 0xFu:
v8 = (unsigned __int64)reg(5, *(v2 - 1), 0LL);
*(_DWORD *)(v8 + 4) = *((_DWORD *)v2 - 4);
v9 = 15;
goto LABEL_8;
case 0x10u:
v8 = *(v2 - 1);
v9 = 16;
goto LABEL_8;
case 0x11u:
v8 = (unsigned __int64)reg(3, 0LL, 0LL);
*(_DWORD *)(v8 + 8) = *(_DWORD *)v2;
v9 = 17;
goto LABEL_8;
case 0x12u:
v8 = (unsigned __int64)reg(4, 0LL, 0LL);
v9 = 18;
goto LABEL_8;
default:
goto LABEL_8;
}
}
++yynerrs;
yyerror("syntax error");
}
v0 = (unsigned __int8)yytable[v6];
if ( yytable[v6] )
{
yychar = -2;
v2[1] = yylval;
++v2;
v7 = v3;
}
else
{
v8 = v2[1];
v9 = 0;
v10 = 0;
LABEL_8:
v7 = &v3[-v10];
v2 = &v2[-v10 + 1];
*v2 = v8;
v11 = (unsigned __int8)yyr1[v9] - 13;
v12 = *v7;
v13 = v12 + yypgoto[v11];
if ( v13 <= 0x16 && v12 == (unsigned __int8)yycheck[v13] )
v0 = (unsigned __int8)yytable[v13];
else
v0 = yydefgoto[v11];
}
v3 = v7 + 1;
v7[1] = v0;
v14 = 2 * v1;
if ( v7 + 1 >= &v4[v1 - 1] )
{
v15 = (char *)v3 - (char *)v4;
if ( v1 > 0x270F )
goto LABEL_46;
v1 = 10000LL;
if ( v14 <= 0x2710 )
v1 = v14;
v16 = (__int16 *)malloc(10 * v1 + 7);
v17 = v16;
if ( !v16 )
LABEL_46:
yyerror("memory exhausted");
memcpy(v16, v4, v15 + 2);
v18 = 8 * ((v15 >> 1) + 1);
v24 = 2 * v1;
v25 = (char *)&v17[v1];
memcpy(v25, v23, v18);
if ( v4 != src )
free(v4);
v3 = (__int16 *)((char *)v17 + v15);
v2 = (__int64 *)&v25[v18 - 8];
if ( v3 >= &v17[v24 / 2 - 1] )
{
v4 = v17;
v21 = 1;
if ( v17 == v3 )
goto LABEL_51;
goto LABEL_49;
}
v23 = v25;
v4 = v17;
}
}
while ( v0 != 11 );
if ( v4 == v3 )
{
v21 = 0;
goto LABEL_50;
}
v21 = 0;
do
LABEL_49:
--v3;
while ( v3 != v4 );
LABEL_50:
if ( v4 == src )
return v21;
LABEL_51:
free(v4);
return v21;
}

canonical_decompiled_code:
__int64 func4()
{
int v0; // ebp
unsigned __int64 v1; // r12
__int64 *v2; // r14
__int16 *v3; // rbx
__int16 *v4; // r15
int v5; // edx
unsigned int v6; // er13
__int16 *v7; // rcx
unsigned __int64 v8; // rdx
int v9; // eax
unsigned __int8 v10; // bp
int v11; // eax
int v12; // esi
unsigned int v13; // edx
unsigned __int64 v14; // rax
__int64 v15; // rbx
__int16 *v16; // rax
__int16 *v17; // r13
size_t v18; // r14
int v19; // er13
unsigned __int8 v20; // cl
unsigned int v21; // ebp
char *v23; // [rsp+8h] [rbp-820h]
unsigned __int64 v24; // [rsp+10h] [rbp-818h]
char *v25; // [rsp+18h] [rbp-810h]
char v26[1600]; // [rsp+20h] [rbp-808h] BYREF
__int16 src[228]; // [rsp+660h] [rbp-1C8h] BYREF

yynerrs = 0;
yychar = -2;
src[0] = 0;
v0 = 0;
v1 = 200LL;
v2 = (__int64 *)v26;
v23 = v26;
v3 = src;
v4 = src;
do
{
v19 = yypact[v0];
if ( v19 == -8 )
goto LABEL_27;
if ( yychar == -2 )
yychar = func0();
if ( yychar <= 0 )
{
yychar = 0;
v5 = 0;
}
else
{
v5 = 2;
if ( (unsigned int)yychar <= 0x103 )
v5 = (unsigned __int8)yytranslate[yychar];
}
v6 = v5 + v19;
if ( v6 > 0x16 || (unsigned __int8)yycheck[v6] != v5 )
{
LABEL_27:
v20 = yydefact[v0];
v9 = v20;
if ( v20 )
{
v10 = yyr2[v20];
v8 = v2[1 - v10];
switch ( v20 )
{
case 2u:
parsed_regexp = *(v2 - 1);
return 1;
case 4u:
v8 = (unsigned __int64)reg(1, *(v2 - 2), *v2);
v9 = 4;
goto LABEL_8;
case 6u:
v8 = (unsigned __int64)reg(2, *(v2 - 1), *v2);
v9 = 6;
goto LABEL_8;
case 8u:
v8 = (unsigned __int64)reg(7, *(v2 - 1), 0LL);
v9 = 8;
goto LABEL_8;
case 9u:
v8 = (unsigned __int64)reg(7, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 9;
goto LABEL_8;
case 0xAu:
v8 = (unsigned __int64)reg(8, *(v2 - 1), 0LL);
v9 = 10;
goto LABEL_8;
case 0xBu:
v8 = (unsigned __int64)reg(8, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 11;
goto LABEL_8;
case 0xCu:
v8 = (unsigned __int64)reg(6, *(v2 - 1), 0LL);
v9 = 12;
goto LABEL_8;
case 0xDu:
v8 = (unsigned __int64)reg(6, *(v2 - 2), 0LL);
*(_DWORD *)(v8 + 4) = 1;
v9 = 13;
goto LABEL_8;
case 0xEu:
v8 = (unsigned int)++nparen | v8 & 0xFFFFFFFF00000000LL;
v9 = 14;
goto LABEL_8;
case 0xFu:
v8 = (unsigned __int64)reg(5, *(v2 - 1), 0LL);
*(_DWORD *)(v8 + 4) = *((_DWORD *)v2 - 4);
v9 = 15;
goto LABEL_8;
case 0x10u:
v8 = *(v2 - 1);
v9 = 16;
goto LABEL_8;
case 0x11u:
v8 = (unsigned __int64)reg(3, 0LL, 0LL);
*(_DWORD *)(v8 + 8) = *(_DWORD *)v2;
v9 = 17;
goto LABEL_8;
case 0x12u:
v8 = (unsigned __int64)reg(4, 0LL, 0LL);
v9 = 18;
goto LABEL_8;
default:
goto LABEL_8;
}
}
++yynerrs;
func2("syntax error");
}
v0 = (unsigned __int8)yytable[v6];
if ( yytable[v6] )
{
yychar = -2;
v2[1] = yylval;
++v2;
v7 = v3;
}
else
{
v8 = v2[1];
v9 = 0;
v10 = 0;
LABEL_8:
v7 = &v3[-v10];
v2 = &v2[-v10 + 1];
*v2 = v8;
v11 = (unsigned __int8)yyr1[v9] - 13;
v12 = *v7;
v13 = v12 + yypgoto[v11];
if ( v13 <= 0x16 && v12 == (unsigned __int8)yycheck[v13] )
v0 = (unsigned __int8)yytable[v13];
else
v0 = yydefgoto[v11];
}
v3 = v7 + 1;
v7[1] = v0;
v14 = 2 * v1;
if ( v7 + 1 >= &v4[v1 - 1] )
{
v15 = (char *)v3 - (char *)v4;
if ( v1 > 0x270F )
goto LABEL_46;
v1 = 10000LL;
if ( v14 <= 0x2710 )
v1 = v14;
v16 = (__int16 *)malloc(10 * v1 + 7);
v17 = v16;
if ( !v16 )
LABEL_46:
func2("memory exhausted");
memcpy(v16, v4, v15 + 2);
v18 = 8 * ((v15 >> 1) + 1);
v24 = 2 * v1;
v25 = (char *)&v17[v1];
memcpy(v25, v23, v18);
if ( v4 != src )
free(v4);
v3 = (__int16 *)((char *)v17 + v15);
v2 = (__int64 *)&v25[v18 - 8];
if ( v3 >= &v17[v24 / 2 - 1] )
{
v4 = v17;
v21 = 1;
if ( v17 == v3 )
goto LABEL_51;
goto LABEL_49;
}
v23 = v25;
v4 = v17;
}
}
while ( v0 != 11 );
if ( v4 == v3 )
{
v21 = 0;
goto LABEL_50;
}
v21 = 0;
do
LABEL_49:
--v3;
while ( v3 != v4 );
LABEL_50:
if ( v4 == src )
return v21;
LABEL_51:
free(v4);
return v21;
}

original_code:
int
yyparse (void)
{
    int yystate;
    int yyerrstatus;
    yytype_int16 yyssa[200];
    yytype_int16 *yyss;
    yytype_int16 *yyssp;
    YYSTYPE yyvsa[200];
    YYSTYPE *yyvs;
    YYSTYPE *yyvsp;
    long unsigned int yystacksize;
  int yyn;
  int yyresult;
  int yytoken = 0;
  YYSTYPE yyval;
  int yylen = 0;
  yyssp = yyss = yyssa;
  yyvsp = yyvs = yyvsa;
  yystacksize = 200;
  ;
  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = (-2);
  goto yysetstate;
yynewstate:
  yyssp++;
yysetstate:
  *yyssp = (yytype_int16) yystate;
  if (yyss + yystacksize - 1 <= yyssp)
    {
      long unsigned int yysize = (long unsigned int) (yyssp - yyss + 1);
      if (10000 <= yystacksize)
        goto yyexhaustedlab;
      yystacksize *= 2;
      if (10000 < yystacksize)
        yystacksize = 10000;
      {
        yytype_int16 *yyss1 = yyss;
        union yyalloc *yyptr =
          (union yyalloc *) malloc (((yystacksize) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) + (sizeof (union yyalloc) - 1)));
        if (! yyptr)
          goto yyexhaustedlab;
        do { long unsigned int yynewbytes; __builtin_memcpy (&yyptr->yyss_alloc, yyss, (yysize) * sizeof (*(yyss))); yyss = &yyptr->yyss_alloc; yynewbytes = yystacksize * sizeof (*yyss) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0);
        do { long unsigned int yynewbytes; __builtin_memcpy (&yyptr->yyvs_alloc, yyvs, (yysize) * sizeof (*(yyvs))); yyvs = &yyptr->yyvs_alloc; yynewbytes = yystacksize * sizeof (*yyvs) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0);
        if (yyss1 != yyssa)
          free (yyss1);
      }
      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;
      ;
      if (yyss + yystacksize - 1 <= yyssp)
        goto yyabortlab;
    }
  ;
  if (yystate == 11)
    goto yyacceptlab;
  goto yybackup;
yybackup:
  yyn = yypact[yystate];
  if ((!!((yyn) == (-8))))
    goto yydefault;
  if (yychar == (-2))
    {
      ;
      yychar = yylex ();
    }
  if (yychar <= 0)
    {
      yychar = yytoken = 0;
      ;
    }
  else
    {
      yytoken = ((unsigned) (yychar) <= 259 ? yytranslate[yychar] : 2);
      ;
    }
  yyn += yytoken;
  if (yyn < 0 || 22 < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (0)
        goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }
  if (yyerrstatus)
    yyerrstatus--;
  ;
  yychar = (-2);
  yystate = yyn;

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wuninitialized"

#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

  *++yyvsp = yylval;

#pragma GCC diagnostic pop

  goto yynewstate;
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;
yyreduce:
  yylen = yyr2[yyn];
  yyval = yyvsp[1-yylen];
  ;
  switch (yyn)
    {
        case 2:
    {
  parsed_regexp = (yyvsp[-1].re);
  return 1;
 }
    break;
  case 4:
    {
  (yyval.re) = reg(Alt, (yyvsp[-2].re), (yyvsp[0].re));
 }
    break;
  case 6:
    {
  (yyval.re) = reg(Cat, (yyvsp[-1].re), (yyvsp[0].re));
 }
    break;
  case 8:
    {
  (yyval.re) = reg(Star, (yyvsp[-1].re), ((void*)0));
 }
    break;
  case 9:
    {
  (yyval.re) = reg(Star, (yyvsp[-2].re), ((void*)0));
  (yyval.re)->n = 1;
 }
    break;
  case 10:
    {
  (yyval.re) = reg(Plus, (yyvsp[-1].re), ((void*)0));
 }
    break;
  case 11:
    {
  (yyval.re) = reg(Plus, (yyvsp[-2].re), ((void*)0));
  (yyval.re)->n = 1;
 }
    break;
  case 12:
    {
  (yyval.re) = reg(Quest, (yyvsp[-1].re), ((void*)0));
 }
    break;
  case 13:
    {
  (yyval.re) = reg(Quest, (yyvsp[-2].re), ((void*)0));
  (yyval.re)->n = 1;
 }
    break;
  case 14:
    {
  (yyval.nparen) = ++nparen;
 }
    break;
  case 15:
    {
  (yyval.re) = reg(Paren, (yyvsp[-1].re), ((void*)0));
  (yyval.re)->n = (yyvsp[-2].nparen);
 }
    break;
  case 16:
    {
  (yyval.re) = (yyvsp[-1].re);
 }
    break;
  case 17:
    {
  (yyval.re) = reg(Lit, ((void*)0), ((void*)0));
  (yyval.re)->ch = (yyvsp[0].c);
 }
    break;
  case 18:
    {
  (yyval.re) = reg(Dot, ((void*)0), ((void*)0));
 }
    break;
      default: break;
    }
  ;
  (yyvsp -= (yylen), yyssp -= (yylen));
  yylen = 0;
  ;
  *++yyvsp = yyval;
  {
    const int yylhs = yyr1[yyn] - 13;
    const int yyi = yypgoto[yylhs] + *yyssp;
    yystate = (0 <= yyi && yyi <= 22 && yycheck[yyi] == *yyssp
               ? yytable[yyi]
               : yydefgoto[yylhs]);
  }
  goto yynewstate;
yyerrlab:
  yytoken = yychar == (-2) ? (-2) : ((unsigned) (yychar) <= 259 ? yytranslate[yychar] : 2);
  if (!yyerrstatus)
    {
      ++yynerrs;
      yyerror ("syntax error");
    }
  if (yyerrstatus == 3)
    {
      if (yychar <= 0)
        {
          if (yychar == 0)
            goto yyabortlab;
        }
      else
        {
          yydestruct ("Error: discarding",
                      yytoken, &yylval);
          yychar = (-2);
        }
    }
  goto yyerrlab1;
yyerrorlab:
  if (0)
    goto yyerrorlab;
  (yyvsp -= (yylen), yyssp -= (yylen));
  yylen = 0;
  ;
  yystate = *yyssp;
  goto yyerrlab1;
yyerrlab1:
  yyerrstatus = 3;
  for (;;)
    {
      yyn = yypact[yystate];
      if (!(!!((yyn) == (-8))))
        {
          yyn += 1;
          if (0 <= yyn && yyn <= 22 && yycheck[yyn] == 1)
            {
              yyn = yytable[yyn];
              if (0 < yyn)
                break;
            }
        }
      if (yyssp == yyss)
        goto yyabortlab;
      yydestruct ("Error: popping",
                  yystos[yystate], yyvsp);
      (yyvsp -= (1), yyssp -= (1));
      yystate = *yyssp;
      ;
    }

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wuninitialized"

#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

  *++yyvsp = yylval;

#pragma GCC diagnostic pop

  ;
  yystate = yyn;
  goto yynewstate;
yyacceptlab:
  yyresult = 0;
  goto yyreturn;
yyabortlab:
  yyresult = 1;
  goto yyreturn;
yyexhaustedlab:
  yyerror ("memory exhausted");
  yyresult = 2;
yyreturn:
  if (yychar != (-2))
    {
      yytoken = ((unsigned) (yychar) <= 259 ? yytranslate[yychar] : 2);
      yydestruct ("Cleanup: discarding lookahead",
                  yytoken, &yylval);
    }
  (yyvsp -= (yylen), yyssp -= (yylen));
  ;
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
                  yystos[*yyssp], yyvsp);
      (yyvsp -= (1), yyssp -= (1));
    }
  if (yyss != yyssa)
    free (yyss);
  return yyresult;
}

canonical_original_code:
int yyparse()
{
    int yystate;
    int yyerrstatus;
    short yyssa[200];
    short *yyss;
    short *yyssp;
    union YYSTYPE yyvsa[200];
    union YYSTYPE *yyvs;
    union YYSTYPE *yyvsp;
    unsigned long yystacksize;
  int yyn;
  int yyresult;
  int yytoken = 0;
  union YYSTYPE yyval;
  int yylen = 0;
  yyssp = yyss = yyssa;
  yyvsp = yyvs = yyvsa;
  yystacksize = 200;
  ;
  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = (-2);
  goto yysetstate;
yynewstate:
  yyssp++;
yysetstate:
  *yyssp = (short) yystate;
  if (yyss + yystacksize - 1 <= yyssp)
    {
      unsigned long yysize = (long unsigned int) (yyssp - yyss + 1);
      if (10000 <= yystacksize)
        goto yyexhaustedlab;
      yystacksize *= 2;
      if (10000 < yystacksize)
        yystacksize = 10000;
      {
        short *yyss1 = yyss;
        union yyalloc *yyptr = (union yyalloc *) malloc (((yystacksize) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) + (sizeof (union yyalloc) - 1)));
        if (! yyptr)
          goto yyexhaustedlab;
        do { unsigned long yynewbytes; __builtin_memcpy (&yyptr->yyss_alloc, yyss, (yysize) * sizeof (*(yyss))); yyss = &yyptr->yyss_alloc; yynewbytes = yystacksize * sizeof (*yyss) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0);
        do { unsigned long yynewbytes; __builtin_memcpy (&yyptr->yyvs_alloc, yyvs, (yysize) * sizeof (*(yyvs))); yyvs = &yyptr->yyvs_alloc; yynewbytes = yystacksize * sizeof (*yyvs) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0);
        if (yyss1 != yyssa)
          free (yyss1);
      }
      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;
      ;
      if (yyss + yystacksize - 1 <= yyssp)
        goto yyabortlab;
    }
  ;
  if (yystate == 11)
    goto yyacceptlab;
  goto yybackup;
yybackup:
  yyn = yypact[yystate];
  if ((!!((yyn) == (-8))))
    goto yydefault;
  if (yychar == (-2))
    {
      ;
      yychar = yylex ();
    }
  if (yychar <= 0)
    {
      yychar = yytoken = 0;
      ;
    }
  else
    {
      yytoken = ((unsigned int) (yychar) <= 259 ? yytranslate[yychar] : 2);
      ;
    }
  yyn += yytoken;
  if (yyn < 0 || 22 < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (0)
        goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }
  if (yyerrstatus)
    yyerrstatus--;
  ;
  yychar = (-2);
  yystate = yyn;

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wuninitialized"

#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

  *++yyvsp = yylval;

#pragma GCC diagnostic pop

  goto yynewstate;
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;
yyreduce:
  yylen = yyr2[yyn];
  yyval = yyvsp[1-yylen];
  ;
  switch (yyn)
    {
        case 2:
    {
  parsed_regexp = (yyvsp[-1].re);
  return 1;
 }
    break;
  case 4:
    {
  (yyval.re) = reg(Alt, (yyvsp[-2].re), (yyvsp[0].re));
 }
    break;
  case 6:
    {
  (yyval.re) = reg(Cat, (yyvsp[-1].re), (yyvsp[0].re));
 }
    break;
  case 8:
    {
  (yyval.re) = reg(Star, (yyvsp[-1].re), ((void *)0));
 }
    break;
  case 9:
    {
  (yyval.re) = reg(Star, (yyvsp[-2].re), ((void *)0));
  (yyval.re)->n = 1;
 }
    break;
  case 10:
    {
  (yyval.re) = reg(Plus, (yyvsp[-1].re), ((void *)0));
 }
    break;
  case 11:
    {
  (yyval.re) = reg(Plus, (yyvsp[-2].re), ((void *)0));
  (yyval.re)->n = 1;
 }
    break;
  case 12:
    {
  (yyval.re) = reg(Quest, (yyvsp[-1].re), ((void *)0));
 }
    break;
  case 13:
    {
  (yyval.re) = reg(Quest, (yyvsp[-2].re), ((void *)0));
  (yyval.re)->n = 1;
 }
    break;
  case 14:
    {
  (yyval.nparen) = ++nparen;
 }
    break;
  case 15:
    {
  (yyval.re) = reg(Paren, (yyvsp[-1].re), ((void *)0));
  (yyval.re)->n = (yyvsp[-2].nparen);
 }
    break;
  case 16:
    {
  (yyval.re) = (yyvsp[-1].re);
 }
    break;
  case 17:
    {
  (yyval.re) = reg(Lit, ((void *)0), ((void *)0));
  (yyval.re)->ch = (yyvsp[0].c);
 }
    break;
  case 18:
    {
  (yyval.re) = reg(Dot, ((void *)0), ((void *)0));
 }
    break;
      default: break;
    }
  ;
  (yyvsp -= (yylen), yyssp -= (yylen));
  yylen = 0;
  ;
  *++yyvsp = yyval;
  {
    int yylhs = yyr1[yyn] - 13;
    int yyi = yypgoto[yylhs] + *yyssp;
    yystate = (0 <= yyi && yyi <= 22 && yycheck[yyi] == *yyssp
               ? yytable[yyi]
               : yydefgoto[yylhs]);
  }
  goto yynewstate;
yyerrlab:
  yytoken = yychar == (-2) ? (-2) : ((unsigned int) (yychar) <= 259 ? yytranslate[yychar] : 2);
  if (!yyerrstatus)
    {
      ++yynerrs;
      yyerror ("syntax error");
    }
  if (yyerrstatus == 3)
    {
      if (yychar <= 0)
        {
          if (yychar == 0)
            goto yyabortlab;
        }
      else
        {
          yydestruct ("Error: discarding",
                      yytoken, &yylval);
          yychar = (-2);
        }
    }
  goto yyerrlab1;
yyerrorlab:
  if (0)
    goto yyerrorlab;
  (yyvsp -= (yylen), yyssp -= (yylen));
  yylen = 0;
  ;
  yystate = *yyssp;
  goto yyerrlab1;
yyerrlab1:
  yyerrstatus = 3;
  for (;;)
    {
      yyn = yypact[yystate];
      if (!(!!((yyn) == (-8))))
        {
          yyn += 1;
          if (0 <= yyn && yyn <= 22 && yycheck[yyn] == 1)
            {
              yyn = yytable[yyn];
              if (0 < yyn)
                break;
            }
        }
      if (yyssp == yyss)
        goto yyabortlab;
      yydestruct ("Error: popping",
                  yystos[yystate], yyvsp);
      (yyvsp -= (1), yyssp -= (1));
      yystate = *yyssp;
      ;
    }

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wuninitialized"

#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

  *++yyvsp = yylval;

#pragma GCC diagnostic pop

  ;
  yystate = yyn;
  goto yynewstate;
yyacceptlab:
  yyresult = 0;
  goto yyreturn;
yyabortlab:
  yyresult = 1;
  goto yyreturn;
yyexhaustedlab:
  yyerror ("memory exhausted");
  yyresult = 2;
yyreturn:
  if (yychar != (-2))
    {
      yytoken = ((unsigned int) (yychar) <= 259 ? yytranslate[yychar] : 2);
      yydestruct ("Cleanup: discarding lookahead",
                  yytoken, &yylval);
    }
  (yyvsp -= (yylen), yyssp -= (yylen));
  ;
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
                  yystos[*yyssp], yyvsp);
      (yyvsp -= (1), yyssp -= (1));
    }
  if (yyss != yyssa)
    free (yyss);
  return yyresult;
}

variable_types: yystate int

variable_types: yyerrstatus int

variable_types:
yyssa
short [200]

variable_types:
yyss
short *

variable_types:
yyssp
short *

variable_types: union YYSTYPE { struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; } *re; int c; int nparen; } [200]

variable_types: union YYSTYPE { struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; } *re; int c; int nparen; } *

variable_types:
yystacksize
unsigned long

variable_types: yyn int

variable_types: yyresult int

variable_types: yytoken int

variable_types: yylen int

variable_types:
yysize
unsigned long

variable_types: union yyalloc { short yyss_alloc; union YYSTYPE { struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; } *re; int c; int nparen; } yyvs_alloc; } *

variable_types:
yynewbytes
unsigned long

variable_types: yylhs int

variable_types: yyi int

user_defined_types: union YYSTYPE { struct Regexp *re; int c; int nparen; }

user_defined_types: union yyalloc { short yyss_alloc; union YYSTYPE yyvs_alloc; }


printre

decompiled_code:
int __fastcall printre(__int64 a1)
{
int result; // eax

switch ( *(_DWORD *)a1 )
{
case 1:
printf("Alt(");
printre(*(_QWORD *)(a1 + 16));
printf(", ");
printre(*(_QWORD *)(a1 + 24));
result = putchar(41);
break;
case 2:
printf("Cat(");
printre(*(_QWORD *)(a1 + 16));
printf(", ");
printre(*(_QWORD *)(a1 + 24));
result = putchar(41);
break;
case 3:
result = printf("Lit(%c)", *(unsigned int *)(a1 + 8));
break;
case 4:
result = printf("Dot");
break;
case 5:
printf("Paren(%d, ", *(unsigned int *)(a1 + 4));
printre(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 6:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Quest(");
printre(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 7:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Star(");
printre(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 8:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Plus(");
printre(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
default:
result = printf("???");
break;
}
return result;
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1)
{
int result; // eax

switch ( *(_DWORD *)a1 )
{
case 1:
printf("Alt(");
func5(*(_QWORD *)(a1 + 16));
printf(", ");
func5(*(_QWORD *)(a1 + 24));
result = putchar(41);
break;
case 2:
printf("Cat(");
func5(*(_QWORD *)(a1 + 16));
printf(", ");
func5(*(_QWORD *)(a1 + 24));
result = putchar(41);
break;
case 3:
result = printf("Lit(%c)", *(unsigned int *)(a1 + 8));
break;
case 4:
result = printf("Dot");
break;
case 5:
printf("Paren(%d, ", *(unsigned int *)(a1 + 4));
func5(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 6:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Quest(");
func5(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 7:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Star(");
func5(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
case 8:
if ( *(_DWORD *)(a1 + 4) )
printf("Ng");
printf("Plus(");
func5(*(_QWORD *)(a1 + 16));
result = putchar(41);
break;
default:
result = printf("???");
break;
}
return result;
}

original_code:
void
printre(Regexp *r)
{
 switch(r->type) {
 default:
  printf("???");
  break;
 case Alt:
  printf("Alt(");
  printre(r->left);
  printf(", ");
  printre(r->right);
  printf(")");
  break;
 case Cat:
  printf("Cat(");
  printre(r->left);
  printf(", ");
  printre(r->right);
  printf(")");
  break;
 case Lit:
  printf("Lit(%c)", r->ch);
  break;
 case Dot:
  printf("Dot");
  break;
 case Paren:
  printf("Paren(%d, ", r->n);
  printre(r->left);
  printf(")");
  break;
 case Star:
  if(r->n)
   printf("Ng");
  printf("Star(");
  printre(r->left);
  printf(")");
  break;
 case Plus:
  if(r->n)
   printf("Ng");
  printf("Plus(");
  printre(r->left);
  printf(")");
  break;
 case Quest:
  if(r->n)
   printf("Ng");
  printf("Quest(");
  printre(r->left);
  printf(")");
  break;
 }
}

canonical_original_code:
void printre(struct Regexp *r)
{
 switch(r->type) {
 default:
  printf("???");
  break;
 case Alt:
  printf("Alt(");
  printre(r->left);
  printf(", ");
  printre(r->right);
  printf(")");
  break;
 case Cat:
  printf("Cat(");
  printre(r->left);
  printf(", ");
  printre(r->right);
  printf(")");
  break;
 case Lit:
  printf("Lit(%c)", r->ch);
  break;
 case Dot:
  printf("Dot");
  break;
 case Paren:
  printf("Paren(%d, ", r->n);
  printre(r->left);
  printf(")");
  break;
 case Star:
  if(r->n)
   printf("Ng");
  printf("Star(");
  printre(r->left);
  printf(")");
  break;
 case Plus:
  if(r->n)
   printf("Ng");
  printf("Plus(");
  printre(r->left);
  printf(")");
  break;
 case Quest:
  if(r->n)
   printf("Ng");
  printf("Quest(");
  printre(r->left);
  printf(")");
  break;
 }
}

variable_types: struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; } *


yylex

decompiled_code:
__int64 yylex()
{
char v0; // dl
unsigned int v1; // ebx

if ( !input )
return 259;
v0 = *(_BYTE *)input;
v1 = 259;
if ( *(_BYTE *)input )
{
++input;
v1 = v0;
if ( !strchr("|*+?():.", v0) )
{
LODWORD(yylval) = v1;
v1 = 258;
}
}
return v1;
}

canonical_decompiled_code:
__int64 func0()
{
char v0; // dl
unsigned int v1; // ebx

if ( !input )
return 259;
v0 = *(_BYTE *)input;
v1 = 259;
if ( *(_BYTE *)input )
{
++input;
v1 = v0;
if ( !strchr("|*+?():.", v0) )
{
LODWORD(yylval) = v1;
v1 = 258;
}
}
return v1;
}

original_code:
static int
yylex(void)
{
 int c;
 if(input == ((void *)0) || *input == 0)
  return 259;
 c = *input++;
 if(strchr("|*+?():.", c))
  return c;
 yylval.c = c;
 return 258;
}

canonical_original_code:
static int yylex()
{
 int c;
 if(input == ((void *)0) || *input == 0)
  return 259;
 c = *input++;
 if(strchr("|*+?():.", c))
  return c;
 yylval.c = c;
 return 258;
}

variable_types: c int


yyerror

decompiled_code:
void __fastcall __noreturn yyerror(const char *a1)
{
fatal("%s", a1);
}

canonical_decompiled_code:
void __fastcall __noreturn func2(const char *a1)
{
func1("%s", a1);
}

original_code:
static void
yyerror(char *s)
{
 fatal("%s", s);
}

variable_types:
s
char *


mal

decompiled_code:
void *__fastcall mal(int a1)
{
void *v1; // rax

v1 = malloc(a1);
if ( !v1 )
fatal("out of memory");
return memset(v1, 0, a1);
}

canonical_decompiled_code:
void *__fastcall func3(int a1)
{
void *v1; // rax

v1 = malloc(a1);
if ( !v1 )
func1("out of memory");
return memset(v1, 0, a1);
}

original_code:
void*
mal(int n)
{
 void *v;
 v = malloc(n);
 if(v == ((void*)0))
  fatal("out of memory");
 memset(v, 0, n);
 return v;
}

canonical_original_code:
void *mal(int n)
{
 void *v;
 v = malloc(n);
 if(v == ((void *)0))
  fatal("out of memory");
 memset(v, 0, n);
 return v;
}

variable_types: n int

variable_types:
v
void *

return_type: void *


recursive

decompiled_code:
__int64 __fastcall recursive(__int64 a1, _BYTE *a2, __int64 a3, int a4)
{
__int64 result; // rax
int v6; // edx
int v7; // eax
__int64 *v8; // rax
__int64 v9; // r14

switch ( *(_DWORD *)a1 )
{
case 1:
result = 0LL;
if ( (char)*a2 == *(_DWORD *)(a1 + 4) )
goto LABEL_3;
break;
case 2:
result = 1LL;
break;
case 3:
result = recursive(*(_QWORD *)(a1 + 16));
break;
case 4:
v6 = recursive(*(_QWORD *)(a1 + 16));
result = 1LL;
if ( !v6 )
result = recursive(*(_QWORD *)(a1 + 24));
break;
case 5:
LABEL_3:
result = 0LL;
if ( *a2 )
goto LABEL_4;
break;
case 6:
v7 = *(_DWORD *)(a1 + 8);
if ( v7 >= a4 )
{
LABEL_4:
result = recursive(a1 + 40);
}
else
{
v8 = (__int64 *)(a3 + 8LL * v7);
v9 = *v8;
*v8 = (__int64)a2;
result = recursive(a1 + 40);
if ( (_DWORD)result )
result = 1LL;
else
*(_QWORD *)(a3 + 8LL * *(int *)(a1 + 8)) = v9;
}
break;
default:
fatal("recursive");
result = 0xFFFFFFFFLL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, _BYTE *a2, __int64 a3, int a4)
{
__int64 result; // rax
int v6; // edx
int v7; // eax
__int64 *v8; // rax
__int64 v9; // r14

switch ( *(_DWORD *)a1 )
{
case 1:
result = 0LL;
if ( (char)*a2 == *(_DWORD *)(a1 + 4) )
goto LABEL_3;
break;
case 2:
result = 1LL;
break;
case 3:
result = func0(*(_QWORD *)(a1 + 16));
break;
case 4:
v6 = func0(*(_QWORD *)(a1 + 16));
result = 1LL;
if ( !v6 )
result = func0(*(_QWORD *)(a1 + 24));
break;
case 5:
LABEL_3:
result = 0LL;
if ( *a2 )
goto LABEL_4;
break;
case 6:
v7 = *(_DWORD *)(a1 + 8);
if ( v7 >= a4 )
{
LABEL_4:
result = func0(a1 + 40);
}
else
{
v8 = (__int64 *)(a3 + 8LL * v7);
v9 = *v8;
*v8 = (__int64)a2;
result = func0(a1 + 40);
if ( (_DWORD)result )
result = 1LL;
else
*(_QWORD *)(a3 + 8LL * *(int *)(a1 + 8)) = v9;
}
break;
default:
fatal("recursive");
result = 0xFFFFFFFFLL;
break;
}
return result;
}

original_code:
int
recursive(Inst *pc, char *sp, char **subp, int nsubp)
{
 char *old;
 switch(pc->opcode) {
 case Char:
  if(*sp != pc->c)
   return 0;
 case Any:
  if(*sp == '\0')
   return 0;
  return recursive(pc+1, sp+1, subp, nsubp);
 case Match:
  return 1;
 case Jmp:
  return recursive(pc->x, sp, subp, nsubp);
 case Split:
  if(recursive(pc->x, sp, subp, nsubp))
   return 1;
  return recursive(pc->y, sp, subp, nsubp);
 case Save:
  if(pc->n >= nsubp)
   return recursive(pc+1, sp, subp, nsubp);
  old = subp[pc->n];
  subp[pc->n] = sp;
  if(recursive(pc+1, sp, subp, nsubp))
   return 1;
  subp[pc->n] = old;
  return 0;
 }
 fatal("recursive");
 return -1;
}

canonical_original_code:
int recursive(struct Inst *pc, char *sp, char **subp, int nsubp)
{
 char *old;
 switch(pc->opcode) {
 case Char:
  if(*sp != pc->c)
   return 0;
 case Any:
  if(*sp == '\0')
   return 0;
  return recursive(pc+1, sp+1, subp, nsubp);
 case Match:
  return 1;
 case Jmp:
  return recursive(pc->x, sp, subp, nsubp);
 case Split:
  if(recursive(pc->x, sp, subp, nsubp))
   return 1;
  return recursive(pc->y, sp, subp, nsubp);
 case Save:
  if(pc->n >= nsubp)
   return recursive(pc+1, sp, subp, nsubp);
  old = subp[pc->n];
  subp[pc->n] = sp;
  if(recursive(pc+1, sp, subp, nsubp))
   return 1;
  subp[pc->n] = old;
  return 0;
 }
 fatal("recursive");
 return -1;
}

variable_types: struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *

variable_types:
sp
char *

variable_types:
subp
char **

variable_types: nsubp int

variable_types:
old
char *


recursiveprog

decompiled_code:
__int64 __fastcall recursiveprog(__int64 *a1, _BYTE *a2, __int64 a3, int a4)
{
return recursive(*a1, a2, a3, a4);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 *a1, _BYTE *a2, __int64 a3, int a4)
{
return func0(*a1, a2, a3, a4);
}

original_code:
int
recursiveprog(Prog *prog, char *input, char **subp, int nsubp)
{
 return recursive(prog->start, input, subp, nsubp);
}

canonical_original_code:
int recursiveprog(struct Prog *prog, char *input, char **subp, int nsubp)
{
 return recursive(prog->start, input, subp, nsubp);
}

variable_types: struct Prog { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *start; int len; } *

variable_types:
input
char *


recursiveloop

decompiled_code:
__int64 __fastcall recursiveloop(__int64 a1, char *a2, __int64 a3, unsigned int a4)
{
__int64 result; // rax
int v9; // eax
char **v10; // rax
char *v11; // r13

while ( 2 )
{
switch ( *(_DWORD *)a1 )
{
case 1:
if ( *a2 == *(_DWORD *)(a1 + 4) )
goto LABEL_4;
return 0LL;
case 2:
return 1LL;
case 3:
a1 = *(_QWORD *)(a1 + 16);
continue;
case 4:
if ( (unsigned int)recursiveloop(*(_QWORD *)(a1 + 16), a2, a3, a4) )
return 1LL;
a1 = *(_QWORD *)(a1 + 24);
continue;
case 5:
LABEL_4:
a1 += 40LL;
++a2;
continue;
case 6:
v9 = *(_DWORD *)(a1 + 8);
if ( v9 >= (int)a4 )
{
a1 += 40LL;
continue;
}
v10 = (char **)(a3 + 8LL * v9);
v11 = *v10;
*v10 = a2;
result = recursiveloop(a1 + 40, a2, a3, a4);
if ( (_DWORD)result )
return 1LL;
*(_QWORD *)(a3 + 8LL * *(int *)(a1 + 8)) = v11;
return result;
default:
fatal("recursiveloop");
continue;
}
}
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, char *a2, __int64 a3, unsigned int a4)
{
__int64 result; // rax
int v9; // eax
char **v10; // rax
char *v11; // r13

while ( 2 )
{
switch ( *(_DWORD *)a1 )
{
case 1:
if ( *a2 == *(_DWORD *)(a1 + 4) )
goto LABEL_4;
return 0LL;
case 2:
return 1LL;
case 3:
a1 = *(_QWORD *)(a1 + 16);
continue;
case 4:
if ( (unsigned int)func2(*(_QWORD *)(a1 + 16), a2, a3, a4) )
return 1LL;
a1 = *(_QWORD *)(a1 + 24);
continue;
case 5:
LABEL_4:
a1 += 40LL;
++a2;
continue;
case 6:
v9 = *(_DWORD *)(a1 + 8);
if ( v9 >= (int)a4 )
{
a1 += 40LL;
continue;
}
v10 = (char **)(a3 + 8LL * v9);
v11 = *v10;
*v10 = a2;
result = func2(a1 + 40, a2, a3, a4);
if ( (_DWORD)result )
return 1LL;
*(_QWORD *)(a3 + 8LL * *(int *)(a1 + 8)) = v11;
return result;
default:
fatal("recursiveloop");
continue;
}
}
}

original_code:
int
recursiveloop(Inst *pc, char *sp, char **subp, int nsubp)
{
 char *old;
 for(;;) {
  switch(pc->opcode) {
  case Char:
   if(*sp != pc->c)
    return 0;
  case Any:
   pc++;
   sp++;
   continue;
  case Match:
   return 1;
  case Jmp:
   pc = pc->x;
   continue;
  case Split:
   if(recursiveloop(pc->x, sp, subp, nsubp))
    return 1;
   pc = pc->y;
   continue;
  case Save:
   if(pc->n >= nsubp) {
    pc++;
    continue;
   }
   old = subp[pc->n];
   subp[pc->n] = sp;
   if(recursiveloop(pc+1, sp, subp, nsubp))
    return 1;
   subp[pc->n] = old;
   return 0;
  }
  fatal("recursiveloop");
 }
}

canonical_original_code:
int recursiveloop(struct Inst *pc, char *sp, char **subp, int nsubp)
{
 char *old;
 for(;;) {
  switch(pc->opcode) {
  case Char:
   if(*sp != pc->c)
    return 0;
  case Any:
   pc++;
   sp++;
   continue;
  case Match:
   return 1;
  case Jmp:
   pc = pc->x;
   continue;
  case Split:
   if(recursiveloop(pc->x, sp, subp, nsubp))
    return 1;
   pc = pc->y;
   continue;
  case Save:
   if(pc->n >= nsubp) {
    pc++;
    continue;
   }
   old = subp[pc->n];
   subp[pc->n] = sp;
   if(recursiveloop(pc+1, sp, subp, nsubp))
    return 1;
   subp[pc->n] = old;
   return 0;
  }
  fatal("recursiveloop");
 }
}

user_defined_types: struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; }


recursiveloopprog

decompiled_code:
__int64 __fastcall recursiveloopprog(__int64 *a1, char *a2, __int64 a3, unsigned int a4)
{
return recursiveloop(*a1, a2, a3, a4);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, char *a2, __int64 a3, unsigned int a4)
{
return func2(*a1, a2, a3, a4);
}

original_code:
int
recursiveloopprog(Prog *prog, char *input, char **subp, int nsubp)
{
 return recursiveloop(prog->start, input, subp, nsubp);
}

canonical_original_code:
int recursiveloopprog(struct Prog *prog, char *input, char **subp, int nsubp)
{
 return recursiveloop(prog->start, input, subp, nsubp);
}


count

decompiled_code:
__int64 __fastcall count(__int64 a1)
{
int v1; // ebp
__int64 result; // rax
int v3; // ebp

switch ( *(_DWORD *)a1 )
{
case 1:
goto LABEL_3;
case 2:
v3 = count(*(_QWORD *)(a1 + 16));
result = v3 + (unsigned int)count(*(_QWORD *)(a1 + 24));
break;
case 3:
case 4:
result = 1LL;
break;
case 5:
case 7:
result = (unsigned int)count(*(_QWORD *)(a1 + 16)) + 2;
break;
case 6:
case 8:
result = (unsigned int)count(*(_QWORD *)(a1 + 16)) + 1;
break;
default:
fatal("bad count");
LABEL_3:
v1 = count(*(_QWORD *)(a1 + 16));
result = v1 + (unsigned int)count(*(_QWORD *)(a1 + 24)) + 2;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
int v1; // ebp
__int64 result; // rax
int v3; // ebp

switch ( *(_DWORD *)a1 )
{
case 1:
goto LABEL_3;
case 2:
v3 = func0(*(_QWORD *)(a1 + 16));
result = v3 + (unsigned int)func0(*(_QWORD *)(a1 + 24));
break;
case 3:
case 4:
result = 1LL;
break;
case 5:
case 7:
result = (unsigned int)func0(*(_QWORD *)(a1 + 16)) + 2;
break;
case 6:
case 8:
result = (unsigned int)func0(*(_QWORD *)(a1 + 16)) + 1;
break;
default:
fatal("bad count");
LABEL_3:
v1 = func0(*(_QWORD *)(a1 + 16));
result = v1 + (unsigned int)func0(*(_QWORD *)(a1 + 24)) + 2;
break;
}
return result;
}

original_code:
static int
count(Regexp *r)
{
 switch(r->type) {
 default:
  fatal("bad count");
 case Alt:
  return 2 + count(r->left) + count(r->right);
 case Cat:
  return count(r->left) + count(r->right);
 case Lit:
 case Dot:
  return 1;
 case Paren:
  return 2 + count(r->left);
 case Quest:
  return 1 + count(r->left);
 case Star:
  return 2 + count(r->left);
 case Plus:
  return 1 + count(r->left);
 }
}

canonical_original_code:
static int count(struct Regexp *r)
{
 switch(r->type) {
 default:
  fatal("bad count");
 case Alt:
  return 2 + count(r->left) + count(r->right);
 case Cat:
  return count(r->left) + count(r->right);
 case Lit:
 case Dot:
  return 1;
 case Paren:
  return 2 + count(r->left);
 case Quest:
  return 1 + count(r->left);
 case Star:
  return 2 + count(r->left);
 case Plus:
  return 1 + count(r->left);
 }
}

user_defined_types: struct Regexp { int type; int n; int ch; struct Regexp *left; struct Regexp *right; }


emit

original_code:
static void
emit(Regexp *r)
{
 Inst *p1, *p2, *t;
 switch(r->type) {
 default:
  fatal("bad emit");
 case Alt:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  pc->opcode = Jmp;
  p2 = pc++;
  p1->y = pc;
  emit(r->right);
  p2->x = pc;
  break;
 case Cat:
  emit(r->left);
  emit(r->right);
  break;
 case Lit:
  pc->opcode = Char;
  pc->c = r->ch;
  pc++;
  break;
 case Dot:
  pc++->opcode = Any;
  break;
 case Paren:
  pc->opcode = Save;
  pc->n = 2*r->n;
  pc++;
  emit(r->left);
  pc->opcode = Save;
  pc->n = 2*r->n + 1;
  pc++;
  break;
 case Quest:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  p1->y = pc;
  if(r->n) {
   t = p1->x;
   p1->x = p1->y;
   p1->y = t;
  }
  break;
 case Star:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  pc->opcode = Jmp;
  pc->x = p1;
  pc++;
  p1->y = pc;
  if(r->n) {
   t = p1->x;
   p1->x = p1->y;
   p1->y = t;
  }
  break;
 case Plus:
  p1 = pc;
  emit(r->left);
  pc->opcode = Split;
  pc->x = p1;
  p2 = pc;
  pc++;
  p2->y = pc;
  if(r->n) {
   t = p2->x;
   p2->x = p2->y;
   p2->y = t;
  }
  break;
 }
}

canonical_original_code:
static void emit(struct Regexp *r)
{
 struct Inst *p1; struct Inst *p2; struct Inst *t;
 switch(r->type) {
 default:
  fatal("bad emit");
 case Alt:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  pc->opcode = Jmp;
  p2 = pc++;
  p1->y = pc;
  emit(r->right);
  p2->x = pc;
  break;
 case Cat:
  emit(r->left);
  emit(r->right);
  break;
 case Lit:
  pc->opcode = Char;
  pc->c = r->ch;
  pc++;
  break;
 case Dot:
  pc++->opcode = Any;
  break;
 case Paren:
  pc->opcode = Save;
  pc->n = 2*r->n;
  pc++;
  emit(r->left);
  pc->opcode = Save;
  pc->n = 2*r->n + 1;
  pc++;
  break;
 case Quest:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  p1->y = pc;
  if(r->n) {
   t = p1->x;
   p1->x = p1->y;
   p1->y = t;
  }
  break;
 case Star:
  pc->opcode = Split;
  p1 = pc++;
  p1->x = pc;
  emit(r->left);
  pc->opcode = Jmp;
  pc->x = p1;
  pc++;
  p1->y = pc;
  if(r->n) {
   t = p1->x;
   p1->x = p1->y;
   p1->y = t;
  }
  break;
 case Plus:
  p1 = pc;
  emit(r->left);
  pc->opcode = Split;
  pc->x = p1;
  p2 = pc;
  pc++;
  p2->y = pc;
  if(r->n) {
   t = p2->x;
   p2->x = p2->y;
   p2->y = t;
  }
  break;
 }
}


compile

original_code:
Prog*
compile(Regexp *r)
{
 int n;
 Prog *p;
 n = count(r) + 1;
 p = mal(sizeof *p + n*sizeof p->start[0]);
 p->start = (Inst*)(p+1);
 pc = p->start;
 emit(r);
 pc->opcode = Match;
 pc++;
 p->len = pc - p->start;
 return p;
}

canonical_original_code:
struct Prog *compile(struct Regexp *r)
{
 int n;
 struct Prog *p;
 n = count(r) + 1;
 p = mal(sizeof *p + n*sizeof p->start[0]);
 p->start = (struct Inst *)(p+1);
 pc = p->start;
 emit(r);
 pc->opcode = Match;
 pc++;
 p->len = pc - p->start;
 return p;
}

return_type: struct Prog { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *start; int len; } *


printprog

decompiled_code:
int __fastcall printprog(__int64 a1)
{
unsigned __int64 v1; // rbx
int result; // eax
unsigned __int64 v3; // r13

v1 = *(_QWORD *)a1;
result = 5 * *(_DWORD *)(a1 + 8);
v3 = *(_QWORD *)a1 + 40LL * *(int *)(a1 + 8);
if ( *(_QWORD *)a1 < v3 )
{
do
{
switch ( *(_DWORD *)v1 )
{
case 1:
result = printf(
"%2d. char %c\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
*(unsigned int *)(v1 + 4));
break;
case 2:
result = printf("%2d. match\n", 0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3));
break;
case 3:
result = printf(
"%2d. jmp %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 16) - *(_QWORD *)a1) >> 3));
break;
case 4:
goto LABEL_4;
case 5:
result = printf("%2d. any\n", 0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3));
break;
case 6:
result = printf(
"%2d. save %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
*(unsigned int *)(v1 + 8));
break;
default:
fatal("printprog");
LABEL_4:
result = printf(
"%2d. split %d, %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 16) - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 24) - *(_QWORD *)a1) >> 3));
break;
}
v1 += 40LL;
}
while ( v3 > v1 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
unsigned __int64 v1; // rbx
int result; // eax
unsigned __int64 v3; // r13

v1 = *(_QWORD *)a1;
result = 5 * *(_DWORD *)(a1 + 8);
v3 = *(_QWORD *)a1 + 40LL * *(int *)(a1 + 8);
if ( *(_QWORD *)a1 < v3 )
{
do
{
switch ( *(_DWORD *)v1 )
{
case 1:
result = printf(
"%2d. char %c\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
*(unsigned int *)(v1 + 4));
break;
case 2:
result = printf("%2d. match\n", 0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3));
break;
case 3:
result = printf(
"%2d. jmp %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 16) - *(_QWORD *)a1) >> 3));
break;
case 4:
goto LABEL_4;
case 5:
result = printf("%2d. any\n", 0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3));
break;
case 6:
result = printf(
"%2d. save %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
*(unsigned int *)(v1 + 8));
break;
default:
fatal("printprog");
LABEL_4:
result = printf(
"%2d. split %d, %d\n",
0xCCCCCCCCCCCCCCCDLL * ((__int64)(v1 - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 16) - *(_QWORD *)a1) >> 3),
0xCCCCCCCCCCCCCCCDLL * ((__int64)(*(_QWORD *)(v1 + 24) - *(_QWORD *)a1) >> 3));
break;
}
v1 += 40LL;
}
while ( v3 > v1 );
}
return result;
}

original_code:
void
printprog(Prog *p)
{
 Inst *pc, *e;
 pc = p->start;
 e = p->start + p->len;
 for(; pc < e; pc++) {
  switch(pc->opcode) {
  default:
   fatal("printprog");
  case Split:
   printf("%2d. split %d, %d\n", (int)(pc-p->start), (int)(pc->x-p->start), (int)(pc->y-p->start));
   break;
  case Jmp:
   printf("%2d. jmp %d\n", (int)(pc-p->start), (int)(pc->x-p->start));
   break;
  case Char:
   printf("%2d. char %c\n", (int)(pc-p->start), pc->c);
   break;
  case Any:
   printf("%2d. any\n", (int)(pc-p->start));
   break;
  case Match:
   printf("%2d. match\n", (int)(pc-p->start));
   break;
  case Save:
   printf("%2d. save %d\n", (int)(pc-p->start), pc->n);
  }
 }
}

canonical_original_code:
void printprog(struct Prog *p)
{
 struct Inst *pc; struct Inst *e;
 pc = p->start;
 e = p->start + p->len;
 for(; pc < e; pc++) {
  switch(pc->opcode) {
  default:
   fatal("printprog");
  case Split:
   printf("%2d. split %d, %d\n", (int)(pc-p->start), (int)(pc->x-p->start), (int)(pc->y-p->start));
   break;
  case Jmp:
   printf("%2d. jmp %d\n", (int)(pc-p->start), (int)(pc->x-p->start));
   break;
  case Char:
   printf("%2d. char %c\n", (int)(pc-p->start), pc->c);
   break;
  case Any:
   printf("%2d. any\n", (int)(pc-p->start));
   break;
  case Match:
   printf("%2d. match\n", (int)(pc-p->start));
   break;
  case Save:
   printf("%2d. save %d\n", (int)(pc-p->start), pc->n);
  }
 }
}


threadlist

decompiled_code:
__int64 __fastcall threadlist(int a1)
{
return mal((unsigned int)(8 * a1 + 16));
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1)
{
return mal((unsigned int)(8 * a1 + 16));
}

original_code:
static ThreadList*
threadlist(int n)
{
 return mal(sizeof(ThreadList)+n*sizeof(Thread));
}

canonical_original_code:
static struct ThreadList *threadlist(int n)
{
 return mal(sizeof(ThreadList)+n*sizeof(Thread));
}

return_type: struct ThreadList { int n; struct Thread { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *pc; struct Sub { int ref; int nsub; char *sub[-1]; } *sub; } t[1]; } *

user_defined_types: struct ThreadList { int n; struct Thread t[1]; }

user_defined_types: struct Thread { struct Inst *pc; struct Sub *sub; }


thompsonvm

original_code:
int
thompsonvm(Prog *prog, char *input, char **subp, int nsubp)
{
 int i, len, matched;
 ThreadList *clist, *nlist, *tmp;
 Inst *pc;
 char *sp;
 for(i=0; i<nsubp; i++)
  subp[i] = ((void*)0);
 len = prog->len;
 clist = threadlist(len);
 nlist = threadlist(len);
 if(nsubp >= 1)
  subp[0] = input;
 gen++;
 addthread(clist, thread(prog->start));
 matched = 0;
 for(sp=input;; sp++) {
  if(clist->n == 0)
   break;
  gen++;
  for(i=0; i<clist->n; i++) {
   pc = clist->t[i].pc;
   switch(pc->opcode) {
   case Char:
    if(*sp != pc->c)
     break;
   case Any:
    if(*sp == 0)
     break;
    addthread(nlist, thread(pc+1));
    break;
   case Match:
    if(nsubp >= 2)
     subp[1] = sp;
    matched = 1;
    goto BreakFor;
   }
  }
 BreakFor:
  tmp = clist;
  clist = nlist;
  nlist = tmp;
  nlist->n = 0;
  if(*sp == '\0')
   break;
 }
 return matched;
}

canonical_original_code:
int thompsonvm(struct Prog *prog, char *input, char **subp, int nsubp)
{
 int i; int len; int matched;
 struct ThreadList *clist; struct ThreadList *nlist; struct ThreadList *tmp;
 struct Inst *pc;
 char *sp;
 for(i=0; i<nsubp; i++)
  subp[i] = ((void *)0);
 len = prog->len;
 clist = threadlist(len);
 nlist = threadlist(len);
 if(nsubp >= 1)
  subp[0] = input;
 gen++;
 addthread(clist, thread(prog->start));
 matched = 0;
 for(sp=input;; sp++) {
  if(clist->n == 0)
   break;
  gen++;
  for(i=0; i<clist->n; i++) {
   pc = clist->t[i].pc;
   switch(pc->opcode) {
   case Char:
    if(*sp != pc->c)
     break;
   case Any:
    if(*sp == 0)
     break;
    addthread(nlist, thread(pc+1));
    break;
   case Match:
    if(nsubp >= 2)
     subp[1] = sp;
    matched = 1;
    goto BreakFor;
   }
  }
 BreakFor:
  tmp = clist;
  clist = nlist;
  nlist = tmp;
  nlist->n = 0;
  if(*sp == '\0')
   break;
 }
 return matched;
}

variable_types: i int

variable_types: len int

variable_types: matched int

variable_types: struct ThreadList { int n; struct Thread { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *pc; } t[1]; } *


update

original_code:
Sub*
update(Sub *s, int i, char *p)
{
 Sub *s1;
 int j;
 if(s->ref > 1) {
  s1 = newsub(s->nsub);
  for(j=0; j<s->nsub; j++)
   s1->sub[j] = s->sub[j];
  s->ref--;
  s = s1;
 }
 s->sub[i] = p;
 return s;
}

canonical_original_code:
struct Sub *update(struct Sub *s, int i, char *p)
{
 struct Sub *s1;
 int j;
 if(s->ref > 1) {
  s1 = newsub(s->nsub);
  for(j=0; j<s->nsub; j++)
   s1->sub[j] = s->sub[j];
  s->ref--;
  s = s1;
 }
 s->sub[i] = p;
 return s;
}

variable_types:
s
struct Sub *

variable_types:
p
char *

variable_types: struct Sub { int ref; int nsub; char *sub[-1]; } *

variable_types: j int


decref

decompiled_code:
__int64 __fastcall decref(__int64 a1)
{
bool v1; // zf
__int64 result; // rax

v1 = *(_DWORD *)a1 == 1;
result = (unsigned int)(*(_DWORD *)a1 - 1);
*(_DWORD *)a1 = result;
if ( v1 )
{
result = freesub;
*(_QWORD *)(a1 + 8) = freesub;
freesub = a1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
bool v1; // zf
__int64 result; // rax

v1 = *(_DWORD *)a1 == 1;
result = (unsigned int)(*(_DWORD *)a1 - 1);
*(_DWORD *)a1 = result;
if ( v1 )
{
result = freesub;
*(_QWORD *)(a1 + 8) = freesub;
freesub = a1;
}
return result;
}

original_code:
void
decref(Sub *s)
{
 if(--s->ref == 0) {
  s->sub[0] = (char*)freesub;
  freesub = s;
 }
}

canonical_original_code:
void decref(struct Sub *s)
{
 if(--s->ref == 0) {
  s->sub[0] = (char *)freesub;
  freesub = s;
 }
}

user_defined_types: struct Sub { int ref; int nsub; char *sub[-1]; }


threadlist

decompiled_code:
__int64 __fastcall threadlist(int a1)
{
return mal((unsigned int)(16 * a1 + 24));
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
return mal((unsigned int)(16 * a1 + 24));
}

variable_types: n int


pikevm

original_code:
int
pikevm(Prog *prog, char *input, char **subp, int nsubp)
{
 int i, len;
 ThreadList *clist, *nlist, *tmp;
 Inst *pc;
 char *sp;
 Sub *sub, *matched;
 matched = ((void*)0);
 for(i=0; i<nsubp; i++)
  subp[i] = ((void*)0);
 sub = newsub(nsubp);
 for(i=0; i<nsubp; i++)
  sub->sub[i] = ((void*)0);
 len = prog->len;
 clist = threadlist(len);
 nlist = threadlist(len);
 gen++;
 addthread(clist, thread(prog->start, sub), input);
 matched = 0;
 for(sp=input;; sp++) {
  if(clist->n == 0)
   break;
  gen++;
  for(i=0; i<clist->n; i++) {
   pc = clist->t[i].pc;
   sub = clist->t[i].sub;
   switch(pc->opcode) {
   case Char:
    if(*sp != pc->c) {
     decref(sub);
     break;
    }
   case Any:
    if(*sp == 0) {
     decref(sub);
     break;
    }
    addthread(nlist, thread(pc+1, sub), sp+1);
    break;
   case Match:
    if(matched)
     decref(matched);
    matched = sub;
    for(i++; i < clist->n; i++)
     decref(clist->t[i].sub);
    goto BreakFor;
   }
  }
 BreakFor:
  tmp = clist;
  clist = nlist;
  nlist = tmp;
  nlist->n = 0;
  if(*sp == '\0')
   break;
 }
 if(matched) {
  for(i=0; i<nsubp; i++)
   subp[i] = matched->sub[i];
  decref(matched);
  return 1;
 }
 return 0;
}

canonical_original_code:
int pikevm(struct Prog *prog, char *input, char **subp, int nsubp)
{
 int i; int len;
 struct ThreadList *clist; struct ThreadList *nlist; struct ThreadList *tmp;
 struct Inst *pc;
 char *sp;
 struct Sub *sub; struct Sub *matched;
 matched = ((void *)0);
 for(i=0; i<nsubp; i++)
  subp[i] = ((void *)0);
 sub = newsub(nsubp);
 for(i=0; i<nsubp; i++)
  sub->sub[i] = ((void *)0);
 len = prog->len;
 clist = threadlist(len);
 nlist = threadlist(len);
 gen++;
 addthread(clist, thread(prog->start, sub), input);
 matched = 0;
 for(sp=input;; sp++) {
  if(clist->n == 0)
   break;
  gen++;
  for(i=0; i<clist->n; i++) {
   pc = clist->t[i].pc;
   sub = clist->t[i].sub;
   switch(pc->opcode) {
   case Char:
    if(*sp != pc->c) {
     decref(sub);
     break;
    }
   case Any:
    if(*sp == 0) {
     decref(sub);
     break;
    }
    addthread(nlist, thread(pc+1, sub), sp+1);
    break;
   case Match:
    if(matched)
     decref(matched);
    matched = sub;
    for(i++; i < clist->n; i++)
     decref(clist->t[i].sub);
    goto BreakFor;
   }
  }
 BreakFor:
  tmp = clist;
  clist = nlist;
  nlist = tmp;
  nlist->n = 0;
  if(*sp == '\0')
   break;
 }
 if(matched) {
  for(i=0; i<nsubp; i++)
   subp[i] = matched->sub[i];
  decref(matched);
  return 1;
 }
 return 0;
}

variable_types: struct ThreadList { int n; struct Thread { struct Inst { int opcode; int c; int n; struct Inst *x; struct Inst *y; int gen; } *pc; struct Sub { int ref; int nsub; char *sub[-1]; } *sub; } t[1]; } *