spiInit

decompiled_code:
__int64 spiInit()
{
int v0; // eax
__int64 result; // rax
unsigned int v2; // ebx
const char *v3; // rax
const char *v4; // rax
const char *v5; // rax

ftdi_init(&ftdic);
v0 = ftdi_usb_open(&ftdic, 1027LL, 53240LL);
if ( v0 < 0 )
{
v2 = v0;
v3 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", v2, v3);
result = 0xFFFFFFFFLL;
}
else if ( (int)ftdi_set_interface(&ftdic, 1LL) < 0 )
{
v4 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "Unable to setup the A channel: %s\n", v4);
result = 0xFFFFFFFFLL;
}
else if ( (int)ftdi_set_bitmode(&ftdic, 0LL, 2LL) < 0 )
{
v5 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "Unable to set the channel in MPSSE mode: %s\n", v5);
result = 0xFFFFFFFFLL;
}
else
{
OE = 1;
dword_4A4 = 1;
buffer = 0x80;
word_4C1 = 6937;
LODWORD(qword_4C3) = -2045050750;
WORD2(qword_4C3) = 4;
result = ftdiSendBuffer((__int64)&buffer, 9u);
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
int v0; // eax
__int64 result; // rax
unsigned int v2; // ebx
const char *v3; // rax
const char *v4; // rax
const char *v5; // rax

ftdi_init(&ftdic);
v0 = ftdi_usb_open(&ftdic, 1027LL, 53240LL);
if ( v0 < 0 )
{
v2 = v0;
v3 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", v2, v3);
result = 0xFFFFFFFFLL;
}
else if ( (int)ftdi_set_interface(&ftdic, 1LL) < 0 )
{
v4 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "Unable to setup the A channel: %s\n", v4);
result = 0xFFFFFFFFLL;
}
else if ( (int)ftdi_set_bitmode(&ftdic, 0LL, 2LL) < 0 )
{
v5 = (const char *)ftdi_get_error_string(&ftdic);
fprintf(stderr, "Unable to set the channel in MPSSE mode: %s\n", v5);
result = 0xFFFFFFFFLL;
}
else
{
OE = 1;
dword_4A4 = 1;
buffer = 0x80;
word_4C1 = 6937;
LODWORD(qword_4C3) = -2045050750;
WORD2(qword_4C3) = 4;
result = func0((__int64)&buffer, 9u);
}
return result;
}

