decompiled_code:
__int64 __fastcall is_list(unsigned int a1)
{
unsigned int v1; // ebp
unsigned int v2; // eax
__int64 result; // rax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
bool v7; // zf

v1 = a1;
v2 = ((__int64 (*)(void))is_null)();
if ( (unsigned int)is_true(v2) )
return a_true;
v4 = is_pair(a1);
if ( !(unsigned int)is_true(v4) )
return a_false;
while ( 1 )
{
v5 = is_pair(v1);
if ( !(unsigned int)is_true(v5) )
break;
v1 = cdr(v1);
}
v6 = is_null(v1);
v7 = (unsigned int)is_true(v6) == 0;
result = a_true;
if ( v7 )
result = a_false;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1)
{
unsigned int v1; // ebp
unsigned int v2; // eax
__int64 result; // rax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
bool v7; // zf

v1 = a1;
v2 = ((__int64 (*)(void))is_null)();
if ( (unsigned int)is_true(v2) )
return a_true;
v4 = is_pair(a1);
if ( !(unsigned int)is_true(v4) )
return a_false;
while ( 1 )
{
v5 = is_pair(v1);
if ( !(unsigned int)is_true(v5) )
break;
v1 = cdr(v1);
}
v6 = is_null(v1);
v7 = (unsigned int)is_true(v6) == 0;
result = a_true;
if ( v7 )
result = a_false;
return result;
}

original_code:
cellpoint is_list(cellpoint point)
{
    if (is_true(is_null(point))){
        return a_true;
    }else if (is_true(is_pair(point))){
  while (is_true(is_pair(point))){
   point = cdr(point);
  }
  if (is_true(is_null(point))){
   return a_true;
  }else {
   return a_false;
  }
 }else {
        return a_false;
    }
}

canonical_original_code:
unsigned int is_list(unsigned int point)
{
    if (is_true(is_null(point))){
        return a_true;
    }else if (is_true(is_pair(point))){
  while (is_true(is_pair(point))){
   point = cdr(point);
  }
  if (is_true(is_null(point))){
   return a_true;
  }else {
   return a_false;
  }
 }else {
        return a_false;
    }
}

variable_types:
point
unsigned int


decompiled_code:
__int64 list_eq()
{
int v0; // ebx
unsigned int v1; // eax
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
unsigned int v10; // eax
unsigned int v11; // eax
unsigned int v12; // eax
int v13; // eax
__int64 result; // rax
unsigned int v15; // eax

v0 = args_ref(1LL);
if ( v0 == (unsigned int)args_ref(2LL) )
{
args_pop(2LL);
result = a_true;
}
else
{
v1 = args_ref(1LL);
stack_push(&vars_stack, v1);
reg = args_ref(2LL);
while ( 1 )
{
v9 = stack_top(&vars_stack);
v10 = is_null(v9);
if ( !(unsigned int)is_false(v10) )
break;
v2 = is_null((unsigned int)reg);
if ( !(unsigned int)is_false(v2) )
break;
v3 = car((unsigned int)reg);
args_push(v3);
v4 = stack_top(&vars_stack);
v5 = car(v4);
args_push(v5);
stack_push(&vars_stack, (unsigned int)reg);
reg = equal();
if ( (unsigned int)is_false((unsigned int)reg) )
{
reg = stack_pop(&vars_stack);
break;
}
v6 = stack_pop(&vars_stack);
reg = cdr(v6);
v7 = stack_pop(&vars_stack);
v8 = cdr(v7);
stack_push(&vars_stack, v8);
}
v11 = stack_pop(&vars_stack);
v12 = is_null(v11);
if ( (unsigned int)is_true(v12) && (v15 = is_null((unsigned int)reg), (unsigned int)is_true(v15)) )
v13 = a_true;
else
v13 = a_false;
reg = v13;
args_pop(2LL);
result = (unsigned int)reg;
}
return result;
}

canonical_decompiled_code:
__int64 func1()
{
int v0; // ebx
unsigned int v1; // eax
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
unsigned int v10; // eax
unsigned int v11; // eax
unsigned int v12; // eax
int v13; // eax
__int64 result; // rax
unsigned int v15; // eax

v0 = args_ref(1LL);
if ( v0 == (unsigned int)args_ref(2LL) )
{
args_pop(2LL);
result = a_true;
}
else
{
v1 = args_ref(1LL);
stack_push(&vars_stack, v1);
reg = args_ref(2LL);
while ( 1 )
{
v9 = stack_top(&vars_stack);
v10 = is_null(v9);
if ( !(unsigned int)is_false(v10) )
break;
v2 = is_null((unsigned int)reg);
if ( !(unsigned int)is_false(v2) )
break;
v3 = car((unsigned int)reg);
args_push(v3);
v4 = stack_top(&vars_stack);
v5 = car(v4);
args_push(v5);
stack_push(&vars_stack, (unsigned int)reg);
reg = equal();
if ( (unsigned int)is_false((unsigned int)reg) )
{
reg = stack_pop(&vars_stack);
break;
}
v6 = stack_pop(&vars_stack);
reg = cdr(v6);
v7 = stack_pop(&vars_stack);
v8 = cdr(v7);
stack_push(&vars_stack, v8);
}
v11 = stack_pop(&vars_stack);
v12 = is_null(v11);
if ( (unsigned int)is_true(v12) && (v15 = is_null((unsigned int)reg), (unsigned int)is_true(v15)) )
v13 = a_true;
else
v13 = a_false;
reg = v13;
args_pop(2LL);
result = (unsigned int)reg;
}
return result;
}

original_code:
cellpoint list_eq(void)
{
    if (args_ref(1) == args_ref(2)){
  args_pop(2);
        return a_true;
    }
 stack_push(&vars_stack, args_ref(1));
 reg = args_ref(2);
    while (is_false(is_null(stack_top(&vars_stack))) &&
     is_false(is_null(reg))){
  args_push(car(reg));
  args_push(car(stack_top(&vars_stack)));
  stack_push(&vars_stack, reg);
  reg = equal();
        if (is_false(reg)){
   reg = stack_pop(&vars_stack);
   break;
        }
        reg = cdr(stack_pop(&vars_stack));
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
    }
    if (is_true(is_null(stack_pop(&vars_stack))) &&
  is_true(is_null(reg))){
  reg = a_true;
    }else {
  reg = a_false;
    }
 args_pop(2);
 return reg;
}

canonical_original_code:
unsigned int list_eq()
{
    if (args_ref(1) == args_ref(2)){
  args_pop(2);
        return a_true;
    }
 stack_push(&vars_stack, args_ref(1));
 reg = args_ref(2);
    while (is_false(is_null(stack_top(&vars_stack))) &&
     is_false(is_null(reg))){
  args_push(car(reg));
  args_push(car(stack_top(&vars_stack)));
  stack_push(&vars_stack, reg);
  reg = equal();
        if (is_false(reg)){
   reg = stack_pop(&vars_stack);
   break;
        }
        reg = cdr(stack_pop(&vars_stack));
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
    }
    if (is_true(is_null(stack_pop(&vars_stack))) &&
  is_true(is_null(reg))){
  reg = a_true;
    }else {
  reg = a_false;
    }
 args_pop(2);
 return reg;
}

return_type: unsigned int


decompiled_code:
__int64 list_len()
{
unsigned int v0; // ebp
__int64 i; // rdi
unsigned int v2; // eax

v0 = 0;
reg = args_ref(1LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v2 = is_null(i);
if ( !(unsigned int)is_false(v2) )
break;
++v0;
reg = cdr((unsigned int)reg);
}
args_pop(1LL);
return make_integer(v0);
}

canonical_decompiled_code:
__int64 func2()
{
unsigned int v0; // ebp
__int64 i; // rdi
unsigned int v2; // eax

v0 = 0;
reg = args_ref(1LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v2 = is_null(i);
if ( !(unsigned int)is_false(v2) )
break;
++v0;
reg = cdr((unsigned int)reg);
}
args_pop(1LL);
return make_integer(v0);
}

original_code:
cellpoint list_len(void)
{
    int len = 0;
 reg = args_ref(1);
 while (is_false(is_null(reg))){
  ++len;
  reg = cdr(reg);
 }
 args_pop(1);
    return make_integer(len);
}

canonical_original_code:
unsigned int list_len()
{
    int len = 0;
 reg = args_ref(1);
 while (is_false(is_null(reg))){
  ++len;
  reg = cdr(reg);
 }
 args_pop(1);
    return make_integer(len);
}

variable_types: len int


reverse

decompiled_code:
__int64 reverse()
{
__int64 i; // rdi
unsigned int v1; // ebp
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax

stack_push(&vars_stack, 0LL);
reg = args_ref(1LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v4 = is_null(i);
if ( !(unsigned int)is_false(v4) )
break;
v1 = stack_pop(&vars_stack);
v2 = car((unsigned int)reg);
v3 = cons(v2, v1);
stack_push(&vars_stack, v3);
reg = cdr((unsigned int)reg);
}
reg = stack_pop(&vars_stack);
args_pop(1LL);
return (unsigned int)reg;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 i; // rdi
unsigned int v1; // ebp
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax

stack_push(&vars_stack, 0LL);
reg = args_ref(1LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v4 = is_null(i);
if ( !(unsigned int)is_false(v4) )
break;
v1 = stack_pop(&vars_stack);
v2 = car((unsigned int)reg);
v3 = cons(v2, v1);
stack_push(&vars_stack, v3);
reg = cdr((unsigned int)reg);
}
reg = stack_pop(&vars_stack);
args_pop(1LL);
return (unsigned int)reg;
}

original_code:
cellpoint reverse(void)
{
 stack_push(&vars_stack, 0);
 reg = args_ref(1);
 while (is_false(is_null(reg))){
  stack_push(&vars_stack, cons(car(reg), stack_pop(&vars_stack)));
  reg = cdr(reg);
 }
 reg = stack_pop(&vars_stack);
 args_pop(1);
 return reg;
}

canonical_original_code:
unsigned int reverse()
{
 stack_push(&vars_stack, 0);
 reg = args_ref(1);
 while (is_false(is_null(reg))){
  stack_push(&vars_stack, cons(car(reg), stack_pop(&vars_stack)));
  reg = cdr(reg);
 }
 reg = stack_pop(&vars_stack);
 args_pop(1);
 return reg;
}


list

decompiled_code:
__int64 list()
{
__int64 i; // rdi
unsigned int v1; // ebp
unsigned int v2; // eax
__int64 v3; // rsi
unsigned int v4; // eax

reg = args_ref(1LL);
stack_push(&vars_stack, 0LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v4 = is_null(i);
if ( !(unsigned int)is_false(v4) )
break;
v1 = stack_pop(&vars_stack);
v2 = car((unsigned int)reg);
v3 = (unsigned int)cons(v2, v1);
stack_push(&vars_stack, v3);
reg = cdr((unsigned int)reg);
}
reg = stack_pop(&vars_stack);
args_push((unsigned int)reg);
reg = reverse();
args_pop(1LL);
return (unsigned int)reg;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 i; // rdi
unsigned int v1; // ebp
unsigned int v2; // eax
__int64 v3; // rsi
unsigned int v4; // eax

reg = args_ref(1LL);
stack_push(&vars_stack, 0LL);
for ( i = (unsigned int)reg; ; i = (unsigned int)reg )
{
v4 = is_null(i);
if ( !(unsigned int)is_false(v4) )
break;
v1 = stack_pop(&vars_stack);
v2 = car((unsigned int)reg);
v3 = (unsigned int)cons(v2, v1);
stack_push(&vars_stack, v3);
reg = cdr((unsigned int)reg);
}
reg = stack_pop(&vars_stack);
args_push((unsigned int)reg);
reg = func3();
args_pop(1LL);
return (unsigned int)reg;
}

original_code:
cellpoint list(void)
{
 reg = args_ref(1);
 stack_push(&vars_stack, 0);
 while (is_false(is_null(reg))){
  stack_push(&vars_stack, cons(car(reg), stack_pop(&vars_stack)));
  reg = cdr(reg);
 }
 reg = stack_pop(&vars_stack);
 args_push(reg);
 reg = reverse();
 args_pop(1);
 return reg;
}

canonical_original_code:
unsigned int list()
{
 reg = args_ref(1);
 stack_push(&vars_stack, 0);
 while (is_false(is_null(reg))){
  stack_push(&vars_stack, cons(car(reg), stack_pop(&vars_stack)));
  reg = cdr(reg);
 }
 reg = stack_pop(&vars_stack);
 args_push(reg);
 reg = reverse();
 args_pop(1);
 return reg;
}


append

