main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // r14
unsigned int v4; // ebx
unsigned int v5; // ebp
__int64 v6; // rdx
__int64 v7; // r13
__int64 v8; // rax
__int64 v9; // rcx
__int64 *v10; // rax
__int64 v11; // rsi
__int64 v12; // rdi
__int64 v13; // rdx
__int64 v14; // rax
__int64 v15; // rsi
__int64 v16; // rdx
__int64 v17; // rcx
int v18; // eax
__int64 i; // r12
__int64 v20; // rsi
struct _IO_FILE *v21; // rdi
__int64 v22; // rdx
__int64 v23; // rcx
__int64 v25[4]; // [rsp+0h] [rbp-C68h] BYREF
char v26[24]; // [rsp+20h] [rbp-C48h] BYREF
__int64 **v27; // [rsp+38h] [rbp-C30h]
__int64 v28[128]; // [rsp+40h] [rbp-C28h] BYREF
char v29[1024]; // [rsp+440h] [rbp-828h] BYREF
char s[4]; // [rsp+840h] [rbp-428h] BYREF
char v31; // [rsp+844h] [rbp-424h]

v3 = new_gca(argc, argv, envp);
cgc_set(v3);
setup_tokenizer();
v4 = readrules(v28, "rules");
v5 = readrules(v29, "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 ( *(_DWORD *)s == 175272737 && !v31 )
{
if ( v4 )
{
if ( (int)v4 <= 1 )
{
printf("%d rule%s memorized%s\n", v4, " has been", ":");
if ( v4 == 1 )
goto LABEL_23;
}
else
{
printf("%d rule%s memorized%s\n", v4, "s have been", ":");
LABEL_23:
for ( i = 0LL; i != v4; ++i )
{
v20 = (unsigned int)i;
printf("%d: ", (unsigned int)i);
v21 = stdout;
fflush(stdout);
printout_tree(v21, v20, v22, v23);
putchar(10);
}
}
}
else
{
printf("%d rule%s memorized%s\n", 0LL, " has been", (const char *)&unk_155);
}
}
}
else
{
v7 = new_gca(s, 1024LL, v6);
cgc_set(v7);
v8 = tokenize(s);
parse(v26, v8);
v10 = *v27;
v11 = **v27;
v12 = (*v27)[1];
v25[0] = v11;
v25[1] = v12;
v13 = v10[3];
v14 = v10[2];
v25[3] = v13;
v25[2] = v14;
if ( (_BYTE)v11 == 14 )
{
v28[v4++] = alloc_exptree(v12, v11, v13, v9);
puts("Rule stored.");
}
else if ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
{
while ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
;
while ( (unsigned int)unwind_expos(v25) )
;
do
v15 = v5;
while ( (unsigned int)apply_rules_and_optimize(v29, v5, v25) );
while ( (unsigned int)check_incomplete((__int64)v25) )
{
v18 = norm((__int64)v25);
if ( (_DWORD)v17 == v18 )
break;
while ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
;
while ( (unsigned int)unwind_expos(v25) )
;
do
v15 = v5;
while ( (unsigned int)apply_rules_and_optimize(v29, v5, v25) );
}
printout_tree_infix(v25, v15, v16, v17);
putchar(10);
}
gca_cleanup(v7);
}
}
}
putchar(10);
gca_cleanup(v3);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // r14
unsigned int v4; // ebx
unsigned int v5; // ebp
__int64 v6; // rdx
__int64 v7; // r13
__int64 v8; // rax
__int64 v9; // rcx
__int64 *v10; // rax
__int64 v11; // rsi
__int64 v12; // rdi
__int64 v13; // rdx
__int64 v14; // rax
__int64 v15; // rsi
__int64 v16; // rdx
__int64 v17; // rcx
int v18; // eax
__int64 i; // r12
__int64 v20; // rsi
struct _IO_FILE *v21; // rdi
__int64 v22; // rdx
__int64 v23; // rcx
__int64 v25[4]; // [rsp+0h] [rbp-C68h] BYREF
char v26[24]; // [rsp+20h] [rbp-C48h] BYREF
__int64 **v27; // [rsp+38h] [rbp-C30h]
__int64 v28[128]; // [rsp+40h] [rbp-C28h] BYREF
char v29[1024]; // [rsp+440h] [rbp-828h] BYREF
char s[4]; // [rsp+840h] [rbp-428h] BYREF
char v31; // [rsp+844h] [rbp-424h]

v3 = new_gca(argc, argv, envp);
cgc_set(v3);
setup_tokenizer();
v4 = readrules(v28, "rules");
v5 = readrules(v29, "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 ( *(_DWORD *)s == 175272737 && !v31 )
{
if ( v4 )
{
if ( (int)v4 <= 1 )
{
printf("%d rule%s memorized%s\n", v4, " has been", ":");
if ( v4 == 1 )
goto LABEL_23;
}
else
{
printf("%d rule%s memorized%s\n", v4, "s have been", ":");
LABEL_23:
for ( i = 0LL; i != v4; ++i )
{
v20 = (unsigned int)i;
printf("%d: ", (unsigned int)i);
v21 = stdout;
fflush(stdout);
printout_tree(v21, v20, v22, v23);
putchar(10);
}
}
}
else
{
printf("%d rule%s memorized%s\n", 0LL, " has been", (const char *)&unk_155);
}
}
}
else
{
v7 = new_gca(s, 1024LL, v6);
cgc_set(v7);
v8 = tokenize(s);
parse(v26, v8);
v10 = *v27;
v11 = **v27;
v12 = (*v27)[1];
v25[0] = v11;
v25[1] = v12;
v13 = v10[3];
v14 = v10[2];
v25[3] = v13;
v25[2] = v14;
if ( (_BYTE)v11 == 14 )
{
v28[v4++] = alloc_exptree(v12, v11, v13, v9);
puts("Rule stored.");
}
else if ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
{
while ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
;
while ( (unsigned int)unwind_expos(v25) )
;
do
v15 = v5;
while ( (unsigned int)apply_rules_and_optimize(v29, v5, v25) );
while ( (unsigned int)func1((__int64)v25) )
{
v18 = func0((__int64)v25);
if ( (_DWORD)v17 == v18 )
break;
while ( (unsigned int)apply_rules_and_optimize(v28, v4, v25) )
;
while ( (unsigned int)unwind_expos(v25) )
;
do
v15 = v5;
while ( (unsigned int)apply_rules_and_optimize(v29, v5, v25) );
}
printout_tree_infix(v25, v15, v16, v17);
putchar(10);
}
gca_cleanup(v7);
}
}
}
putchar(10);
gca_cleanup(v3);
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(int a1)
{
__int64 v1; // rdi
__int64 result; // rax

v1 = (unsigned int)(a1 - 1);
result = 0LL;
if ( (unsigned int)v1 <= 0x27 )
result = (unsigned int)CSWTCH_15[v1];
return result;
}

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

v1 = (unsigned int)(a1 - 1);
result = 0LL;
if ( (unsigned int)v1 <= 0x27 )
result = (unsigned int)CSWTCH_15[v1];
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;
 }
}

return_type: int


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


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

variable_types: i int