original_code:
int spiInit()
{
  int i, ret;
  ftdi_init(&ftdic);
  if((ret = ftdi_usb_open(&ftdic, 0x0403, 0xcff8)) < 0)
  {
    fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret,
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  if (ftdi_set_interface(&ftdic, INTERFACE_A)<0)
  {
    fprintf(stderr, "Unable to setup the A channel: %s\n",
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  if (ftdi_set_bitmode(&ftdic, 0, BITMODE_MPSSE)<0)
  {
    fprintf(stderr, "Unable to set the channel in MPSSE mode: %s\n",
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  OE=1;
  CS=1;
  i=0;
  buffer[i++] = 0x80;
  buffer[i++] = 0x19;
  buffer[i++] = 0x1B;
  buffer[i++] = 0x82;
  buffer[i++] = 0x00;
  buffer[i++] = 0x1B;
  buffer[i++] = 0x86;
  buffer[i++] = 0x04;
  buffer[i++] = 0;
  return ftdiSendBuffer(buffer, i);
}

canonical_original_code:
int spiInit()
{
  int i; int ret;
  ftdi_init(&ftdic);
  if((ret = ftdi_usb_open(&ftdic, 0x0403, 0xcff8)) < 0)
  {
    fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret,
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  if (ftdi_set_interface(&ftdic, INTERFACE_A)<0)
  {
    fprintf(stderr, "Unable to setup the A channel: %s\n",
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  if (ftdi_set_bitmode(&ftdic, 0, BITMODE_MPSSE)<0)
  {
    fprintf(stderr, "Unable to set the channel in MPSSE mode: %s\n",
            ftdi_get_error_string(&ftdic));
    return -1;
  }
  OE=1;
  CS=1;
  i=0;
  buffer[i++] = 0x80;
  buffer[i++] = 0x19;
  buffer[i++] = 0x1B;
  buffer[i++] = 0x82;
  buffer[i++] = 0x00;
  buffer[i++] = 0x1B;
  buffer[i++] = 0x86;
  buffer[i++] = 0x04;
  buffer[i++] = 0;
  return ftdiSendBuffer(buffer, i);
}


spiSetResetProg

repo: bitcraze/crazyradio-firmware

decompiled_code:
__int64 __fastcall spiSetResetProg(int a1, int a2)
{
if ( a1 )
LOBYTE(a1) = 2;
if ( a2 )
LOBYTE(a1) = a1 | 1;
buffer = -126;
LOBYTE(word_4C1) = a1;
HIBYTE(word_4C1) = 15;
return ftdiSendBuffer((__int64)&buffer, 3u);
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1, int a2)
{
if ( a1 )
LOBYTE(a1) = 2;
if ( a2 )
LOBYTE(a1) = a1 | 1;
buffer = -126;
LOBYTE(word_4C1) = a1;
HIBYTE(word_4C1) = 15;
return func0((__int64)&buffer, 3u);
}

original_code:
int spiSetResetProg(int reset, int prog)
{
  int i=0;
  int value=0;
  if (reset) value |= 0x02;
  if (prog) value |= 0x01;
  buffer[i++] = 0x82;
  buffer[i++] = value;
  buffer[i++] = 0x0F;
  return ftdiSendBuffer(buffer, i);
}

canonical_original_code:
int spiSetResetProg(int reset, int prog)
{
  int i = 0;
  int value = 0;
  if (reset) value |= 0x02;
  if (prog) value |= 0x01;
  buffer[i++] = 0x82;
  buffer[i++] = value;
  buffer[i++] = 0x0F;
  return ftdiSendBuffer(buffer, i);
}

variable_types: reset int

variable_types: prog int

variable_types: i int

variable_types: value int

return_type: int


spiSetSpiOE

decompiled_code:
__int64 __fastcall spiSetSpiOE(int a1)
{
char v1; // al

OE = a1;
v1 = dword_4A4;
if ( dword_4A4 )
v1 = 8;
if ( a1 )
v1 |= 0x10u;
buffer = 0x80;
LOBYTE(word_4C1) = v1;
HIBYTE(word_4C1) = 27;
return ftdiSendBuffer((__int64)&buffer, 3u);
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1)
{
char v1; // al

OE = a1;
v1 = dword_4A4;
if ( dword_4A4 )
v1 = 8;
if ( a1 )
v1 |= 0x10u;
buffer = 0x80;
LOBYTE(word_4C1) = v1;
HIBYTE(word_4C1) = 27;
return func0((__int64)&buffer, 3u);
}

original_code:
int spiSetSpiOE(int oe) {
  int i=0;
  int value=0x00;
  OE=oe;
  if (CS) value |= 0x08;
  if (OE) value |= 0x10;
  buffer[i++] = 0x80;
  buffer[i++] = value;
  buffer[i++] = 0x1B;
  return ftdiSendBuffer(buffer, i);
}

canonical_original_code:
int spiSetSpiOE(int oe) {
  int i = 0;
  int value = 0x00;
  OE=oe;
  if (CS) value |= 0x08;
  if (OE) value |= 0x10;
  buffer[i++] = 0x80;
  buffer[i++] = value;
  buffer[i++] = 0x1B;
  return ftdiSendBuffer(buffer, i);
}

variable_types: oe int


spiSetCS

decompiled_code:
__int64 __fastcall spiSetCS(int a1)
{
dword_4A4 = a1;
if ( a1 )
LOBYTE(a1) = 8;
if ( OE )
LOBYTE(a1) = a1 | 0x10;
buffer = 0x80;
LOBYTE(word_4C1) = a1;
HIBYTE(word_4C1) = 27;
return ftdiSendBuffer((__int64)&buffer, 3u);
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1)
{
dword_4A4 = a1;
if ( a1 )
LOBYTE(a1) = 8;
if ( OE )
LOBYTE(a1) = a1 | 0x10;
buffer = 0x80;
LOBYTE(word_4C1) = a1;
HIBYTE(word_4C1) = 27;
return func0((__int64)&buffer, 3u);
}

original_code:
int spiSetCS(int cs)
{
  int i=0;
  int value=0x00;
  CS=cs;
  if (CS) value |= 0x08;
  if (OE) value |= 0x10;
  buffer[i++] = 0x80;
  buffer[i++] = value;
  buffer[i++] = 0x1B;
  return ftdiSendBuffer(buffer, i);
}

canonical_original_code:
int spiSetCS(int cs)
{
  int i = 0;
  int value = 0x00;
  CS=cs;
  if (CS) value |= 0x08;
  if (OE) value |= 0x10;
  buffer[i++] = 0x80;
  buffer[i++] = value;
  buffer[i++] = 0x1B;
  return ftdiSendBuffer(buffer, i);
}

variable_types: cs int


spiDeinit

decompiled_code:
__int64 spiDeinit()
{
ftdi_usb_close(&ftdic);
return ftdi_deinit(&ftdic);
}

canonical_decompiled_code:
__int64 func6()
{
ftdi_usb_close(&ftdic);
return ftdi_deinit(&ftdic);
}

original_code:
void spiDeinit()
{
  ftdi_usb_close(&ftdic);
  ftdi_deinit(&ftdic);
}

return_type: void


spiSend

decompiled_code:
__int64 __fastcall spiSend(__int64 *a1, unsigned int a2)
{
unsigned int v2; // ecx

if ( (int)a2 <= 0 )
return 0LL;
if ( (int)a2 > 128 )
{
fwrite("Unable to send more than 128 bytes!\n", 1uLL, 0x24uLL, stderr);
v2 = -1;
}
else
{
buffer = 17;
word_4C1 = (unsigned __int8)(a2 - 1);
if ( a2 >= 8 )
{
qword_4C3 = *a1;
*(_QWORD *)((char *)&unk_4BB + a2) = *(__int64 *)((char *)a1 + a2 - 8);
qmemcpy(
(void *)((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL),
(const void *)((char *)a1 - ((char *)&qword_4C3 - ((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL))),
8LL
* ((a2 + (unsigned int)((unsigned int)&qword_4C3 - ((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL))) >> 3));
}
else if ( (a2 & 4) != 0 )
{
LODWORD(qword_4C3) = *(_DWORD *)a1;
*(_DWORD *)((char *)&unk_4BF + a2) = *(_DWORD *)((char *)a1 + a2 - 4);
}
else
{
LOBYTE(qword_4C3) = *(_BYTE *)a1;
if ( (a2 & 2) != 0 )
*(__int16 *)((char *)&word_4C1 + a2) = *(_WORD *)((char *)a1 + a2 - 2);
}
v2 = ftdiSendBuffer((__int64)&buffer, a2 + 3) - 3;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 *a1, unsigned int a2)
{
unsigned int v2; // ecx

if ( (int)a2 <= 0 )
return 0LL;
if ( (int)a2 > 128 )
{
fwrite("Unable to send more than 128 bytes!\n", 1uLL, 0x24uLL, stderr);
v2 = -1;
}
else
{
buffer = 17;
word_4C1 = (unsigned __int8)(a2 - 1);
if ( a2 >= 8 )
{
qword_4C3 = *a1;
*(_QWORD *)((char *)&unk_4BB + a2) = *(__int64 *)((char *)a1 + a2 - 8);
qmemcpy(
(void *)((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL),
(const void *)((char *)a1 - ((char *)&qword_4C3 - ((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL))),
8LL
* ((a2 + (unsigned int)((unsigned int)&qword_4C3 - ((unsigned __int64)&unk_4CB & 0xFFFFFFFFFFFFFFF8LL))) >> 3));
}
else if ( (a2 & 4) != 0 )
{
LODWORD(qword_4C3) = *(_DWORD *)a1;
*(_DWORD *)((char *)&unk_4BF + a2) = *(_DWORD *)((char *)a1 + a2 - 4);
}
else
{
LOBYTE(qword_4C3) = *(_BYTE *)a1;
if ( (a2 & 2) != 0 )
*(__int16 *)((char *)&word_4C1 + a2) = *(_WORD *)((char *)a1 + a2 - 2);
}
v2 = func0((__int64)&buffer, a2 + 3) - 3;
}
return v2;
}

original_code:
int spiSend(char *data, int len)
{
  int i=0;
  if(len<1) return 0;
  if(len>128) {
    fprintf(stderr, "Unable to send more than 128 bytes!\n");
    return -1;
  }
  len--;
  buffer[i++] = 0x10 | 0x01;
  buffer[i++] = len&0x0FF;
  buffer[i++] = (len>>8)&0x0FF;
  memcpy(buffer+3, data, len+1);
  return ftdiSendBuffer(buffer, len+1+3)-3;
}

canonical_original_code:
int spiSend(char *data, int len)
{
  int i = 0;
  if(len<1) return 0;
  if(len>128) {
    fprintf(stderr, "Unable to send more than 128 bytes!\n");
    return -1;
  }
  len--;
  buffer[i++] = 0x10 | 0x01;
  buffer[i++] = len&0x0FF;
  buffer[i++] = (len>>8)&0x0FF;
  memcpy(buffer+3, data, len+1);
  return ftdiSendBuffer(buffer, len+1+3)-3;
}

variable_types:
data
char *

variable_types: len int


spiReceive

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

result = 0LL;
if ( a2 > 0 )
{
if ( a2 > 256 )
{
fwrite("Unable to receive more than 128 bytes!\n", 1uLL, 0x27uLL, stderr);
result = 0xFFFFFFFFLL;
}
else
{
buffer = 32;
word_4C1 = (unsigned __int8)(a2 - 1);
if ( (int)ftdiSendBuffer((__int64)&buffer, 3u) < 0 )
result = 0xFFFFFFFFLL;
else
result = ftdiRecvBuffer(a1, a2);
}
}
return result;
}

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

result = 0LL;
if ( a2 > 0 )
{
if ( a2 > 256 )
{
fwrite("Unable to receive more than 128 bytes!\n", 1uLL, 0x27uLL, stderr);
result = 0xFFFFFFFFLL;
}
else
{
buffer = 32;
word_4C1 = (unsigned __int8)(a2 - 1);
if ( (int)func0((__int64)&buffer, 3u) < 0 )
result = 0xFFFFFFFFLL;
else
result = func1(a1, a2);
}
}
return result;
}

original_code:
int spiReceive(char *data, int len)
{
  int i=0;
  if(len<1) return 0;
  if(len>256) {
    fprintf(stderr, "Unable to receive more than 128 bytes!\n");
    return -1;
  }
  len--;
  buffer[i++] = 0x20;
  buffer[i++] = len&0x0FF;
  buffer[i++] = (len>>8)&0x0FF;
  if (ftdiSendBuffer(buffer, i)<0)
    return -1;
  return ftdiRecvBuffer(data, len+1);
}

canonical_original_code:
int spiReceive(char *data, int len)
{
  int i = 0;
  if(len<1) return 0;
  if(len>256) {
    fprintf(stderr, "Unable to receive more than 128 bytes!\n");
    return -1;
  }
  len--;
  buffer[i++] = 0x20;
  buffer[i++] = len&0x0FF;
  buffer[i++] = (len>>8)&0x0FF;
  if (ftdiSendBuffer(buffer, i)<0)
    return -1;
  return ftdiRecvBuffer(data, len+1);
}


indep

decompiled_code:
__int64 __fastcall indep(__int64 a1, __int64 a2)
{
unsigned int v3; // er13
__int64 v4; // rbx
__int64 v5; // rdi

v3 = 0;
if ( !(unsigned int)((__int64 (*)(void))sametree)() )
{
v3 = 0;
if ( *(_DWORD *)(a1 + 16) )
{
v4 = 0LL;
while ( !(unsigned int)sametree(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v4), a2) )
{
v5 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v4);
if ( *(_DWORD *)(v5 + 16) && !(unsigned int)indep(v5, a2) )
return 0;
if ( *(_DWORD *)(a1 + 16) <= (unsigned int)++v4 )
return 1;
}
}
else
{
v3 = 1;
}
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
unsigned int v3; // er13
__int64 v4; // rbx
__int64 v5; // rdi

v3 = 0;
if ( !(unsigned int)((__int64 (*)(void))sametree)() )
{
v3 = 0;
if ( *(_DWORD *)(a1 + 16) )
{
v4 = 0LL;
while ( !(unsigned int)sametree(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v4), a2) )
{
v5 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v4);
if ( *(_DWORD *)(v5 + 16) && !(unsigned int)func0(v5, a2) )
return 0;
if ( *(_DWORD *)(a1 + 16) <= (unsigned int)++v4 )
return 1;
}
}
else
{
v3 = 1;
}
}
return v3;
}

original_code:
int indep(exp_tree_t *tree, exp_tree_t *key)
{
 int i;
 if(sametree(tree, key))
  return 0;
 for (i = 0; i < tree->child_count; ++i) {
  if (sametree(tree->child[i], key))
   return 0;
  if (tree->child[i]->child_count)
   if(!indep(tree->child[i], key))
    return 0;
 }
 return 1;
}

canonical_original_code:
int indep(struct exp_tree *tree, struct exp_tree *key)
{
 int i;
 if(sametree(tree, key))
  return 0;
 for (i = 0; i < tree->child_count; ++i) {
  if (sametree(tree->child[i], key))
   return 0;
  if (tree->child[i]->child_count)
   if(!indep(tree->child[i], key))
    return 0;
 }
 return 1;
}

variable_types: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } *

variable_types:
key
struct exp_tree *

user_defined_types: struct exp_tree { char head_type; struct token *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; }


decompiled_code:
__int64 __fastcall find_subtree(__int64 a1, __int64 a2)
{
int v3; // edx
__int64 result; // rax
__int64 v5; // rbx
__int64 v6; // rdi

v3 = sametree(a1, a2);
result = a1;
if ( !v3 )
{
if ( *(_DWORD *)(a1 + 16) )
{
v5 = 0LL;
do
{
if ( (unsigned int)sametree(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5), a2) )
return *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5);
v6 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5);
if ( *(_DWORD *)(v6 + 16) )
{
result = find_subtree(v6, a2);
if ( result )
return result;
}
++v5;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)v5 );
result = 0LL;
}
else
{
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
int v3; // edx
__int64 result; // rax
__int64 v5; // rbx
__int64 v6; // rdi

v3 = sametree(a1, a2);
result = a1;
if ( !v3 )
{
if ( *(_DWORD *)(a1 + 16) )
{
v5 = 0LL;
do
{
if ( (unsigned int)sametree(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5), a2) )
return *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5);
v6 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * v5);
if ( *(_DWORD *)(v6 + 16) )
{
result = func1(v6, a2);
if ( result )
return result;
}
++v5;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)v5 );
result = 0LL;
}
else
{
result = 0LL;
}
}
return result;
}

original_code:
exp_tree_t* find_subtree(exp_tree_t *tree, exp_tree_t *key)
{
 int i;
 exp_tree_t *catch;
 if(sametree(tree, key))
  return tree;
 for (i = 0; i < tree->child_count; ++i) {
  if (sametree(tree->child[i], key))
   return tree->child[i];
  if (tree->child[i]->child_count)
   if((catch = find_subtree(tree->child[i], key)) != ((void *)0))
    return catch;
 }
 return ((void *)0);
}

canonical_original_code:
struct exp_tree *find_subtree(struct exp_tree *tree, struct exp_tree *key)
{
 int i;
 struct exp_tree *catch;
 if(sametree(tree, key))
  return tree;
 for (i = 0; i < tree->child_count; ++i) {
  if (sametree(tree->child[i], key))
   return tree->child[i];
  if (tree->child[i]->child_count)
   if((catch = find_subtree(tree->child[i], key)) != ((void *)0))
    return catch;
 }
 return ((void *)0);
}

variable_types:
tree
struct exp_tree *

return_type: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } *


original_code:
int same_tokens(exp_tree_t *a, exp_tree_t *b)
{
 strncpy(buf_a, b->tok->start, b->tok->len);
 buf_a[b->tok->len] = 0;
 strncpy(buf_b, a->tok->start, a->tok->len);
 buf_b[a->tok->len] = 0;
 return !strcmp(buf_a, buf_b);
}

canonical_original_code:
int same_tokens(struct exp_tree *a, struct exp_tree *b)
{
 strncpy(buf_a, b->tok->start, b->tok->len);
 buf_a[b->tok->len] = 0;
 strncpy(buf_b, a->tok->start, a->tok->len);
 buf_b[a->tok->len] = 0;
 return !strcmp(buf_a, buf_b);
}

variable_types:
b
struct exp_tree *

user_defined_types: struct token { char type; char *start; int len; int from_line; int from_char; }


treematch

original_code:
int treematch(exp_tree_t *a, exp_tree_t *b, dict_t* d)
{
 int i;
 int id;
 if (b->head_type == VARIABLE
 || (b->head_type == MATCH_NUM && a->head_type == NUMBER)
 || (b->head_type == MATCH_VAR && a->head_type == VARIABLE)
 || (b->head_type == MATCH_NAN && a->head_type != NUMBER)
 || (b->head_type == SYMBOL && a->head_type == VARIABLE
  && same_tokens(a, b))) {
  strncpy(buf_a, b->tok->start, b->tok->len);
  buf_a[b->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   if (!sametree(d->match[id], a))
    return 0;
   return 1;
  } else {
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
   return 1;
  }
 }
 if (b->head_type == MATCH_IND_SYM) {
  if (a->head_type != VARIABLE) {
   strncpy(buf_a, b->child[0]->tok->start, b->child[0]->tok->len);
   buf_a[b->child[0]->tok->len] = 0;
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
   return 1;
  } else {
   if (same_tokens(a, b->child[1]))
    return 0;
   else {
    strncpy(buf_a, b->child[0]->tok->start, b->child[0]->tok->len);
    buf_a[b->child[0]->tok->len] = 0;
    strcpy(d->symbol[d->count], buf_a);
    d->match[d->count] = a;
    if (++d->count > d->alloc)
     expand_dict(d, d->count + 10);
    return 1;
   }
  }
 }
 if (b->head_type == MATCH_IND
  || b->head_type == MATCH_CONT
  || b->head_type == MATCH_CONTX) {
  strncpy(buf_a, b->child[1]->tok->start, b->child[1]->tok->len);
  buf_a[b->child[1]->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   if ((b->head_type == MATCH_IND
       && indep(a, d->match[id]))
   || (b->head_type == MATCH_CONT
       && !indep(a, d->match[id]))
   || (b->head_type == MATCH_CONTX
       && !indep(a, d->match[id])
       && !sametree(a, d->match[id]))) {
    strncpy(buf_a, b->child[0]->tok->start,
     b->child[0]->tok->len);
    buf_a[b->child[0]->tok->len] = 0;
    if ((id = dict_search(d, buf_a)) != -1) {
     if (!sametree(d->match[id], a))
      return 0;
     return 1;
    } else {
     strcpy(d->symbol[d->count], buf_a);
     d->match[d->count] = a;
     if (++d->count > d->alloc)
      expand_dict(d, d->count + 10);
     return 1;
    }
   }
  } else {
   printf("[forward substitution issue]\n");
   return 0;
  }
 }
 if (b->head_type == MATCH_FUNC && a->head_type == FUNC) {
  strncpy(buf_a, b->tok->start, b->tok->len);
  buf_a[b->tok->len] = 0;
  strncpy(buf_b, a->tok->start, a->tok->len);
  buf_b[a->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   strncpy(buf_c, d->match[id]->tok->start,
    d->match[id]->tok->len);
   buf_c[d->match[id]->tok->len] = 0;
   if (strcmp(buf_c, buf_b))
    return 0;
  } else {
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
  }
  if (a->child_count != b->child_count)
   return 0;
  for (i = 0; i < a->child_count; ++i) {
   if (!treematch(a->child[i], b->child[i], d))
    return 0;
  }
  return 1;
 }
 if (a->head_type != b->head_type)
  return 0;
 if (a->child_count != b->child_count)
  return 0;
 if (a->tok && b->tok) {
  strncpy(buf_a, a->tok->start, a->tok->len);
  buf_a[a->tok->len] = 0;
  strncpy(buf_b, b->tok->start, b->tok->len);
  buf_b[b->tok->len] = 0;
  if (strcmp(buf_a, buf_b))
   return 0;
 }
 for (i = 0; i < a->child_count; ++i) {
  if (!treematch(a->child[i], b->child[i], d))
   return 0;
 }
 return 1;
}

canonical_original_code:
int treematch(struct exp_tree *a, struct exp_tree *b, struct dict_s *d)
{
 int i;
 int id;
 if (b->head_type == VARIABLE
 || (b->head_type == MATCH_NUM && a->head_type == NUMBER)
 || (b->head_type == MATCH_VAR && a->head_type == VARIABLE)
 || (b->head_type == MATCH_NAN && a->head_type != NUMBER)
 || (b->head_type == SYMBOL && a->head_type == VARIABLE
  && same_tokens(a, b))) {
  strncpy(buf_a, b->tok->start, b->tok->len);
  buf_a[b->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   if (!sametree(d->match[id], a))
    return 0;
   return 1;
  } else {
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
   return 1;
  }
 }
 if (b->head_type == MATCH_IND_SYM) {
  if (a->head_type != VARIABLE) {
   strncpy(buf_a, b->child[0]->tok->start, b->child[0]->tok->len);
   buf_a[b->child[0]->tok->len] = 0;
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
   return 1;
  } else {
   if (same_tokens(a, b->child[1]))
    return 0;
   else {
    strncpy(buf_a, b->child[0]->tok->start, b->child[0]->tok->len);
    buf_a[b->child[0]->tok->len] = 0;
    strcpy(d->symbol[d->count], buf_a);
    d->match[d->count] = a;
    if (++d->count > d->alloc)
     expand_dict(d, d->count + 10);
    return 1;
   }
  }
 }
 if (b->head_type == MATCH_IND
  || b->head_type == MATCH_CONT
  || b->head_type == MATCH_CONTX) {
  strncpy(buf_a, b->child[1]->tok->start, b->child[1]->tok->len);
  buf_a[b->child[1]->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   if ((b->head_type == MATCH_IND
       && indep(a, d->match[id]))
   || (b->head_type == MATCH_CONT
       && !indep(a, d->match[id]))
   || (b->head_type == MATCH_CONTX
       && !indep(a, d->match[id])
       && !sametree(a, d->match[id]))) {
    strncpy(buf_a, b->child[0]->tok->start,
     b->child[0]->tok->len);
    buf_a[b->child[0]->tok->len] = 0;
    if ((id = dict_search(d, buf_a)) != -1) {
     if (!sametree(d->match[id], a))
      return 0;
     return 1;
    } else {
     strcpy(d->symbol[d->count], buf_a);
     d->match[d->count] = a;
     if (++d->count > d->alloc)
      expand_dict(d, d->count + 10);
     return 1;
    }
   }
  } else {
   printf("[forward substitution issue]\n");
   return 0;
  }
 }
 if (b->head_type == MATCH_FUNC && a->head_type == FUNC) {
  strncpy(buf_a, b->tok->start, b->tok->len);
  buf_a[b->tok->len] = 0;
  strncpy(buf_b, a->tok->start, a->tok->len);
  buf_b[a->tok->len] = 0;
  if ((id = dict_search(d, buf_a)) != -1) {
   strncpy(buf_c, d->match[id]->tok->start,
    d->match[id]->tok->len);
   buf_c[d->match[id]->tok->len] = 0;
   if (strcmp(buf_c, buf_b))
    return 0;
  } else {
   strcpy(d->symbol[d->count], buf_a);
   d->match[d->count] = a;
   if (++d->count > d->alloc)
    expand_dict(d, d->count + 10);
  }
  if (a->child_count != b->child_count)
   return 0;
  for (i = 0; i < a->child_count; ++i) {
   if (!treematch(a->child[i], b->child[i], d))
    return 0;
  }
  return 1;
 }
 if (a->head_type != b->head_type)
  return 0;
 if (a->child_count != b->child_count)
  return 0;
 if (a->tok && b->tok) {
  strncpy(buf_a, a->tok->start, a->tok->len);
  buf_a[a->tok->len] = 0;
  strncpy(buf_b, b->tok->start, b->tok->len);
  buf_b[b->tok->len] = 0;
  if (strcmp(buf_a, buf_b))
   return 0;
 }
 for (i = 0; i < a->child_count; ++i) {
  if (!treematch(a->child[i], b->child[i], d))
   return 0;
 }
 return 1;
}

variable_types: struct dict_s { char **symbol; struct exp_tree **match; int count; int alloc; int success; } *

variable_types: id int


matchloop

original_code:
int matchloop(exp_tree_t** rules, int rc, exp_tree_t* tree)
{
 dict_t *dict;
 exp_tree_t *skel;
 int i;
 int mc;
 int m = 0;
 do {
  mc = 0;
  dict = new_dict();
  for (i = 0; i < rc; ++i) {
   if (dict->count)
    dict->count = 0;
   if (treematch(tree, rules[i]->child[0], dict)) {
    ++mc;
    m = 1;
    if (dict->count) {
     skel = copy_tree(rules[i]->child[1]);
     subst(skel, dict, &skel);
     *tree = *skel;
    } else {
     *tree = *copy_tree(rules[i]->child[1]);
    }
    break;
   }
  }
 } while (mc);
 for (i = 0; i < tree->child_count; ++i)
  if (matchloop(rules, rc, tree->child[i])) {
   m = 1;
  }
 return m;
}

canonical_original_code:
int matchloop(struct exp_tree **rules, int rc, struct exp_tree *tree)
{
 struct dict_s *dict;
 struct exp_tree *skel;
 int i;
 int mc;
 int m = 0;
 do {
  mc = 0;
  dict = new_dict();
  for (i = 0; i < rc; ++i) {
   if (dict->count)
    dict->count = 0;
   if (treematch(tree, rules[i]->child[0], dict)) {
    ++mc;
    m = 1;
    if (dict->count) {
     skel = copy_tree(rules[i]->child[1]);
     subst(skel, dict, &skel);
     *tree = *skel;
    } else {
     *tree = *copy_tree(rules[i]->child[1]);
    }
    break;
   }
  }
 } while (mc);
 for (i = 0; i < tree->child_count; ++i)
  if (matchloop(rules, rc, tree->child[i])) {
   m = 1;
  }
 return m;
}

variable_types: rc int

variable_types: struct dict_s { char **symbol; struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } **match; int count; int alloc; int success; } *