decompiled_code:
__int64 __fastcall append(__int64 a1, const void *a2)
{
unsigned int v2; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
__int64 v10; // rdi
unsigned int v11; // ebp
unsigned int v12; // eax
unsigned int v13; // eax
unsigned int v14; // eax
unsigned int v15; // eax
unsigned int v16; // eax
unsigned int v17; // eax
size_t v18; // rdx

reg = args_ref(1LL);
v2 = is_null((unsigned int)reg);
if ( (unsigned int)is_true(v2) )
{
reg = args_ref(1LL);
LABEL_3:
args_pop(1LL);
return (unsigned int)reg;
}
v4 = cdr((unsigned int)reg);
v5 = is_null(v4);
if ( (unsigned int)is_true(v5) )
{
v6 = args_ref(1LL);
reg = car(v6);
goto LABEL_3;
}
v7 = args_ref(1LL);
reg = car(v7);
v8 = is_list(reg);
if ( !(unsigned int)is_false(v8) )
{
args_push((unsigned int)reg);
reg = reverse();
stack_push(&vars_stack, (unsigned int)reg);
v9 = args_ref(1LL);
v10 = (unsigned int)cdr(v9);
args_push(v10);
reg = append();
while ( 1 )
{
v16 = stack_top(&vars_stack);
v17 = is_null(v16);
if ( !(unsigned int)is_false(v17) )
break;
v11 = reg;
v12 = stack_top(&vars_stack);
v13 = car(v12);
reg = cons(v13, v11);
v14 = stack_pop(&vars_stack);
v15 = cdr(v14);
stack_push(&vars_stack, v15);
}
stack_pop(&vars_stack);
goto LABEL_3;
}
printf("Error: procedure \"append\" requires its arguments must be a list. but give a argument ");
write(reg, a2, v18);
error_handler();
args_pop(1LL);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, const void *a2)
{
unsigned int v2; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
__int64 v10; // rdi
unsigned int v11; // ebp
unsigned int v12; // eax
unsigned int v13; // eax
unsigned int v14; // eax
unsigned int v15; // eax
unsigned int v16; // eax
unsigned int v17; // eax
size_t v18; // rdx

reg = args_ref(1LL);
v2 = is_null((unsigned int)reg);
if ( (unsigned int)is_true(v2) )
{
reg = args_ref(1LL);
LABEL_3:
args_pop(1LL);
return (unsigned int)reg;
}
v4 = cdr((unsigned int)reg);
v5 = is_null(v4);
if ( (unsigned int)is_true(v5) )
{
v6 = args_ref(1LL);
reg = car(v6);
goto LABEL_3;
}
v7 = args_ref(1LL);
reg = car(v7);
v8 = func0(reg);
if ( !(unsigned int)is_false(v8) )
{
args_push((unsigned int)reg);
reg = func3();
stack_push(&vars_stack, (unsigned int)reg);
v9 = args_ref(1LL);
v10 = (unsigned int)cdr(v9);
args_push(v10);
reg = func5();
while ( 1 )
{
v16 = stack_top(&vars_stack);
v17 = is_null(v16);
if ( !(unsigned int)is_false(v17) )
break;
v11 = reg;
v12 = stack_top(&vars_stack);
v13 = car(v12);
reg = cons(v13, v11);
v14 = stack_pop(&vars_stack);
v15 = cdr(v14);
stack_push(&vars_stack, v15);
}
stack_pop(&vars_stack);
goto LABEL_3;
}
printf("Error: procedure \"append\" requires its arguments must be a list. but give a argument ");
write(reg, a2, v18);
error_handler();
args_pop(1LL);
return 0LL;
}

original_code:
cellpoint append(void)
{
 reg = args_ref(1);
 if (is_true(is_null(reg))){
  reg = args_ref(1);
 }else if (is_true(is_null(cdr(reg)))){
  reg = car(args_ref(1));
 }else {
  reg = car(args_ref(1));
  if (is_false(is_list(reg))){
   printf("Error: procedure \"append\" requires its arguments must be a list. but give a argument ");
   write(reg);
   error_handler();
   args_pop(1);
   return 0;
  }
  args_push(reg);
  reg = reverse();
  stack_push(&vars_stack, reg);
  args_push(cdr(args_ref(1)));
  reg = append();
  while (is_false(is_null(stack_top(&vars_stack)))){
   reg = cons(car(stack_top(&vars_stack)), reg);
   stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
  }
  stack_pop(&vars_stack);
 }
 args_pop(1);
 return reg;
}

canonical_original_code:
unsigned int append()
{
 reg = args_ref(1);
 if (is_true(is_null(reg))){
  reg = args_ref(1);
 }else if (is_true(is_null(cdr(reg)))){
  reg = car(args_ref(1));
 }else {
  reg = car(args_ref(1));
  if (is_false(is_list(reg))){
   printf("Error: procedure \"append\" requires its arguments must be a list. but give a argument ");
   write(reg);
   error_handler();
   args_pop(1);
   return 0;
  }
  args_push(reg);
  reg = reverse();
  stack_push(&vars_stack, reg);
  args_push(cdr(args_ref(1)));
  reg = append();
  while (is_false(is_null(stack_top(&vars_stack)))){
   reg = cons(car(stack_top(&vars_stack)), reg);
   stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
  }
  stack_pop(&vars_stack);
 }
 args_pop(1);
 return reg;
}


decompiled_code:
__int64 list_tail()
{
unsigned int v0; // eax
int v1; // ebx
unsigned int v2; // eax
__int64 v3; // rdi
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax

v0 = args_ref(2LL);
v1 = get_integer(v0);
v2 = args_ref(1LL);
reg = v2;
if ( v1 > 0 )
{
v3 = v2;
do
{
v4 = is_null(v3);
if ( (unsigned int)is_true(v4) )
{
v5 = args_ref(2LL);
v6 = get_integer(v5);
printf("Error:the parameter list has fewer than %d elements. --LIST-TAIL\n", v6);
error_handler();
}
reg = cdr((unsigned int)reg);
v3 = (unsigned int)reg;
--v1;
}
while ( v1 );
}
args_pop(2LL);
return (unsigned int)reg;
}

canonical_decompiled_code:
__int64 func6()
{
unsigned int v0; // eax
int v1; // ebx
unsigned int v2; // eax
__int64 v3; // rdi
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax

v0 = args_ref(2LL);
v1 = get_integer(v0);
v2 = args_ref(1LL);
reg = v2;
if ( v1 > 0 )
{
v3 = v2;
do
{
v4 = is_null(v3);
if ( (unsigned int)is_true(v4) )
{
v5 = args_ref(2LL);
v6 = get_integer(v5);
printf("Error:the parameter list has fewer than %d elements. --LIST-TAIL\n", v6);
error_handler();
}
reg = cdr((unsigned int)reg);
v3 = (unsigned int)reg;
--v1;
}
while ( v1 );
}
args_pop(2LL);
return (unsigned int)reg;
}

original_code:
cellpoint list_tail(void)
{
    int count = get_integer(args_ref(2));
 reg = args_ref(1);
    while (count > 0){
        if (is_true(is_null(reg))){
            printf("Error:the parameter list has fewer than %d elements. --LIST-TAIL\n", get_integer(args_ref(2)));
   error_handler();
        }
  reg = cdr(reg);
        --count;
    }
 args_pop(2);
    return reg;
}

canonical_original_code:
unsigned int list_tail()
{
    int count = get_integer(args_ref(2));
 reg = args_ref(1);
    while (count > 0){
        if (is_true(is_null(reg))){
            printf("Error:the parameter list has fewer than %d elements. --LIST-TAIL\n", get_integer(args_ref(2)));
   error_handler();
        }
  reg = cdr(reg);
        --count;
    }
 args_pop(2);
    return reg;
}

variable_types: count int


decompiled_code:
__int64 list_ref()
{
unsigned int v0; // eax
int v1; // ebx
__int64 v2; // rdi
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax

v0 = args_ref(2LL);
v1 = get_integer(v0);
reg = args_ref(1LL);
v2 = (unsigned int)reg;
if ( v1 > 0 )
{
do
{
v3 = is_null(v2);
if ( (unsigned int)is_true(v3) )
{
v4 = args_ref(2LL);
v5 = get_integer(v4);
printf("Error:the parameter list has fewer than %d elements. --LIST-REF\n", v5);
error_handler();
}
reg = cdr((unsigned int)reg);
v2 = (unsigned int)reg;
--v1;
}
while ( v1 );
}
args_pop(2LL);
return car((unsigned int)reg);
}

canonical_decompiled_code:
__int64 func7()
{
unsigned int v0; // eax
int v1; // ebx
__int64 v2; // rdi
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax

v0 = args_ref(2LL);
v1 = get_integer(v0);
reg = args_ref(1LL);
v2 = (unsigned int)reg;
if ( v1 > 0 )
{
do
{
v3 = is_null(v2);
if ( (unsigned int)is_true(v3) )
{
v4 = args_ref(2LL);
v5 = get_integer(v4);
printf("Error:the parameter list has fewer than %d elements. --LIST-REF\n", v5);
error_handler();
}
reg = cdr((unsigned int)reg);
v2 = (unsigned int)reg;
--v1;
}
while ( v1 );
}
args_pop(2LL);
return car((unsigned int)reg);
}

original_code:
cellpoint list_ref(void)
{
    int count = get_integer(args_ref(2));
 reg = args_ref(1);
    while (count > 0){
        if (is_true(is_null(reg))){
            printf("Error:the parameter list has fewer than %d elements. --LIST-REF\n", get_integer(args_ref(2)));
   error_handler();
        }
        reg = cdr(reg);
        --count;
    }
 args_pop(2);
    return car(reg);
}

canonical_original_code:
unsigned int list_ref()
{
    int count = get_integer(args_ref(2));
 reg = args_ref(1);
    while (count > 0){
        if (is_true(is_null(reg))){
            printf("Error:the parameter list has fewer than %d elements. --LIST-REF\n", get_integer(args_ref(2)));
   error_handler();
        }
        reg = cdr(reg);
        --count;
    }
 args_pop(2);
    return car(reg);
}


member

decompiled_code:
__int64 __fastcall member(__int64 (*a1)(void))
{
__int64 v1; // rsi
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
__int64 v5; // rsi
unsigned int v6; // eax
unsigned int v7; // eax

v1 = (unsigned int)args_ref(2LL);
stack_push(&vars_stack, v1);
while ( 1 )
{
v6 = stack_top(&vars_stack);
v7 = is_null(v6);
if ( !(unsigned int)is_false(v7) )
{
stack_pop(&vars_stack);
args_pop(2LL);
return a_false;
}
reg = args_ref(1LL);
v2 = stack_top(&vars_stack);
v3 = car(v2);
args_push(v3);
args_push((unsigned int)reg);
reg = a1();
if ( (unsigned int)is_true((unsigned int)reg) )
break;
v4 = stack_pop(&vars_stack);
v5 = (unsigned int)cdr(v4);
stack_push(&vars_stack, v5);
}
args_pop(2LL);
return stack_pop(&vars_stack);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 (*a1)(void))
{
__int64 v1; // rsi
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
__int64 v5; // rsi
unsigned int v6; // eax
unsigned int v7; // eax

v1 = (unsigned int)args_ref(2LL);
stack_push(&vars_stack, v1);
while ( 1 )
{
v6 = stack_top(&vars_stack);
v7 = is_null(v6);
if ( !(unsigned int)is_false(v7) )
{
stack_pop(&vars_stack);
args_pop(2LL);
return a_false;
}
reg = args_ref(1LL);
v2 = stack_top(&vars_stack);
v3 = car(v2);
args_push(v3);
args_push((unsigned int)reg);
reg = a1();
if ( (unsigned int)is_true((unsigned int)reg) )
break;
v4 = stack_pop(&vars_stack);
v5 = (unsigned int)cdr(v4);
stack_push(&vars_stack, v5);
}
args_pop(2LL);
return stack_pop(&vars_stack);
}

original_code:
cellpoint member(cellpoint (*eqfunc)(void))
{
 stack_push(&vars_stack, args_ref(2));
 while (is_false(is_null(stack_top(&vars_stack)))){
  reg = args_ref(1);
  args_push(car(stack_top(&vars_stack)));
  args_push(reg);
  reg = eqfunc();
  if (is_true(reg)){
   args_pop(2);
   return stack_pop(&vars_stack);
  }
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
 }
 stack_pop(&vars_stack);
 args_pop(2);
 return a_false;
}

canonical_original_code:
unsigned int member(unsigned int (*eqfunc)())
{
 stack_push(&vars_stack, args_ref(2));
 while (is_false(is_null(stack_top(&vars_stack)))){
  reg = args_ref(1);
  args_push(car(stack_top(&vars_stack)));
  args_push(reg);
  reg = eqfunc();
  if (is_true(reg)){
   args_pop(2);
   return stack_pop(&vars_stack);
  }
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
 }
 stack_pop(&vars_stack);
 args_pop(2);
 return a_false;
}

variable_types:
eqfunc
unsigned int (*)()


assoc

decompiled_code:
__int64 __fastcall assoc(__int64 (*a1)(void))
{
__int64 v1; // rsi
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
__int64 v6; // rsi
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v10; // eax

v1 = (unsigned int)args_ref(2LL);
stack_push(&vars_stack, v1);
while ( 1 )
{
v7 = stack_top(&vars_stack);
v8 = is_null(v7);
if ( !(unsigned int)is_false(v8) )
{
stack_pop(&vars_stack);
args_pop(2LL);
return a_false;
}
reg = args_ref(1LL);
v2 = stack_top(&vars_stack);
v3 = car(v2);
v4 = car(v3);
args_push(v4);
args_push((unsigned int)reg);
reg = a1();
if ( (unsigned int)is_true((unsigned int)reg) )
break;
v5 = stack_pop(&vars_stack);
v6 = (unsigned int)cdr(v5);
stack_push(&vars_stack, v6);
}
args_pop(2LL);
v10 = stack_pop(&vars_stack);
return car(v10);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 (*a1)(void))
{
__int64 v1; // rsi
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
__int64 v6; // rsi
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v10; // eax

v1 = (unsigned int)args_ref(2LL);
stack_push(&vars_stack, v1);
while ( 1 )
{
v7 = stack_top(&vars_stack);
v8 = is_null(v7);
if ( !(unsigned int)is_false(v8) )
{
stack_pop(&vars_stack);
args_pop(2LL);
return a_false;
}
reg = args_ref(1LL);
v2 = stack_top(&vars_stack);
v3 = car(v2);
v4 = car(v3);
args_push(v4);
args_push((unsigned int)reg);
reg = a1();
if ( (unsigned int)is_true((unsigned int)reg) )
break;
v5 = stack_pop(&vars_stack);
v6 = (unsigned int)cdr(v5);
stack_push(&vars_stack, v6);
}
args_pop(2LL);
v10 = stack_pop(&vars_stack);
return car(v10);
}

original_code:
cellpoint assoc(cellpoint (*eqfunc)(void))
{
 stack_push(&vars_stack, args_ref(2));
 while (is_false(is_null(stack_top(&vars_stack)))){
  reg = args_ref(1);
  args_push(car(car(stack_top(&vars_stack))));
  args_push(reg);
  reg = eqfunc();
  if (is_true(reg)){
   args_pop(2);
   return car(stack_pop(&vars_stack));
  }
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
 }
 stack_pop(&vars_stack);
 args_pop(2);
 return a_false;
}