return_type: void

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:
int __fastcall printout_tree_infix(__m128i a1, __m128i a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8)
{
return printout_tree_infix_derp(0, a4, a5, a6, a7, a8, a1, a2);
}

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)
{
int v5; // eax
int v8; // er9
unsigned int i; // edx
int v10; // eax
int v11; // ecx

v5 = *a1;
if ( a3 )
{
if ( (_BYTE)v5 )
return (unsigned int)((int)(a5 + 100 * abs32(v5 - a4) + v5) % a2);
return a5;
}
v8 = (char)v5;
if ( !(_BYTE)v5 )
return a5;
for ( i = (int)(a5 + (char)v5) % a2; ; i = (int)(v11 + i + 100 * abs32(v10)) % a2 )
{
v11 = *++a1;
if ( !(_BYTE)v11 )
break;
v10 = v11 - v8;
v8 = v11;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *a1, int a2, int a3, char a4, unsigned int a5)
{
int v5; // eax
int v8; // er9
unsigned int i; // edx
int v10; // eax
int v11; // ecx

v5 = *a1;
if ( a3 )
{
if ( (_BYTE)v5 )
return (unsigned int)((int)(a5 + 100 * abs32(v5 - a4) + v5) % a2);
return a5;
}
v8 = (char)v5;
if ( !(_BYTE)v5 )
return a5;
for ( i = (int)(a5 + (char)v5) % a2; ; i = (int)(v11 + i + 100 * abs32(v10)) % a2 )
{
v11 = *++a1;
if ( !(_BYTE)v11 )
break;
v10 = v11 - v8;
v8 = v11;
}
return i;
}

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; // r12
void *v1; // rax
void *v2; // rdi
int v3; // eax
size_t v4; // rdx

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

canonical_decompiled_code:
_QWORD *func3()
{
_QWORD *v0; // r12
void *v1; // rax
void *v2; // rdi
int v3; // eax
size_t v4; // rdx

v0 = malloc(0x10uLL);
if ( !v0 )
fail("couldn't allocate a hash table");
*(_DWORD *)v0 = 241;
v1 = malloc(0x788uLL);
v0[1] = v1;
v2 = v1;
if ( v1 )
{
v3 = 241;
}
else
{
fail("couldn't allocate hash table buckets");
v3 = *(_DWORD *)v0;
if ( *(int *)v0 <= 0 )
return v0;
v2 = (void *)v0[1];
}
v4 = 8LL * v3;
if ( v3 <= 0 )
v4 = 8LL;
memset(v2, 0, 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; } *

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; // r12

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; // r12

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
__int64 v3; // r10
const char *v4; // r11

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

canonical_decompiled_code:
__int64 __fastcall func5(int *a1, char *a2)
{
int v2; // eax
__int64 v3; // r10
const char *v4; // r11

v2 = func1(a2, *a1);
return func4(v3, v4, 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(int *a1, char *a2)
{
__int64 v2; // r10
int result; // eax
__int64 v4; // rbx
const char *v5; // rbp

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

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

result = func1(a2, *a1);
v4 = *(_QWORD *)(*(_QWORD *)(v2 + 8) + 8LL * result);
if ( v4 )
{
while ( 1 )
{
v5 = *(const char **)v4;
result = strcmp(*(const char **)v4, a2);
if ( !result )
break;
v4 = *(_QWORD *)(v4 + 16);
if ( !v4 )
return result;
}
*v5 = 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(int *a1, char *a2, char *a3)
{
int v4; // eax
__int64 v5; // r10
char ***v6; // rbx
char **v7; // rax
char **v8; // rdx
char **v9; // rax
size_t v10; // rax
char **v11; // r13
char *v12; // rax
char *v13; // rdi
char **result; // rax

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

canonical_decompiled_code:
char **__fastcall func7(int *a1, char *a2, char *a3)
{
int v4; // eax
__int64 v5; // r10
char ***v6; // rbx
char **v7; // rax
char **v8; // rdx
char **v9; // rax
size_t v10; // rax
char **v11; // r13
char *v12; // rax
char *v13; // rdi
char **result; // rax

v4 = func1(a2, *a1);
v6 = (char ***)(*(_QWORD *)(v5 + 8) + 8LL * v4);
v7 = *v6;
if ( *v6 )
{
do
{
v8 = v7;
v7 = (char **)v7[2];
}
while ( v7 );
v6 = (char ***)(v8 + 2);
}
v9 = (char **)malloc(0x18uLL);
*v6 = v9;
if ( !v9 )
fail("couldn't create a hash table bucket node");
v10 = strlen(a2);
v11 = *v6;
v12 = (char *)malloc(v10 + 1);
*v11 = v12;
v13 = v12;
if ( !v12 )
{
fail("couldn't allocate a string");
v13 = **v6;
}
strcpy(v13, a2);
(*v6)[1] = a3;
result = *v6;
(*v6)[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; // r12

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

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

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; // r12
void *v1; // rax
_QWORD *result; // rax

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

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

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

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 v2; // rbx
void *v3; // rdi

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

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
__int64 v2; // rbx
void *v3; // rdi

if ( *((int *)ptr + 1) > 0 )
{
v2 = 0LL;
do
{
v3 = *(void **)(*((_QWORD *)ptr + 1) + 8 * v2++);
free(v3);
}
while ( *((_DWORD *)ptr + 1) > (int)v2 );
}
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_11F, &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_11F, &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; // r12
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; // r12
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: i 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; } *

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


decompiled_code:
char *__fastcall expand_dict(char **a1, int a2)
{
int v2; // er14
char *v3; // rax
__int64 i; // rbp
char *result; // rax

v2 = *((_DWORD *)a1 + 5);
*((_DWORD *)a1 + 5) = a2;
v3 = (char *)realloc(*a1, 8LL * a2);
*a1 = v3;
if ( v2 < a2 )
{
for ( i = 8LL * v2; ; i += 8LL )
{
*(_QWORD *)&v3[i] = cgc_malloc(128LL);
if ( i == 8 * ((unsigned int)(a2 - 1 - v2) + (__int64)v2) )
break;
v3 = *a1;
}
}
result = (char *)realloc(a1[1], 8LL * *((int *)a1 + 5));
a1[1] = result;
return result;
}

canonical_decompiled_code:
char *__fastcall func1(char **a1, int a2)
{
int v2; // er14
char *v3; // rax
__int64 i; // rbp
char *result; // rax

v2 = *((_DWORD *)a1 + 5);
*((_DWORD *)a1 + 5) = a2;
v3 = (char *)realloc(*a1, 8LL * a2);
*a1 = v3;
if ( v2 < a2 )
{
for ( i = 8LL * v2; ; i += 8LL )
{
*(_QWORD *)&v3[i] = cgc_malloc(128LL);
if ( i == 8 * ((unsigned int)(a2 - 1 - v2) + (__int64)v2) )
break;
v3 = *a1;
}
}
result = (char *)realloc(a1[1], 8LL * *((int *)a1 + 5));
a1[1] = 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

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


decompiled_code:
__int64 __fastcall dict_search(__int64 *a1, const char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx

v2 = *((int *)a1 + 4);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = *a1;
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), a2) )
{
if ( ++v4 == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v4;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 *a1, const char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx

v2 = *((int *)a1 + 4);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = *a1;
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), a2) )
{
if ( ++v4 == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v4;
}

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 *v3; // rsi
struct _IO_FILE *v4; // rdi
__int64 v5; // rdx
__int64 v6; // rcx

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

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

v2 = 0LL;
putchar(91);
if ( *(int *)(a1 + 16) > 0 )
{
while ( 1 )
{
v3 = *(const char **)(*(_QWORD *)a1 + 8 * v2);
printf("%s: ", v3);
v4 = stdout;
fflush(stdout);
++v2;
printout_tree(v4, v3, v5, v6);
fflush(stdout);
if ( *(_DWORD *)(a1 + 16) <= (int)v2 )
break;
printf(", ");
}
}
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)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx

v2 = *((int *)a2 + 4);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = *a2;
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), s2) )
{
if ( ++v4 == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v4;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s2, __int64 *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx

v2 = *((int *)a2 + 4);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = *a2;
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), s2) )
{
if ( ++v4 == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v4;
}

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

decompiled_code:
__int64 __fastcall subst(unsigned __int8 *a1, __int64 *a2, __int64 *a3)
{
__int64 result; // rax
__int64 i; // rbx
char **v7; // rdx
char *v8; // rdi
char v9; // al
int v10; // eax
__int64 v11; // rdx
int v12; // [rsp+Ch] [rbp-2Ch]
int v13; // [rsp+Ch] [rbp-2Ch]

result = *a1;
if ( (_BYTE)result == 30 )
{
strncpy(buf, *(const char **)(*((_QWORD *)a1 + 1) + 8LL), *(int *)(*((_QWORD *)a1 + 1) + 16LL));
buf[*(int *)(*((_QWORD *)a1 + 1) + 16LL)] = 0;
v10 = findkey(buf, a2);
if ( v10 != -1 )
{
if ( !a3 )
{
v13 = v10;
fail("null pointer substitution....");
v10 = v13;
}
v11 = *(_QWORD *)(*(_QWORD *)(a2[1] + 8LL * v10) + 8LL);
result = *a3;
*(_QWORD *)(*a3 + 8) = v11;
goto LABEL_3;
}
result = *a1;
if ( (_BYTE)result != 9 )
{
LABEL_3:
for ( i = 0LL; *((_DWORD *)a1 + 4) > (unsigned int)i; ++i )
{
v7 = (char **)(*((_QWORD *)a1 + 3) + 8 * i);
v8 = *v7;
v9 = **v7;
if ( v9 != 9 && v9 != 30 )
{
result = *((unsigned int *)v8 + 4);
if ( !(_DWORD)result )
continue;
}
result = subst(v8, a2);
}
return result;
}
}
else if ( (_BYTE)result != 9 )
{
goto LABEL_3;
}
strncpy(buf, *(const char **)(*((_QWORD *)a1 + 1) + 8LL), *(int *)(*((_QWORD *)a1 + 1) + 16LL));
buf[*(int *)(*((_QWORD *)a1 + 1) + 16LL)] = 0;
result = findkey(buf, a2);
if ( (_DWORD)result != -1 )
{
if ( !a3 )
{
v12 = result;
fail("null pointer substitution....");
LODWORD(result) = v12;
}
result = copy_tree(*(_QWORD *)(a2[1] + 8LL * (int)result));
*a3 = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 *a1, __int64 *a2, __int64 *a3)
{
__int64 result; // rax
__int64 i; // rbx
char **v7; // rdx
char *v8; // rdi
char v9; // al
int v10; // eax
__int64 v11; // rdx
int v12; // [rsp+Ch] [rbp-2Ch]
int v13; // [rsp+Ch] [rbp-2Ch]

result = *a1;
if ( (_BYTE)result == 30 )
{
strncpy(buf, *(const char **)(*((_QWORD *)a1 + 1) + 8LL), *(int *)(*((_QWORD *)a1 + 1) + 16LL));
buf[*(int *)(*((_QWORD *)a1 + 1) + 16LL)] = 0;
v10 = func0(buf, a2);
if ( v10 != -1 )
{
if ( !a3 )
{
v13 = v10;
fail("null pointer substitution....");
v10 = v13;
}
v11 = *(_QWORD *)(*(_QWORD *)(a2[1] + 8LL * v10) + 8LL);
result = *a3;
*(_QWORD *)(*a3 + 8) = v11;
goto LABEL_3;
}
result = *a1;
if ( (_BYTE)result != 9 )
{
LABEL_3:
for ( i = 0LL; *((_DWORD *)a1 + 4) > (unsigned int)i; ++i )
{
v7 = (char **)(*((_QWORD *)a1 + 3) + 8 * i);
v8 = *v7;
v9 = **v7;
if ( v9 != 9 && v9 != 30 )
{
result = *((unsigned int *)v8 + 4);
if ( !(_DWORD)result )
continue;
}
result = func1(v8, a2);
}
return result;
}
}
else if ( (_BYTE)result != 9 )
{
goto LABEL_3;
}
strncpy(buf, *(const char **)(*((_QWORD *)a1 + 1) + 8LL), *(int *)(*((_QWORD *)a1 + 1) + 16LL));
buf[*(int *)(*((_QWORD *)a1 + 1) + 16LL)] = 0;
result = func0(buf, a2);
if ( (_DWORD)result != -1 )
{
if ( !a3 )
{
v12 = result;
fail("null pointer substitution....");
LODWORD(result) = v12;
}
result = copy_tree(*(_QWORD *)(a2[1] + 8LL * (int)result));
*a3 = result;
}
return result;
}

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 *


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 func2(__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, int a9, _QWORD **a10)
{
_QWORD **v10; // rbp
_QWORD **i; // rbx
int v12; // esi
int v13; // edi
_QWORD *v14; // rax
int v15; // edx
int v16; // ecx
int v17; // er8
int v18; // er9

fprintf(stderr, "(%s", tree_nam[a7]);
if ( a8 && *(_QWORD *)(a8 + 8) )
{
fputc(58, stderr);
tok_display(stderr);
}
if ( a9 )
{
v10 = a10;
for ( i = a10 + 1; ; ++i )
{
v12 = (int)stderr;
fputc(32, stderr);
v13 = (int)stderr;
fflush(stderr);
v14 = *v10;
v10 = i;
printout_tree(v13, v12, v15, v16, v17, v18, *v14, v14[1], v14[2], v14[3]);
if ( &a10[(unsigned int)(a9 - 1) + 1] == i )
break;
}
}
fputc(41, stderr);
return fflush(stderr);
}

canonical_decompiled_code:
int __fastcall func6(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7, __int64 a8, int a9, _QWORD **a10)
{
_QWORD **v10; // rbp
_QWORD **i; // rbx
int v12; // esi
int v13; // edi
_QWORD *v14; // rax
int v15; // edx
int v16; // ecx
int v17; // er8
int v18; // er9

fprintf(stderr, "(%s", tree_nam[a7]);
if ( a8 && *(_QWORD *)(a8 + 8) )
{
fputc(58, stderr);
tok_display(stderr);
}
if ( a9 )
{
v10 = a10;
for ( i = a10 + 1; ; ++i )
{
v12 = (int)stderr;
fputc(32, stderr);
v13 = (int)stderr;
fflush(stderr);
v14 = *v10;
v10 = i;
func6(v13, v12, v15, v16, v17, v18, *v14, v14[1], v14[2], v14[3]);
if ( &a10[(unsigned int)(a9 - 1) + 1] == i )
break;
}
}
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 func7(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);
}


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); } []


decompiled_code:
void __fastcall __noreturn compiler_fail(const char *a1, __int64 a2, unsigned int a3, int a4)
{
unsigned int v5; // er12
int v6; // ebp
__int64 v7; // rax
__int64 v8; // rdx
FILE *v9; // rdi
char *v10; // rbx
char *v11; // rbp
char v12; // [rsp+1h] [rbp-429h]
char v13[1064]; // [rsp+2h] [rbp-428h] BYREF

if ( a3 )
{
v5 = a3;
v6 = a4;
}
else
{
v5 = *(_DWORD *)(a2 + 20);
v6 = *(_DWORD *)(a2 + 24);
}
fflush(stdout);
fflush(stderr);
strncpy(v13, *((const char **)&code_lines + (int)v5), 0x400uLL);
v7 = 1LL;
v13[1023] = 0;
if ( v13[0] == 10 )
{
v8 = 0LL;
}
else
{
do
v8 = (int)v7++;
while ( *(&v12 + v7) != 10 );
}
v9 = stderr;
v13[v8] = 0;
fprintf(v9, "%s\n", v13);
if ( v6 > 1 )
{
v10 = v13;
v11 = &v13[v6 - 2 + 1];
do
{
while ( *v10 != 9 )
{
++v10;
fputc(32, stderr);
if ( v10 == v11 )
goto LABEL_10;
}
++v10;
fputc(9, stderr);
}
while ( v10 != v11 );
}
LABEL_10:
fputc(94, stderr);
fputc(10, stderr);
fprintf(stderr, "line %d: %s\n", v5, a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(const char *a1, __int64 a2, unsigned int a3, int a4)
{
unsigned int v5; // er12
int v6; // ebp
__int64 v7; // rax
__int64 v8; // rdx
FILE *v9; // rdi
char *v10; // rbx
char *v11; // rbp
char v12; // [rsp+1h] [rbp-429h]
char v13[1064]; // [rsp+2h] [rbp-428h] BYREF

if ( a3 )
{
v5 = a3;
v6 = a4;
}
else
{
v5 = *(_DWORD *)(a2 + 20);
v6 = *(_DWORD *)(a2 + 24);
}
fflush(stdout);
fflush(stderr);
strncpy(v13, *((const char **)&code_lines + (int)v5), 0x400uLL);
v7 = 1LL;
v13[1023] = 0;
if ( v13[0] == 10 )
{
v8 = 0LL;
}
else
{
do
v8 = (int)v7++;
while ( *(&v12 + v7) != 10 );
}
v9 = stderr;
v13[v8] = 0;
fprintf(v9, "%s\n", v13);
if ( v6 > 1 )
{
v10 = v13;
v11 = &v13[v6 - 2 + 1];
do
{
while ( *v10 != 9 )
{
++v10;
fputc(32, stderr);
if ( v10 == v11 )
goto LABEL_10;
}
++v10;
fputc(9, stderr);
}
while ( v10 != v11 );
}
LABEL_10:
fputc(94, stderr);
fputc(10, stderr);
fprintf(stderr, "line %d: %s\n", v5, a1);
exit(1);
}

original_code:
void compiler_fail(char *message, token_t *token,
        int in_line, int in_chr)
{
 char buf[1024];
 int line;
 int chr;
 int i;
 line = in_line ? in_line : token->from_line;
 chr = in_line ? in_chr : token->from_char;
 fflush(stdout);
 fflush(stderr);
 strncpy(buf, code_lines[line], 1024);
 buf[1023] = 0;
 for (i = 0; code_lines[line]; ++i)
  if (buf[i] == '\n') {
   buf[i] = 0;
   break;
  }
 fprintf(stderr, "%s\n", buf);
 for (i = 1; i < chr; ++i)
  if (buf[i - 1] == '\t')
   fputc(buf[i - 1], stderr);
  else
   fputc(' ', stderr);
 fputc('^', stderr);
 fputc('\n', stderr);
 fprintf(stderr, "line %d: %s\n",
  line,
  message);
 exit(1);
}

canonical_original_code:
void compiler_fail(char *message, struct token *token, int in_line, int in_chr)
{
 char buf[1024];
 int line;
 int chr;
 int i;
 line = in_line ? in_line : token->from_line;
 chr = in_line ? in_chr : token->from_char;
 fflush(stdout);
 fflush(stderr);
 strncpy(buf, code_lines[line], 1024);
 buf[1023] = 0;
 for (i = 0; code_lines[line]; ++i)
  if (buf[i] == '\n') {
   buf[i] = 0;
   break;
  }
 fprintf(stderr, "%s\n", buf);
 for (i = 1; i < chr; ++i)
  if (buf[i - 1] == '\t')
   fputc(buf[i - 1], stderr);
  else
   fputc(' ', stderr);
 fputc('^', stderr);
 fputc('\n', stderr);
 fprintf(stderr, "line %d: %s\n",
  line,
  message);
 exit(1);
}

variable_types:
message
char *

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

variable_types:
buf
char [1024]

variable_types: line int

variable_types: chr int

variable_types: i int


fail

decompiled_code:
void __fastcall __noreturn fail(const char *a1)
{
fprintf(stderr, "error: %s\n", a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(const char *a1)
{
fprintf(stderr, "error: %s\n", a1);
exit(1);
}

original_code:
void fail(char* mesg)
{
 fprintf(stderr, "error: %s\n", mesg);
 exit(1);
}

canonical_original_code:
void fail(char *mesg)
{
 fprintf(stderr, "error: %s\n", mesg);
 exit(1);
}

variable_types:
mesg
char *


decompiled_code:
void __fastcall sanity_requires(int a1)
{
if ( !a1 )
fail("that doesn't make any sense");
}

canonical_decompiled_code:
void __fastcall func1(int a1)
{
if ( !a1 )
func0("that doesn't make any sense");
}

original_code:
void sanity_requires(int exp)
{
 if(!exp)
  fail("that doesn't make any sense");
}

variable_types: exp int


decompiled_code:
char *__fastcall get_tok_str(int a1, int a2, int a3, int a4, int a5, int a6, int a7, char *src, int a9)
{
strncpy(buf, src, a9);
buf[a9] = 0;
return buf;
}

canonical_decompiled_code:
char *__fastcall func2(int a1, int a2, int a3, int a4, int a5, int a6, int a7, char *src, int a9)
{
strncpy(buf, src, a9);
buf[a9] = 0;
return buf;
}

original_code:
char* get_tok_str(token_t t)
{
        strncpy(buf, t.start, t.len);
        buf[t.len] = 0;
        return buf;
}

canonical_original_code:
char *get_tok_str(struct token t)
{
        strncpy(buf, t.start, t.len);
        buf[t.len] = 0;
        return buf;
}

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

return_type: char *


decompiled_code:
__int64 __fastcall apply_rules_and_optimize(__int64 a1, unsigned int a2, __int64 a3)
{
unsigned int i; // er12

for ( i = 0; ; i = 1 )
{
if ( (unsigned int)matchloop(a1, a2, a3) )
i = 1;
if ( !(unsigned int)optimize(a3) )
break;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2, __int64 a3)
{
unsigned int i; // er12

for ( i = 0; ; i = 1 )
{
if ( (unsigned int)matchloop(a1, a2, a3) )
i = 1;
if ( !(unsigned int)optimize(a3) )
break;
}
return i;
}

original_code:
int apply_rules_and_optimize(exp_tree_t** rules, int rc, exp_tree_t *tree)
{
 int success = 0;
 while (1) {
  if (matchloop(rules, rc, tree)) {
   success = 1;
  }
  if (optimize(tree)) {
   success = 1;
   continue;
  }
  break;
 }
 return success;
}

canonical_original_code:
int apply_rules_and_optimize(struct exp_tree **rules, int rc, struct exp_tree *tree)
{
 int success = 0;
 while (1) {
  if (matchloop(rules, rc, tree)) {
   success = 1;
  }
  if (optimize(tree)) {
   success = 1;
   continue;
  }
  break;
 }
 return success;
}

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: rc int

variable_types:
tree
struct exp_tree *

variable_types: success int


rule

decompiled_code:
__int64 __fastcall rule(__int64 a1, __int64 a2, int *a3)
{
char *v5; // rdi
__int64 v6; // rsi
__int64 v7; // rcx
__int64 v8; // rdx
__int64 v9; // rcx
__int64 v10; // rax
__int64 v11; // rdx
__int64 *v12; // rbx
__int64 result; // rax
char v14[24]; // [rsp+20h] [rbp-38h] BYREF
_BYTE **v15; // [rsp+38h] [rbp-20h]

v5 = v14;
v6 = tokenize();
parse(v14, v6);
if ( **v15 != 14 )
{
putchar(10);
fail("you asked me to store, as a rule, a non-rule expression :(");
printout_tree("you asked me to store, as a rule, a non-rule expression :(", v6, v8, v9);
v5 = (_BYTE *)(&loc_8 + 2);
putchar(10);
}
v10 = *a3;
v11 = (unsigned int)(v10 + 1);
*a3 = v11;
v12 = (__int64 *)(a2 + 8 * v10);
result = alloc_exptree(v5, v6, v11, v7);
*v12 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, int *a3)
{
char *v5; // rdi
__int64 v6; // rsi
__int64 v7; // rcx
__int64 v8; // rdx
__int64 v9; // rcx
__int64 v10; // rax
__int64 v11; // rdx
__int64 *v12; // rbx
__int64 result; // rax
char v14[24]; // [rsp+20h] [rbp-38h] BYREF
_BYTE **v15; // [rsp+38h] [rbp-20h]

v5 = v14;
v6 = tokenize();
parse(v14, v6);
if ( **v15 != 14 )
{
putchar(10);
fail("you asked me to store, as a rule, a non-rule expression :(");
printout_tree("you asked me to store, as a rule, a non-rule expression :(", v6, v8, v9);
v5 = (_BYTE *)(&loc_8 + 2);
putchar(10);
}
v10 = *a3;
v11 = (unsigned int)(v10 + 1);
*a3 = v11;
v12 = (__int64 *)(a2 + 8 * v10);
result = alloc_exptree(v5, v6, v11, v7);
*v12 = result;
return result;
}

original_code:
void rule(char *r, exp_tree_t **rules, int* rc)
{
 token_t* tokens;
 exp_tree_t tree;
 extern void fail(char*);
 tokens = tokenize(r);
 tree = *((parse(tokens)).child[0]);
 if (tree.head_type != EQL) {
  printf("\n");
  fail("you asked me to store, as a rule, a non-rule expression :(");
  printout_tree(tree);
  printf("\n");
 }
 rules[(*rc)++] = alloc_exptree(tree);
}

canonical_original_code:
void rule(char *r, struct exp_tree **rules, int *rc)
{
 struct token *tokens;
 struct exp_tree tree;
 extern void fail(char *);
 tokens = tokenize(r);
 tree = *((parse(tokens)).child[0]);
 if (tree.head_type != EQL) {
  printf("\n");
  fail("you asked me to store, as a rule, a non-rule expression :(");
  printout_tree(tree);
  printf("\n");
 }
 rules[(*rc)++] = alloc_exptree(tree);
}

variable_types:
r
char *

variable_types:
rc
int *

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:
fail
void (char *)


evlist

decompiled_code:
__int64 __fastcall evlist(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rbx
__int64 *v4; // rbp

result = *(unsigned int *)(a1 + 24);
if ( (int)result > 0 )
{
v3 = 0LL;
do
{
v4 = (__int64 *)(*(_QWORD *)(a1 + 32) + 8 * v3++);
result = eval_apply_tco(0LL, *v4, a2, 0LL, 0LL);
*v4 = result;
}
while ( *(_DWORD *)(a1 + 24) > (int)v3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rbx
__int64 *v4; // rbp

result = *(unsigned int *)(a1 + 24);
if ( (int)result > 0 )
{
v3 = 0LL;
do
{
v4 = (__int64 *)(*(_QWORD *)(a1 + 32) + 8 * v3++);
result = eval_apply_tco(0LL, *v4, a2, 0LL, 0LL);
*v4 = result;
}
while ( *(_DWORD *)(a1 + 24) > (int)v3 );
}
return result;
}

original_code:
void evlist(list_t* l, env_t *env)
{
 int i = 0;
 for (i = 0; i < l->cc; ++i)
  l->c[i] = eval_apply_tco(0, l->c[i], env, ((void *)0), ((void *)0));
}

canonical_original_code:
void evlist(struct list *l, struct env *env)
{
 int i = 0;
 for (i = 0; i < l->cc; ++i)
  l->c[i] = eval_apply_tco(0, l->c[i], env, ((void *)0), ((void *)0));
}

variable_types: struct list { char *head; int type; int val; struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *closure; int cc; int ca; struct list **c; } *

variable_types:
env
struct env *

user_defined_types: struct list { char *head; int type; int val; struct env *closure; int cc; int ca; struct list **c; }


decompiled_code:
int __fastcall error_msg(const char *a1)
{
return printf("Error: %s\n", a1);
}

canonical_decompiled_code:
int __fastcall func1(const char *a1)
{
return printf("Error: %s\n", a1);
}

original_code:
void error_msg(char *s)
{
  printf("Error: %s\n", s);
}

variable_types:
s
char *


decompiled_code:
int __fastcall fatal_error_msg(const char *a1)
{
return printf("Fatal error: %s\n", a1);
}

canonical_decompiled_code:
int __fastcall func2(const char *a1)
{
return printf("Fatal error: %s\n", a1);
}

original_code:
void fatal_error_msg(char *s)
{
  printf("Fatal error: %s\n", s);
}


decompiled_code:
_BOOL8 __fastcall check_comment(char *a1)
{
char v1; // al

while ( 1 )
{
v1 = *a1;
if ( !*a1 )
return 0LL;
if ( (unsigned __int8)(v1 - 9) > 1u && v1 != 32 )
break;
++a1;
}
return v1 == 59;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(char *a1)
{
char v1; // al

while ( 1 )
{
v1 = *a1;
if ( !*a1 )
return 0LL;
if ( (unsigned __int8)(v1 - 9) > 1u && v1 != 32 )
break;
++a1;
}
return v1 == 59;
}


decompiled_code:
void __noreturn code_error()
{
stacktracer_prebarf();
if ( interactive )
longjmp(repl_jmp, 1);
puts("Shutting down.");
exit(1);
}

canonical_decompiled_code:
void __noreturn func4()
{
stacktracer_prebarf();
if ( interactive )
longjmp(repl_jmp, 1);
puts("Shutting down.");
exit(1);
}

original_code:
int code_error()
{
 stacktracer_prebarf();
 if (interactive)
  longjmp(repl_jmp, 1);
 else {
  printf("Shutting down.\n");
  exit(1);
 }
}


decompiled_code:
__int64 __fastcall strip_nl(_BYTE *a1)
{
__int64 result; // rax

while ( 1 )
{
result = (unsigned __int8)*a1;
if ( !(_BYTE)result )
break;
if ( (_BYTE)result == 10 )
{
*a1 = 0;
return result;
}
++a1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(_BYTE *a1)
{
__int64 result; // rax

while ( 1 )
{
result = (unsigned __int8)*a1;
if ( !(_BYTE)result )
break;
if ( (_BYTE)result == 10 )
{
*a1 = 0;
return result;
}
++a1;
}
return result;
}

original_code:
void strip_nl(char *s)
{
 while (*s) {
  if (*s == '\n') {
   *s = 0;
   break;
  }
  ++s;
 }
}


decompiled_code:
void *__fastcall c_malloc(size_t a1)
{
void *v1; // rax
void *v2; // r12

v1 = malloc(a1);
if ( !v1 )
{
fatal_error_msg("malloc() has failed");
exit(1);
}
v2 = v1;
add_ptr(v1);
return v2;
}

canonical_decompiled_code:
void *__fastcall func7(size_t a1)
{
void *v1; // rax
void *v2; // r12

v1 = malloc(a1);
if ( !v1 )
{
func2("malloc() has failed");
exit(1);
}
v2 = v1;
add_ptr(v1);
return v2;
}

original_code:
void *c_malloc(long size)
{
 void *ptr = malloc(size);
 if (!ptr) {
  fatal_error_msg("malloc() has failed");
  exit(1);
 }
 add_ptr(ptr);
 return ptr;
}

variable_types: size long

variable_types:
ptr
void *


original_code:
list_t *cons2list(list_t *c)
{
 list_t *curr = c;
 list_t *nw;
 nw = new_list();
 nw->type = LIST;
 if (curr->cc == 2) {
  do {
   add_child(nw, copy_list(curr->c[0]));
   curr = curr->c[1];
  } while (curr->cc == 2);
 }
 return nw;
}

canonical_original_code:
struct list *cons2list(struct list *c)
{
 struct list *curr = c;
 struct list *nw;
 nw = new_list();
 nw->type = LIST;
 if (curr->cc == 2) {
  do {
   add_child(nw, copy_list(curr->c[0]));
   curr = curr->c[1];
  } while (curr->cc == 2);
 }
 return nw;
}

variable_types:
c
struct list *

return_type: struct list { char *head; int type; int val; struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *closure; int cc; int ca; struct list **c; } *


mksym

decompiled_code:
__int64 __fastcall mksym(char *src)
{
__int64 v1; // r12
__int64 result; // rax

v1 = new_list();
strcpy(*(char **)v1, src);
result = v1;
*(_DWORD *)(v1 + 8) = 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(char *src)
{
__int64 v1; // r12
__int64 result; // rax

v1 = new_list();
strcpy(*(char **)v1, src);
result = v1;
*(_DWORD *)(v1 + 8) = 0;
return result;
}

original_code:
list_t* mksym(char *s)
{
 list_t *sl = new_list();
 strcpy(sl->head, s);
 sl->type = SYMBOL;
 return sl;
}

canonical_original_code:
struct list *mksym(char *s)
{
 struct list *sl = new_list();
 strcpy(sl->head, s);
 sl->type = SYMBOL;
 return sl;
}

user_defined_types: struct env { int count; int alloc; char **sym; void **ptr; struct env *father; }


makelist

original_code:
list_t* makelist(list_t* argl)
{
 list_t *nw, *nw2, *nw3;
 list_t *cons;
 int i;
 nw3 = nw = new_list();
 nw->type = CONS;
 for (i = 0; i < argl->cc; ++i) {
  if (argl->c[i]->type == LIST) {
   cons = makelist(argl->c[i]);
   add_child(nw, cons);
  } else
   add_child(nw, argl->c[i]);
  if ((i + 1) < argl->cc) {
   nw2 = new_list();
   nw2->type = CONS;
   add_child(nw, nw2);
   nw = nw2;
  } else {
   add_child(nw, mksym("NIL"));
  }
 }
 return nw3;
}

canonical_original_code:
struct list *makelist(struct list *argl)
{
 struct list *nw; struct list *nw2; struct list *nw3;
 struct list *cons;
 int i;
 nw3 = nw = new_list();
 nw->type = CONS;
 for (i = 0; i < argl->cc; ++i) {
  if (argl->c[i]->type == LIST) {
   cons = makelist(argl->c[i]);
   add_child(nw, cons);
  } else
   add_child(nw, argl->c[i]);
  if ((i + 1) < argl->cc) {
   nw2 = new_list();
   nw2->type = CONS;
   add_child(nw, nw2);
   nw = nw2;
  } else {
   add_child(nw, mksym("NIL"));
  }
 }
 return nw3;
}

variable_types:
argl
struct list *

variable_types: i int


makebool

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

result = new_list();
*(_DWORD *)(result + 8) = 5;
*(_DWORD *)(result + 12) = a1;
return result;
}

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

result = new_list();
*(_DWORD *)(result + 8) = 5;
*(_DWORD *)(result + 12) = a1;
return result;
}

original_code:
list_t* makebool(int cbool)
{
 list_t *b = new_list();
 b->type = BOOL;
 b->val = cbool;
 return b;
}

canonical_original_code:
struct list *makebool(int cbool)
{
 struct list *b = new_list();
 b->type = BOOL;
 b->val = cbool;
 return b;
}

variable_types: cbool int


isnum

decompiled_code:
_BOOL8 __fastcall isnum(char a1)
{
return (unsigned __int8)(a1 - 48) <= 9u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func12(char a1)
{
return (unsigned __int8)(a1 - 48) <= 9u;
}

original_code:
int isnum(char c)
{
 return c >= '0' && c <= '9';
}

variable_types: c char


decompiled_code:
void *__fastcall better_realloc(void *ptr, size_t a2)
{
void *result; // rax

result = realloc(ptr, a2);
if ( !result )
{
free(ptr);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
void *__fastcall func13(void *ptr, size_t a2)
{
void *result; // rax

result = realloc(ptr, a2);
if ( !result )
{
free(ptr);
result = 0LL;
}
return result;
}

original_code:
void* better_realloc(void *ptr, long size)
{
 void *tmp;
 if (!(tmp = realloc(ptr, size)))
  free(ptr);
 return tmp;
}

canonical_original_code:
void *better_realloc(void *ptr, long size)
{
 void *tmp;
 if (!(tmp = realloc(ptr, size)))
  free(ptr);
 return tmp;
}

variable_types:
tmp
void *


decompiled_code:
__int64 final_clean_up()
{
gc();
return gc_selfdestroy();
}

canonical_decompiled_code:
__int64 func0()
{
gc();
return gc_selfdestroy();
}

original_code:
void final_clean_up()
{
 gc();
 gc_selfdestroy();
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
_BOOL4 v3; // eax
__int64 v4; // rax
__int64 v5; // rbp
_BYTE *ptr; // [rsp+8h] [rbp-420h]
char s[1048]; // [rsp+10h] [rbp-418h] BYREF

ptr = malloc(0x80000uLL);
if ( !ptr )
{
puts("could not allocate a buffer");
exit(1);
}
stacktracer_init();
*ptr = 0;
global = new_env();
install_primitives(global);
load_code_from_file("prefix.txt");
v3 = 0;
if ( argc == 2 )
v3 = strcmp(argv[1], "-i") == 0;
interactive = v3;
if ( setjmp(repl_jmp) )
*ptr = 0;
stacktracer_reset();
while ( 1 )
{
*ptr = 0;
v5 = new_list();
if ( save_mode )
fputc(10, save_file);
if ( !(unsigned int)do_read_file(ptr, stdin, (unsigned int)interactive) )
break;
if ( !*ptr )
break;
build(v5, ptr);
if ( feof(stdin) )
break;
if ( interactive )
{
s[0] = 0;
v4 = eval_apply_tco(0LL, v5, global, 0LL, 0LL);
printout(v4, s);
puts(s);
if ( save_mode )
{
fwrite(";; ", 1uLL, 3uLL, save_file);
fflush(save_file);
fputs(s, save_file);
fputc(10, save_file);
}
}
else
{
eval_apply_tco(0LL, v5, global, 0LL, 0LL);
}
gc();
stacktracer_reset();
}
if ( save_mode )
fclose(save_file);
final_clean_up();
free(ptr);
stacktracer_destroy();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
_BOOL4 v3; // eax
__int64 v4; // rax
__int64 v5; // rbp
_BYTE *ptr; // [rsp+8h] [rbp-420h]
char s[1048]; // [rsp+10h] [rbp-418h] BYREF

ptr = malloc(0x80000uLL);
if ( !ptr )
{
puts("could not allocate a buffer");
exit(1);
}
stacktracer_init();
*ptr = 0;
global = new_env();
install_primitives(global);
load_code_from_file("prefix.txt");
v3 = 0;
if ( argc == 2 )
v3 = strcmp(argv[1], "-i") == 0;
interactive = v3;
if ( setjmp(repl_jmp) )
*ptr = 0;
stacktracer_reset();
while ( 1 )
{
*ptr = 0;
v5 = new_list();
if ( save_mode )
fputc(10, save_file);
if ( !(unsigned int)do_read_file(ptr, stdin, (unsigned int)interactive) )
break;
if ( !*ptr )
break;
build(v5, ptr);
if ( feof(stdin) )
break;
if ( interactive )
{
s[0] = 0;
v4 = eval_apply_tco(0LL, v5, global, 0LL, 0LL);
printout(v4, s);
puts(s);
if ( save_mode )
{
fwrite(";; ", 1uLL, 3uLL, save_file);
fflush(save_file);
fputs(s, save_file);
fputc(10, save_file);
}
}
else
{
eval_apply_tco(0LL, v5, global, 0LL, 0LL);
}
gc();
stacktracer_reset();
}
if ( save_mode )
fclose(save_file);
func0();
free(ptr);
stacktracer_destroy();
return 0;
}

original_code:
int main(int argc, char **argv)
{
 char *buf = malloc(1024 * 512);
 char out[1024];
 list_t *expr;
 if (!buf) {
  printf("could not allocate a buffer\n");
  exit(1);
 }
 stacktracer_init();
 *buf = 0;
 global = new_env();
 install_primitives(global);
 load_code_from_file("prefix.txt");
 interactive = argc == 2 && !strcmp(argv[1], "-i");
 if (_setjmp (repl_jmp))
  *buf = 0;
 stacktracer_reset();
 while (1) {
  *buf = 0;
  expr = new_list();
   if (save_mode)
    fprintf(save_file, "\n");
   if (!do_read_file(buf, stdin, interactive))
    break;
  if (!*buf)
   break;
  build(expr, buf);
  if (feof(stdin))
   break;
  if (interactive) {
   *out = 0;
   printout(eval_apply_tco(0, expr, global, ((void *)0), ((void *)0)), out);
   puts(out);
   if (save_mode) {
    fprintf(save_file, ";; ");
    fflush(save_file);
    fputs(out, save_file);
    fprintf(save_file, "\n");
   }
  } else {
   eval_apply_tco(0, expr, global, ((void *)0), ((void *)0));
  }
  gc();
  stacktracer_reset();
 }
 if (save_mode)
  fclose(save_file);
 final_clean_up();
 free(buf);
 stacktracer_destroy();
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 char *buf = malloc(1024 * 512);
 char out[1024];
 struct list *expr;
 if (!buf) {
  printf("could not allocate a buffer\n");
  exit(1);
 }
 stacktracer_init();
 *buf = 0;
 global = new_env();
 install_primitives(global);
 load_code_from_file("prefix.txt");
 interactive = argc == 2 && !strcmp(argv[1], "-i");
 if (_setjmp (repl_jmp))
  *buf = 0;
 stacktracer_reset();
 while (1) {
  *buf = 0;
  expr = new_list();
   if (save_mode)
    fprintf(save_file, "\n");
   if (!do_read_file(buf, stdin, interactive))
    break;
  if (!*buf)
   break;
  build(expr, buf);
  if (feof(stdin))
   break;
  if (interactive) {
   *out = 0;
   printout(eval_apply_tco(0, expr, global, ((void *)0), ((void *)0)), out);
   puts(out);
   if (save_mode) {
    fprintf(save_file, ";; ");
    fflush(save_file);
    fputs(out, save_file);
    fprintf(save_file, "\n");
   }
  } else {
   eval_apply_tco(0, expr, global, ((void *)0), ((void *)0));
  }
  gc();
  stacktracer_reset();
 }
 if (save_mode)
  fclose(save_file);
 final_clean_up();
 free(buf);
 stacktracer_destroy();
 return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
buf
char *

variable_types:
out
char [1024]


decompiled_code:
_QWORD *new_list()
{
__int64 v0; // rax
_QWORD *v1; // r12
_BYTE *v2; // rax
_QWORD *result; // rax

v0 = c_malloc(40LL);
*(_QWORD *)(v0 + 8) = 0LL;
v1 = (_QWORD *)v0;
v2 = (_BYTE *)c_malloc(32LL);
*v1 = v2;
*v2 = 0;
result = v1;
v1[3] = 0LL;
v1[4] = 0LL;
return result;
}

canonical_decompiled_code:
_QWORD *func0()
{
__int64 v0; // rax
_QWORD *v1; // r12
_BYTE *v2; // rax
_QWORD *result; // rax

v0 = c_malloc(40LL);
*(_QWORD *)(v0 + 8) = 0LL;
v1 = (_QWORD *)v0;
v2 = (_BYTE *)c_malloc(32LL);
*v1 = v2;
*v2 = 0;
result = v1;
v1[3] = 0LL;
v1[4] = 0LL;
return result;
}

original_code:
list_t *new_list(void)
{
 list_t* nl = c_malloc(sizeof(list_t));
 nl->type = SYMBOL;
 nl->val = 0;
 nl->head = c_malloc(32);
 nl->head[0] = 0;
 nl->c = ((void *)0);
 nl->ca = 0;
 nl->cc = 0;
 return nl;
}

canonical_original_code:
struct list *new_list()
{
 struct list *nl = c_malloc(sizeof(list_t));
 nl->type = SYMBOL;
 nl->val = 0;
 nl->head = c_malloc(32);
 nl->head[0] = 0;
 nl->c = ((void *)0);
 nl->ca = 0;
 nl->cc = 0;
 return nl;
}


original_code:
void add_child(list_t *parent, list_t* child)
{
 list_t **new;
 int i;
 if (++(parent->cc) >= parent->ca) {
  parent->ca += 16;
  new = c_malloc(parent->ca * sizeof(list_t *));
  for (i = 0; i < parent->ca - 16; ++i)
   new[i] = parent->c[i];
  parent->c = new;
 }
 parent->c[parent->cc - 1] = child;
}

canonical_original_code:
void add_child(struct list *parent, struct list *child)
{
 struct list **new;
 int i;
 if (++(parent->cc) >= parent->ca) {
  parent->ca += 16;
  new = c_malloc(parent->ca * sizeof(struct list *));
  for (i = 0; i < parent->ca - 16; ++i)
   new[i] = parent->c[i];
  parent->c = new;
 }
 parent->c[parent->cc - 1] = child;
}

variable_types:
child
struct list *

variable_types: struct list { char *head; int type; int val; struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *closure; int cc; int ca; struct list **c; } **


original_code:
env_t* new_env(void)
{
 env_t *e = c_malloc(sizeof(env_t));
 e->count = 0;
 e->father = ((void *)0);
 e->alloc = 8;
 e->sym = c_malloc(e->alloc * sizeof(char *));
 e->ptr = c_malloc(e->alloc * sizeof(void *));
 return e;
}

canonical_original_code:
struct env *new_env()
{
 struct env *e = c_malloc(sizeof(env_t));
 e->count = 0;
 e->father = ((void *)0);
 e->alloc = 8;
 e->sym = c_malloc(e->alloc * sizeof(char *));
 e->ptr = c_malloc(e->alloc * sizeof(void *));
 return e;
}

variable_types: struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *


lookup

decompiled_code:
__int64 __fastcall lookup(int *a1, const char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx
__int64 result; // rax

v2 = *a1;
if ( (int)v2 <= 0 )
{
LABEL_6:
result = *((_QWORD *)a1 + 3);
if ( result )
result = lookup(result, a2, 0LL);
}
else
{
v3 = *((_QWORD *)a1 + 1);
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), a2) )
{
if ( ++v4 == v2 )
goto LABEL_6;
}
result = (__int64)a1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int *a1, const char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
__int64 v4; // rbx
__int64 result; // rax

v2 = *a1;
if ( (int)v2 <= 0 )
{
LABEL_6:
result = *((_QWORD *)a1 + 3);
if ( result )
result = func1(result, a2, 0LL);
}
else
{
v3 = *((_QWORD *)a1 + 1);
v4 = 0LL;
while ( strcmp(*(const char **)(v3 + 8 * v4), a2) )
{
if ( ++v4 == v2 )
goto LABEL_6;
}
result = (__int64)a1;
}
return result;
}

original_code:
env_ref_t lookup(env_t *e, char *sym)
{
 int i;
 env_ref_t ret;
 for (i = 0; i < e->count; ++i) {
  if (!strcmp(e->sym[i], sym)) {
   ret.i = i;
   ret.e = e;
   return ret;
  }
 }
 ret.i = 0;
 ret.e = ((void *)0);
 if (e->father)
  ret = lookup(e->father, sym);
 return ret;
}

canonical_original_code:
struct env_ref lookup(struct env *e, char *sym)
{
 int i;
 struct env_ref ret;
 for (i = 0; i < e->count; ++i) {
  if (!strcmp(e->sym[i], sym)) {
   ret.i = i;
   ret.e = e;
   return ret;
  }
 }
 ret.i = 0;
 ret.e = ((void *)0);
 if (e->father)
  ret = lookup(e->father, sym);
 return ret;
}

variable_types:
e
struct env *

variable_types:
sym
char *

variable_types: struct env_ref { struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *e; int i; }

user_defined_types: struct env_ref { struct env *e; int i; }


decompiled_code:
__int64 __fastcall env_set(int *a1, const char *a2, __int64 a3)
{
__int64 v4; // rbp
int v5; // edx
int v6; // ebx
size_t v7; // rax
_QWORD *v8; // r14
__int64 result; // rax
char *v10; // r14

v4 = lookup(a1, a2);
v6 = v5;
if ( !v4 )
{
v10 = (char *)malloc(0x20uLL);
if ( !v10 )
{
error_msg("malloc failed");
code_error();
}
sprintf(v10, "unbound variable `%s'", a2);
error_msg(v10);
free(v10);
code_error();
}
v7 = strlen(a2);
v8 = (_QWORD *)(*(_QWORD *)(v4 + 8) + 8LL * v6);
*v8 = c_malloc(v7 + 1);
strcpy(*(char **)(*(_QWORD *)(v4 + 8) + 8LL * v6), a2);
result = *(_QWORD *)(v4 + 16);
*(_QWORD *)(result + 8LL * v6) = a3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int *a1, const char *a2, __int64 a3)
{
__int64 v4; // rbp
int v5; // edx
int v6; // ebx
size_t v7; // rax
_QWORD *v8; // r14
__int64 result; // rax
char *v10; // r14

v4 = func1(a1, a2);
v6 = v5;
if ( !v4 )
{
v10 = (char *)malloc(0x20uLL);
if ( !v10 )
{
error_msg("malloc failed");
code_error();
}
sprintf(v10, "unbound variable `%s'", a2);
error_msg(v10);
free(v10);
code_error();
}
v7 = strlen(a2);
v8 = (_QWORD *)(*(_QWORD *)(v4 + 8) + 8LL * v6);
*v8 = c_malloc(v7 + 1);
strcpy(*(char **)(*(_QWORD *)(v4 + 8) + 8LL * v6), a2);
result = *(_QWORD *)(v4 + 16);
*(_QWORD *)(result + 8LL * v6) = a3;
return result;
}

original_code:
void env_set(env_t *e, char *sym, void *p)
{
 env_ref_t ref = lookup(e, sym);
 char *tmp;
 if (ref.e == ((void *)0)) {
  tmp = malloc(32);
  if (!tmp) {
   error_msg("malloc failed");
   code_error();
  }
  sprintf(tmp, "unbound variable `%s'", sym);
  error_msg(tmp);
  free(tmp);
  code_error();
 }
 (ref.e)->sym[ref.i] = c_malloc(strlen(sym) + 1);
 strcpy((ref.e)->sym[ref.i], sym);
 (ref.e)->ptr[ref.i] = p;
}

canonical_original_code:
void env_set(struct env *e, char *sym, void *p)
{
 struct env_ref ref = lookup(e, sym);
 char *tmp;
 if (ref.e == ((void *)0)) {
  tmp = malloc(32);
  if (!tmp) {
   error_msg("malloc failed");
   code_error();
  }
  sprintf(tmp, "unbound variable `%s'", sym);
  error_msg(tmp);
  free(tmp);
  code_error();
 }
 (ref.e)->sym[ref.i] = c_malloc(strlen(sym) + 1);
 strcpy((ref.e)->sym[ref.i], sym);
 (ref.e)->ptr[ref.i] = p;
}

variable_types:
p
void *

variable_types:
tmp
char *


original_code:
void env_add(env_t *e, char *sym, void *p)
{
 int c = e->count;
 char **nsym;
 void **nptr;
 int i;
 if ((lookup(e, sym)).e == e) {
  env_set(e, sym, p);
  return;
 }
 if (++(e->count) >= e->alloc) {
  e->alloc += 16;
  nsym = c_malloc(e->alloc * sizeof(char *));
  nptr = c_malloc(e->alloc * sizeof(void *));
  for (i = 0; i < e->alloc - 16; ++i) {
   nsym[i] = e->sym[i];
   nptr[i] = e->ptr[i];
  }
  e->sym = nsym;
  e->ptr = nptr;
 }
 e->sym[c] = c_malloc(strlen(sym) + 1);
 strcpy(e->sym[c], sym);
 e->ptr[c] = p;
}

canonical_original_code:
void env_add(struct env *e, char *sym, void *p)
{
 int c = e->count;
 char **nsym;
 void **nptr;
 int i;
 if ((lookup(e, sym)).e == e) {
  env_set(e, sym, p);
  return;
 }
 if (++(e->count) >= e->alloc) {
  e->alloc += 16;
  nsym = c_malloc(e->alloc * sizeof(char *));
  nptr = c_malloc(e->alloc * sizeof(void *));
  for (i = 0; i < e->alloc - 16; ++i) {
   nsym[i] = e->sym[i];
   nptr[i] = e->ptr[i];
  }
  e->sym = nsym;
  e->ptr = nptr;
 }
 e->sym[c] = c_malloc(strlen(sym) + 1);
 strcpy(e->sym[c], sym);
 e->ptr[c] = p;
}

variable_types: c int

variable_types:
nsym
char **

variable_types:
nptr
void **


decompiled_code:
__int64 __fastcall add_primop(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // r12
__int64 v4; // rax
__int64 v5; // rax

v2 = new_list();
*(_DWORD *)(v2 + 8) = 2;
v3 = v2;
v4 = mksym("PRIM-OP");
add_child(v3, v4);
v5 = mksym(a2);
add_child(v3, v5);
return env_add(a1, a2, v3);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // r12
__int64 v4; // rax
__int64 v5; // rax

v2 = new_list();
*(_DWORD *)(v2 + 8) = 2;
v3 = v2;
v4 = mksym("PRIM-OP");
add_child(v3, v4);
v5 = mksym(a2);
add_child(v3, v5);
return env_add(a1, a2, v3);
}

original_code:
void add_primop(env_t *e, char *sym)
{
 list_t *l = new_list();
 l->type = LIST;
 add_child(l, mksym("PRIM-OP"));
 add_child(l, mksym(sym));
 env_add(e, sym, l);
}

canonical_original_code:
void add_primop(struct env *e, char *sym)
{
 struct list *l = new_list();
 l->type = LIST;
 add_child(l, mksym("PRIM-OP"));
 add_child(l, mksym(sym));
 env_add(e, sym, l);
}

variable_types: struct list { char *head; int type; int val; struct env { int count; int alloc; char **sym; void **ptr; struct env *father; } *closure; int cc; int ca; struct list **c; } *


decompiled_code:
__int64 __fastcall install_primitives(__int64 a1)
{
add_primop(a1, (__int64)"+");
add_primop(a1, (__int64)"-");
add_primop(a1, (__int64)"*");
add_primop(a1, (__int64)"remainder");
add_primop(a1, (__int64)"=");
add_primop(a1, (__int64)">");
add_primop(a1, (__int64)"<");
add_primop(a1, (__int64)">=");
add_primop(a1, (__int64)"<=");
add_primop(a1, (__int64)"not");
add_primop(a1, (__int64)"car");
add_primop(a1, (__int64)"cdr");
add_primop(a1, (__int64)"cons");
add_primop(a1, (__int64)"null?");
add_primop(a1, (__int64)"display");
add_primop(a1, (__int64)"newline");
add_primop(a1, (__int64)"pair?");
add_primop(a1, (__int64)"symbol?");
add_primop(a1, (__int64)"eq?");
add_primop(a1, (__int64)"number?");
add_primop(a1, (__int64)"newline");
add_primop(a1, (__int64)"save-to");
add_primop(a1, (__int64)"load");
add_primop(a1, (__int64)"cons2list");
add_primop(a1, (__int64)"debuglog");
return add_primop(a1, (__int64)"reverse");
}

original_code:
void install_primitives(env_t *env)
{
 add_primop(env, "+");
 add_primop(env, "-");
 add_primop(env, "*");
 add_primop(env, "remainder");
 add_primop(env, "=");
 add_primop(env, ">");
 add_primop(env, "<");
 add_primop(env, ">=");
 add_primop(env, "<=");
 add_primop(env, "not");
 add_primop(env, "car");
 add_primop(env, "cdr");
 add_primop(env, "cons");
 add_primop(env, "null?");
 add_primop(env, "display");
 add_primop(env, "newline");
 add_primop(env, "pair?");
 add_primop(env, "symbol?");
 add_primop(env, "eq?");
 add_primop(env, "number?");
 add_primop(env, "newline");
 add_primop(env, "save-to");
 add_primop(env, "load");
 add_primop(env, "cons2list");
 add_primop(env, "debuglog");
 add_primop(env, "reverse");
}

canonical_original_code:
void install_primitives(struct env *env)
{
 add_primop(env, "+");
 add_primop(env, "-");
 add_primop(env, "*");
 add_primop(env, "remainder");
 add_primop(env, "=");
 add_primop(env, ">");
 add_primop(env, "<");
 add_primop(env, ">=");
 add_primop(env, "<=");
 add_primop(env, "not");
 add_primop(env, "car");
 add_primop(env, "cdr");
 add_primop(env, "cons");
 add_primop(env, "null?");
 add_primop(env, "display");
 add_primop(env, "newline");
 add_primop(env, "pair?");
 add_primop(env, "symbol?");
 add_primop(env, "eq?");
 add_primop(env, "number?");
 add_primop(env, "newline");
 add_primop(env, "save-to");
 add_primop(env, "load");
 add_primop(env, "cons2list");
 add_primop(env, "debuglog");
 add_primop(env, "reverse");
}


decompiled_code:
void stacktracer_reset()
{
ptr = 0;
full = 0;
sym = 0;
sym_ptr = 0;
}

canonical_decompiled_code:
void func0()
{
ptr = 0;
full = 0;
sym = 0;
sym_ptr = 0;
}


decompiled_code:
void stacktracer_init()
{
char *v0; // rax
_QWORD *v1; // rbx
char *v2; // rbp
char *v3; // r12
_QWORD *v4; // r13
void *v5; // rax
__int64 i; // rbx
void *v7; // rax
void *v8; // rax

debug_buff_written = 0;
v0 = (char *)malloc(0x800uLL);
debug_buff = v0;
if ( !v0
|| (*v0 = 0, stacktraces = malloc(0x28uLL), (v1 = stacktraces) == 0LL)
|| (sym_name = malloc(0x40uLL), (v2 = (char *)sym_name) == 0LL)
|| (sym_print = malloc(0x40uLL), (v3 = (char *)sym_print) == 0LL) )
{
LABEL_13:
error_msg("stacktracer_init() has failed");
exit(1);
}
v4 = v1 + 5;
do
{
v5 = malloc(0x800uLL);
*v1 = v5;
if ( !v5 )
goto LABEL_13;
++v1;
}
while ( v4 != v1 );
for ( i = 0LL; i != 64; i += 8LL )
{
v7 = malloc(0x20uLL);
*(_QWORD *)&v2[i] = v7;
if ( !v7 )
goto LABEL_13;
v8 = malloc(0x400uLL);
*(_QWORD *)&v3[i] = v8;
if ( !v8 )
goto LABEL_13;
}
stacktracer_reset();
}

canonical_decompiled_code:
void func1()
{
char *v0; // rax
_QWORD *v1; // rbx
char *v2; // rbp
char *v3; // r12
_QWORD *v4; // r13
void *v5; // rax
__int64 i; // rbx
void *v7; // rax
void *v8; // rax

debug_buff_written = 0;
v0 = (char *)malloc(0x800uLL);
debug_buff = v0;
if ( !v0
|| (*v0 = 0, stacktraces = malloc(0x28uLL), (v1 = stacktraces) == 0LL)
|| (sym_name = malloc(0x40uLL), (v2 = (char *)sym_name) == 0LL)
|| (sym_print = malloc(0x40uLL), (v3 = (char *)sym_print) == 0LL) )
{
LABEL_13:
error_msg("stacktracer_init() has failed");
exit(1);
}
v4 = v1 + 5;
do
{
v5 = malloc(0x800uLL);
*v1 = v5;
if ( !v5 )
goto LABEL_13;
++v1;
}
while ( v4 != v1 );
for ( i = 0LL; i != 64; i += 8LL )
{
v7 = malloc(0x20uLL);
*(_QWORD *)&v2[i] = v7;
if ( !v7 )
goto LABEL_13;
v8 = malloc(0x400uLL);
*(_QWORD *)&v3[i] = v8;
if ( !v8 )
goto LABEL_13;
}
func0();
}

original_code:
void stacktracer_init()
{
 int i;
 debug_buff_written = 0;
 debug_buff = malloc(1024 * 2);
 if (!debug_buff)
  goto fail;
 *debug_buff = 0;
 stacktraces = malloc(5 * sizeof(char *));
 if (!stacktraces)
  goto fail;
 sym_name = malloc(8 * sizeof(char *));
 if (!sym_name)
  goto fail;
 sym_print = malloc(8 * sizeof(char *));
 if (!sym_print)
  goto fail;
 for (i = 0; i < 5; ++i) {
  stacktraces[i] = malloc(1024 * 2);
  if (!(stacktraces[i]))
   goto fail;
 }
 for (i = 0; i < 8; ++i) {
  sym_name[i] = malloc(32);
  if (!(sym_name[i]))
   goto fail;
  sym_print[i] = malloc(1024);
  if (!(sym_print[i]))
   goto fail;
 }
 stacktracer_reset();
 return;
fail:
 error_msg("stacktracer_init() has failed");
 exit(1);
}

variable_types: i int


decompiled_code:
void stacktracer_destroy()
{
void *v0; // r12
void **v1; // rbx
void **v2; // rbp
void *v3; // rdi
char *v4; // r13
char *v5; // rbp
__int64 i; // rbx
void *v7; // rdi

v0 = stacktraces;
v1 = (void **)stacktraces;
v2 = (void **)((char *)stacktraces + 40);
do
{
v3 = *v1++;
free(v3);
}
while ( v2 != v1 );
v4 = (char *)sym_name;
v5 = (char *)sym_print;
for ( i = 0LL; i != 64; i += 8LL )
{
free(*(void **)&v4[i]);
v7 = *(void **)&v5[i];
free(v7);
}
free(v0);
free(v4);
free(v5);
free(debug_buff);
}

canonical_decompiled_code:
void func2()
{
void *v0; // r12
void **v1; // rbx
void **v2; // rbp
void *v3; // rdi
char *v4; // r13
char *v5; // rbp
__int64 i; // rbx
void *v7; // rdi

v0 = stacktraces;
v1 = (void **)stacktraces;
v2 = (void **)((char *)stacktraces + 40);
do
{
v3 = *v1++;
free(v3);
}
while ( v2 != v1 );
v4 = (char *)sym_name;
v5 = (char *)sym_print;
for ( i = 0LL; i != 64; i += 8LL )
{
free(*(void **)&v4[i]);
v7 = *(void **)&v5[i];
free(v7);
}
free(v0);
free(v4);
free(v5);
free(debug_buff);
}

original_code:
void stacktracer_destroy()
{
 int i;
 for (i = 0; i < 5; ++i) {
  free(stacktraces[i]);
 }
 for (i = 0; i < 8; ++i) {
  free(sym_name[i]);
  free(sym_print[i]);
 }
 free(stacktraces);
 free(sym_name);
 free(sym_print);
 free(debug_buff);
}


decompiled_code:
size_t __fastcall stacktracer_push(const char *a1)
{
size_t result; // rax
unsigned int v3; // eax
int v4; // er8
char *v5; // rcx
_BYTE *v6; // rdi
signed __int64 v7; // rcx
const char *v8; // rsi
__int64 v9; // rcx

result = strlen(a1);
if ( result <= 0x800 )
{
v3 = result + 1;
v4 = ptr;
v5 = (char *)*((_QWORD *)stacktraces + ptr);
if ( v3 >= 8 )
{
v6 = (_BYTE *)((unsigned __int64)(v5 + 8) & 0xFFFFFFFFFFFFFFF8LL);
*(_QWORD *)v5 = *(_QWORD *)a1;
*(_QWORD *)&v5[v3 - 8] = *(_QWORD *)&a1[v3 - 8];
v7 = v5 - v6;
v8 = &a1[-v7];
v9 = ((unsigned int)v7 + v3) >> 3;
result = (unsigned int)(v4 + 1);
qmemcpy(v6, v8, 8 * v9);
if ( (int)result <= 4 )
{
LABEL_6:
ptr = result;
return result;
}
}
else
{
if ( (v3 & 4) != 0 )
{
*(_DWORD *)v5 = *(_DWORD *)a1;
*(_DWORD *)&v5[v3 - 4] = *(_DWORD *)&a1[v3 - 4];
}
else if ( v3 )
{
*v5 = *a1;
if ( (v3 & 2) != 0 )
*(_WORD *)&v5[v3 - 2] = *(_WORD *)&a1[v3 - 2];
}
result = (unsigned int)(v4 + 1);
if ( (int)result <= 4 )
goto LABEL_6;
}
ptr = 0;
full = 1;
}
return result;
}

canonical_decompiled_code:
size_t __fastcall func3(const char *a1)
{
size_t result; // rax
unsigned int v3; // eax
int v4; // er8
char *v5; // rcx
_BYTE *v6; // rdi
signed __int64 v7; // rcx
const char *v8; // rsi
__int64 v9; // rcx

result = strlen(a1);
if ( result <= 0x800 )
{
v3 = result + 1;
v4 = ptr;
v5 = (char *)*((_QWORD *)stacktraces + ptr);
if ( v3 >= 8 )
{
v6 = (_BYTE *)((unsigned __int64)(v5 + 8) & 0xFFFFFFFFFFFFFFF8LL);
*(_QWORD *)v5 = *(_QWORD *)a1;
*(_QWORD *)&v5[v3 - 8] = *(_QWORD *)&a1[v3 - 8];
v7 = v5 - v6;
v8 = &a1[-v7];
v9 = ((unsigned int)v7 + v3) >> 3;
result = (unsigned int)(v4 + 1);
qmemcpy(v6, v8, 8 * v9);
if ( (int)result <= 4 )
{
LABEL_6:
ptr = result;
return result;
}
}
else
{
if ( (v3 & 4) != 0 )
{
*(_DWORD *)v5 = *(_DWORD *)a1;
*(_DWORD *)&v5[v3 - 4] = *(_DWORD *)&a1[v3 - 4];
}
else if ( v3 )
{
*v5 = *a1;
if ( (v3 & 2) != 0 )
*(_WORD *)&v5[v3 - 2] = *(_WORD *)&a1[v3 - 2];
}
result = (unsigned int)(v4 + 1);
if ( (int)result <= 4 )
goto LABEL_6;
}
ptr = 0;
full = 1;
}
return result;
}

original_code:
void stacktracer_push(char *s)
{
 if (strlen(s) > 1024 * 2)
  return;
 strcpy(stacktraces[ptr], s);
 if (++ptr >= 5) {
  ptr = 0;
  full = 1;
 }
}

variable_types:
s
char *


original_code:
void stacktracer_push_sym(char *symb, char *prnt)
{
 int i;
 if (strlen(symb) > 32
  || strlen(prnt) > 1024 * 2)
  return;
 for (i = 0; i < sym; ++i) {
  if (!strcmp(sym_name[i], symb)) {
   strcpy(sym_name[i], symb);
   strcpy(sym_print[i], prnt);
   return;
  }
 }
 if (sym_ptr >= 8)
  sym_ptr = 0;
 strcpy(sym_name[sym_ptr], symb);
 strcpy(sym_print[sym_ptr], prnt);
 if (++sym >= 8)
  sym = 8 - 1;
 ++sym_ptr;
}

variable_types:
symb
char *

variable_types:
prnt
char *


decompiled_code:
// attributes: thunk
int stacktracer_print(const char *s)
{
return puts(s);
}

canonical_decompiled_code:
int func5(const char *s)
{
return puts(s);
}

original_code:
void stacktracer_print(char *s)
{
  printf("%s\n", s);
}


decompiled_code:
int stacktracer_barf()
{
int result; // eax

if ( debug_buff_written )
result = stacktracer_print(debug_buff);
else
result = stacktracer_print("no debug log available");
return result;
}

canonical_decompiled_code:
int func6()
{
int result; // eax

if ( debug_buff_written )
result = func5(debug_buff);
else
result = func5("no debug log available");
return result;
}

original_code:
void stacktracer_barf()
{
 if (debug_buff_written)
  stacktracer_print(debug_buff);
 else
  stacktracer_print("no debug log available");
}