variable_types: mc int

variable_types: m int

user_defined_types: struct dict_s { char **symbol; struct exp_tree **match; int count; int alloc; int success; }


norm

original_code:
int norm(exp_tree_t *et)
{
 int i = 0;
 int j = 0;
 if (et->child_count == 0) {
  return 1;
 } else {
  for (i = 0; i < et->child_count; ++i) {
   j += norm(et->child[i]);
  }
  return j;
 }
}

canonical_original_code:
int norm(struct exp_tree *et)
{
 int i = 0;
 int j = 0;
 if (et->child_count == 0) {
  return 1;
 } else {
  for (i = 0; i < et->child_count; ++i) {
   j += norm(et->child[i]);
  }
  return j;
 }
}

variable_types: j int


decompiled_code:
__int64 __fastcall check_incomplete(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx

if ( *(_BYTE *)a1 != 30
|| (v4 = *(_QWORD *)(a1 + 8), result = *(unsigned int *)(v4 + 16), (_DWORD)result != 1)
|| **(_BYTE **)(v4 + 8) != 68 )
{
result = *(unsigned int *)(a1 + 16);
if ( (_DWORD)result )
{
v2 = *(_QWORD **)(a1 + 24);
v3 = (__int64)&v2[(unsigned int)(result - 1) + 1];
while ( 1 )
{
result = check_incomplete(*v2);
if ( (_DWORD)result )
break;
if ( (_QWORD *)v3 == ++v2 )
return result;
}
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx

if ( *(_BYTE *)a1 != 30
|| (v4 = *(_QWORD *)(a1 + 8), result = *(unsigned int *)(v4 + 16), (_DWORD)result != 1)
|| **(_BYTE **)(v4 + 8) != 68 )
{
result = *(unsigned int *)(a1 + 16);
if ( (_DWORD)result )
{
v2 = *(_QWORD **)(a1 + 24);
v3 = (__int64)&v2[(unsigned int)(result - 1) + 1];
while ( 1 )
{
result = func1(*v2);
if ( (_DWORD)result )
break;
if ( (_QWORD *)v3 == ++v2 )
return result;
}
result = 1LL;
}
}
return result;
}

original_code:
int check_incomplete(exp_tree_t *et)
{
 int i = 0;
 if (et->head_type == FUNC
      && et->tok->len == 1
      && et->tok->start[0] == 'D')
  return 1;
 for (i = 0; i < et->child_count; ++i)
  if (check_incomplete(et->child[i]))
   return 1;
 return 0;
}

canonical_original_code:
int check_incomplete(struct exp_tree *et)
{
 int i = 0;
 if (et->head_type == FUNC
      && et->tok->len == 1
      && et->tok->start[0] == 'D')
  return 1;
 for (i = 0; i < et->child_count; ++i)
  if (check_incomplete(et->child[i]))
   return 1;
 return 0;
}

variable_types: i int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
unsigned int v4; // ebp
__int64 i; // r12
struct _IO_FILE *v6; // rdi
__int64 v7; // rdx
__int64 v8; // rcx
__int64 v9; // rdx
__int64 v10; // r13
__int64 v11; // rsi
__int64 v12; // rdx
__int64 v13; // rcx
const __m128i *v14; // rax
__int64 v15; // rsi
int j; // er15
__int64 v17; // rdx
__int64 v18; // rcx
int v19; // er12
__int64 v21; // [rsp+8h] [rbp-C80h]
char v22[24]; // [rsp+10h] [rbp-C78h] BYREF
const __m128i **v23; // [rsp+28h] [rbp-C60h]
char s[1024]; // [rsp+30h] [rbp-C58h] BYREF
char v25[1024]; // [rsp+430h] [rbp-858h] BYREF
__int64 v26[128]; // [rsp+830h] [rbp-458h] BYREF
__int128 v27[5]; // [rsp+C30h] [rbp-58h] BYREF

v21 = new_gca(argc, argv, envp);
cgc_set(v21);
setup_tokenizer();
v3 = readrules(v26, "rules");
v4 = readrules(v25, "pres-rules");
puts("\n-------------------------------------------------------");
puts("Welcome to SYMDIFF, a program trained to compute ");
puts("symbolic derivatives. You may enter requests such as: \n");
puts("\t diff(3cos(x^2)^3 + x^x, x)\n");
puts("and quickly obtain the symbolic result.");
puts("(This code was speed-tuned on an ancient 400 MHz machine.)");
puts("\nYou will be given a prompt. As always, you can use");
puts("CTRL-C to exit.");
putchar(10);
puts("This is version v1.10 + epsilon");
puts("programmed by blockeduser, 2012-2016");
puts("special thanks go to knipil for fixing a parser bug and to");
puts("customers all around the world for using the software and");
puts("sending improvement requests! thank you Umair, Sebastian,");
puts("shoran, and others!");
puts("\n-------------------------------------------------------");
putchar(10);
while ( 1 )
{
printf("]=> ");
fflush(stdout);
if ( !fgets(s, 1024, stdin) )
break;
if ( s[1] )
{
if ( s[0] == 33 )
{
if ( !strcmp(s, "!sr\n") )
{
if ( v3 )
{
if ( (int)v3 <= 1 )
{
printf("%d rule%s memorized%s\n", v3, " has been", ":");
if ( (int)v3 > 0 )
goto LABEL_6;
}
else
{
printf("%d rule%s memorized%s\n", v3, "s have been", ":");
LABEL_6:
for ( i = 0LL; i != v3; ++i )
{
printf("%d: ", (unsigned int)i);
v6 = stdout;
fflush(stdout);
printout_tree(v6, (unsigned int)i, v7, v8);
putchar(10);
}
}
}
else
{
printf("%d rule%s memorized%s\n", 0LL, " has been", (const char *)&unk_54A);
}
}
}
else
{
v10 = new_gca(s, 1024LL, v9);
cgc_set(v10);
v11 = tokenize(s);
parse(v22, v11);
v14 = *v23;
v27[0] = (__int128)_mm_loadu_si128(*v23);
v27[1] = (__int128)_mm_loadu_si128(v14 + 1);
if ( LOBYTE(v27[0]) == 14 )
{
v26[v3] = alloc_exptree(v22, v11, v12, v13);
puts("Rule stored.");
++v3;
}
else if ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
{
while ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
;
while ( (unsigned int)unwind_expos(v27) )
;
do
v15 = v4;
while ( (unsigned int)apply_rules_and_optimize(v25, v4, v27) );
for ( j = -1; (unsigned int)check_incomplete((__int64)v27); j = v19 )
{
v19 = norm((__int64)v27);
if ( j == v19 )
break;
while ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
;
while ( (unsigned int)unwind_expos(v27) )
;
do
v15 = v4;
while ( (unsigned int)apply_rules_and_optimize(v25, v4, v27) );
}
printout_tree_infix(v27, v15, v17, v18);
putchar(10);
}
gca_cleanup(v10);
}
}
}
putchar(10);
gca_cleanup(v21);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
unsigned int v4; // ebp
__int64 i; // r12
struct _IO_FILE *v6; // rdi
__int64 v7; // rdx
__int64 v8; // rcx
__int64 v9; // rdx
__int64 v10; // r13
__int64 v11; // rsi
__int64 v12; // rdx
__int64 v13; // rcx
const __m128i *v14; // rax
__int64 v15; // rsi
int j; // er15
__int64 v17; // rdx
__int64 v18; // rcx
int v19; // er12
__int64 v21; // [rsp+8h] [rbp-C80h]
char v22[24]; // [rsp+10h] [rbp-C78h] BYREF
const __m128i **v23; // [rsp+28h] [rbp-C60h]
char s[1024]; // [rsp+30h] [rbp-C58h] BYREF
char v25[1024]; // [rsp+430h] [rbp-858h] BYREF
__int64 v26[128]; // [rsp+830h] [rbp-458h] BYREF
__int128 v27[5]; // [rsp+C30h] [rbp-58h] BYREF

v21 = new_gca(argc, argv, envp);
cgc_set(v21);
setup_tokenizer();
v3 = readrules(v26, "rules");
v4 = readrules(v25, "pres-rules");
puts("\n-------------------------------------------------------");
puts("Welcome to SYMDIFF, a program trained to compute ");
puts("symbolic derivatives. You may enter requests such as: \n");
puts("\t diff(3cos(x^2)^3 + x^x, x)\n");
puts("and quickly obtain the symbolic result.");
puts("(This code was speed-tuned on an ancient 400 MHz machine.)");
puts("\nYou will be given a prompt. As always, you can use");
puts("CTRL-C to exit.");
putchar(10);
puts("This is version v1.10 + epsilon");
puts("programmed by blockeduser, 2012-2016");
puts("special thanks go to knipil for fixing a parser bug and to");
puts("customers all around the world for using the software and");
puts("sending improvement requests! thank you Umair, Sebastian,");
puts("shoran, and others!");
puts("\n-------------------------------------------------------");
putchar(10);
while ( 1 )
{
printf("]=> ");
fflush(stdout);
if ( !fgets(s, 1024, stdin) )
break;
if ( s[1] )
{
if ( s[0] == 33 )
{
if ( !strcmp(s, "!sr\n") )
{
if ( v3 )
{
if ( (int)v3 <= 1 )
{
printf("%d rule%s memorized%s\n", v3, " has been", ":");
if ( (int)v3 > 0 )
goto LABEL_6;
}
else
{
printf("%d rule%s memorized%s\n", v3, "s have been", ":");
LABEL_6:
for ( i = 0LL; i != v3; ++i )
{
printf("%d: ", (unsigned int)i);
v6 = stdout;
fflush(stdout);
printout_tree(v6, (unsigned int)i, v7, v8);
putchar(10);
}
}
}
else
{
printf("%d rule%s memorized%s\n", 0LL, " has been", (const char *)&unk_54A);
}
}
}
else
{
v10 = new_gca(s, 1024LL, v9);
cgc_set(v10);
v11 = tokenize(s);
parse(v22, v11);
v14 = *v23;
v27[0] = (__int128)_mm_loadu_si128(*v23);
v27[1] = (__int128)_mm_loadu_si128(v14 + 1);
if ( LOBYTE(v27[0]) == 14 )
{
v26[v3] = alloc_exptree(v22, v11, v12, v13);
puts("Rule stored.");
++v3;
}
else if ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
{
while ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
;
while ( (unsigned int)unwind_expos(v27) )
;
do
v15 = v4;
while ( (unsigned int)apply_rules_and_optimize(v25, v4, v27) );
for ( j = -1; (unsigned int)func1((__int64)v27); j = v19 )
{
v19 = func0((__int64)v27);
if ( j == v19 )
break;
while ( (unsigned int)apply_rules_and_optimize(v26, v3, v27) )
;
while ( (unsigned int)unwind_expos(v27) )
;
do
v15 = v4;
while ( (unsigned int)apply_rules_and_optimize(v25, v4, v27) );
}
printout_tree_infix(v27, v15, v17, v18);
putchar(10);
}
gca_cleanup(v10);
}
}
}
putchar(10);
gca_cleanup(v21);
return 0;
}

original_code:
int main(int argc, char** argv)
{
 token_t* tokens;
 exp_tree_t tree;
 int i;
 exp_tree_t* rules[128];
 exp_tree_t* pres_rules[128];
 int rc;
 int prc;
 char lin[1024];
 gcarray_t *setup, *iter;
 double fe_expected, fe_result, fe_error;
 int fe_run;
 double fe_eval_point = 2.0;
 int tnorm, tnorm_old;
 extern void fail(char*);
 extern int unwind_expos(exp_tree_t *et);
 cgc_set(setup = new_gca());
 setup_tokenizer();
 rc = readrules(rules, "rules");
 prc = readrules(pres_rules, "pres-rules");
  printf("\n-------------------------------------------------------\n");
  printf("Welcome to SYMDIFF, a program trained to compute \n");
  printf("symbolic derivatives. You may enter requests such as: \n\n");
  printf("\t diff(3cos(x^2)^3 + x^x, x)\n\n");
  printf("and quickly obtain the symbolic result.\n");
  printf("(This code was speed-tuned on an ancient 400 MHz machine.)\n");
  printf("\nYou will be given a prompt. As always, you can use\n");
  printf("CTRL-C to exit.\n");
  printf("\n");
  printf("This is version v1.10 + epsilon\n");
  printf("programmed by blockeduser, 2012-2016\n");
  printf("special thanks go to knipil for fixing a parser bug and to\n");
  printf("customers all around the world for using the software and\n");
  printf("sending improvement requests! thank you Umair, Sebastian,\n");
  printf("shoran, and others!\n");
  printf("\n-------------------------------------------------------\n");
  printf("\n");
 while (1) {
    printf("]=> ");
    fflush(stdout);
   if (!fgets(lin, 1024, stdin)) {
    printf("\n");
    break;
   }
  if (!lin[1])
   continue;
  if (*lin == '!') {
   if (!strcmp(lin, "!sr\n")) {
    printf("%d rule%s memorized%s\n",
     rc,
     rc > 1 ? "s have been" : " has been",
     rc ? ":" : "");
    for (i = 0; i < rc; ++i) {
     printf("%d: ", i);
     fflush(stdout);
     printout_tree(*rules[i]);
     putchar('\n');
    }
   }
   continue;
  }
  cgc_set(iter = new_gca());
  tokens = tokenize(lin);
  tree = *((parse(tokens)).child[0]);
  if (tree.head_type == EQL) {
   rules[rc++] = alloc_exptree(tree);
   printf("Rule stored.\n");
  } else {
   if (apply_rules_and_optimize(rules, rc, &tree)) {
    while(apply_rules_and_optimize(rules, rc, &tree))
     ;
    while(unwind_expos(&tree))
     ;
    while (apply_rules_and_optimize(pres_rules, prc,
                                    &tree))
     ;
    tnorm_old = -1;
    while (check_incomplete(&tree)) {
     tnorm = norm(&tree);
     if (tnorm == tnorm_old) {
      break;
     }
     while(apply_rules_and_optimize(rules, rc, &tree))
      ;
     while (unwind_expos(&tree))
      ;
     while (apply_rules_and_optimize(pres_rules, prc, &tree))
      ;
     tnorm_old = tnorm;
    }
     printout_tree_infix(tree);
     printf("\n");
   }
  }
  gca_cleanup(iter);
 }
 gca_cleanup(setup);
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 struct token *tokens;
 struct exp_tree tree;
 int i;
 struct exp_tree *rules[128];
 struct exp_tree *pres_rules[128];
 int rc;
 int prc;
 char lin[1024];
 struct gcarray_t *setup; struct gcarray_t *iter;
 double fe_expected; double fe_result; double fe_error;
 int fe_run;
 double fe_eval_point = 2.0;
 int tnorm; int tnorm_old;
 extern void fail(char *);
 extern int unwind_expos(struct exp_tree *et);
 cgc_set(setup = new_gca());
 setup_tokenizer();
 rc = readrules(rules, "rules");
 prc = readrules(pres_rules, "pres-rules");
  printf("\n-------------------------------------------------------\n");
  printf("Welcome to SYMDIFF, a program trained to compute \n");
  printf("symbolic derivatives. You may enter requests such as: \n\n");
  printf("\t diff(3cos(x^2)^3 + x^x, x)\n\n");
  printf("and quickly obtain the symbolic result.\n");
  printf("(This code was speed-tuned on an ancient 400 MHz machine.)\n");
  printf("\nYou will be given a prompt. As always, you can use\n");
  printf("CTRL-C to exit.\n");
  printf("\n");
  printf("This is version v1.10 + epsilon\n");
  printf("programmed by blockeduser, 2012-2016\n");
  printf("special thanks go to knipil for fixing a parser bug and to\n");
  printf("customers all around the world for using the software and\n");
  printf("sending improvement requests! thank you Umair, Sebastian,\n");
  printf("shoran, and others!\n");
  printf("\n-------------------------------------------------------\n");
  printf("\n");
 while (1) {
    printf("]=> ");
    fflush(stdout);
   if (!fgets(lin, 1024, stdin)) {
    printf("\n");
    break;
   }
  if (!lin[1])
   continue;
  if (*lin == '!') {
   if (!strcmp(lin, "!sr\n")) {
    printf("%d rule%s memorized%s\n",
     rc,
     rc > 1 ? "s have been" : " has been",
     rc ? ":" : "");
    for (i = 0; i < rc; ++i) {
     printf("%d: ", i);
     fflush(stdout);
     printout_tree(*rules[i]);
     putchar('\n');
    }
   }
   continue;
  }
  cgc_set(iter = new_gca());
  tokens = tokenize(lin);
  tree = *((parse(tokens)).child[0]);
  if (tree.head_type == EQL) {
   rules[rc++] = alloc_exptree(tree);
   printf("Rule stored.\n");
  } else {
   if (apply_rules_and_optimize(rules, rc, &tree)) {
    while(apply_rules_and_optimize(rules, rc, &tree))
     ;
    while(unwind_expos(&tree))
     ;
    while (apply_rules_and_optimize(pres_rules, prc,
                                    &tree))
     ;
    tnorm_old = -1;
    while (check_incomplete(&tree)) {
     tnorm = norm(&tree);
     if (tnorm == tnorm_old) {
      break;
     }
     while(apply_rules_and_optimize(rules, rc, &tree))
      ;
     while (unwind_expos(&tree))
      ;
     while (apply_rules_and_optimize(pres_rules, prc, &tree))
      ;
     tnorm_old = tnorm;
    }
     printout_tree_infix(tree);
     printf("\n");
   }
  }
  gca_cleanup(iter);
 }
 gca_cleanup(setup);
 return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } *[128]

variable_types: prc int

variable_types:
lin
char [1024]

variable_types: struct gcarray_t { int alloc; int memb; void **pile; } *

variable_types: tnorm int

variable_types:
fail
void (char *)

variable_types: int (struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } *et)