canonical_original_code:
unsigned int assoc(unsigned int (*eqfunc)())
{
 stack_push(&vars_stack, args_ref(2));
 while (is_false(is_null(stack_top(&vars_stack)))){
  reg = args_ref(1);
  args_push(car(car(stack_top(&vars_stack))));
  args_push(reg);
  reg = eqfunc();
  if (is_true(reg)){
   args_pop(2);
   return car(stack_pop(&vars_stack));
  }
  stack_push(&vars_stack, cdr(stack_pop(&vars_stack)));
 }
 stack_pop(&vars_stack);
 args_pop(2);
 return a_false;
}


decompiled_code:
__int64 __fastcall combine_args(unsigned int a1, const void *a2)
{
unsigned int v2; // eax
unsigned int v3; // eax
__int64 v4; // r12
unsigned int v5; // eax
__int64 result; // rax
unsigned int v7; // eax
unsigned int v8; // er12
unsigned int v9; // eax
size_t v10; // rdx

v2 = ((__int64 (*)(void))cdr)();
v3 = is_null(v2);
if ( (unsigned int)is_true(v3) )
{
v4 = (unsigned int)car(a1);
v5 = is_list(v4);
if ( (unsigned int)is_false(v5) )
{
printf("Error: the procedure \"apply\" expects the last argument must be a list, but given: ");
write(v4, a2, v10);
newline();
error_handler();
}
result = (unsigned int)v4;
}
else
{
v7 = cdr(a1);
v8 = combine_args(v7);
v9 = car(a1);
result = cons(v9, v8);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, const void *a2)
{
unsigned int v2; // eax
unsigned int v3; // eax
__int64 v4; // r12
unsigned int v5; // eax
__int64 result; // rax
unsigned int v7; // eax
unsigned int v8; // er12
unsigned int v9; // eax
size_t v10; // rdx

v2 = ((__int64 (*)(void))cdr)();
v3 = is_null(v2);
if ( (unsigned int)is_true(v3) )
{
v4 = (unsigned int)car(a1);
v5 = is_list(v4);
if ( (unsigned int)is_false(v5) )
{
printf("Error: the procedure \"apply\" expects the last argument must be a list, but given: ");
write(v4, a2, v10);
newline();
error_handler();
}
result = (unsigned int)v4;
}
else
{
v7 = cdr(a1);
v8 = func0(v7);
v9 = car(a1);
result = cons(v9, v8);
}
return result;
}

original_code:
static cellpoint combine_args(cellpoint arglst)
{
 if (is_true(is_null(cdr(arglst)))){
  cellpoint last_arg = car(arglst);
  if (is_false(is_list(last_arg))){
   printf("Error: the procedure \"apply\" expects the last argument must be a list, but given: ");
   write(last_arg);
   newline();
   error_handler();
  }
  return last_arg;
 }else {
  return cons(car(arglst), combine_args(cdr(arglst)));
 }
}

canonical_original_code:
static unsigned int combine_args(unsigned int arglst)
{
 if (is_true(is_null(cdr(arglst)))){
  unsigned int last_arg = car(arglst);
  if (is_false(is_list(last_arg))){
   printf("Error: the procedure \"apply\" expects the last argument must be a list, but given: ");
   write(last_arg);
   newline();
   error_handler();
  }
  return last_arg;
 }else {
  return cons(car(arglst), combine_args(cdr(arglst)));
 }
}

variable_types:
arglst
unsigned int


decompiled_code:
__int64 __fastcall proc_pred_proc(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("procedure?", 1LL, a1);
v1 = car(a1);
return is_procedure(v1);
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("procedure?", 1LL, a1);
v1 = car(a1);
return is_procedure(v1);
}

original_code:
cellpoint proc_pred_proc(cellpoint arglst)
{
 check_arglst_len_eq("procedure?", 1, arglst);
 return is_procedure(car(arglst));
}

canonical_original_code:
unsigned int proc_pred_proc(unsigned int arglst)
{
 check_arglst_len_eq("procedure?", 1, arglst);
 return is_procedure(car(arglst));
}


decompiled_code:
__int64 __fastcall apply_proc(unsigned int a1)
{
unsigned int v1; // eax
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax

((void (*)(void))args_push)();
v1 = list_len();
if ( (int)get_integer(v1) <= 1 )
{
puts("Error: the procedure \"apply\" expects at least 2 arguments.");
error_handler();
}
v2 = car(a1);
check_arg_type("apply", "first", v2, 9LL);
args_push(a_false);
v3 = cdr(a1);
v4 = combine_args(v3, "first");
args_push(v4);
v5 = car(a1);
args_push(v5);
return apply();
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1)
{
unsigned int v1; // eax
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax

((void (*)(void))args_push)();
v1 = list_len();
if ( (int)get_integer(v1) <= 1 )
{
puts("Error: the procedure \"apply\" expects at least 2 arguments.");
error_handler();
}
v2 = car(a1);
check_arg_type("apply", "first", v2, 9LL);
args_push(a_false);
v3 = cdr(a1);
v4 = func0(v3, "first");
args_push(v4);
v5 = car(a1);
args_push(v5);
return apply();
}

original_code:
cellpoint apply_proc(cellpoint arglst)
{
 int len;
 args_push(arglst);
 len = get_integer(list_len());
 if (len < 2){
  printf("Error: the procedure \"apply\" expects at least 2 arguments.\n");
  error_handler();
 }
 check_arg_type("apply", "first", car(arglst), 9);
 args_push(a_false);
 args_push(combine_args(cdr(arglst)));
 args_push(car(arglst));
 return apply();
}

canonical_original_code:
unsigned int apply_proc(unsigned int arglst)
{
 int len;
 args_push(arglst);
 len = get_integer(list_len());
 if (len < 2){
  printf("Error: the procedure \"apply\" expects at least 2 arguments.\n");
  error_handler();
 }
 check_arg_type("apply", "first", car(arglst), 9);
 args_push(a_false);
 args_push(combine_args(cdr(arglst)));
 args_push(car(arglst));
 return apply();
}


decompiled_code:
__int64 read_sexp()
{
return read_parse(&ibuffer, &scan);
}

canonical_decompiled_code:
__int64 func0()
{
return read_parse(&ibuffer, &scan);
}

original_code:
static cellpoint read_sexp(void)
{
    return read_parse(ibuffer, &scan);
}

canonical_original_code:
static unsigned int read_sexp()
{
    return read_parse(ibuffer, &scan);
}


decompiled_code:
void __noreturn driver_loop()
{
size_t v0; // rdx

initial();
puts("initialed.");
while ( 1 )
{
if ( setjmp(jump_buffer) )
{
vars_init();
}
else
{
printf("\n%s\n", ";;;CSchemer input: ");
reg = read_sexp();
args_push(a_false);
args_push((unsigned int)reg);
reg = eval();
printf("\n%s\n", ";;;CSchemer output: ");
write(reg, ";;;CSchemer output: ", v0);
newline();
}
}
}

canonical_decompiled_code:
void __noreturn func1()
{
size_t v0; // rdx

initial();
puts("initialed.");
while ( 1 )
{
if ( setjmp(jump_buffer) )
{
vars_init();
}
else
{
printf("\n%s\n", ";;;CSchemer input: ");
reg = func0();
args_push(a_false);
args_push((unsigned int)reg);
reg = eval();
printf("\n%s\n", ";;;CSchemer output: ");
write(reg, ";;;CSchemer output: ", v0);
newline();
}
}
}

original_code:
void driver_loop(void)
{
 initial();
 printf("initialed.\n");
 while (1){
  if (_setjmp (jump_buffer) == 0){
   printf("\n%s\n", input_prompt);
   reg = read_sexp();
   args_push(a_false);
   args_push(reg);
   reg = eval();
   printf("\n%s\n", output_prompt);
   write(reg);
   newline();
  }else {
   vars_init();
  }
 }
}

canonical_original_code:
void driver_loop()
{
 initial();
 printf("initialed.\n");
 while (1){
  if (_setjmp (jump_buffer) == 0){
   printf("\n%s\n", input_prompt);
   reg = read_sexp();
   args_push(a_false);
   args_push(reg);
   reg = eval();
   printf("\n%s\n", output_prompt);
   write(reg);
   newline();
  }else {
   vars_init();
  }
 }
}

return_type: void


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Hello CSchemer");
driver_loop("Hello CSchemer", argv);
return 0;
}

original_code:
int main()
{
    printf("Hello CSchemer\n");
 driver_loop();
    return 0;
}

return_type: int


decompiled_code:
__int64 __fastcall boolean_pred_proc(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("boolean?", 1LL, a1);
v1 = car(a1);
return is_boolean(v1);
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("boolean?", 1LL, a1);
v1 = car(a1);
return is_boolean(v1);
}

original_code:
cellpoint boolean_pred_proc(cellpoint arglst)
{
    check_arglst_len_eq("boolean?",1,arglst);
    return is_boolean(car(arglst));
}

canonical_original_code:
unsigned int boolean_pred_proc(unsigned int arglst)
{
    check_arglst_len_eq("boolean?",1,arglst);
    return is_boolean(car(arglst));
}


decompiled_code:
__int64 __fastcall boolean_not_proc(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("not", 1LL, a1);
v1 = car(a1);
args_push(v1);
return boolean_not();
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1)
{
unsigned int v1; // eax

check_arglst_len_eq("not", 1LL, a1);
v1 = car(a1);
args_push(v1);
return boolean_not();
}

original_code:
cellpoint boolean_not_proc(cellpoint arglst)
{
 check_arglst_len_eq("not", 1, arglst);
 args_push(car(arglst));
    return boolean_not();
}

canonical_original_code:
unsigned int boolean_not_proc(unsigned int arglst)
{
 check_arglst_len_eq("not", 1, arglst);
 args_push(car(arglst));
    return boolean_not();
}


repo: lightcaster/fslib

decompiled_code:
__int64 __fastcall fnv32(const char *a1)
{
size_t v1; // rax
unsigned int v2; // edx
unsigned __int64 v3; // rsi
__int64 result; // rax
int v5; // ecx

v1 = strlen(a1);
v2 = 0;
v3 = v1;
result = 2166136261LL;
while ( v2 < v3 )
{
v5 = a1[v2++];
result = 16777619 * (v5 ^ (unsigned int)result);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1)
{
size_t v1; // rax
unsigned int v2; // edx
unsigned __int64 v3; // rsi
__int64 result; // rax
int v5; // ecx

v1 = strlen(a1);
v2 = 0;
v3 = v1;
result = 2166136261LL;
while ( v2 < v3 )
{
v5 = a1[v2++];
result = 16777619 * (v5 ^ (unsigned int)result);
}
return result;
}

original_code:
static size_t fnv32(void * str) {
    const char * s = str;
    uint32_t hsh = 2166136261U, i;
    for(i = 0; i < strlen(s); i++) {
        hsh = hsh ^ (s[i]);
        hsh = hsh * 16777619;
    }
    return hsh;
}

canonical_original_code:
static unsigned long fnv32(void *str) {
    char *s = str;
    unsigned int hsh = 2166136261U; unsigned int i;
    for(i = 0; i < strlen(s); i++) {
        hsh = hsh ^ (s[i]);
        hsh = hsh * 16777619;
    }
    return hsh;
}

variable_types:
str
void *

variable_types:
s
char *

variable_types:
hsh
unsigned int

variable_types:
i
unsigned int

return_type: unsigned long


decompiled_code:
_BOOL8 __fastcall str_cmp(const char *a1, const char *a2)
{
return strcmp(a1, a2) == 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(const char *a1, const char *a2)
{
return strcmp(a1, a2) == 0;
}

original_code:
static int str_cmp(void * a, void * b) {
    return strcmp((const char *)a, (const char *)b) == 0 ? 1: 0;
}

canonical_original_code:
static int str_cmp(void *a, void *b) {
    return strcmp((char *)a, (char *)b) == 0 ? 1: 0;
}

variable_types:
a
void *

variable_types:
b
void *


decompiled_code:
_QWORD *symt_create()
{
_QWORD *v0; // rax
_QWORD *v1; // r12
void *v2; // rax
_QWORD *result; // rax

v0 = malloc(0x20uLL);
v0[3] = 0LL;
v1 = v0;
v2 = calloc(0x2000uLL, 1uLL);
*v1 = 0LL;
v1[2] = v2;
result = v1;
v1[1] = 1024LL;
return result;
}

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

v0 = malloc(0x20uLL);
v0[3] = 0LL;
v1 = v0;
v2 = calloc(0x2000uLL, 1uLL);
*v1 = 0LL;
v1[2] = v2;
result = v1;
v1[1] = 1024LL;
return result;
}

original_code:
struct _symt * symt_create() {
    struct _symt * st = malloc(sizeof(struct _symt));
    st->rev = ((void *)0);
    st->sym = malloc(1024 * sizeof(char *));
    st->n_items = 0;
    st->n_max = 1024;
    for(size_t i=0; i < st->n_max; ++i)
        st->sym[i] = ((void *)0);
    return st;
}

canonical_original_code:
struct _symt *symt_create() {
    struct _symt *st = malloc(sizeof(struct _symt));
    st->rev = ((void *)0);
    st->sym = malloc(1024 * sizeof(char *));
    st->n_items = 0;
    st->n_max = 1024;
    for(unsigned long i = 0; i < st->n_max; ++i)
        st->sym[i] = ((void *)0);
    return st;
}

variable_types: struct _symt { unsigned long n_items; unsigned long n_max; char **sym; struct _hash { struct _bucket { struct _bitem { void *key; void *value; struct _bitem *next; } *head; struct _bitem *tail; } *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); } *rev; } *

variable_types:
i
unsigned long

user_defined_types: struct _symt { unsigned long n_items; unsigned long n_max; char **sym; struct _hash *rev; }

user_defined_types: struct _hash { struct _bucket *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); }

user_defined_types: struct _bucket { struct _bitem *head; struct _bitem *tail; }


decompiled_code:
void __fastcall symt_remove(void *ptr)
{
unsigned __int64 v2; // rbx
void *v3; // rdi

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

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

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

original_code:
void symt_remove(struct _symt * st) {
    for(size_t i=0; i < st->n_max; ++i)
        if(st->sym[i] != ((void *)0))
            free(st->sym[i]);
    if (st->rev != ((void *)0))
        hash_remove(st->rev);
    free(st->sym);
    free(st);
}

canonical_original_code:
void symt_remove(struct _symt *st) {
    for(unsigned long i = 0; i < st->n_max; ++i)
        if(st->sym[i] != ((void *)0))
            free(st->sym[i]);
    if (st->rev != ((void *)0))
        hash_remove(st->rev);
    free(st->sym);
    free(st);
}

user_defined_types: struct _bitem { void *key; void *value; struct _bitem *next; }


decompiled_code:
void *__fastcall symt_add(_QWORD *a1, unsigned __int64 a2, const char *a3)
{
unsigned __int64 v4; // r13
void *v5; // rdi
unsigned __int64 v8; // rax
unsigned __int64 v9; // rsi
size_t v10; // r13
void *v11; // rax
void *result; // rax
char *v13; // rax
unsigned __int64 v14; // rdx

v4 = a1[1];
v5 = (void *)a1[2];
if ( !v5 )
_assert_fail("st->sym != NULL", "src/symt.c", 0x7Du, "symt_add");
if ( !v4 )
_assert_fail("st->n_max != 0", "src/symt.c", 0x7Eu, "symt_add");
v8 = v4;
if ( v4 <= a2 )
{
do
{
v9 = v8;
v8 *= 2LL;
}
while ( v8 <= a2 );
a1[1] = v8;
if ( v8 > v4 )
{
v13 = (char *)realloc(v5, 16 * v9);
v14 = a1[1];
a1[2] = v13;
if ( v14 > v4 )
memset(&v13[8 * v4], 0, 8 * (v14 - v4));
}
}
v10 = strlen(a3) + 1;
v11 = malloc(v10);
result = memcpy(v11, a3, v10);
*(_QWORD *)(a1[2] + 8 * a2) = result;
++*a1;
return result;
}

canonical_decompiled_code:
void *__fastcall func4(_QWORD *a1, unsigned __int64 a2, const char *a3)
{
unsigned __int64 v4; // r13
void *v5; // rdi
unsigned __int64 v8; // rax
unsigned __int64 v9; // rsi
size_t v10; // r13
void *v11; // rax
void *result; // rax
char *v13; // rax
unsigned __int64 v14; // rdx

v4 = a1[1];
v5 = (void *)a1[2];
if ( !v5 )
_assert_fail("st->sym != NULL", "src/symt.c", 0x7Du, "symt_add");
if ( !v4 )
_assert_fail("st->n_max != 0", "src/symt.c", 0x7Eu, "symt_add");
v8 = v4;
if ( v4 <= a2 )
{
do
{
v9 = v8;
v8 *= 2LL;
}
while ( v8 <= a2 );
a1[1] = v8;
if ( v8 > v4 )
{
v13 = (char *)realloc(v5, 16 * v9);
v14 = a1[1];
a1[2] = v13;
if ( v14 > v4 )
memset(&v13[8 * v4], 0, 8 * (v14 - v4));
}
}
v10 = strlen(a3) + 1;
v11 = malloc(v10);
result = memcpy(v11, a3, v10);
*(_QWORD *)(a1[2] + 8 * a2) = result;
++*a1;
return result;
}

original_code:
char * symt_add(
                        struct _symt * st,
                        size_t id,
                        const char * token) {
    size_t s = st->n_max;
    char ** p;
    ((st->sym != ((void *)0)) ? (void) (0) : __assert_fail ("st->sym != NULL", "src/symt.c", 125, __extension__ __PRETTY_FUNCTION__));
    ((st->n_max != 0) ? (void) (0) : __assert_fail ("st->n_max != 0", "src/symt.c", 126, __extension__ __PRETTY_FUNCTION__));
    while (st->n_max <= id) {
        st->n_max *= 2;
    }
    if( st->n_max > s) {
        p = realloc(st->sym, st->n_max * sizeof(char *));
        st->sym = p;
    }
    for(size_t i = s; i < st->n_max; ++i)
        st->sym[i] = ((void *)0);
    char * t = malloc(strlen(token) + 1);
    strcpy(t, token);
    st->sym[id] = t;
    ++st->n_items;
    return st->sym[id];
}

canonical_original_code:
char *symt_add(struct _symt *st, unsigned long id, char *token) {
    unsigned long s = st->n_max;
    char **p;
    ((st->sym != ((void *)0)) ? (void) (0) : __assert_fail ("st->sym != NULL", "src/symt.c", 125, __extension__ __PRETTY_FUNCTION__));
    ((st->n_max != 0) ? (void) (0) : __assert_fail ("st->n_max != 0", "src/symt.c", 126, __extension__ __PRETTY_FUNCTION__));
    while (st->n_max <= id) {
        st->n_max *= 2;
    }
    if( st->n_max > s) {
        p = realloc(st->sym, st->n_max * sizeof(char *));
        st->sym = p;
    }
    for(unsigned long i = s; i < st->n_max; ++i)
        st->sym[i] = ((void *)0);
    char *t = malloc(strlen(token) + 1);
    strcpy(t, token);
    st->sym[id] = t;
    ++st->n_items;
    return st->sym[id];
}

variable_types:
id
unsigned long

variable_types:
token
char *

variable_types:
s
unsigned long

variable_types:
p
char **

variable_types:
t
char *

return_type: char *


decompiled_code:
int __fastcall symt_print(__int64 a1)
{
unsigned __int64 v1; // rbx
__int64 v2; // rax
const char *v3; // rsi

if ( *(_QWORD *)(a1 + 8) )
{
v1 = 0LL;
do
{
v2 = *(_QWORD *)(a1 + 16);
v3 = *(const char **)(v2 + 8 * v1);
if ( v3 )
LODWORD(v2) = printf("%s\t%zd\n", v3, v1);
++v1;
}
while ( *(_QWORD *)(a1 + 8) > v1 );
}
return v2;
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1)
{
unsigned __int64 v1; // rbx
__int64 v2; // rax
const char *v3; // rsi

if ( *(_QWORD *)(a1 + 8) )
{
v1 = 0LL;
do
{
v2 = *(_QWORD *)(a1 + 16);
v3 = *(const char **)(v2 + 8 * v1);
if ( v3 )
LODWORD(v2) = printf("%s\t%zd\n", v3, v1);
++v1;
}
while ( *(_QWORD *)(a1 + 8) > v1 );
}
return v2;
}

original_code:
void symt_print(struct _symt * st) {
    for(size_t i=0; i < st->n_max; ++i) {
        if ( st->sym[i] != ((void *)0) )
            printf("%s\t%zd\n", st->sym[i], i);
    }
}

canonical_original_code:
void symt_print(struct _symt *st) {
    for(unsigned long i = 0; i < st->n_max; ++i) {
        if ( st->sym[i] != ((void *)0) )
            printf("%s\t%zd\n", st->sym[i], i);
    }
}


decompiled_code:
__int64 __fastcall symt_reverse(_QWORD *a1)
{
__int64 v1; // rax
__int64 v2; // r8
unsigned __int64 v3; // rax
bool v4; // zf
const char *v5; // rsi
unsigned __int64 v7; // [rsp+8h] [rbp-410h] BYREF
char dest[16]; // [rsp+10h] [rbp-408h] BYREF
char v9[1008]; // [rsp+20h] [rbp-3F8h] BYREF

if ( a1[3] )
hash_remove();
v1 = hash_create(fnv32, str_cmp, 1024LL, 8LL, 2LL * *a1);
a1[3] = v1;
v2 = v1;
v3 = 0LL;
v4 = a1[1] == 0LL;
memset(v9, 0, sizeof(v9));
*(_OWORD *)dest = 0LL;
v7 = 0LL;
if ( !v4 )
{
do
{
v5 = *(const char **)(a1[2] + 8 * v3);
if ( v5 )
{
strncpy(dest, v5, 0x3FFuLL);
hash_add(a1[3], dest, &v7, 0.0);
}
v3 = v7 + 1;
v7 = v3;
}
while ( v3 < a1[1] );
v2 = a1[3];
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func6(_QWORD *a1)
{
__int64 v1; // rax
__int64 v2; // r8
unsigned __int64 v3; // rax
bool v4; // zf
const char *v5; // rsi
unsigned __int64 v7; // [rsp+8h] [rbp-410h] BYREF
char dest[16]; // [rsp+10h] [rbp-408h] BYREF
char v9[1008]; // [rsp+20h] [rbp-3F8h] BYREF

if ( a1[3] )
hash_remove();
v1 = hash_create(fnv32, str_cmp, 1024LL, 8LL, 2LL * *a1);
a1[3] = v1;
v2 = v1;
v3 = 0LL;
v4 = a1[1] == 0LL;
memset(v9, 0, sizeof(v9));
*(_OWORD *)dest = 0LL;
v7 = 0LL;
if ( !v4 )
{
do
{
v5 = *(const char **)(a1[2] + 8 * v3);
if ( v5 )
{
strncpy(dest, v5, 0x3FFuLL);
hash_add(a1[3], dest, &v7, 0.0);
}
v3 = v7 + 1;
v7 = v3;
}
while ( v3 < a1[1] );
v2 = a1[3];
}
return v2;
}

original_code:
struct _hash * symt_reverse(struct _symt * st) {
    if(st->rev != ((void *)0))
        hash_remove(st->rev);
    st->rev = hash_create(
                    fnv32,
                    str_cmp,
                    1024,
                    sizeof(size_t),
                    st->n_items * 2);
    char token[1024] = {0};
    for(size_t i=0; i < st->n_max; ++i) {
        if ( st->sym[i] != ((void *)0) ) {
            strncpy(token, st->sym[i], 1024 - 1);
            hash_add(st->rev, token, &i);
        }
    }
    return st->rev;
}

canonical_original_code:
struct _hash *symt_reverse(struct _symt *st) {
    if(st->rev != ((void *)0))
        hash_remove(st->rev);
    st->rev = hash_create(
                    fnv32,
                    str_cmp,
                    1024,
                    sizeof(unsigned long),
                    st->n_items * 2);
    char token[1024] = {0};
    for(unsigned long i = 0; i < st->n_max; ++i) {
        if ( st->sym[i] != ((void *)0) ) {
            strncpy(token, st->sym[i], 1024 - 1);
            hash_add(st->rev, token, &i);
        }
    }
    return st->rev;
}

variable_types: struct _symt { unsigned long n_items; unsigned long n_max; char **sym; struct _hash *rev; } *

variable_types:
token
char [1024]

return_type: struct _hash { struct _bucket { struct _bitem { void *key; void *value; struct _bitem *next; } *head; struct _bitem *tail; } *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); } *


decompiled_code:
__int64 __fastcall symt_getr(_QWORD *a1, __int64 a2)
{
__int64 v3; // rdi
__int64 v5; // [rsp+18h] [rbp-10h] BYREF

v3 = a1[3];
v5 = -1LL;
if ( !v3 )
{
symt_reverse(a1);
v3 = a1[3];
}
hash_get(v3, a2, &v5);
return v5;
}

original_code:
size_t symt_getr(struct _symt * st, char * token) {
    size_t id = -1;
    if (st->rev == ((void *)0))
       symt_reverse(st);
    hash_get(st->rev, token, &id);
    return id;
}

canonical_original_code:
unsigned long symt_getr(struct _symt *st, char *token) {
    unsigned long id = -1;
    if (st->rev == ((void *)0))
       symt_reverse(st);
    hash_get(st->rev, token, &id);
    return id;
}


decompiled_code:
__int64 __fastcall symt_get(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

if ( *a1 < a2 )
result = 0LL;
else
result = *(_QWORD *)(a1[2] + 8 * a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

if ( *a1 < a2 )
result = 0LL;
else
result = *(_QWORD *)(a1[2] + 8 * a2);
return result;
}

original_code:
char * symt_get(struct _symt * st, size_t id) {
    if ( id > st->n_items )
        return ((void *)0);
    return st->sym[id];
}

canonical_original_code:
char *symt_get(struct _symt *st, unsigned long id) {
    if ( id > st->n_items )
        return ((void *)0);
    return st->sym[id];
}


decompiled_code:
__int64 __fastcall hash_pair(unsigned int *a1)
{
return 31 * (*a1 + 527LL) + a1[1];
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int *a1)
{
return 31 * (*a1 + 527LL) + a1[1];
}

original_code:
static size_t hash_pair(void * p) {
    size_t hash = 17;
    hash = hash*31 + ((struct _spair *)p)->a;
    hash = hash*31 + ((struct _spair *)p)->b;
    return hash;
}

canonical_original_code:
static unsigned long hash_pair(void *p) {
    unsigned long hash = 17;
    hash = hash*31 + ((struct _spair *)p)->a;
    hash = hash*31 + ((struct _spair *)p)->b;
    return hash;
}

variable_types:
p
void *

variable_types:
hash
unsigned long

user_defined_types: struct _spair { unsigned int a; unsigned int b; }


decompiled_code:
_BOOL8 __fastcall cmp_pair(_QWORD *a1, _QWORD *a2)
{
return *a1 == *a2;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(_QWORD *a1, _QWORD *a2)
{
return *a1 == *a2;
}

original_code:
static int cmp_pair(void * a, void * b) {
    return memcmp(a, b, sizeof(struct _spair)) == 0 ? 1 : 0;
}

canonical_original_code:
static int cmp_pair(void *a, void *b) {
    return memcmp(a, b, sizeof(struct _spair)) == 0 ? 1 : 0;
}


original_code:
void match_arcs(
                    const struct _fst * fst_a,
                    const struct _fst * fst_b,
                    const struct _spair * pair,
                    struct _sr * sr,
                    struct _queue * mq)
{
    struct _state * state_a = &fst_a->states[pair->a];
    struct _state * state_b = &fst_b->states[pair->b];
    int osort = fst_a->flags & 0x02;
    int isort = fst_b->flags & 0x01;
    size_t asize = sizeof(struct _arc);
    uint32_t m = state_a->n_arcs + 1;
    uint32_t n = state_b->n_arcs + 1;
    struct _arc * arcs_a = malloc(asize * m);
    struct _arc * arcs_b = malloc(asize * n);
    memcpy(arcs_a + 1, state_a->arcs, asize * (m-1));
    memcpy(arcs_b + 1, state_b->arcs, asize * (n-1));
    struct _arc loop_arc_a = {
            .state = pair->a,
            .ilabel = 0,
            .olabel = 0,
            .weight = sr->one
    };
    struct _arc loop_arc_b = {
            .state = pair->b,
            .ilabel = 0,
            .olabel = 0,
            .weight = sr->one
    };
    arcs_a[0] = loop_arc_a;
    arcs_b[0] = loop_arc_b;
    if (isort && osort)
        match_full_sorted(arcs_a, arcs_b, m, n, mq);
    else
        if (isort || osort) {
            if (isort) {
                match_half_sorted(arcs_a, arcs_b, m, n, mq);
            } else {
                match_half_sorted_rev(arcs_a, arcs_b, m, n, mq);
            }
        } else {
            match_unsorted(arcs_a, arcs_b, m, n, mq);
        }
    free(arcs_a);
    free(arcs_b);
}

canonical_original_code:
void match_arcs(struct _fst *fst_a, struct _fst *fst_b, struct _spair *pair, struct _sr *sr, struct _queue *mq)
{
    struct _state *state_a = &fst_a->states[pair->a];
    struct _state *state_b = &fst_b->states[pair->b];
    int osort = fst_a->flags & 0x02;
    int isort = fst_b->flags & 0x01;
    unsigned long asize = sizeof(struct _arc);
    unsigned int m = state_a->n_arcs + 1;
    unsigned int n = state_b->n_arcs + 1;
    struct _arc *arcs_a = malloc(asize * m);
    struct _arc *arcs_b = malloc(asize * n);
    memcpy(arcs_a + 1, state_a->arcs, asize * (m-1));
    memcpy(arcs_b + 1, state_b->arcs, asize * (n-1));
    struct _arc loop_arc_a = {
            .state = pair->a,
            .ilabel = 0,
            .olabel = 0,
            .weight = sr->one
    };
    struct _arc loop_arc_b = {
            .state = pair->b,
            .ilabel = 0,
            .olabel = 0,
            .weight = sr->one
    };
    arcs_a[0] = loop_arc_a;
    arcs_b[0] = loop_arc_b;
    if (isort && osort)
        match_full_sorted(arcs_a, arcs_b, m, n, mq);
    else
        if (isort || osort) {
            if (isort) {
                match_half_sorted(arcs_a, arcs_b, m, n, mq);
            } else {
                match_half_sorted_rev(arcs_a, arcs_b, m, n, mq);
            }
        } else {
            match_unsorted(arcs_a, arcs_b, m, n, mq);
        }
    free(arcs_a);
    free(arcs_b);
}

variable_types: struct _fst { unsigned int start; unsigned int n_states; unsigned int n_max; unsigned char sr_type; unsigned char flags; struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; } *states; } *

variable_types: struct _spair { unsigned int a; unsigned int b; } *

variable_types: struct _sr { float (*sum)(float a, float b); float (*prod)(float a, float b); float zero; float one; } *

variable_types: struct _queue { struct _qnode { struct _qnode *next; char item[1]; } *head; struct _qnode *tail; unsigned long item_size; unsigned long n_items; } *

variable_types: osort int

variable_types: isort int

variable_types:
asize
unsigned long

variable_types:
m
unsigned int

variable_types:
n
unsigned int

user_defined_types: struct _fst { unsigned int start; unsigned int n_states; unsigned int n_max; unsigned char sr_type; unsigned char flags; struct _state *states; }

user_defined_types: struct _queue { struct _qnode *head; struct _qnode *tail; unsigned long item_size; unsigned long n_items; }

user_defined_types: struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc *arcs; }


decompiled_code:
unsigned int *__fastcall fst_compose(__int64 a1, __int64 a2, unsigned int *a3)
{
__int64 v4; // r15
__int64 v5; // r12
__int64 v6; // rbp
__int64 v8; // [rsp+0h] [rbp-A8h]
__int64 v9; // [rsp+0h] [rbp-A8h]
unsigned int v10; // [rsp+8h] [rbp-A0h]
__int64 v11; // [rsp+8h] [rbp-A0h]
__int64 v12; // [rsp+10h] [rbp-98h]
unsigned int v13; // [rsp+10h] [rbp-98h]
unsigned int v14; // [rsp+1Ch] [rbp-8Ch]
unsigned int v15; // [rsp+20h] [rbp-88h] BYREF
unsigned int v16; // [rsp+24h] [rbp-84h] BYREF
int v17; // [rsp+28h] [rbp-80h] BYREF
unsigned int v18; // [rsp+2Ch] [rbp-7Ch]
char v19[8]; // [rsp+30h] [rbp-78h] BYREF
void (__fastcall *v20)(float, float); // [rsp+38h] [rbp-70h]
float v21; // [rsp+44h] [rbp-64h]
int v22[22]; // [rsp+50h] [rbp-58h] BYREF

sr_get(v19, *(unsigned __int8 *)(a1 + 12));
v4 = queue_create(8LL);
v5 = queue_create(32LL);
v6 = hash_create(hash_pair, cmp_pair, 8LL, 4LL, 1000LL);
v17 = *(_DWORD *)a1;
v18 = *(_DWORD *)a2;
queue_enque(v4, &v17);
while ( queue_deque(v4, &v17) )
{
v8 = *(_QWORD *)(a1 + 16);
v10 = v17;
v12 = *(_QWORD *)(a2 + 16);
v14 = v18;
if ( !hash_get(v6, &v17, &v15) )
{
v15 = fst_add_state(a3);
if ( *(_DWORD *)(v8 + 24LL * v10 + 12) && *(_DWORD *)(v12 + 24LL * v14 + 12) )
{
fst_set_final(a3, v15, v21);
if ( v17 != *(_DWORD *)a1 )
goto LABEL_15;
}
else if ( v17 != *(_DWORD *)a1 )
{
LABEL_15:
hash_add(v6, &v17, &v15);
goto LABEL_4;
}
if ( v18 == *(_DWORD *)a2 )
*a3 = v15;
goto LABEL_15;
}
LABEL_4:
match_arcs(a1, a2, (unsigned int *)&v17, (__int64)v19, v5);
while ( queue_deque(v5, v22) )
{
v17 = v22[0];
v18 = v22[4];
if ( !hash_get(v6, &v17, &v16) )
{
v13 = v18;
v9 = *(_QWORD *)(a1 + 16) + 24LL * (unsigned int)v17;
v11 = *(_QWORD *)(a2 + 16);
v16 = fst_add_state(a3);
if ( *(_DWORD *)(v9 + 12) )
{
if ( *(_DWORD *)(v11 + 24LL * v13 + 12) )
fst_set_final(a3, v16, v21);
}
queue_enque(v4, &v17);
hash_add(v6, &v17, &v16);
}
v20(*(float *)&v22[1], *(float *)&v22[5]);
fst_add_arc(a3, v15, v16, (unsigned int)v22[2], (unsigned int)v22[7]);
}
}
queue_remove(v4);
queue_remove(v5);
hash_remove(v6);
return a3;
}

canonical_decompiled_code:
unsigned int *__fastcall func3(__int64 a1, __int64 a2, unsigned int *a3)
{
__int64 v4; // r15
__int64 v5; // r12
__int64 v6; // rbp
__int64 v8; // [rsp+0h] [rbp-A8h]
__int64 v9; // [rsp+0h] [rbp-A8h]
unsigned int v10; // [rsp+8h] [rbp-A0h]
__int64 v11; // [rsp+8h] [rbp-A0h]
__int64 v12; // [rsp+10h] [rbp-98h]
unsigned int v13; // [rsp+10h] [rbp-98h]
unsigned int v14; // [rsp+1Ch] [rbp-8Ch]
unsigned int v15; // [rsp+20h] [rbp-88h] BYREF
unsigned int v16; // [rsp+24h] [rbp-84h] BYREF
int v17; // [rsp+28h] [rbp-80h] BYREF
unsigned int v18; // [rsp+2Ch] [rbp-7Ch]
char v19[8]; // [rsp+30h] [rbp-78h] BYREF
void (__fastcall *v20)(float, float); // [rsp+38h] [rbp-70h]
float v21; // [rsp+44h] [rbp-64h]
int v22[22]; // [rsp+50h] [rbp-58h] BYREF

sr_get(v19, *(unsigned __int8 *)(a1 + 12));
v4 = queue_create(8LL);
v5 = queue_create(32LL);
v6 = hash_create(hash_pair, cmp_pair, 8LL, 4LL, 1000LL);
v17 = *(_DWORD *)a1;
v18 = *(_DWORD *)a2;
queue_enque(v4, &v17);
while ( queue_deque(v4, &v17) )
{
v8 = *(_QWORD *)(a1 + 16);
v10 = v17;
v12 = *(_QWORD *)(a2 + 16);
v14 = v18;
if ( !hash_get(v6, &v17, &v15) )
{
v15 = fst_add_state(a3);
if ( *(_DWORD *)(v8 + 24LL * v10 + 12) && *(_DWORD *)(v12 + 24LL * v14 + 12) )
{
fst_set_final(a3, v15, v21);
if ( v17 != *(_DWORD *)a1 )
goto LABEL_15;
}
else if ( v17 != *(_DWORD *)a1 )
{
LABEL_15:
hash_add(v6, &v17, &v15);
goto LABEL_4;
}
if ( v18 == *(_DWORD *)a2 )
*a3 = v15;
goto LABEL_15;
}
LABEL_4:
func2(a1, a2, (unsigned int *)&v17, (__int64)v19, v5);
while ( queue_deque(v5, v22) )
{
v17 = v22[0];
v18 = v22[4];
if ( !hash_get(v6, &v17, &v16) )
{
v13 = v18;
v9 = *(_QWORD *)(a1 + 16) + 24LL * (unsigned int)v17;
v11 = *(_QWORD *)(a2 + 16);
v16 = fst_add_state(a3);
if ( *(_DWORD *)(v9 + 12) )
{
if ( *(_DWORD *)(v11 + 24LL * v13 + 12) )
fst_set_final(a3, v16, v21);
}
queue_enque(v4, &v17);
hash_add(v6, &v17, &v16);
}
v20(*(float *)&v22[1], *(float *)&v22[5]);
fst_add_arc(a3, v15, v16, (unsigned int)v22[2], (unsigned int)v22[7]);
}
}
queue_remove(v4);
queue_remove(v5);
hash_remove(v6);
return a3;
}

original_code:
struct _fst * fst_compose(
    const struct _fst * fst_a,
    const struct _fst * fst_b,
    struct _fst * fst_c )
{
    struct _sr sr = sr_get(fst_a->sr_type);
    struct _queue * q = queue_create(sizeof(struct _spair));
    struct _queue * mq = queue_create(sizeof(struct _arc_pair));
    struct _hash * marked = hash_create(
                    hash_pair,
                    cmp_pair,
                    sizeof(struct _spair),
                    sizeof(uint32_t),
                    1000 );
    struct _spair pair;
    struct _arc_pair mi;
    uint32_t sc, dst_sc;
    struct _state * state_a, * state_b;
    struct _state * dst_state_a, * dst_state_b;
    struct _arc * arc_a, * arc_b;
    pair.a = fst_a->start;
    pair.b = fst_b->start;
    queue_enque(q, &pair);
    while( (queue_deque(q, &pair)) != ((void *)0) ) {
        state_a = &fst_a->states[pair.a];
        state_b = &fst_b->states[pair.b];
        if (hash_get(marked, &pair, &sc) == ((void *)0)) {
            sc = fst_add_state(fst_c);
            if (state_a->final && state_b->final)
                fst_set_final(fst_c, sc, sr.one);
            if (pair.a == fst_a->start && pair.b == fst_b->start)
                fst_c->start = sc;
            hash_add(marked, &pair, &sc);
        }
        match_arcs( fst_a, fst_b,
                        &pair,
                        &sr,
                        mq );
        while ( queue_deque(mq, &mi) != ((void *)0) ) {
            arc_a = &mi.a;
            arc_b = &mi.b;
            pair.a = arc_a->state;
            pair.b = arc_b->state;
            if (hash_get(marked, &pair, &dst_sc) == ((void *)0)) {
                dst_state_a = &fst_a->states[pair.a];
                dst_state_b = &fst_b->states[pair.b];
                dst_sc = fst_add_state(fst_c);
                if (dst_state_a->final && dst_state_b->final) {
                    fst_set_final(fst_c, dst_sc, sr.one);
                }
                queue_enque(q, &pair);
                hash_add(marked, &pair, &dst_sc);
            }
            fst_add_arc(
                fst_c,
                sc,
                dst_sc,
                arc_a->ilabel,
                arc_b->olabel,
                sr.prod(arc_a->weight, arc_b->weight));
        }
    }
    queue_remove(q);
    queue_remove(mq);
    hash_remove(marked);
    return fst_c;
}

canonical_original_code:
struct _fst *fst_compose(struct _fst *fst_a, struct _fst *fst_b, struct _fst *fst_c)
{
    struct _sr sr = sr_get(fst_a->sr_type);
    struct _queue *q = queue_create(sizeof(struct _spair));
    struct _queue *mq = queue_create(sizeof(struct _arc_pair));
    struct _hash *marked = hash_create(
                    hash_pair,
                    cmp_pair,
                    sizeof(struct _spair),
                    sizeof(uint32_t),
                    1000 );
    struct _spair pair;
    struct _arc_pair mi;
    unsigned int sc; unsigned int dst_sc;
    struct _state *state_a; struct _state *state_b;
    struct _state *dst_state_a; struct _state *dst_state_b;
    struct _arc *arc_a; struct _arc *arc_b;
    pair.a = fst_a->start;
    pair.b = fst_b->start;
    queue_enque(q, &pair);
    while( (queue_deque(q, &pair)) != ((void *)0) ) {
        state_a = &fst_a->states[pair.a];
        state_b = &fst_b->states[pair.b];
        if (hash_get(marked, &pair, &sc) == ((void *)0)) {
            sc = fst_add_state(fst_c);
            if (state_a->final && state_b->final)
                fst_set_final(fst_c, sc, sr.one);
            if (pair.a == fst_a->start && pair.b == fst_b->start)
                fst_c->start = sc;
            hash_add(marked, &pair, &sc);
        }
        match_arcs( fst_a, fst_b,
                        &pair,
                        &sr,
                        mq );
        while ( queue_deque(mq, &mi) != ((void *)0) ) {
            arc_a = &mi.a;
            arc_b = &mi.b;
            pair.a = arc_a->state;
            pair.b = arc_b->state;
            if (hash_get(marked, &pair, &dst_sc) == ((void *)0)) {
                dst_state_a = &fst_a->states[pair.a];
                dst_state_b = &fst_b->states[pair.b];
                dst_sc = fst_add_state(fst_c);
                if (dst_state_a->final && dst_state_b->final) {
                    fst_set_final(fst_c, dst_sc, sr.one);
                }
                queue_enque(q, &pair);
                hash_add(marked, &pair, &dst_sc);
            }
            fst_add_arc(
                fst_c,
                sc,
                dst_sc,
                arc_a->ilabel,
                arc_b->olabel,
                sr.prod(arc_a->weight, arc_b->weight));
        }
    }
    queue_remove(q);
    queue_remove(mq);
    hash_remove(marked);
    return fst_c;
}

variable_types: struct _sr { float (*sum)(float a, float b); float (*prod)(float a, float b); float zero; float one; }

variable_types: struct _hash { struct _bucket { struct _bitem { void *key; void *value; struct _bitem *next; } *head; struct _bitem *tail; } *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); } *

variable_types: struct _spair { unsigned int a; unsigned int b; }

variable_types: struct _arc_pair { struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } a; struct _arc b; }