decompiled_code:
__int64 __fastcall op_prec(unsigned int a1)
{
__int64 result; // rax

switch ( a1 )
{
case 1u:
result = 4LL;
break;
case 2u:
result = 4LL;
break;
case 3u:
result = a1;
break;
case 4u:
result = 3LL;
break;
case 0xEu:
result = 1LL;
break;
case 0x28u:
result = 2LL;
break;
default:
result = 0LL;
break;
}
return result;
}

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

switch ( a1 )
{
case 1u:
result = 4LL;
break;
case 2u:
result = 4LL;
break;
case 3u:
result = a1;
break;
case 4u:
result = 3LL;
break;
case 0xEu:
result = 1LL;
break;
case 0x28u:
result = 2LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
int op_prec(int head_type)
{
 switch (head_type) {
  case EQL: return 1;
  case EXP: return 2;
  case DIV: return 3;
  case MULT: return 3;
  case SUB: return 4;
  case ADD: return 4;
  default: return 0;
 }
}


opsym

decompiled_code:
__int64 __fastcall opsym(int a1)
{
__int64 result; // rax

switch ( a1 )
{
case 1:
result = 43LL;
break;
case 2:
result = 45LL;
break;
case 3:
result = 42LL;
break;
case 4:
result = 47LL;
break;
case 14:
result = 61LL;
break;
case 40:
result = 94LL;
break;
default:
return result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
__int64 result; // rax

switch ( a1 )
{
case 1:
result = 43LL;
break;
case 2:
result = 45LL;
break;
case 3:
result = 42LL;
break;
case 4:
result = 47LL;
break;
case 14:
result = 61LL;
break;
case 40:
result = 94LL;
break;
default:
return result;
}
return result;
}

original_code:
char opsym(int head_type)
{
 switch (head_type) {
  case MULT: return '*';
  case SUB: return '-';
  case ADD: return '+';
  case DIV: return '/';
  case EQL: return '=';
  case EXP: return '^';
 }
}

return_type: char


decompiled_code:
int __fastcall printout_tree_infix_derp(int a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, unsigned __int8 a7, __int64 a8, unsigned int a9, __int64 a10)
{
__int64 v10; // rax
int v11; // er12
__int64 v12; // rbx
int v13; // edx
int v14; // ecx
int v15; // er8
int v16; // er9
__int64 i; // rbx
int v18; // edx
int v19; // ecx
int v20; // er8
int v21; // er9
int v22; // edx
int v23; // ecx
int v24; // er8
int v25; // er9
_QWORD *v26; // rbp
int v27; // edx
int v28; // ecx
int v29; // er8
int v30; // er9
int v32; // [rsp+8h] [rbp-40h]

if ( a7 == 30 )
{
strncpy(&name, *(const char **)(a8 + 8), *(int *)(a8 + 16));
*(&name + *(int *)(a8 + 16)) = 0;
printf("%s(", &name);
fflush(stdout);
if ( a9 )
{
for ( i = 1LL; ; ++i )
{
printout_tree_infix_derp(
0,
(unsigned int)&name,
v13,
v14,
v15,
v16,
**(_QWORD **)(a10 + 8 * i - 8),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * i - 8) + 8LL),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * i - 8) + 16LL),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * i - 8) + 24LL));
if ( i == a9 )
break;
if ( (_DWORD)i )
{
printf(", ");
fflush(stdout);
}
}
}
goto LABEL_31;
}
LODWORD(v10) = a7 - 8;
if ( (unsigned __int8)(a7 - 8) <= 1u )
{
strncpy(&name, *(const char **)(a8 + 8), *(int *)(a8 + 16));
*(&name + *(int *)(a8 + 16)) = 0;
printf("%s", &name);
LODWORD(v10) = fflush(stdout);
return v10;
}
if ( a7 == 18 )
{
putchar(45);
fflush(stdout);
LODWORD(v10) = printout_tree_infix_derp(
0,
a2,
v18,
v19,
v20,
v21,
**(_QWORD **)a10,
*(_QWORD *)(*(_QWORD *)a10 + 8LL),
*(_QWORD *)(*(_QWORD *)a10 + 16LL),
*(_QWORD *)(*(_QWORD *)a10 + 24LL));
return v10;
}
if ( a7 <= 0x28u )
{
v10 = 0x1000000401ELL;
if ( _bittest64(&v10, a7) )
{
if ( a1 && (LODWORD(v10) = op_prec((char)a7), (int)v10 > a1) )
{
putchar(40);
fflush(stdout);
if ( !a9 )
goto LABEL_31;
v32 = 1;
}
else
{
v32 = 0;
if ( !a9 )
return v10;
}
v11 = op_prec((char)a7);
v12 = 0LL;
do
{
v26 = *(_QWORD **)(a10 + 8 * v12);
if ( v11 == (unsigned int)op_prec(*(char *)v26) && *((_DWORD *)v26 + 4) && v11 != 0 && (a7 & 0xFD) != 1 )
{
putchar(40);
printout_tree_infix_derp(
v11,
a2,
v22,
v23,
v24,
v25,
**(_QWORD **)(a10 + 8 * v12),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * v12) + 8LL),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * v12) + 16LL),
*(_QWORD *)(*(_QWORD *)(a10 + 8 * v12) + 24LL));
putchar(41);
LODWORD(v10) = fflush(stdout);
}
else
{
LODWORD(v10) = printout_tree_infix_derp(v11, a2, v27, v28, v29, v30, *v26, v26[1], v26[2], v26[3]);
}
if ( a9 - 1 > (unsigned int)v12 )
{
a2 = (unsigned int)(char)opsym((char)a7);
printf(" %c ", a2);
LODWORD(v10) = fflush(stdout);
}
++v12;
}
while ( a9 > (unsigned int)v12 );
if ( !v32 )
return v10;
LABEL_31:
putchar(41);
LODWORD(v10) = fflush(stdout);
return v10;
}
}
return v10;
}

original_code:
void printout_tree_infix_derp(exp_tree_t et, int pp)
{
 int i;
 int parens_a = 0;
 int parens_b = 0;
 if (et.head_type == FUNC) {
  strncpy(name, (et.tok)->start, (et.tok)->len);
  name[(et.tok)->len] = 0;
  printf("%s(", name);
  fflush(stdout);
  for (i = 0; i < et.child_count; i++) {
   if (i) {
    printf(", ");
    fflush(stdout);
   }
   printout_tree_infix_derp(*(et.child[i]), 0);
  }
  printf(")");
  fflush(stdout);
  return;
 }
 if (et.head_type == VARIABLE
 || et.head_type == NUMBER) {
  strncpy(name, (et.tok)->start, (et.tok)->len);
  name[(et.tok)->len] = 0;
  printf("%s", name);
  fflush(stdout);
  return;
 }
 if (et.head_type == NEGATIVE) {
  printf("-");
  fflush(stdout);
  printout_tree_infix_derp(**et.child, 0);
  return;
 }
 if (et.head_type == MULT
 || et.head_type == ADD
 || et.head_type == SUB
 || et.head_type == DIV
 || et.head_type == EQL
 || et.head_type == EXP) {
  parens_a = pp && pp < op_prec(et.head_type);
  if (parens_a) {
   printf("(");
   fflush(stdout);
  }
  for (i = 0; i < et.child_count; i++) {
   parens_b = op_prec(et.head_type) ==
     op_prec(et.child[i]->head_type)
       && et.child[i]->child_count
    && op_prec(et.head_type)
    && et.head_type != MULT
    && et.head_type != ADD;
   if (parens_b)
    printf("(");
   printout_tree_infix_derp(*(et.child[i]), op_prec(et.head_type));
   if (parens_b) {
    printf(")");
    fflush(stdout);
   }
   if (i < et.child_count - 1) {
    printf(" %c ", opsym(et.head_type));
    fflush(stdout);
   }
  }
  if (parens_a) {
   printf(")");
   fflush(stdout);
  }
  return;
 }
}

canonical_original_code:
void printout_tree_infix_derp(struct exp_tree et, int pp)
{
 int i;
 int parens_a = 0;
 int parens_b = 0;
 if (et.head_type == FUNC) {
  strncpy(name, (et.tok)->start, (et.tok)->len);
  name[(et.tok)->len] = 0;
  printf("%s(", name);
  fflush(stdout);
  for (i = 0; i < et.child_count; i++) {
   if (i) {
    printf(", ");
    fflush(stdout);
   }
   printout_tree_infix_derp(*(et.child[i]), 0);
  }
  printf(")");
  fflush(stdout);
  return;
 }
 if (et.head_type == VARIABLE
 || et.head_type == NUMBER) {
  strncpy(name, (et.tok)->start, (et.tok)->len);
  name[(et.tok)->len] = 0;
  printf("%s", name);
  fflush(stdout);
  return;
 }
 if (et.head_type == NEGATIVE) {
  printf("-");
  fflush(stdout);
  printout_tree_infix_derp(**et.child, 0);
  return;
 }
 if (et.head_type == MULT
 || et.head_type == ADD
 || et.head_type == SUB
 || et.head_type == DIV
 || et.head_type == EQL
 || et.head_type == EXP) {
  parens_a = pp && pp < op_prec(et.head_type);
  if (parens_a) {
   printf("(");
   fflush(stdout);
  }
  for (i = 0; i < et.child_count; i++) {
   parens_b = op_prec(et.head_type) ==
     op_prec(et.child[i]->head_type)
       && et.child[i]->child_count
    && op_prec(et.head_type)
    && et.head_type != MULT
    && et.head_type != ADD;
   if (parens_b)
    printf("(");
   printout_tree_infix_derp(*(et.child[i]), op_prec(et.head_type));
   if (parens_b) {
    printf(")");
    fflush(stdout);
   }
   if (i < et.child_count - 1) {
    printf(" %c ", opsym(et.head_type));
    fflush(stdout);
   }
  }
  if (parens_a) {
   printf(")");
   fflush(stdout);
  }
  return;
 }
}

variable_types: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; }

variable_types: pp int


decompiled_code:
int __fastcall printout_tree_infix(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10)
{
return printout_tree_infix_derp(0, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}

original_code:
void printout_tree_infix(exp_tree_t et)
{
 extern void printout_tree_infix_derp(exp_tree_t et, int pp);
 printout_tree_infix_derp(et, 0);
}

canonical_original_code:
void printout_tree_infix(struct exp_tree et)
{
 extern void printout_tree_infix_derp(struct exp_tree et, int pp);
 printout_tree_infix_derp(et, 0);
}

variable_types: void (struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } et, int pp)