variable_types:
sc
unsigned int

return_type: struct _fst { unsigned int start; unsigned int n_states; unsigned int n_max; unsigned char sr_type; unsigned char flags; struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; } *states; } *

user_defined_types: struct _arc_pair { struct _arc a; struct _arc b; }

user_defined_types: struct _qnode { struct _qnode *next; char item[1]; }


original_code:
void match_unsorted(
                struct _arc * a,
                struct _arc * b,
                uint32_t M,
                uint32_t N,
                struct _queue * q)
{
    struct _match_item mi;
    for (uint32_t i = 0; i < M; ++i)
        for (uint32_t j = 0; j < N; ++j)
            if ( a[i].olabel == b[j].ilabel && _match(a, b, i, j)) {
                mi.a = a[i];
                mi.b = b[j];
                queue_enque(q, &mi);
            }
}

canonical_original_code:
void match_unsorted(struct _arc *a, struct _arc *b, unsigned int M, unsigned int N, struct _queue *q)
{
    struct _match_item mi;
    for (unsigned int i = 0; i < M; ++i)
        for (unsigned int j = 0; j < N; ++j)
            if ( a[i].olabel == b[j].ilabel && _match(a, b, i, j)) {
                mi.a = a[i];
                mi.b = b[j];
                queue_enque(q, &mi);
            }
}

variable_types: struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *

variable_types:
b
struct _arc *

variable_types:
M
unsigned int

variable_types:
N
unsigned int

variable_types: struct _match_item { struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } a; struct _arc b; }

variable_types:
i
unsigned int

variable_types:
j
unsigned int

user_defined_types: struct _match_item { struct _arc a; struct _arc b; }


decompiled_code:
__int64 __fastcall match_half_sorted(const __m128i *a1, __int64 a2, int a3, int a4, __int64 a5)
{
__int64 result; // rax
__int64 v6; // rbp
const __m128i *v8; // r12
unsigned int i; // er13
unsigned __int32 v10; // edi
unsigned int v11; // esi
unsigned int v12; // edx
unsigned int v13; // ebx
unsigned int j; // er14
__m128i v15; // xmm1
unsigned int v16; // [rsp+0h] [rbp-68h]
__int128 v19[5]; // [rsp+10h] [rbp-58h] BYREF

result = (unsigned int)(a4 - 1);
v16 = a4 - 1;
if ( a3 )
{
v6 = (__int64)a1;
v8 = a1;
for ( i = 0; a3 != i; ++i )
{
v10 = v8->m128i_u32[3];
v11 = v16;
v12 = 0;
while ( 1 )
{
while ( 1 )
{
v13 = (v12 + v11) >> 1;
result = 16LL * v13;
if ( v10 <= *(_DWORD *)(a2 + result + 8) )
break;
v12 = v13 + 1;
if ( v13 + 1 > v11 )
goto LABEL_9;
}
if ( v10 >= *(_DWORD *)(a2 + result + 8) )
break;
if ( v13 )
{
v11 = v13 - 1;
if ( v12 <= v13 - 1 )
continue;
}
goto LABEL_9;
}
for ( j = (v12 + v11) >> 1; j > v12; --j )
{
result = 16LL * (j - 1);
if ( v10 != *(_DWORD *)(a2 + result + 8) )
goto LABEL_18;
}
while ( v13 < v11 )
{
result = 16LL * (v13 + 1);
if ( v10 != *(_DWORD *)(a2 + result + 8) )
break;
++v13;
LABEL_18:
;
}
for ( ; v13 >= j; ++j )
{
v15 = _mm_loadu_si128((const __m128i *)(a2 + 16LL * j));
v19[0] = (__int128)_mm_loadu_si128(v8);
v19[1] = (__int128)v15;
result = match_constprop_0(v6, i, j);
if ( (_DWORD)result )
result = queue_enque(a5, v19);
}
LABEL_9:
++v8;
}
}
return result;
}

original_code:
void match_half_sorted(
                struct _arc * a,
                struct _arc * b,
                uint32_t M,
                uint32_t N,
                struct _queue * q)
{
    uint32_t l, h, ll, hh;
    uint32_t i,m;
    struct _match_item mi;
    for (i=0; i < M; ++i) {
        l = 0;
        h = N-1;
        while ( l <= h ) {
            m = (l + h) >> 1;
            if (a[i].olabel > b[m].ilabel) l = m + 1;
            else
                if (a[i].olabel < b[m].ilabel) {
                    if (m == 0) break;
                    h = m - 1;
                }
                else {
                    ll = hh = m;
                    while ((ll > l) && (a[i].olabel == b[ll-1].ilabel)) --ll;
                    while ((hh < h) && (a[i].olabel == b[hh+1].ilabel)) ++hh;
                    while (ll <= hh ) {
                        mi.a = a[i];
                        mi.b = b[ll];
                        if (_match(a, b, i, ll))
                            queue_enque(q, &mi);
                        ++ll;
                    }
                    break;
                }
        }
    }
}

canonical_original_code:
void match_half_sorted(struct _arc *a, struct _arc *b, unsigned int M, unsigned int N, struct _queue *q)
{
    unsigned int l; unsigned int h; unsigned int ll; unsigned int hh;
    unsigned int i; unsigned int m;
    struct _match_item mi;
    for (i=0; i < M; ++i) {
        l = 0;
        h = N-1;
        while ( l <= h ) {
            m = (l + h) >> 1;
            if (a[i].olabel > b[m].ilabel) l = m + 1;
            else
                if (a[i].olabel < b[m].ilabel) {
                    if (m == 0) break;
                    h = m - 1;
                }
                else {
                    ll = hh = m;
                    while ((ll > l) && (a[i].olabel == b[ll-1].ilabel)) --ll;
                    while ((hh < h) && (a[i].olabel == b[hh+1].ilabel)) ++hh;
                    while (ll <= hh ) {
                        mi.a = a[i];
                        mi.b = b[ll];
                        if (_match(a, b, i, ll))
                            queue_enque(q, &mi);
                        ++ll;
                    }
                    break;
                }
        }
    }
}

variable_types: struct _queue { struct _qnode { struct _qnode *next; char item[1]; } *head; struct _qnode *tail; unsigned long item_size; unsigned long n_items; } *

variable_types:
l
unsigned int

variable_types:
h
unsigned int

variable_types:
ll
unsigned int

variable_types:
hh
unsigned int

user_defined_types: struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; }


decompiled_code:
__int64 __fastcall match_half_sorted_rev(__int64 a1, const __m128i *a2, int a3, int a4, __int64 a5)
{
__int64 result; // rax
int i; // er12
unsigned __int32 v9; // esi
unsigned int v10; // ecx
unsigned int v11; // edx
unsigned int v12; // ebx
unsigned int j; // ebp
__m128i v14; // xmm0
unsigned int v15; // [rsp+8h] [rbp-60h]
__int128 v17[5]; // [rsp+10h] [rbp-58h] BYREF

result = (unsigned int)(a3 - 1);
v15 = a3 - 1;
if ( a4 )
{
for ( i = 0; a4 != i; ++i )
{
v9 = a2->m128i_u32[2];
v10 = v15;
v11 = 0;
while ( 1 )
{
while ( 1 )
{
v12 = (v11 + v10) >> 1;
result = 16LL * v12;
if ( v9 <= *(_DWORD *)(a1 + result + 12) )
break;
v11 = v12 + 1;
if ( v12 + 1 > v10 )
goto LABEL_9;
}
if ( v9 >= *(_DWORD *)(a1 + result + 12) )
break;
if ( v12 )
{
v10 = v12 - 1;
if ( v11 <= v12 - 1 )
continue;
}
goto LABEL_9;
}
for ( j = (v11 + v10) >> 1; j > v11; --j )
{
result = 16LL * (j - 1);
if ( v9 != *(_DWORD *)(a1 + result + 12) )
goto LABEL_18;
}
while ( v12 < v10 )
{
result = 16LL * (v12 + 1);
if ( v9 != *(_DWORD *)(a1 + result + 12) )
break;
++v12;
LABEL_18:
;
}
for ( ; v12 >= j; ++j )
{
v14 = _mm_loadu_si128((const __m128i *)(a1 + 16LL * j));
v17[1] = (__int128)_mm_loadu_si128(a2);
v17[0] = (__int128)v14;
result = match_constprop_0(a1, j, i);
if ( (_DWORD)result )
result = queue_enque(a5, v17);
}
LABEL_9:
++a2;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, const __m128i *a2, int a3, int a4, __int64 a5)
{
__int64 result; // rax
int i; // er12
unsigned __int32 v9; // esi
unsigned int v10; // ecx
unsigned int v11; // edx
unsigned int v12; // ebx
unsigned int j; // ebp
__m128i v14; // xmm0
unsigned int v15; // [rsp+8h] [rbp-60h]
__int128 v17[5]; // [rsp+10h] [rbp-58h] BYREF

result = (unsigned int)(a3 - 1);
v15 = a3 - 1;
if ( a4 )
{
for ( i = 0; a4 != i; ++i )
{
v9 = a2->m128i_u32[2];
v10 = v15;
v11 = 0;
while ( 1 )
{
while ( 1 )
{
v12 = (v11 + v10) >> 1;
result = 16LL * v12;
if ( v9 <= *(_DWORD *)(a1 + result + 12) )
break;
v11 = v12 + 1;
if ( v12 + 1 > v10 )
goto LABEL_9;
}
if ( v9 >= *(_DWORD *)(a1 + result + 12) )
break;
if ( v12 )
{
v10 = v12 - 1;
if ( v11 <= v12 - 1 )
continue;
}
goto LABEL_9;
}
for ( j = (v11 + v10) >> 1; j > v11; --j )
{
result = 16LL * (j - 1);
if ( v9 != *(_DWORD *)(a1 + result + 12) )
goto LABEL_18;
}
while ( v12 < v10 )
{
result = 16LL * (v12 + 1);
if ( v9 != *(_DWORD *)(a1 + result + 12) )
break;
++v12;
LABEL_18:
;
}
for ( ; v12 >= j; ++j )
{
v14 = _mm_loadu_si128((const __m128i *)(a1 + 16LL * j));
v17[1] = (__int128)_mm_loadu_si128(a2);
v17[0] = (__int128)v14;
result = func0(a1, j, i);
if ( (_DWORD)result )
result = queue_enque(a5, v17);
}
LABEL_9:
++a2;
}
}
return result;
}

original_code:
void match_half_sorted_rev(
                struct _arc * a,
                struct _arc * b,
                uint32_t M,
                uint32_t N,
                struct _queue * q)
{
    uint32_t l, h, ll, hh;
    uint32_t i,m;
    struct _match_item mi;
    for (i=0; i < N; ++i) {
        l = 0;
        h = M-1;
        while ( l <= h ) {
            m = (l + h) >> 1;
            if (b[i].ilabel > a[m].olabel) l = m + 1;
            else
                if (b[i].ilabel < a[m].olabel) {
                    if (m == 0) break;
                    h = m - 1;
                }
                else {
                    ll = hh = m;
                    while ((ll > l) && (b[i].ilabel == a[ll-1].olabel)) --ll;
                    while ((hh < h) && (b[i].ilabel == a[hh+1].olabel)) ++hh;
                    while (ll <= hh ) {
                        mi.a = a[ll];
                        mi.b = b[i];
                        if (_match(a, b, ll, i))
                            queue_enque(q, &mi);
                        ++ll;
                    }
                    break;
                }
        }
    }
}

canonical_original_code:
void match_half_sorted_rev(struct _arc *a, struct _arc *b, unsigned int M, unsigned int N, struct _queue *q)
{
    unsigned int l; unsigned int h; unsigned int ll; unsigned int hh;
    unsigned int i; unsigned int m;
    struct _match_item mi;
    for (i=0; i < N; ++i) {
        l = 0;
        h = M-1;
        while ( l <= h ) {
            m = (l + h) >> 1;
            if (b[i].ilabel > a[m].olabel) l = m + 1;
            else
                if (b[i].ilabel < a[m].olabel) {
                    if (m == 0) break;
                    h = m - 1;
                }
                else {
                    ll = hh = m;
                    while ((ll > l) && (b[i].ilabel == a[ll-1].olabel)) --ll;
                    while ((hh < h) && (b[i].ilabel == a[hh+1].olabel)) ++hh;
                    while (ll <= hh ) {
                        mi.a = a[ll];
                        mi.b = b[i];
                        if (_match(a, b, ll, i))
                            queue_enque(q, &mi);
                        ++ll;
                    }
                    break;
                }
        }
    }
}

variable_types:
m
unsigned int


original_code:
void match_full_sorted(
                struct _arc * a,
                struct _arc * b,
                uint32_t M,
                uint32_t N,
                struct _queue * q)
{
    uint32_t i = 0;
    uint32_t j = 0;
    uint32_t t;
    struct _match_item mi;
    while (i < M && j < N) {
        if ( a[i].olabel < b[j].ilabel ) ++i;
        else
            if ( a[i].olabel > b[j].ilabel ) ++j;
            else {
                for (t=j; a[i].olabel == b[t].ilabel; ++t ) {
                    mi.a = a[i];
                    mi.b = b[t];
                    if (_match(a, b, i, t))
                        queue_enque(q, &mi);
                }
                ++i;
            }
    }
}

canonical_original_code:
void match_full_sorted(struct _arc *a, struct _arc *b, unsigned int M, unsigned int N, struct _queue *q)
{
    unsigned int i = 0;
    unsigned int j = 0;
    unsigned int t;
    struct _match_item mi;
    while (i < M && j < N) {
        if ( a[i].olabel < b[j].ilabel ) ++i;
        else
            if ( a[i].olabel > b[j].ilabel ) ++j;
            else {
                for (t=j; a[i].olabel == b[t].ilabel; ++t ) {
                    mi.a = a[i];
                    mi.b = b[t];
                    if (_match(a, b, i, t))
                        queue_enque(q, &mi);
                }
                ++i;
            }
    }
}

variable_types:
t
unsigned int


decompiled_code:
_DWORD *fst_create()
{
_DWORD *result; // rax

result = malloc(0x18uLL);
*(_QWORD *)result = 0LL;
result[2] = 0;
*((_WORD *)result + 6) = 0;
*((_QWORD *)result + 2) = 0LL;
return result;
}

canonical_decompiled_code:
_DWORD *func0()
{
_DWORD *result; // rax

result = malloc(0x18uLL);
*(_QWORD *)result = 0LL;
result[2] = 0;
*((_WORD *)result + 6) = 0;
*((_QWORD *)result + 2) = 0LL;
return result;
}

original_code:
struct _fst * fst_create() {
    struct _fst * fst;
    fst = malloc(sizeof(struct _fst));
    fst->sr_type = 0;
    fst->n_states = 0;
    fst->n_max = 0;
    fst->start = 0;
    fst->flags = 0;
    fst->states = ((void *)0);
    return fst;
}

canonical_original_code:
struct _fst *fst_create() {
    struct _fst *fst;
    fst = malloc(sizeof(struct _fst));
    fst->sr_type = 0;
    fst->n_states = 0;
    fst->n_max = 0;
    fst->start = 0;
    fst->flags = 0;
    fst->states = ((void *)0);
    return fst;
}

variable_types: struct _fst { unsigned int start; unsigned int n_states; unsigned int n_max; unsigned char sr_type; unsigned char flags; struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; } *states; } *


original_code:
uint32_t fst_add_state(struct _fst * fst) {
    struct _state * state;
    ++fst->n_states;
    if (fst->n_states > fst->n_max) {
        fst->n_max = fst->n_states * 2;
        fst->states = realloc(fst->states,
            sizeof(struct _state) * fst->n_max);
    }
    state = &fst->states[fst->n_states - 1];
    state->n_arcs = 0;
    state->n_max = 0;
    state->final = 0;
    state->weight = 0;
    state->arcs = ((void *)0);
    return fst->n_states - 1;
}

canonical_original_code:
unsigned int fst_add_state(struct _fst *fst) {
    struct _state *state;
    ++fst->n_states;
    if (fst->n_states > fst->n_max) {
        fst->n_max = fst->n_states * 2;
        fst->states = realloc(fst->states,
            sizeof(struct _state) * fst->n_max);
    }
    state = &fst->states[fst->n_states - 1];
    state->n_arcs = 0;
    state->n_max = 0;
    state->final = 0;
    state->weight = 0;
    state->arcs = ((void *)0);
    return fst->n_states - 1;
}

variable_types: struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; } *