decompiled_code:
__int64 __fastcall hashtab_hash_mode(char *a1, int a2, int a3, char a4, unsigned int a5)
{
char v6; // al
int v7; // er10
unsigned int v8; // edx
int v10; // esi

v6 = *a1;
v7 = *a1;
if ( a3 )
{
if ( v6 )
v8 = (int)(v7 + a5 + 100 * abs32(v7 - a4)) % a2;
else
v8 = a5;
}
else if ( v6 )
{
v8 = (int)(a5 + v7) % a2;
while ( *++a1 )
{
v10 = *a1;
v8 = (int)(v10 + v8 + 100 * abs32(v10 - v7)) % a2;
v7 = (char)v10;
}
}
else
{
v8 = a5;
}
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *a1, int a2, int a3, char a4, unsigned int a5)
{
char v6; // al
int v7; // er10
unsigned int v8; // edx
int v10; // esi

v6 = *a1;
v7 = *a1;
if ( a3 )
{
if ( v6 )
v8 = (int)(v7 + a5 + 100 * abs32(v7 - a4)) % a2;
else
v8 = a5;
}
else if ( v6 )
{
v8 = (int)(a5 + v7) % a2;
while ( *++a1 )
{
v10 = *a1;
v8 = (int)(v10 + v8 + 100 * abs32(v10 - v7)) % a2;
v7 = (char)v10;
}
}
else
{
v8 = a5;
}
return v8;
}

original_code:
int hashtab_hash_mode(char *key, int nbuck, int single_char_mode, char prev, int prev_hash)
{
 int hash = prev_hash;
 int prev_key = *key;
 if (single_char_mode)
  prev_key = prev;
 while (*key) {
  hash += abs(*key - prev_key) * 100;
  hash += (prev_key = *key);
  hash %= nbuck;
  if (single_char_mode)
   break;
  else
   ++key;
 }
 return hash;
}

variable_types:
key
char *

variable_types: nbuck int

variable_types: prev char

variable_types: hash int


decompiled_code:
__int64 __fastcall hashtab_hash(char *a1, int a2)
{
return hashtab_hash_mode(a1, a2, 0, 0, 0);
}

canonical_decompiled_code:
__int64 __fastcall func1(char *a1, int a2)
{
return func0(a1, a2, 0, 0, 0);
}

original_code:
int hashtab_hash(char *key, int nbuck)
{
 return hashtab_hash_mode(key, nbuck, 0, 0, 0);
}


decompiled_code:
__int64 __fastcall hashtab_hash_char(char a1, char a2, int a3, unsigned int a4)
{
char v5[4]; // [rsp+4h] [rbp-4h] BYREF

v5[0] = a1;
return hashtab_hash_mode(v5, a3, 1, a2, a4);
}

canonical_decompiled_code:
__int64 __fastcall func2(char a1, char a2, int a3, unsigned int a4)
{
char v5[4]; // [rsp+4h] [rbp-4h] BYREF

v5[0] = a1;
return func0(v5, a3, 1, a2, a4);
}

original_code:
int hashtab_hash_char(char c, char prev, int nbuck, int prev_hash)
{
 return hashtab_hash_mode(&c, nbuck, 1, prev, prev_hash);
}

variable_types: c char


decompiled_code:
_QWORD *new_hashtab()
{
_QWORD *v0; // rbx
void *v1; // rax
int v2; // edx
__int64 v3; // rcx
__int64 v4; // rax

v0 = malloc(0x10uLL);
if ( !v0 )
fail("couldn't allocate a hash table");
*(_DWORD *)v0 = 241;
v1 = malloc(0x788uLL);
v0[1] = v1;
if ( v1 )
{
v2 = 241;
}
else
{
fail("couldn't allocate hash table buckets");
v2 = *(_DWORD *)v0;
if ( *(int *)v0 <= 0 )
return v0;
}
v3 = v0[1];
v4 = 0LL;
do
*(_QWORD *)(v3 + 8 * v4++) = 0LL;
while ( v2 > (int)v4 );
return v0;
}

canonical_decompiled_code:
_QWORD *func3()
{
_QWORD *v0; // rbx
void *v1; // rax
int v2; // edx
__int64 v3; // rcx
__int64 v4; // rax

v0 = malloc(0x10uLL);
if ( !v0 )
fail("couldn't allocate a hash table");
*(_DWORD *)v0 = 241;
v1 = malloc(0x788uLL);
v0[1] = v1;
if ( v1 )
{
v2 = 241;
}
else
{
fail("couldn't allocate hash table buckets");
v2 = *(_DWORD *)v0;
if ( *(int *)v0 <= 0 )
return v0;
}
v3 = v0[1];
v4 = 0LL;
do
*(_QWORD *)(v3 + 8 * v4++) = 0LL;
while ( v2 > (int)v4 );
return v0;
}

original_code:
hashtab_t* new_hashtab(void)
{
 hashtab_t* htab;
 int i;
 htab = malloc(sizeof(hashtab_t));
 if (!htab)
  fail("couldn't allocate a hash table");
 htab->nbuck = 241;
 htab->buck = malloc(htab->nbuck * sizeof(hashtab_entry_t *));
 if (!(htab->buck))
  fail("couldn't allocate hash table buckets");
 for (i = 0; i < htab->nbuck; ++i)
  htab->buck[i] = ((void *)0);
 return htab;
}

canonical_original_code:
struct hashtab *new_hashtab()
{
 struct hashtab *htab;
 int i;
 htab = malloc(sizeof(hashtab_t));
 if (!htab)
  fail("couldn't allocate a hash table");
 htab->nbuck = 241;
 htab->buck = malloc(htab->nbuck * sizeof(struct hashtab_entry *));
 if (!(htab->buck))
  fail("couldn't allocate hash table buckets");
 for (i = 0; i < htab->nbuck; ++i)
  htab->buck[i] = ((void *)0);
 return htab;
}

variable_types: struct hashtab { int nbuck; struct hashtab_entry { char *key; void *val; struct hashtab_entry *next; } **buck; } *

variable_types: i int

user_defined_types: struct hashtab { int nbuck; struct hashtab_entry **buck; }


decompiled_code:
__int64 __fastcall hashtab_lookup_with_hash(__int64 a1, const char *a2, int a3)
{
__int64 v3; // rbx

v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * a3);
if ( v3 )
{
while ( strcmp(*(const char **)v3, a2) )
{
v3 = *(_QWORD *)(v3 + 16);
if ( !v3 )
return v3;
}
v3 = *(_QWORD *)(v3 + 8);
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, const char *a2, int a3)
{
__int64 v3; // rbx

v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * a3);
if ( v3 )
{
while ( strcmp(*(const char **)v3, a2) )
{
v3 = *(_QWORD *)(v3 + 16);
if ( !v3 )
return v3;
}
v3 = *(_QWORD *)(v3 + 8);
}
return v3;
}

original_code:
void* hashtab_lookup_with_hash(hashtab_t* htab, char* key, int hash)
{
 hashtab_entry_t *ptr = htab->buck[hash];
 while (ptr)
  if (!strcmp(ptr->key, key))
   break;
  else
   ptr = ptr->next;
 if (ptr && strcmp(ptr->key, key))
  return ((void *)0);
 else if (ptr)
  return ptr->val;
 else
  return ((void *)0);
}

canonical_original_code:
void *hashtab_lookup_with_hash(struct hashtab *htab, char *key, int hash)
{
 struct hashtab_entry *ptr = htab->buck[hash];
 while (ptr)
  if (!strcmp(ptr->key, key))
   break;
  else
   ptr = ptr->next;
 if (ptr && strcmp(ptr->key, key))
  return ((void *)0);
 else if (ptr)
  return ptr->val;
 else
  return ((void *)0);
}

variable_types: struct hashtab_entry { char *key; void *val; struct hashtab_entry *next; } *

return_type: void *


decompiled_code:
__int64 __fastcall hashtab_lookup(int *a1, char *a2)
{
int v2; // eax

v2 = hashtab_hash(a2, *a1);
return hashtab_lookup_with_hash((__int64)a1, a2, v2);
}

canonical_decompiled_code:
__int64 __fastcall func5(int *a1, char *a2)
{
int v2; // eax

v2 = func1(a2, *a1);
return func4((__int64)a1, a2, v2);
}

original_code:
void* hashtab_lookup(hashtab_t* htab, char* key)
{
 return hashtab_lookup_with_hash(
   htab,
   key,
   hashtab_hash(key, htab->nbuck));
}

canonical_original_code:
void *hashtab_lookup(struct hashtab *htab, char *key)
{
 return hashtab_lookup_with_hash(
   htab,
   key,
   hashtab_hash(key, htab->nbuck));
}

user_defined_types: struct hashtab_entry { char *key; void *val; struct hashtab_entry *next; }


decompiled_code:
int __fastcall hashtab_pseudo_delete(__int64 a1, char *a2)
{
int result; // eax
__int64 v3; // rbx
const char *v4; // rbp

result = hashtab_hash(a2, *(_DWORD *)a1);
v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * result);
if ( v3 )
{
while ( 1 )
{
v4 = *(const char **)v3;
result = strcmp(*(const char **)v3, a2);
if ( !result )
break;
v3 = *(_QWORD *)(v3 + 16);
if ( !v3 )
return result;
}
*v4 = 0;
}
return result;
}

canonical_decompiled_code:
int __fastcall func6(__int64 a1, char *a2)
{
int result; // eax
__int64 v3; // rbx
const char *v4; // rbp

result = func1(a2, *(_DWORD *)a1);
v3 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * result);
if ( v3 )
{
while ( 1 )
{
v4 = *(const char **)v3;
result = strcmp(*(const char **)v3, a2);
if ( !result )
break;
v3 = *(_QWORD *)(v3 + 16);
if ( !v3 )
return result;
}
*v4 = 0;
}
return result;
}

original_code:
void hashtab_pseudo_delete(hashtab_t *htab, char* key)
{
 int hash = hashtab_hash(key, htab->nbuck);
        hashtab_entry_t *ptr = htab->buck[hash];
        while (ptr)
                if (!strcmp(ptr->key, key))
                        break;
                else
                        ptr = ptr->next;
 if (ptr && !strcmp(ptr->key, key))
  *(ptr->key) = 0;
}

canonical_original_code:
void hashtab_pseudo_delete(struct hashtab *htab, char *key)
{
 int hash = hashtab_hash(key, htab->nbuck);
        struct hashtab_entry *ptr = htab->buck[hash];
        while (ptr)
                if (!strcmp(ptr->key, key))
                        break;
                else
                        ptr = ptr->next;
 if (ptr && !strcmp(ptr->key, key))
  *(ptr->key) = 0;
}


decompiled_code:
char **__fastcall hashtab_insert(__int64 a1, char *a2, char *a3)
{
char ***v4; // rbx
char **v5; // rax
char **v6; // rdx
char **v7; // rax
size_t v8; // rax
_QWORD *v9; // r13
char **result; // rax

v4 = (char ***)(*(_QWORD *)(a1 + 8) + 8LL * (int)hashtab_hash(a2, *(_DWORD *)a1));
v5 = *v4;
if ( *v4 )
{
do
{
v6 = v5;
v5 = (char **)v5[2];
}
while ( v5 );
v4 = (char ***)(v6 + 2);
}
v7 = (char **)malloc(0x18uLL);
*v4 = v7;
if ( !v7 )
fail("couldn't create a hash table bucket node");
v8 = strlen(a2);
v9 = *v4;
*v9 = malloc(v8 + 1);
if ( !**v4 )
fail("couldn't allocate a string");
strcpy(**v4, a2);
(*v4)[1] = a3;
result = *v4;
(*v4)[2] = 0LL;
return result;
}

canonical_decompiled_code:
char **__fastcall func7(__int64 a1, char *a2, char *a3)
{
char ***v4; // rbx
char **v5; // rax
char **v6; // rdx
char **v7; // rax
size_t v8; // rax
_QWORD *v9; // r13
char **result; // rax

v4 = (char ***)(*(_QWORD *)(a1 + 8) + 8LL * (int)func1(a2, *(_DWORD *)a1));
v5 = *v4;
if ( *v4 )
{
do
{
v6 = v5;
v5 = (char **)v5[2];
}
while ( v5 );
v4 = (char ***)(v6 + 2);
}
v7 = (char **)malloc(0x18uLL);
*v4 = v7;
if ( !v7 )
fail("couldn't create a hash table bucket node");
v8 = strlen(a2);
v9 = *v4;
*v9 = malloc(v8 + 1);
if ( !**v4 )
fail("couldn't allocate a string");
strcpy(**v4, a2);
(*v4)[1] = a3;
result = *v4;
(*v4)[2] = 0LL;
return result;
}

original_code:
void hashtab_insert(hashtab_t* htab, char* key, void* val)
{
 int hash = hashtab_hash(key, htab->nbuck);
 hashtab_entry_t **ptr = &(htab->buck[hash]);
 while (*ptr)
  ptr = &((*ptr)->next);
 *ptr = malloc(sizeof(hashtab_entry_t));
 if (!*ptr)
  fail("couldn't create a hash table bucket node");
 (*ptr)->key = malloc(strlen(key) + 1);
 if (!((*ptr)->key))
  fail("couldn't allocate a string");
 strcpy((*ptr)->key, key);
 (*ptr)->val = val;
 (*ptr)->next = ((void *)0);
}

canonical_original_code:
void hashtab_insert(struct hashtab *htab, char *key, void *val)
{
 int hash = hashtab_hash(key, htab->nbuck);
 struct hashtab_entry **ptr = &(htab->buck[hash]);
 while (*ptr)
  ptr = &((*ptr)->next);
 *ptr = malloc(sizeof(hashtab_entry_t));
 if (!*ptr)
  fail("couldn't create a hash table bucket node");
 (*ptr)->key = malloc(strlen(key) + 1);
 if (!((*ptr)->key))
  fail("couldn't allocate a string");
 strcpy((*ptr)->key, key);
 (*ptr)->val = val;
 (*ptr)->next = ((void *)0);
}

variable_types:
val
void *

variable_types: struct hashtab_entry { char *key; void *val; struct hashtab_entry *next; } **


original_code:
void add_to_pile(gcarray_t *gca, void *ptr)
{
 if (!gca)
  return;
 if (++(gca->memb) > gca->alloc) {
  gca->alloc += 32;
  if (!(gca->pile = realloc(gca->pile, gca->alloc * sizeof(void *))))
   fail("out of memory");
 }
 gca->pile[gca->memb - 1] = ptr;
}

canonical_original_code:
void add_to_pile(struct gcarray_t *gca, void *ptr)
{
 if (!gca)
  return;
 if (++(gca->memb) > gca->alloc) {
  gca->alloc += 32;
  if (!(gca->pile = realloc(gca->pile, gca->alloc * sizeof(void *))))
   fail("out of memory");
 }
 gca->pile[gca->memb - 1] = ptr;
}

variable_types: struct gcarray_t { int alloc; int memb; void **pile; } *

variable_types:
ptr
void *