decompiled_code:
__int64 __fastcall fst_add_arc(__int64 a1, unsigned int a2, int a3, int a4, int a5, float a6)
{
unsigned int *v9; // rbx
__int64 result; // rax
char *v11; // rdi
char *v12; // rdi
__int64 v13; // rsi
char *v14; // rax

v9 = (unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL * a2);
result = *v9;
v11 = (char *)*((_QWORD *)v9 + 2);
*v9 = result + 1;
if ( (int)result + 1 > v9[1] )
{
v13 = (unsigned int)(2 * (result + 1));
v9[1] = v13;
v14 = (char *)realloc(v11, 16 * v13);
*((_QWORD *)v9 + 2) = v14;
v11 = v14;
result = *v9 - 1;
}
v12 = &v11[16 * (unsigned int)result];
*(_DWORD *)v12 = a3;
*((_DWORD *)v12 + 2) = a4;
*((_DWORD *)v12 + 3) = a5;
*((float *)v12 + 1) = a6;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, unsigned int a2, int a3, int a4, int a5, float a6)
{
unsigned int *v9; // rbx
__int64 result; // rax
char *v11; // rdi
char *v12; // rdi
__int64 v13; // rsi
char *v14; // rax

v9 = (unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL * a2);
result = *v9;
v11 = (char *)*((_QWORD *)v9 + 2);
*v9 = result + 1;
if ( (int)result + 1 > v9[1] )
{
v13 = (unsigned int)(2 * (result + 1));
v9[1] = v13;
v14 = (char *)realloc(v11, 16 * v13);
*((_QWORD *)v9 + 2) = v14;
v11 = v14;
result = *v9 - 1;
}
v12 = &v11[16 * (unsigned int)result];
*(_DWORD *)v12 = a3;
*((_DWORD *)v12 + 2) = a4;
*((_DWORD *)v12 + 3) = a5;
*((float *)v12 + 1) = a6;
return result;
}

original_code:
uint32_t fst_add_arc(
            struct _fst * fst,
            uint32_t src,
            uint32_t dst,
            uint32_t il,
            uint32_t ol,
            float weight)
{
    struct _arc * arc;
    struct _state * state = &fst->states[src];
    ++state->n_arcs;
    if (state->n_arcs > state->n_max) {
        state->n_max = state->n_arcs * 2;
        state->arcs = realloc(state->arcs,
            sizeof(struct _arc) * state->n_max);
    }
    arc = &state->arcs[state->n_arcs - 1];
    arc->state = dst;
    arc->ilabel = il;
    arc->olabel = ol;
    arc->weight = weight;
    return state->n_arcs - 1;
}

canonical_original_code:
unsigned int fst_add_arc(struct _fst *fst, unsigned int src, unsigned int dst, unsigned int il, unsigned int ol, float weight)
{
    struct _arc *arc;
    struct _state *state = &fst->states[src];
    ++state->n_arcs;
    if (state->n_arcs > state->n_max) {
        state->n_max = state->n_arcs * 2;
        state->arcs = realloc(state->arcs,
            sizeof(struct _arc) * state->n_max);
    }
    arc = &state->arcs[state->n_arcs - 1];
    arc->state = dst;
    arc->ilabel = il;
    arc->olabel = ol;
    arc->weight = weight;
    return state->n_arcs - 1;
}

variable_types:
src
unsigned int

variable_types:
dst
unsigned int

variable_types:
il
unsigned int

variable_types:
ol
unsigned int

variable_types: weight float


original_code:
void fst_empty(struct _fst * fst) {
    struct _state * state;
    for(uint32_t s=0; s < fst->n_states; ++s) {
        state = fst->states + s;
        if (state->arcs != ((void *)0))
            free(state->arcs);
    }
    if ( fst->states != ((void *)0) )
        free(fst->states);
    fst->n_states = 0;
    fst->n_max = 0;
    fst->states = ((void *)0);
    fst->start = 0;
}

canonical_original_code:
void fst_empty(struct _fst *fst) {
    struct _state *state;
    for(unsigned int s = 0; s < fst->n_states; ++s) {
        state = fst->states + s;
        if (state->arcs != ((void *)0))
            free(state->arcs);
    }
    if ( fst->states != ((void *)0) )
        free(fst->states);
    fst->n_states = 0;
    fst->n_max = 0;
    fst->states = ((void *)0);
    fst->start = 0;
}

variable_types:
s
unsigned int


decompiled_code:
void __fastcall fst_remove(void *ptr)
{
fst_empty((__int64)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
func3((__int64)ptr);
free(ptr);
}

original_code:
void fst_remove(struct _fst * fst) {
    fst_empty(fst);
    free(fst);
}

canonical_original_code:
void fst_remove(struct _fst *fst) {
    fst_empty(fst);
    free(fst);
}


decompiled_code:
__int64 __fastcall fst_set_final(__int64 a1, unsigned int a2, float a3)
{
__int64 result; // rax

result = *(_QWORD *)(a1 + 16) + 24LL * a2;
*(_DWORD *)(result + 12) = 1;
*(float *)(result + 8) = a3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, unsigned int a2, float a3)
{
__int64 result; // rax

result = *(_QWORD *)(a1 + 16) + 24LL * a2;
*(_DWORD *)(result + 12) = 1;
*(float *)(result + 8) = a3;
return result;
}

original_code:
void fst_set_final(struct _fst * fst, uint32_t s, float w) {
    (&fst->states[s])->final = 1;
    (&fst->states[s])->weight = w;
}

canonical_original_code:
void fst_set_final(struct _fst *fst, unsigned int s, float w) {
    (&fst->states[s])->final = 1;
    (&fst->states[s])->weight = w;
}

variable_types: w float


original_code:
uint32_t fst_get_n_arcs(const struct _fst * fst) {
    uint32_t n = 0;
    for (uint32_t s = 0; s < fst->n_states; ++s) {
        n += fst->states[s].n_arcs;
    }
    return n;
}

canonical_original_code:
unsigned int fst_get_n_arcs(struct _fst *fst) {
    unsigned int n = 0;
    for (unsigned int s = 0; s < fst->n_states; ++s) {
        n += fst->states[s].n_arcs;
    }
    return n;
}

variable_types:
n
unsigned int


original_code:
void fst_copy(const struct _fst * orig, struct _fst * copy) {
    struct _state * so, * sc;
    memcpy(copy, orig, sizeof(struct _fst));
    copy->states = malloc(sizeof(struct _state) * orig->n_max);
    memcpy(copy->states, orig->states, sizeof(struct _state) * orig->n_states);
    for(uint32_t s=0; s < copy->n_states; ++s) {
        sc = &copy->states[s];
        so = &orig->states[s];
        sc->arcs = malloc(sizeof(struct _arc) * sc->n_max);
        memcpy(sc->arcs, so->arcs, sizeof(struct _arc) * sc->n_arcs);
    }
}

canonical_original_code:
void fst_copy(struct _fst *orig, struct _fst *copy) {
    struct _state *so; struct _state *sc;
    memcpy(copy, orig, sizeof(struct _fst));
    copy->states = malloc(sizeof(struct _state) * orig->n_max);
    memcpy(copy->states, orig->states, sizeof(struct _state) * orig->n_states);
    for(unsigned int s = 0; s < copy->n_states; ++s) {
        sc = &copy->states[s];
        so = &orig->states[s];
        sc->arcs = malloc(sizeof(struct _arc) * sc->n_max);
        memcpy(sc->arcs, so->arcs, sizeof(struct _arc) * sc->n_arcs);
    }
}

variable_types:
copy
struct _fst *


original_code:
void fst_relabel(struct _fst * fst, uint32_t old, uint32_t new, int dir) {
    struct _state * state;
    struct _arc * arc;
    for (uint32_t s = 0; s < fst->n_states; ++s) {
        state = &fst->states[s];
        for (uint32_t a = 0; a < state->n_arcs; ++a) {
            arc = &state->arcs[a];
            if (dir == 0) {
                if (arc->ilabel == old) arc->ilabel = new;
            } else {
                if (arc->olabel == old) arc->olabel = new;
            }
        }
    }
}

canonical_original_code:
void fst_relabel(struct _fst *fst, unsigned int old, unsigned int new, int dir) {
    struct _state *state;
    struct _arc *arc;
    for (unsigned int s = 0; s < fst->n_states; ++s) {
        state = &fst->states[s];
        for (unsigned int a = 0; a < state->n_arcs; ++a) {
            arc = &state->arcs[a];
            if (dir == 0) {
                if (arc->ilabel == old) arc->ilabel = new;
            } else {
                if (arc->olabel == old) arc->olabel = new;
            }
        }
    }
}

variable_types:
old
unsigned int

variable_types:
new
unsigned int

variable_types: dir int

variable_types: struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *

variable_types:
a
unsigned int


original_code:
void fst_print(const struct _fst * fst) {
    struct _state state;
    struct _arc arc;
    uint32_t s;
    uint32_t a;
    struct _queue *finals = queue_create(sizeof(uint32_t));
    for(s=0; s < fst->n_states; ++s) {
        state = fst->states[s];
        for(a=0; a < state.n_arcs; ++a) {
            arc = state.arcs[a];
            printf("%""u""\t%""u""\t%""u""\t%""u""\t%.5f\n",
                s,
                arc.state,
                arc.ilabel,
                arc.olabel,
                arc.weight);
        }
        if(state.final == 1) {
            queue_enque(finals, &s);
        }
    }
    while(queue_deque(finals, &s) != ((void *)0)) {
        state = fst->states[s];
        printf("%""u""\t%f\n", s, state.weight);
    }
    queue_remove(finals);
}

canonical_original_code:
void fst_print(struct _fst *fst) {
    struct _state state;
    struct _arc arc;
    unsigned int s;
    unsigned int a;
    struct _queue *finals = queue_create(sizeof(uint32_t));
    for(s=0; s < fst->n_states; ++s) {
        state = fst->states[s];
        for(a=0; a < state.n_arcs; ++a) {
            arc = state.arcs[a];
            printf("%""u""\t%""u""\t%""u""\t%""u""\t%.5f\n",
                s,
                arc.state,
                arc.ilabel,
                arc.olabel,
                arc.weight);
        }
        if(state.final == 1) {
            queue_enque(finals, &s);
        }
    }
    while(queue_deque(finals, &s) != ((void *)0)) {
        state = fst->states[s];
        printf("%""u""\t%f\n", s, state.weight);
    }
    queue_remove(finals);
}

variable_types: struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; }