decompiled_code:
void *__fastcall cgc_malloc(size_t a1)
{
void *v1; // rbx

v1 = malloc(a1);
add_to_pile(curr, (__int64)v1);
return v1;
}

canonical_decompiled_code:
void *__fastcall func1(size_t a1)
{
void *v1; // rbx

v1 = malloc(a1);
func0(curr, (__int64)v1);
return v1;
}

original_code:
void *cgc_malloc(size_t size)
{
 void *ptr = malloc(size);
 add_to_pile(curr, ptr);
 return ptr;
}

canonical_original_code:
void *cgc_malloc(unsigned long size)
{
 void *ptr = malloc(size);
 add_to_pile(curr, ptr);
 return ptr;
}

variable_types:
size
unsigned long


decompiled_code:
void __fastcall cgc_set(__int64 a1)
{
curr = a1;
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1)
{
curr = a1;
}

original_code:
void cgc_set(gcarray_t *gca)
{
 curr = gca;
}

canonical_original_code:
void cgc_set(struct gcarray_t *gca)
{
 curr = gca;
}

user_defined_types: struct gcarray_t { int alloc; int memb; void **pile; }


decompiled_code:
_QWORD *new_gca()
{
_QWORD *v0; // rbx
void *v1; // rax

v0 = malloc(0x10uLL);
if ( !v0 )
fail("out of memory");
v1 = malloc(0x40uLL);
v0[1] = v1;
if ( !v1 )
fail("out of memory");
*((_DWORD *)v0 + 1) = 0;
*(_DWORD *)v0 = 8;
return v0;
}

canonical_decompiled_code:
_QWORD *func3()
{
_QWORD *v0; // rbx
void *v1; // rax

v0 = malloc(0x10uLL);
if ( !v0 )
fail("out of memory");
v1 = malloc(0x40uLL);
v0[1] = v1;
if ( !v1 )
fail("out of memory");
*((_DWORD *)v0 + 1) = 0;
*(_DWORD *)v0 = 8;
return v0;
}

original_code:
gcarray_t* new_gca(void)
{
 gcarray_t *g = malloc(sizeof(gcarray_t));
 if (!g)
  fail("out of memory");
 g->pile = malloc(8 * sizeof(void *));
 if (!(g->pile))
  fail("out of memory");
 g->memb = 0;
 g->alloc = 8;
 return g;
}

canonical_original_code:
struct gcarray_t *new_gca()
{
 struct gcarray_t *g = malloc(sizeof(gcarray_t));
 if (!g)
  fail("out of memory");
 g->pile = malloc(8 * sizeof(void *));
 if (!(g->pile))
  fail("out of memory");
 g->memb = 0;
 g->alloc = 8;
 return g;
}

return_type: struct gcarray_t { int alloc; int memb; void **pile; } *


decompiled_code:
void __fastcall gca_cleanup(void *ptr)
{
__int64 v1; // rbx

if ( *((int *)ptr + 1) > 0 )
{
v1 = 0LL;
do
free(*(void **)(*((_QWORD *)ptr + 1) + 8 * v1++));
while ( *((_DWORD *)ptr + 1) > (int)v1 );
}
free(*((void **)ptr + 1));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
__int64 v1; // rbx

if ( *((int *)ptr + 1) > 0 )
{
v1 = 0LL;
do
free(*(void **)(*((_QWORD *)ptr + 1) + 8 * v1++));
while ( *((_DWORD *)ptr + 1) > (int)v1 );
}
free(*((void **)ptr + 1));
free(ptr);
}

original_code:
void gca_cleanup(gcarray_t *gca)
{
 int i;
 for (i = 0; i < gca->memb; ++i)
  free(gca->pile[i]);
 free(gca->pile);
 free(gca);
}

canonical_original_code:
void gca_cleanup(struct gcarray_t *gca)
{
 int i;
 for (i = 0; i < gca->memb; ++i)
  free(gca->pile[i]);
 free(gca->pile);
 free(gca);
}


decompiled_code:
__int64 __fastcall tok2int(__int64 a1)
{
size_t v1; // rbx
unsigned int v3; // [rsp+Ch] [rbp-40Ch] BYREF
char dest[1032]; // [rsp+10h] [rbp-408h] BYREF

v1 = *(int *)(a1 + 16);
strncpy(dest, *(const char **)(a1 + 8), v1);
dest[v1] = 0;
_isoc99_sscanf(dest, &unk_102, &v3);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
size_t v1; // rbx
unsigned int v3; // [rsp+Ch] [rbp-40Ch] BYREF
char dest[1032]; // [rsp+10h] [rbp-408h] BYREF

v1 = *(int *)(a1 + 16);
strncpy(dest, *(const char **)(a1 + 8), v1);
dest[v1] = 0;
_isoc99_sscanf(dest, &unk_102, &v3);
return v3;
}

original_code:
int tok2int(token_t *t)
{
 char buf[1024];
 int i;
 strncpy(buf, t->start, t->len);
 buf[t->len] = 0;
 sscanf(buf, "%d", &i);
 return i;
}

canonical_original_code:
int tok2int(struct token *t)
{
 char buf[1024];
 int i;
 strncpy(buf, t->start, t->len);
 buf[t->len] = 0;
 sscanf(buf, "%d", &i);
 return i;
}

variable_types: struct token { char type; char *start; int len; int from_line; int from_char; } *

variable_types:
buf
char [1024]


decompiled_code:
__int64 __fastcall make_fake_tok(char *src)
{
__int64 v1; // rbx
size_t v2; // rax
char *v3; // rax

v1 = cgc_malloc(32LL);
if ( !v1 )
fail("cgc_malloc(sizeof(token_t))");
v2 = strlen(src);
v3 = (char *)cgc_malloc(v2 + 1);
*(_QWORD *)(v1 + 8) = v3;
strcpy(v3, src);
*(_DWORD *)(v1 + 16) = strlen(src);
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *src)
{
__int64 v1; // rbx
size_t v2; // rax
char *v3; // rax

v1 = cgc_malloc(32LL);
if ( !v1 )
fail("cgc_malloc(sizeof(token_t))");
v2 = strlen(src);
v3 = (char *)cgc_malloc(v2 + 1);
*(_QWORD *)(v1 + 8) = v3;
strcpy(v3, src);
*(_DWORD *)(v1 + 16) = strlen(src);
return v1;
}

original_code:
token_t* make_fake_tok(char *s)
{
 token_t *t = cgc_malloc(sizeof(token_t));
 if (!t)
  fail("cgc_malloc(sizeof(token_t))");
 t->start = cgc_malloc(strlen(s) + 1);
 strcpy(t->start, s);
 t->len = strlen(s);
 return t;
}

canonical_original_code:
struct token *make_fake_tok(char *s)
{
 struct token *t = cgc_malloc(sizeof(token_t));
 if (!t)
  fail("cgc_malloc(sizeof(token_t))");
 t->start = cgc_malloc(strlen(s) + 1);
 strcpy(t->start, s);
 t->len = strlen(s);
 return t;
}

variable_types:
s
char *

return_type: struct token { char type; char *start; int len; int from_line; int from_char; } *