variable_types: struct _queue { struct _qnode { struct _qnode *next; char item[1]; } *head; struct _qnode *tail; unsigned long item_size; unsigned long n_items; } *


original_code:
void fst_print_sym(
                    const struct _fst * fst,
                    struct _symt * ist,
                    struct _symt * ost,
                    struct _symt * sst)
{
    struct _state state;
    struct _arc arc;
    token_t sa, sb, li, lo;
    rtrans_f strans, itrans, otrans;
    uint32_t s;
    uint32_t a;
    itrans = (ist == ((void *)0) ? trn:trt);
    otrans = (ost == ((void *)0) ? trn:trt);
    strans = (sst == ((void *)0) ? trn:trt);
    struct _queue *finals = queue_create(sizeof(uint32_t));
    for(s=0; s < fst->n_states; ++s) {
        state = fst->states[s];
        for(a=0; a < state.n_arcs; ++a) {
            arc = state.arcs[a];
            strans(sst, s, sa);
            strans(sst, arc.state, sb);
            itrans(ist, arc.ilabel, li);
            otrans(ost, arc.olabel, lo);
            if (sa == ((void *)0) || sb == ((void *)0) || li == ((void *)0) || lo == ((void *)0)) {
                fprintf(stderr, "Invalid symbol\n");
                exit(1);
            }
            printf("%s\t%s\t%s\t%s\t%.5f\n",
                sa,
                sb,
                li,
                lo,
                arc.weight);
        }
        if(state.final == 1) {
            queue_enque(finals, &s);
        }
    }
    while(queue_deque(finals, &s) != ((void *)0)) {
        state = fst->states[s];
        strans(sst, s, sa);
        if (sa == ((void *)0)) {
            fprintf(stderr, "Invalid symbol\n");
            exit(1);
        }
        printf("%s\t%f\n", sa, state.weight);
    }
    queue_remove(finals);
}

canonical_original_code:
void fst_print_sym(struct _fst *fst, struct _symt *ist, struct _symt *ost, struct _symt *sst)
{
    struct _state state;
    struct _arc arc;
    char sa[1024]; char sb[1024]; char li[1024]; char lo[1024];
    char *(*strans)(struct _symt *st, unsigned long id, char *token); char *(*itrans)(struct _symt *st, unsigned long id, char *token); char *(*otrans)(struct _symt *st, unsigned long id, char *token);
    unsigned int s;
    unsigned int a;
    itrans = (ist == ((void *)0) ? trn:trt);
    otrans = (ost == ((void *)0) ? trn:trt);
    strans = (sst == ((void *)0) ? trn:trt);
    struct _queue *finals = queue_create(sizeof(uint32_t));
    for(s=0; s < fst->n_states; ++s) {
        state = fst->states[s];
        for(a=0; a < state.n_arcs; ++a) {
            arc = state.arcs[a];
            strans(sst, s, sa);
            strans(sst, arc.state, sb);
            itrans(ist, arc.ilabel, li);
            otrans(ost, arc.olabel, lo);
            if (sa == ((void *)0) || sb == ((void *)0) || li == ((void *)0) || lo == ((void *)0)) {
                fprintf(stderr, "Invalid symbol\n");
                exit(1);
            }
            printf("%s\t%s\t%s\t%s\t%.5f\n",
                sa,
                sb,
                li,
                lo,
                arc.weight);
        }
        if(state.final == 1) {
            queue_enque(finals, &s);
        }
    }
    while(queue_deque(finals, &s) != ((void *)0)) {
        state = fst->states[s];
        strans(sst, s, sa);
        if (sa == ((void *)0)) {
            fprintf(stderr, "Invalid symbol\n");
            exit(1);
        }
        printf("%s\t%f\n", sa, state.weight);
    }
    queue_remove(finals);
}

variable_types: struct _fst { unsigned int start; unsigned int n_states; unsigned int n_max; unsigned char sr_type; unsigned char flags; struct _state { unsigned int n_arcs; unsigned int n_max; float weight; int final; struct _arc { unsigned int state; float weight; unsigned int ilabel; unsigned int olabel; } *arcs; } *states; } *

variable_types:
ost
struct _symt *

variable_types:
sst
struct _symt *

variable_types:
sa
char [1024]

variable_types:
sb
char [1024]

variable_types:
li
char [1024]

variable_types:
lo
char [1024]

variable_types: char *(*)(struct _symt { unsigned long n_items; unsigned long n_max; char **sym; struct _hash { struct _bucket { struct _bitem { void *key; void *value; struct _bitem *next; } *head; struct _bitem *tail; } *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); } *rev; } *st, unsigned long id, char *token)


trt

decompiled_code:
char *__fastcall trt(__int64 a1, __int64 a2, char *a3)
{
const char *v4; // rax
char *result; // rax

v4 = (const char *)symt_get();
if ( v4 )
{
strcpy(a3, v4);
result = a3;
}
else
{
fprintf(stderr, "Unknown token: %s\n", 0LL);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
char *__fastcall func0(__int64 a1, __int64 a2, char *a3)
{
const char *v4; // rax
char *result; // rax

v4 = (const char *)symt_get();
if ( v4 )
{
strcpy(a3, v4);
result = a3;
}
else
{
fprintf(stderr, "Unknown token: %s\n", 0LL);
result = 0LL;
}
return result;
}

original_code:
static char * trt(struct _symt * st, size_t id, char * token) {
    char * t = symt_get(st, id);
    if (t == ((void *)0)) {
        token = ((void *)0);
        fprintf(stderr, "Unknown token: %s\n", token);
    } else {
        strcpy(token, t);
    }
    return token;
}

canonical_original_code:
static char *trt(struct _symt *st, unsigned long id, char *token) {
    char *t = symt_get(st, id);
    if (t == ((void *)0)) {
        token = ((void *)0);
        fprintf(stderr, "Unknown token: %s\n", token);
    } else {
        strcpy(token, t);
    }
    return token;
}

variable_types: struct _symt { unsigned long n_items; unsigned long n_max; char **sym; struct _hash { struct _bucket { struct _bitem { void *key; void *value; struct _bitem *next; } *head; struct _bitem *tail; } *buckets; unsigned long item_size; unsigned long key_size; unsigned long size; unsigned long n_items; unsigned long (*hash_f)(void *key); int (*cmp_f)(void *key_a, void *key_b); } *rev; } *

variable_types:
id
unsigned long

variable_types:
token
char *

variable_types:
t
char *


trn

decompiled_code:
char *__fastcall trn(__int64 a1, __int64 a2, char *a3)
{
sprintf(a3, "%zu", a2);
return a3;
}

canonical_decompiled_code:
char *__fastcall func1(__int64 a1, __int64 a2, char *a3)
{
sprintf(a3, "%zu", a2);
return a3;
}

original_code:
static char * trn(struct _symt * st, size_t id, char * token) {
    sprintf(token, "%zu", id);
    return token;
}

canonical_original_code:
static char *trn(struct _symt *st, unsigned long id, char *token) {
    sprintf(token, "%zu", id);
    return token;
}


bindex

decompiled_code:
__int64 __fastcall bindex(int a1)
{
return (unsigned int)(a1 / 32);
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
return (unsigned int)(a1 / 32);
}

original_code: static inline int bindex(int b) { return b / WORD_SIZE; }

variable_types: b int


boffset

decompiled_code:
__int64 __fastcall boffset(int a1)
{
return (unsigned int)(a1 % 32);
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
return (unsigned int)(a1 % 32);
}

original_code: static inline int boffset(int b) { return b % WORD_SIZE; }


decompiled_code:
void __fastcall bitset_remove(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

original_code:
void bitset_remove(struct _bitset * bitset) {
    free(bitset->words);
    free(bitset);
}

canonical_original_code:
void bitset_remove(struct _bitset *bitset) {
    free(bitset->words);
    free(bitset);
}

variable_types: struct _bitset { unsigned int *words; int n_words; } *


decompiled_code:
__int64 __fastcall bitset_set(__int64 a1, int a2)
{
_QWORD *v2; // r8
int v3; // edx
char v4; // cl
__int64 result; // rax

boffset(a2);
result = (int)bindex(a2);
*(_DWORD *)(*v2 + 4LL * (int)result) |= v3 << v4;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, int a2)
{
_QWORD *v2; // r8
int v3; // edx
char v4; // cl
__int64 result; // rax

func1(a2);
result = (int)func0(a2);
*(_DWORD *)(*v2 + 4LL * (int)result) |= v3 << v4;
return result;
}

original_code:
void bitset_set(struct _bitset * bitset, int b) {
    bitset->words[bindex(b)] |= 1 << (boffset(b));
}

canonical_original_code:
void bitset_set(struct _bitset *bitset, int b) {
    bitset->words[bindex(b)] |= 1 << (boffset(b));
}

user_defined_types: struct _bitset { unsigned int *words; int n_words; }


decompiled_code:
__int64 __fastcall bitset_clear(__int64 a1, int a2)
{
_QWORD *v2; // r8
int v3; // edx
char v4; // cl
__int64 result; // rax

boffset(a2);
result = (int)bindex(a2);
*(_DWORD *)(*v2 + 4LL * (int)result) &= __ROL4__(v3, v4);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
_QWORD *v2; // r8
int v3; // edx
char v4; // cl
__int64 result; // rax

func1(a2);
result = (int)func0(a2);
*(_DWORD *)(*v2 + 4LL * (int)result) &= __ROL4__(v3, v4);
return result;
}

original_code:
void bitset_clear(struct _bitset * bitset, int b) {
    bitset->words[bindex(b)] &= ~(1 << (boffset(b)));
}

canonical_original_code:
void bitset_clear(struct _bitset *bitset, int b) {
    bitset->words[bindex(b)] &= ~(1 << (boffset(b)));
}


decompiled_code:
_BOOL8 __fastcall bitset_get(__int64 a1, int a2)
{
__int64 v3; // rsi
char v4; // al
_QWORD *v5; // r8

v3 = (int)bindex(a2);
v4 = boffset(a2);
return (*(_DWORD *)(*v5 + 4 * v3) & (1 << v4)) != 0;
}

original_code:
int bitset_get(struct _bitset * bitset, int b) {
    return bitset->words[bindex(b)] & (1 << (boffset(b))) ? 1 : 0;
}

canonical_original_code:
int bitset_get(struct _bitset *bitset, int b) {
    return bitset->words[bindex(b)] & (1 << (boffset(b))) ? 1 : 0;
}


decompiled_code:
__int64 __fastcall bitset_clear_all(__int64 *a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *((unsigned int *)a1 + 2);
if ( (int)result > 0 )
{
v2 = *a1;
result = 0LL;
do
*(_DWORD *)(v2 + 4 * result++) = 0;
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

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

result = *((unsigned int *)a1 + 2);
if ( (int)result > 0 )
{
v2 = *a1;
result = 0LL;
do
*(_DWORD *)(v2 + 4 * result++) = 0;
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

original_code:
void bitset_clear_all(struct _bitset * bitset) {
    for(int i = 0; i < bitset->n_words; ++i)
        bitset->words[i] = 0;
}

canonical_original_code:
void bitset_clear_all(struct _bitset *bitset) {
    for(int i = 0; i < bitset->n_words; ++i)
        bitset->words[i] = 0;
}

variable_types: i int


decompiled_code:
__int64 __fastcall bitset_set_all(__int64 *a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *((unsigned int *)a1 + 2);
if ( (int)result > 0 )
{
v2 = *a1;
result = 0LL;
do
*(_DWORD *)(v2 + 4 * result++) = -1;
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 *a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *((unsigned int *)a1 + 2);
if ( (int)result > 0 )
{
v2 = *a1;
result = 0LL;
do
*(_DWORD *)(v2 + 4 * result++) = -1;
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

original_code:
void bitset_set_all(struct _bitset * bitset) {
    for(int i = 0; i < bitset->n_words; ++i)
        bitset->words[i] = ~0;
}

canonical_original_code:
void bitset_set_all(struct _bitset *bitset) {
    for(int i = 0; i < bitset->n_words; ++i)
        bitset->words[i] = ~0;
}


decompiled_code:
__int64 __fastcall bitset_union(__int64 *a1, __int64 *a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rsi

result = *((unsigned int *)a1 + 2);
if ( (_DWORD)result != *((_DWORD *)a2 + 2) )
_assert_fail("a->n_words == b->n_words", "src/bitset.c", 0x35u, "bitset_union");
if ( (int)result > 0 )
{
v3 = *a1;
v4 = *a2;
result = 0LL;
do
{
*(_DWORD *)(v3 + 4 * result) |= *(_DWORD *)(v4 + 4 * result);
++result;
}
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 *a1, __int64 *a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rsi

result = *((unsigned int *)a1 + 2);
if ( (_DWORD)result != *((_DWORD *)a2 + 2) )
_assert_fail("a->n_words == b->n_words", "src/bitset.c", 0x35u, "bitset_union");
if ( (int)result > 0 )
{
v3 = *a1;
v4 = *a2;
result = 0LL;
do
{
*(_DWORD *)(v3 + 4 * result) |= *(_DWORD *)(v4 + 4 * result);
++result;
}
while ( *((_DWORD *)a1 + 2) > (int)result );
}
return result;
}

original_code:
void bitset_union(struct _bitset * a, const struct _bitset * b) {
    ((a->n_words == b->n_words) ? (void) (0) : __assert_fail ("a->n_words == b->n_words", "src/bitset.c", 53, __extension__ __PRETTY_FUNCTION__));
    for(int i = 0; i < a->n_words; ++i)
        a->words[i] |= b->words[i];
}

canonical_original_code:
void bitset_union(struct _bitset *a, struct _bitset *b) {
    ((a->n_words == b->n_words) ? (void) (0) : __assert_fail ("a->n_words == b->n_words", "src/bitset.c", 53, __extension__ __PRETTY_FUNCTION__));
    for(int i = 0; i < a->n_words; ++i)
        a->words[i] |= b->words[i];
}

variable_types:
b
struct _bitset *