decompiled_code:
_BOOL8 __fastcall is_add_op(char a1)
{
return (unsigned __int8)(a1 - 12) <= 1u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(char a1)
{
return (unsigned __int8)(a1 - 12) <= 1u;
}

original_code:
int is_add_op(char type)
{
 return type == TOK_PLUS || type == TOK_MINUS;
}

variable_types: type char


decompiled_code:
_BOOL8 __fastcall is_mul_op(char a1)
{
return (unsigned __int8)(a1 - 14) <= 1u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(char a1)
{
return (unsigned __int8)(a1 - 14) <= 1u;
}

original_code:
int is_mul_op(char type)
{
 return type == TOK_MUL || type == TOK_DIV;
}


original_code:
dict_t* new_dict()
{
 int i;
 dict_t* d = cgc_malloc(sizeof(dict_t));
 d->symbol = cgc_malloc(100 * sizeof(char *));
 for (i = 0; i < 100; ++i)
  d->symbol[i] = cgc_malloc(128);
 d->match = cgc_malloc(100 * sizeof(exp_tree_t *));
 if (!d->symbol || !d->match)
  fail("cgc_malloc dict");
 d->count = 0;
 d->alloc = 100;
 d->success = 0;
 return d;
}

canonical_original_code:
struct dict_s *new_dict()
{
 int i;
 struct dict_s *d = cgc_malloc(sizeof(dict_t));
 d->symbol = cgc_malloc(100 * sizeof(char *));
 for (i = 0; i < 100; ++i)
  d->symbol[i] = cgc_malloc(128);
 d->match = cgc_malloc(100 * sizeof(struct exp_tree *));
 if (!d->symbol || !d->match)
  fail("cgc_malloc dict");
 d->count = 0;
 d->alloc = 100;
 d->success = 0;
 return d;
}

variable_types: struct dict_s { char **symbol; struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } **match; int count; int alloc; int success; } *


decompiled_code:
void *__fastcall expand_dict(__int64 a1, int a2)
{
int v2; // er13
__int64 v3; // rbx
unsigned __int64 v4; // r13
_QWORD *v5; // r12
void *result; // rax

v2 = *(_DWORD *)(a1 + 20);
*(_DWORD *)(a1 + 20) = a2;
*(_QWORD *)a1 = realloc(*(void **)a1, 8LL * a2);
if ( v2 < a2 )
{
v3 = 8LL * v2;
v4 = 8 * (v2 + (unsigned __int64)(unsigned int)(a2 - 1 - v2) + 1);
do
{
v5 = (_QWORD *)(*(_QWORD *)a1 + v3);
*v5 = cgc_malloc(128LL);
v3 += 8LL;
}
while ( v3 != v4 );
}
result = realloc(*(void **)(a1 + 8), 8LL * *(int *)(a1 + 20));
*(_QWORD *)(a1 + 8) = result;
return result;
}

canonical_decompiled_code:
void *__fastcall func1(__int64 a1, int a2)
{
int v2; // er13
__int64 v3; // rbx
unsigned __int64 v4; // r13
_QWORD *v5; // r12
void *result; // rax

v2 = *(_DWORD *)(a1 + 20);
*(_DWORD *)(a1 + 20) = a2;
*(_QWORD *)a1 = realloc(*(void **)a1, 8LL * a2);
if ( v2 < a2 )
{
v3 = 8LL * v2;
v4 = 8 * (v2 + (unsigned __int64)(unsigned int)(a2 - 1 - v2) + 1);
do
{
v5 = (_QWORD *)(*(_QWORD *)a1 + v3);
*v5 = cgc_malloc(128LL);
v3 += 8LL;
}
while ( v3 != v4 );
}
result = realloc(*(void **)(a1 + 8), 8LL * *(int *)(a1 + 20));
*(_QWORD *)(a1 + 8) = result;
return result;
}

original_code:
void expand_dict(dict_t* d, int alloc)
{
 int i;
 int old = d->alloc;
 d->alloc = alloc;
 d->symbol = realloc(d->symbol, d->alloc * sizeof(char *));
 for (i = old; i < alloc; ++i)
  d->symbol[i] = cgc_malloc(128);
 d->match = realloc(d->match, d->alloc * sizeof(exp_tree_t *));
}

canonical_original_code:
void expand_dict(struct dict_s *d, int alloc)
{
 int i;
 int old = d->alloc;
 d->alloc = alloc;
 d->symbol = realloc(d->symbol, d->alloc * sizeof(char *));
 for (i = old; i < alloc; ++i)
  d->symbol[i] = cgc_malloc(128);
 d->match = realloc(d->match, d->alloc * sizeof(struct exp_tree *));
}

variable_types: alloc int

variable_types: old int


decompiled_code:
__int64 __fastcall dict_search(__int64 *a1, const char *a2)
{
int v2; // ebp
__int64 v3; // r13
__int64 v4; // rbx
unsigned int v5; // er14

v2 = *((_DWORD *)a1 + 4);
if ( v2 <= 0 )
return (unsigned int)-1;
v3 = *a1;
v4 = 0LL;
while ( 1 )
{
v5 = v4;
if ( !strcmp(*(const char **)(v3 + 8 * v4), a2) )
break;
if ( ++v4 == v2 )
return (unsigned int)-1;
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 *a1, const char *a2)
{
int v2; // ebp
__int64 v3; // r13
__int64 v4; // rbx
unsigned int v5; // er14

v2 = *((_DWORD *)a1 + 4);
if ( v2 <= 0 )
return (unsigned int)-1;
v3 = *a1;
v4 = 0LL;
while ( 1 )
{
v5 = v4;
if ( !strcmp(*(const char **)(v3 + 8 * v4), a2) )
break;
if ( ++v4 == v2 )
return (unsigned int)-1;
}
return v5;
}

original_code:
int dict_search(dict_t *d, char* var)
{
 int i;
 for (i = 0; i < d->count; ++i)
  if (!strcmp(d->symbol[i], var))
   return i;
 return -1;
}

canonical_original_code:
int dict_search(struct dict_s *d, char *var)
{
 int i;
 for (i = 0; i < d->count; ++i)
  if (!strcmp(d->symbol[i], var))
   return i;
 return -1;
}

variable_types:
var
char *


decompiled_code:
int __fastcall printout_dict(__int64 a1)
{
__int64 v2; // rbx
const char *v4; // rsi
struct _IO_FILE *v5; // rdi
__int64 v6; // rdx
__int64 v7; // rcx

putchar(91);
v2 = 0LL;
if ( *(int *)(a1 + 16) > 0 )
{
while ( 1 )
{
v4 = *(const char **)(*(_QWORD *)a1 + 8 * v2);
printf("%s: ", v4);
v5 = stdout;
fflush(stdout);
printout_tree(v5, v4, v6, v7);
fflush(stdout);
if ( *(_DWORD *)(a1 + 16) <= (int)v2 + 1 )
break;
if ( (_DWORD)v2 != -1 )
printf(", ");
++v2;
}
}
putchar(93);
return fflush(stdout);
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
__int64 v2; // rbx
const char *v4; // rsi
struct _IO_FILE *v5; // rdi
__int64 v6; // rdx
__int64 v7; // rcx

putchar(91);
v2 = 0LL;
if ( *(int *)(a1 + 16) > 0 )
{
while ( 1 )
{
v4 = *(const char **)(*(_QWORD *)a1 + 8 * v2);
printf("%s: ", v4);
v5 = stdout;
fflush(stdout);
printout_tree(v5, v4, v6, v7);
fflush(stdout);
if ( *(_DWORD *)(a1 + 16) <= (int)v2 + 1 )
break;
if ( (_DWORD)v2 != -1 )
printf(", ");
++v2;
}
}
putchar(93);
return fflush(stdout);
}

original_code:
void printout_dict(dict_t *d)
{
 int i =0;
 printf("[");
 for (i = 0; i < d->count; ++i) {
  if (i)
   printf(", ");
  printf("%s: ", d->symbol[i]);
  fflush(stdout);
  printout_tree(*(d->match[i]));
  fflush(stdout);
 }
 printf("]");
 fflush(stdout);
}

canonical_original_code:
void printout_dict(struct dict_s *d)
{
 int i = 0;
 printf("[");
 for (i = 0; i < d->count; ++i) {
  if (i)
   printf(", ");
  printf("%s: ", d->symbol[i]);
  fflush(stdout);
  printout_tree(*(d->match[i]));
  fflush(stdout);
 }
 printf("]");
 fflush(stdout);
}


findkey

decompiled_code:
__int64 __fastcall findkey(char *s2, __int64 *a2)
{
int v2; // ebp
__int64 v3; // r13
__int64 v4; // rbx
unsigned int v5; // er14

v2 = *((_DWORD *)a2 + 4);
if ( v2 <= 0 )
return (unsigned int)-1;
v3 = *a2;
v4 = 0LL;
while ( 1 )
{
v5 = v4;
if ( !strcmp(*(const char **)(v3 + 8 * v4), s2) )
break;
if ( ++v4 == v2 )
return (unsigned int)-1;
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s2, __int64 *a2)
{
int v2; // ebp
__int64 v3; // r13
__int64 v4; // rbx
unsigned int v5; // er14

v2 = *((_DWORD *)a2 + 4);
if ( v2 <= 0 )
return (unsigned int)-1;
v3 = *a2;
v4 = 0LL;
while ( 1 )
{
v5 = v4;
if ( !strcmp(*(const char **)(v3 + 8 * v4), s2) )
break;
if ( ++v4 == v2 )
return (unsigned int)-1;
}
return v5;
}

original_code:
int findkey(char *buf, dict_t* d)
{
 int i;
 for (i = 0; i < d->count; ++i)
  if (!strcmp(d->symbol[i], buf))
   return i;
 return -1;
}

canonical_original_code:
int findkey(char *buf, struct dict_s *d)
{
 int i;
 for (i = 0; i < d->count; ++i)
  if (!strcmp(d->symbol[i], buf))
   return i;
 return -1;
}

variable_types:
buf
char *


subst

original_code:
void subst(exp_tree_t *tree, dict_t *d, exp_tree_t **father_ptr)
{
 int i, key;
 if (tree->head_type == FUNC) {
  strncpy(buf, tree->tok->start, tree->tok->len);
  buf[tree->tok->len] = 0;
  if((key = findkey(buf, d)) != -1) {
   if (!father_ptr)
    fail("null pointer substitution....");
   (*father_ptr)->tok = d->match[key]->tok;
   goto match_children;
  }
 }
 if (tree->head_type == VARIABLE) {
  strncpy(buf, tree->tok->start, tree->tok->len);
  buf[tree->tok->len] = 0;
  if((key = findkey(buf, d)) != -1) {
   if (!father_ptr)
    fail("null pointer substitution....");
   *father_ptr = copy_tree(d->match[key]);
  }
 } else {
match_children:
  for (i = 0; i < tree->child_count; ++i) {
   if(tree->child[i]->head_type == VARIABLE
   || tree->child[i]->head_type == FUNC
   || tree->child[i]->child_count)
    subst(tree->child[i], d, &(tree->child[i]));
  }
 }
}

canonical_original_code:
void subst(struct exp_tree *tree, struct dict_s *d, struct exp_tree **father_ptr)
{
 int i; int key;
 if (tree->head_type == FUNC) {
  strncpy(buf, tree->tok->start, tree->tok->len);
  buf[tree->tok->len] = 0;
  if((key = findkey(buf, d)) != -1) {
   if (!father_ptr)
    fail("null pointer substitution....");
   (*father_ptr)->tok = d->match[key]->tok;
   goto match_children;
  }
 }
 if (tree->head_type == VARIABLE) {
  strncpy(buf, tree->tok->start, tree->tok->len);
  buf[tree->tok->len] = 0;
  if((key = findkey(buf, d)) != -1) {
   if (!father_ptr)
    fail("null pointer substitution....");
   *father_ptr = copy_tree(d->match[key]);
  }
 } else {
match_children:
  for (i = 0; i < tree->child_count; ++i) {
   if(tree->child[i]->head_type == VARIABLE
   || tree->child[i]->head_type == FUNC
   || tree->child[i]->child_count)
    subst(tree->child[i], d, &(tree->child[i]));
  }
 }
}

variable_types: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; } *

variable_types: struct dict_s { char **symbol; struct exp_tree **match; int count; int alloc; int success; } *

variable_types: key int


sametree

original_code:
int sametree(exp_tree_t *a, exp_tree_t *b)
{
 int i;
 if (a->child_count != b->child_count)
  return 0;
 if (a->head_type != b->head_type)
  return 0;
 if (a->tok && b->tok) {
  strncpy(buf_a, a->tok->start, a->tok->len);
  buf_a[a->tok->len] = 0;
  strncpy(buf_b, b->tok->start, b->tok->len);
  buf_b[b->tok->len] = 0;
  if (strcmp(buf_a, buf_b))
   return 0;
 }
 for (i = 0; i < a->child_count; ++i)
  if (!sametree(a->child[i], b->child[i]))
   return 0;
 return 1;
}

canonical_original_code:
int sametree(struct exp_tree *a, struct exp_tree *b)
{
 int i;
 if (a->child_count != b->child_count)
  return 0;
 if (a->head_type != b->head_type)
  return 0;
 if (a->tok && b->tok) {
  strncpy(buf_a, a->tok->start, a->tok->len);
  buf_a[a->tok->len] = 0;
  strncpy(buf_b, b->tok->start, b->tok->len);
  buf_b[b->tok->len] = 0;
  if (strcmp(buf_a, buf_b))
   return 0;
 }
 for (i = 0; i < a->child_count; ++i)
  if (!sametree(a->child[i], b->child[i]))
   return 0;
 return 1;
}

variable_types:
b
struct exp_tree *

variable_types: i int


decompiled_code:
_BOOL8 __fastcall valid_tree(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7)
{
return a7 != 41;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7)
{
return a7 != 41;
}

original_code:
int valid_tree(exp_tree_t et)
{
 return et.head_type != NULL_TREE;
}

canonical_original_code:
int valid_tree(struct exp_tree et)
{
 return et.head_type != NULL_TREE;
}

variable_types: struct exp_tree { char head_type; struct token { char type; char *start; int len; int from_line; int from_char; } *tok; unsigned int child_count; unsigned int child_alloc; struct exp_tree **child; }


decompiled_code:
int __fastcall printout_tree(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7, __int64 a8, unsigned int a9, __int64 a10)
{
__int64 v10; // rbx
int v11; // esi
int v12; // edi
int v13; // edx
int v14; // ecx
int v15; // er8
int v16; // er9

fprintf(stderr, "(%s", tree_nam[a7]);
if ( a8 && *(_QWORD *)(a8 + 8) )
{
fputc(58, stderr);
tok_display(stderr);
}
if ( a9 )
{
v10 = 0LL;
do
{
v11 = (int)stderr;
fputc(32, stderr);
v12 = (int)stderr;
fflush(stderr);
printout_tree(
v12,
v11,
v13,
v14,
v15,
v16,
**(_QWORD **)(a10 + v10),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 8LL),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 16LL),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 24LL));
v10 += 8LL;
}
while ( 8LL * a9 != v10 );
}
fputc(41, stderr);
return fflush(stderr);
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7, __int64 a8, unsigned int a9, __int64 a10)
{
__int64 v10; // rbx
int v11; // esi
int v12; // edi
int v13; // edx
int v14; // ecx
int v15; // er8
int v16; // er9

fprintf(stderr, "(%s", tree_nam[a7]);
if ( a8 && *(_QWORD *)(a8 + 8) )
{
fputc(58, stderr);
tok_display(stderr);
}
if ( a9 )
{
v10 = 0LL;
do
{
v11 = (int)stderr;
fputc(32, stderr);
v12 = (int)stderr;
fflush(stderr);
func4(
v12,
v11,
v13,
v14,
v15,
v16,
**(_QWORD **)(a10 + v10),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 8LL),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 16LL),
*(_QWORD *)(*(_QWORD *)(a10 + v10) + 24LL));
v10 += 8LL;
}
while ( 8LL * a9 != v10 );
}
fputc(41, stderr);
return fflush(stderr);
}

original_code:
void printout_tree(exp_tree_t et)
{
 int i;
 fprintf(stderr, "(%s", tree_nam[et.head_type]);
 if (et.tok && et.tok->start) {
  fprintf(stderr, ":");
  tok_display(stderr, *et.tok);
 }
 for (i = 0; i < et.child_count; i++) {
  fprintf(stderr, " ");
  fflush(stderr);
  printout_tree(*(et.child[i]));
 }
 fprintf(stderr, ")");
 fflush(stderr);
}

canonical_original_code:
void printout_tree(struct exp_tree et)
{
 int i;
 fprintf(stderr, "(%s", tree_nam[et.head_type]);
 if (et.tok && et.tok->start) {
  fprintf(stderr, ":");
  tok_display(stderr, *et.tok);
 }
 for (i = 0; i < et.child_count; i++) {
  fprintf(stderr, " ");
  fflush(stderr);
  printout_tree(*(et.child[i]));
 }
 fprintf(stderr, ")");
 fflush(stderr);
}


decompiled_code:
_BOOL8 __fastcall is_special_tree(int a1)
{
return (unsigned int)(a1 - 32) <= 6;
}

canonical_decompiled_code:
_BOOL8 __fastcall func5(int a1)
{
return (unsigned int)(a1 - 32) <= 6;
}

original_code:
int is_special_tree(int ht)
{
 return ((ht == MATCH_NUM)
 || (ht == MATCH_VAR)
 || (ht == MATCH_IND)
 || (ht == MATCH_CONT)
 || (ht == MATCH_FUNC)
 || (ht == MATCH_CONTX)
 || (ht == MATCH_NAN));
}

variable_types: ht int


decompiled_code:
double give_a_nan()
{
return 1.0 / 0.0;
}

canonical_decompiled_code:
double func0()
{
return 1.0 / 0.0;
}

original_code:
double give_a_nan(double x) {
 return (float)1.0/0.0;
}

variable_types: x double

return_type: double


decompiled_code:
double __fastcall my_sec(double a1)
{
return 1.0 / cos(a1);
}

canonical_decompiled_code:
double __fastcall func1(double a1)
{
return 1.0 / cos(a1);
}

original_code:
double my_sec(double x)
{
 return 1 / cos(x);
}


decompiled_code:
double __fastcall my_cot(double a1)
{
return 1.0 / tan(a1);
}

canonical_decompiled_code:
double __fastcall func2(double a1)
{
return 1.0 / tan(a1);
}

original_code:
double my_cot(double x)
{
 return 1 / tan(x);
}


decompiled_code:
double __fastcall my_csc(double a1)
{
return 1.0 / sin(a1);
}

canonical_decompiled_code:
double __fastcall func3(double a1)
{
return 1.0 / sin(a1);
}

original_code:
double my_csc(double x)
{
 return 1 / sin(x);
}


decompiled_code:
double __fastcall float_eval(__int64 a1, double a2)
{
__int64 v3; // rbp
char *v4; // rbx
__int64 v5; // rsi
__int64 v6; // rdx
__int64 v7; // rcx
double v8; // rbx
__int64 v9; // rdx
__int64 v10; // rbp
__int64 v11; // rdx
__int64 v12; // rbp
__int64 v13; // rdx
__int64 v14; // rbp
__int64 v15; // rdx
__int64 v16; // rbp
__int64 v17; // rdx
__int64 v18; // rbp
double v19; // xmm1_8
float v20; // xmm0_4
__int64 v21; // rsi
__int64 v22; // rdx
__int64 v23; // rcx
double (__fastcall *v24)(__int64, __int64, __int64, __int64, __int64, __int64, const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (__fastcall *)(double), const char *, double (__fastcall *)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double)); // rbx
__int64 v25; // rdi
__int64 v26; // rdx
__int64 v27; // rcx
__int64 v28; // r8
__int64 v29; // r9
const char *v30; // rax
bool v31; // cf
bool v32; // zf
__int64 v33; // rdx
const char *v34; // rsi
const char *v35; // rdi
__int64 v36; // rcx
__int64 v37; // rax
const char *v39; // [rsp+0h] [rbp-108h] BYREF
double (**v40)(double); // [rsp+8h] [rbp-100h]
const char *v41; // [rsp+10h] [rbp-F8h]
double (**v42)(double); // [rsp+18h] [rbp-F0h]
const char *v43; // [rsp+20h] [rbp-E8h]
double (**v44)(double); // [rsp+28h] [rbp-E0h]
const char *v45; // [rsp+30h] [rbp-D8h]
double (**v46)(double); // [rsp+38h] [rbp-D0h]
const char *v47; // [rsp+40h] [rbp-C8h]
double (__fastcall *v48)(double); // [rsp+48h] [rbp-C0h]
const char *v49; // [rsp+50h] [rbp-B8h]
double (__fastcall *v50)(double); // [rsp+58h] [rbp-B0h]
const char *v51; // [rsp+60h] [rbp-A8h]
double (**v52)(double); // [rsp+68h] [rbp-A0h]
const char *v53; // [rsp+70h] [rbp-98h]
double (**v54)(double); // [rsp+78h] [rbp-90h]
const char *v55; // [rsp+80h] [rbp-88h]
double (**v56)(double); // [rsp+88h] [rbp-80h]
const char *v57; // [rsp+90h] [rbp-78h]
double (**v58)(double); // [rsp+98h] [rbp-70h]
const char *v59; // [rsp+A0h] [rbp-68h]
double (**v60)(double); // [rsp+A8h] [rbp-60h]
const char *v61; // [rsp+B0h] [rbp-58h]
double (__fastcall *v62)(double); // [rsp+B8h] [rbp-50h]
const char *v63; // [rsp+C0h] [rbp-48h]
double (*v64)(); // [rsp+C8h] [rbp-40h]
char v65; // [rsp+D0h] [rbp-38h] BYREF
int v66; // [rsp+DCh] [rbp-2Ch] BYREF

v3 = new_hashtab();
v39 = "arccos";
v40 = &acos;
v41 = "arcsin";
v42 = &asin;
v43 = "arctan";
v44 = &atan;
v45 = "cos";
v46 = &cos;
v47 = "cot";
v48 = my_cot;
v49 = "csc";
v50 = my_csc;
v51 = "ln";
v52 = &log;
v53 = "log";
v54 = &log;
v55 = "sin";
v56 = &sin;
v57 = "sqrt";
v58 = &sqrt;
v59 = "tan";
v60 = &tan;
v61 = "sec";
v62 = my_sec;
v63 = "D";
v64 = give_a_nan;
v4 = (char *)&v39;
do
{
v5 = *(_QWORD *)v4;
hashtab_insert(v3, *(_QWORD *)v4, *((_QWORD *)v4 + 1));
v4 += 16;
}
while ( &v65 != v4 );
switch ( *(_BYTE *)a1 )
{
case 1:
v8 = float_eval(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v9 = 0LL;
do
{
v10 = v9 + 1;
v8 = v8 + float_eval(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v9 + 1)), a2);
v9 = v10;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v10 + 1) );
}
break;
case 2:
v8 = float_eval(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v11 = 0LL;
do
{
v12 = v11 + 1;
v8 = v8 - float_eval(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v11 + 1)), a2);
v11 = v12;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v12 + 1) );
}
break;
case 3:
v8 = float_eval(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v13 = 0LL;
do
{
v14 = v13 + 1;
v8 = v8 * float_eval(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v13 + 1)), a2);
v13 = v14;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v14 + 1) );
}
break;
case 4:
v8 = float_eval(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v15 = 0LL;
do
{
v16 = v15 + 1;
v8 = v8 / float_eval(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v15 + 1)), a2);
v15 = v16;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v16 + 1) );
}
break;
case 8:
v37 = get_tok_str(v3, v5, v6, v7);
_isoc99_sscanf(v37, "%d", &v66);
v8 = (double)v66;
break;
case 9:
v34 = (const char *)get_tok_str(v3, v5, v6, v7);
v35 = "e";
v36 = 2LL;
do
{
if ( !v36 )
break;
v31 = *v34 < (unsigned int)*v35;
v32 = *v34++ == *v35++;
--v36;
}
while ( v32 );
v8 = *(double *)&LC2;
if ( (!v31 && !v32) != v31 )
v8 = a2 + (double)(*(char *)get_tok_str(v35, v34, v33, v36) % 5);
break;
case 0x12:
*(_QWORD *)&v8 = COERCE_UNSIGNED_INT64(float_eval(**(_QWORD **)(a1 + 24), a2)) ^ LC16;
break;
case 0x1E:
v21 = get_tok_str(v3, v5, v6, v7);
v24 = (double (__fastcall *)(__int64, __int64, __int64, __int64, __int64, __int64, const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (__fastcall *)(double), const char *, double (__fastcall *)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double)))hashtab_lookup(v3, v21);
if ( !v24 )
{
v30 = (const char *)get_tok_str(v3, v21, v22, v23);
fprintf(stderr, "error: FLOATEVAL: uncoded function: %s\n", v30);
exit(1);
}
v25 = **(_QWORD **)(a1 + 24);
float_eval(v25, a2);
v8 = v24(
v25,
v21,
v26,
v27,
v28,
v29,
v39,
v40,
v41,
v42,
v43,
v44,
v45,
v46,
v47,
v48,
v49,
v50,
v51,
v52,
v53,
v54,
v55,
v56,
v57,
v58);
break;
case 0x28:
v8 = float_eval(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v17 = 0LL;
do
{
v18 = v17 + 1;
v19 = float_eval(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v17 + 1)), a2);
v20 = v8;
*(float *)&v19 = v19;
v8 = powf(v20, *(float *)&v19);
v17 = v18;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v18 + 1) );
}
break;
default:
v8 = *(double *)&LC1;
break;
}
return v8;
}

canonical_decompiled_code:
double __fastcall func4(__int64 a1, double a2)
{
__int64 v3; // rbp
char *v4; // rbx
__int64 v5; // rsi
__int64 v6; // rdx
__int64 v7; // rcx
double v8; // rbx
__int64 v9; // rdx
__int64 v10; // rbp
__int64 v11; // rdx
__int64 v12; // rbp
__int64 v13; // rdx
__int64 v14; // rbp
__int64 v15; // rdx
__int64 v16; // rbp
__int64 v17; // rdx
__int64 v18; // rbp
double v19; // xmm1_8
float v20; // xmm0_4
__int64 v21; // rsi
__int64 v22; // rdx
__int64 v23; // rcx
double (__fastcall *v24)(__int64, __int64, __int64, __int64, __int64, __int64, const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (__fastcall *)(double), const char *, double (__fastcall *)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double)); // rbx
__int64 v25; // rdi
__int64 v26; // rdx
__int64 v27; // rcx
__int64 v28; // r8
__int64 v29; // r9
const char *v30; // rax
bool v31; // cf
bool v32; // zf
__int64 v33; // rdx
const char *v34; // rsi
const char *v35; // rdi
__int64 v36; // rcx
__int64 v37; // rax
const char *v39; // [rsp+0h] [rbp-108h] BYREF
double (**v40)(double); // [rsp+8h] [rbp-100h]
const char *v41; // [rsp+10h] [rbp-F8h]
double (**v42)(double); // [rsp+18h] [rbp-F0h]
const char *v43; // [rsp+20h] [rbp-E8h]
double (**v44)(double); // [rsp+28h] [rbp-E0h]
const char *v45; // [rsp+30h] [rbp-D8h]
double (**v46)(double); // [rsp+38h] [rbp-D0h]
const char *v47; // [rsp+40h] [rbp-C8h]
double (__fastcall *v48)(double); // [rsp+48h] [rbp-C0h]
const char *v49; // [rsp+50h] [rbp-B8h]
double (__fastcall *v50)(double); // [rsp+58h] [rbp-B0h]
const char *v51; // [rsp+60h] [rbp-A8h]
double (**v52)(double); // [rsp+68h] [rbp-A0h]
const char *v53; // [rsp+70h] [rbp-98h]
double (**v54)(double); // [rsp+78h] [rbp-90h]
const char *v55; // [rsp+80h] [rbp-88h]
double (**v56)(double); // [rsp+88h] [rbp-80h]
const char *v57; // [rsp+90h] [rbp-78h]
double (**v58)(double); // [rsp+98h] [rbp-70h]
const char *v59; // [rsp+A0h] [rbp-68h]
double (**v60)(double); // [rsp+A8h] [rbp-60h]
const char *v61; // [rsp+B0h] [rbp-58h]
double (__fastcall *v62)(double); // [rsp+B8h] [rbp-50h]
const char *v63; // [rsp+C0h] [rbp-48h]
double (*v64)(); // [rsp+C8h] [rbp-40h]
char v65; // [rsp+D0h] [rbp-38h] BYREF
int v66; // [rsp+DCh] [rbp-2Ch] BYREF

v3 = new_hashtab();
v39 = "arccos";
v40 = &acos;
v41 = "arcsin";
v42 = &asin;
v43 = "arctan";
v44 = &atan;
v45 = "cos";
v46 = &cos;
v47 = "cot";
v48 = my_cot;
v49 = "csc";
v50 = my_csc;
v51 = "ln";
v52 = &log;
v53 = "log";
v54 = &log;
v55 = "sin";
v56 = &sin;
v57 = "sqrt";
v58 = &sqrt;
v59 = "tan";
v60 = &tan;
v61 = "sec";
v62 = my_sec;
v63 = "D";
v64 = give_a_nan;
v4 = (char *)&v39;
do
{
v5 = *(_QWORD *)v4;
hashtab_insert(v3, *(_QWORD *)v4, *((_QWORD *)v4 + 1));
v4 += 16;
}
while ( &v65 != v4 );
switch ( *(_BYTE *)a1 )
{
case 1:
v8 = func4(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v9 = 0LL;
do
{
v10 = v9 + 1;
v8 = v8 + func4(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v9 + 1)), a2);
v9 = v10;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v10 + 1) );
}
break;
case 2:
v8 = func4(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v11 = 0LL;
do
{
v12 = v11 + 1;
v8 = v8 - func4(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v11 + 1)), a2);
v11 = v12;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v12 + 1) );
}
break;
case 3:
v8 = func4(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v13 = 0LL;
do
{
v14 = v13 + 1;
v8 = v8 * func4(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v13 + 1)), a2);
v13 = v14;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v14 + 1) );
}
break;
case 4:
v8 = func4(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v15 = 0LL;
do
{
v16 = v15 + 1;
v8 = v8 / func4(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v15 + 1)), a2);
v15 = v16;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v16 + 1) );
}
break;
case 8:
v37 = get_tok_str(v3, v5, v6, v7);
_isoc99_sscanf(v37, "%d", &v66);
v8 = (double)v66;
break;
case 9:
v34 = (const char *)get_tok_str(v3, v5, v6, v7);
v35 = "e";
v36 = 2LL;
do
{
if ( !v36 )
break;
v31 = *v34 < (unsigned int)*v35;
v32 = *v34++ == *v35++;
--v36;
}
while ( v32 );
v8 = *(double *)&LC2;
if ( (!v31 && !v32) != v31 )
v8 = a2 + (double)(*(char *)get_tok_str(v35, v34, v33, v36) % 5);
break;
case 0x12:
*(_QWORD *)&v8 = COERCE_UNSIGNED_INT64(float_eval(**(_QWORD **)(a1 + 24), a2)) ^ LC16;
break;
case 0x1E:
v21 = get_tok_str(v3, v5, v6, v7);
v24 = (double (__fastcall *)(__int64, __int64, __int64, __int64, __int64, __int64, const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (__fastcall *)(double), const char *, double (__fastcall *)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double), const char *, double (**)(double)))hashtab_lookup(v3, v21);
if ( !v24 )
{
v30 = (const char *)get_tok_str(v3, v21, v22, v23);
fprintf(stderr, "error: FLOATEVAL: uncoded function: %s\n", v30);
exit(1);
}
v25 = **(_QWORD **)(a1 + 24);
func4(v25, a2);
v8 = v24(
v25,
v21,
v26,
v27,
v28,
v29,
v39,
v40,
v41,
v42,
v43,
v44,
v45,
v46,
v47,
v48,
v49,
v50,
v51,
v52,
v53,
v54,
v55,
v56,
v57,
v58);
break;
case 0x28:
v8 = func4(**(_QWORD **)(a1 + 24), a2);
if ( *(_DWORD *)(a1 + 16) > 1u )
{
v17 = 0LL;
do
{
v18 = v17 + 1;
v19 = func4(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 8 * (v17 + 1)), a2);
v20 = v8;
*(float *)&v19 = v19;
v8 = powf(v20, *(float *)&v19);
v17 = v18;
}
while ( *(_DWORD *)(a1 + 16) > (unsigned int)(v18 + 1) );
}
break;
default:
v8 = *(double *)&LC1;
break;
}
return v8;
}

original_code:
double float_eval(exp_tree_t *t, double val)
{
 int i;
 double result = 0.0;
 double (*fp)(double);
 int v;
 hashtab_t *function_dispatch_table = new_hashtab();
 struct fts {
  char *key;
  double (*val)(double);
 } function_table[] = {
  { "arccos", &acos },
  { "arcsin", &asin },
  { "arctan", &atan },
  { "cos", &cos},
  { "cot", &my_cot },
  { "csc", &my_csc },
  { "ln", &log },
  { "log", &log },
  { "sin", &sin },
  { "sqrt", &sqrt },
  { "tan", &tan },
  { "sec", &my_sec },
  { "D", &give_a_nan }
 };
 for (i = 0; i < sizeof(function_table) / sizeof(struct fts); ++i) {
  hashtab_insert(function_dispatch_table,
          function_table[i].key,
          (void *)function_table[i].val);
 }
 switch (t->head_type) {
  case NEGATIVE: return -float_eval(t->child[0], val);
  case ADD: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result + float_eval(t->child[i], val);; break;
  case SUB: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result - float_eval(t->child[i], val);; break;
  case MULT: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result * float_eval(t->child[i], val);; break;
  case DIV: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result / float_eval(t->child[i], val);; break;
  case EXP: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = powf ( result , float_eval(t->child[i], val) );; break;
  case FUNC: {
   fp = hashtab_lookup(function_dispatch_table,
                get_tok_str(*(t->tok)));
   if (!fp) {
    fprintf(stderr, "error: FLOATEVAL: uncoded function: %s\n", get_tok_str(*(t->tok)));
    exit(1);
   }
   result = fp(float_eval(t->child[0], val));
  }
  break;
  case VARIABLE: {
   if (!strcmp(get_tok_str(*(t->tok)), "e"))
    result = 2.71828182845904523536028747135266;
   else
    result = val + (float)(1.0 * (*get_tok_str(*(t->tok)) % 5));
  }
  break;
  case NUMBER: {
   sscanf(get_tok_str(*(t->tok)), "%d", &v);
   result = (double)v;
  }
  break;
 }
 return result;
}

canonical_original_code:
double float_eval(struct exp_tree *t, double val)
{
 int i;
 double result = 0.0;
 double (*fp)(double);
 int v;
 struct hashtab *function_dispatch_table = new_hashtab();
 struct fts function_table[] = {
  { "arccos", &acos },
  { "arcsin", &asin },
  { "arctan", &atan },
  { "cos", &cos},
  { "cot", &my_cot },
  { "csc", &my_csc },
  { "ln", &log },
  { "log", &log },
  { "sin", &sin },
  { "sqrt", &sqrt },
  { "tan", &tan },
  { "sec", &my_sec },
  { "D", &give_a_nan }
 };
 for (i = 0; i < sizeof(function_table) / sizeof(struct fts); ++i) {
  hashtab_insert(function_dispatch_table,
          function_table[i].key,
          (void *)function_table[i].val);
 }
 switch (t->head_type) {
  case NEGATIVE: return -float_eval(t->child[0], val);
  case ADD: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result + float_eval(t->child[i], val);; break;
  case SUB: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result - float_eval(t->child[i], val);; break;
  case MULT: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result * float_eval(t->child[i], val);; break;
  case DIV: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = result / float_eval(t->child[i], val);; break;
  case EXP: for (i = 1, result = float_eval(t->child[0], val); i < t->child_count; ++i) result = powf ( result , float_eval(t->child[i], val) );; break;
  case FUNC: {
   fp = hashtab_lookup(function_dispatch_table,
                get_tok_str(*(t->tok)));
   if (!fp) {
    fprintf(stderr, "error: FLOATEVAL: uncoded function: %s\n", get_tok_str(*(t->tok)));
    exit(1);
   }
   result = fp(float_eval(t->child[0], val));
  }
  break;
  case VARIABLE: {
   if (!strcmp(get_tok_str(*(t->tok)), "e"))
    result = 2.71828182845904523536028747135266;
   else
    result = val + (float)(1.0 * (*get_tok_str(*(t->tok)) % 5));
  }
  break;
  case NUMBER: {
   sscanf(get_tok_str(*(t->tok)), "%d", &v);
   result = (double)v;
  }
  break;
 }
 return result;
}

variable_types: val double

variable_types: result double

variable_types:
fp
double (*)(double)

variable_types: v int

variable_types: struct hashtab { int nbuck; struct hashtab_entry { char *key; void *val; struct hashtab_entry *next; } **buck; } *

variable_types: struct fts { char *key; double (*val)(double); } []