hashHC

repo: acharal/mhtransf-lar

decompiled_code:
__int64 __fastcall hashHC(unsigned __int8 a1, int a2)
{
return (HCTABLESIZE - 1) & ((a2 ^ (a1 << 13)) + 177573);
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned __int8 a1, int a2)
{
return (HCTABLESIZE - 1) & ((a2 ^ (a1 << 13)) + 177573);
}

original_code:
static tagHC hashHC (tag h, list l)
{
  register tagHC hash = 5381;
  hash = ((hash << 5) + hash) + (((tagHC) l)^((tagHC) h<<13));
  return hash & ((tagHC) (HCTABLESIZE - 1));
}

canonical_original_code:
static unsigned int hashHC(unsigned char h, unsigned int l)
{
  register unsigned int hash = 5381;
  hash = ((hash << 5) + hash) + (((unsigned int) l)^((unsigned int) h<<13));
  return hash & ((tagHC) (HCTABLESIZE - 1));
}

variable_types:
h
unsigned char

variable_types:
l
unsigned int

variable_types:
hash
unsigned int

return_type: unsigned int


hashCons

decompiled_code:
__int64 __fastcall hashCons(unsigned __int8 a1, int a2)
{
unsigned __int8 v2; // r12
__int64 v5; // rsi
_DWORD *v6; // rdi
__int64 result; // rax
char *v8; // rdx
__int64 v9; // rdx
unsigned __int8 *v10; // rcx

v2 = a1;
v5 = (unsigned int)hashHC(a1, a2);
v6 = (char *)tableHC + 4 * v5;
result = (unsigned int)*v6;
if ( (_DWORD)result == -1 )
{
LABEL_7:
result = (unsigned int)freeHC;
v9 = 12LL * (unsigned int)freeHC;
v10 = (unsigned __int8 *)heapHC + v9;
freeHC = *(_DWORD *)((char *)heapHC + v9 + 8);
++entriesHC;
*((_DWORD *)v10 + 2) = *v6;
*v10 = v2;
*(_DWORD *)((char *)heapHC + v9 + 4) = a2;
*((_DWORD *)tableHC + v5) = result;
}
else
{
while ( 1 )
{
v8 = (char *)heapHC + 12 * (unsigned int)result;
if ( *v8 == a1 && *((_DWORD *)v8 + 1) == a2 )
break;
result = *((unsigned int *)v8 + 2);
if ( (_DWORD)result == -1 )
goto LABEL_7;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 a1, int a2)
{
unsigned __int8 v2; // r12
__int64 v5; // rsi
_DWORD *v6; // rdi
__int64 result; // rax
char *v8; // rdx
__int64 v9; // rdx
unsigned __int8 *v10; // rcx

v2 = a1;
v5 = (unsigned int)func0(a1, a2);
v6 = (char *)tableHC + 4 * v5;
result = (unsigned int)*v6;
if ( (_DWORD)result == -1 )
{
LABEL_7:
result = (unsigned int)freeHC;
v9 = 12LL * (unsigned int)freeHC;
v10 = (unsigned __int8 *)heapHC + v9;
freeHC = *(_DWORD *)((char *)heapHC + v9 + 8);
++entriesHC;
*((_DWORD *)v10 + 2) = *v6;
*v10 = v2;
*(_DWORD *)((char *)heapHC + v9 + 4) = a2;
*((_DWORD *)tableHC + v5) = result;
}
else
{
while ( 1 )
{
v8 = (char *)heapHC + 12 * (unsigned int)result;
if ( *v8 == a1 && *((_DWORD *)v8 + 1) == a2 )
break;
result = *((unsigned int *)v8 + 2);
if ( (_DWORD)result == -1 )
goto LABEL_7;
}
}
return result;
}

original_code:
static list hashCons (tag h, list l)
{
  tagHC hashval = hashHC(h, l);
  tagHC ptr;
  for (ptr = tableHC[hashval].ptr; ptr != ((tagHC) (-1)); ptr = heapHC[ptr].ptr)
    if (heapHC[ptr].head == h && heapHC[ptr].tail == l) {
      return ptr;
    }
    else {
      ;
    }
  ptr = freeHC;
  freeHC = heapHC[freeHC].ptr;
  entriesHC++;
  heapHC[ptr].ptr = tableHC[hashval].ptr;
  heapHC[ptr].head = h;
  heapHC[ptr].tail = l;
  tableHC[hashval].ptr = ptr;
  return ptr;
}

canonical_original_code:
static unsigned int hashCons(unsigned char h, unsigned int l)
{
  unsigned int hashval = hashHC(h, l);
  unsigned int ptr;
  for (ptr = tableHC[hashval].ptr; ptr != ((tagHC) (-1)); ptr = heapHC[ptr].ptr)
    if (heapHC[ptr].head == h && heapHC[ptr].tail == l) {
      return ptr;
    }
    else {
      ;
    }
  ptr = freeHC;
  freeHC = heapHC[freeHC].ptr;
  entriesHC++;
  heapHC[ptr].ptr = tableHC[hashval].ptr;
  heapHC[ptr].head = h;
  heapHC[ptr].tail = l;
  tableHC[hashval].ptr = ptr;
  return ptr;
}

variable_types:
hashval
unsigned int

variable_types:
ptr
unsigned int


initializeHC

decompiled_code:
int initializeHC()
{
unsigned int v0; // ebp
__int64 v1; // rbx
__int64 v2; // rax
int v3; // ebp
__int64 v4; // r12
_DWORD *v5; // rax
_DWORD *v6; // rsi
unsigned int v7; // ecx
_DWORD *v8; // rdx
int v9; // eax

if ( tableHC )
free(tableHC);
v0 = HCTABLESIZE;
v1 = HCTABLESIZE;
tableHC = malloc(4LL * HCTABLESIZE);
if ( !tableHC )
{
fwrite("Out of memory: allocating the table for hash consing\n", 1uLL, 0x35uLL, stderr);
exit(1);
}
v2 = 0LL;
if ( v0 )
{
do
{
*(_DWORD *)((char *)tableHC + v2) = -1;
v2 += 4LL;
}
while ( v2 != 4LL * v0 );
}
if ( heapHC )
free(heapHC);
v3 = HCHEAPSIZE;
v4 = HCHEAPSIZE;
v5 = malloc(12LL * HCHEAPSIZE);
v6 = v5;
heapHC = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the heap for hash consing\n", 1uLL, 0x34uLL, stderr);
exit(1);
}
*(_BYTE *)v5 = 0;
v5[1] = -1;
v5[2] = -1;
v7 = v3 - 1;
if ( (unsigned int)(v3 - 1) > 1 )
{
v8 = v5 + 5;
v9 = 1;
do
{
*v8 = ++v9;
v8 += 3;
}
while ( v9 != v7 );
}
v6[3 * v7 + 2] = -1;
entriesHC = 1;
HCGCLIMIT = (int)((double)v3 * 0.98 - (double)MAXDIM);
freeHC = 1;
return printf("HC memory: %u bytes\n", 4 * (v1 + 3 * v4));
}

canonical_decompiled_code:
int func2()
{
unsigned int v0; // ebp
__int64 v1; // rbx
__int64 v2; // rax
int v3; // ebp
__int64 v4; // r12
_DWORD *v5; // rax
_DWORD *v6; // rsi
unsigned int v7; // ecx
_DWORD *v8; // rdx
int v9; // eax

if ( tableHC )
free(tableHC);
v0 = HCTABLESIZE;
v1 = HCTABLESIZE;
tableHC = malloc(4LL * HCTABLESIZE);
if ( !tableHC )
{
fwrite("Out of memory: allocating the table for hash consing\n", 1uLL, 0x35uLL, stderr);
exit(1);
}
v2 = 0LL;
if ( v0 )
{
do
{
*(_DWORD *)((char *)tableHC + v2) = -1;
v2 += 4LL;
}
while ( v2 != 4LL * v0 );
}
if ( heapHC )
free(heapHC);
v3 = HCHEAPSIZE;
v4 = HCHEAPSIZE;
v5 = malloc(12LL * HCHEAPSIZE);
v6 = v5;
heapHC = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the heap for hash consing\n", 1uLL, 0x34uLL, stderr);
exit(1);
}
*(_BYTE *)v5 = 0;
v5[1] = -1;
v5[2] = -1;
v7 = v3 - 1;
if ( (unsigned int)(v3 - 1) > 1 )
{
v8 = v5 + 5;
v9 = 1;
do
{
*v8 = ++v9;
v8 += 3;
}
while ( v9 != v7 );
}
v6[3 * v7 + 2] = -1;
entriesHC = 1;
HCGCLIMIT = (int)((double)v3 * 0.98 - (double)MAXDIM);
freeHC = 1;
return printf("HC memory: %u bytes\n", 4 * (v1 + 3 * v4));
}

original_code:
void initializeHC ()
{
  if (tableHC != ((void *)0))
    free(tableHC);
  tableHC = (struct bucketHC *) malloc(HCTABLESIZE * sizeof(struct bucketHC));
  if (tableHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the table for hash consing\n");
    exit(1);
  }
  for (tagHC i = 0; i < HCTABLESIZE; i++)
    tableHC[i].ptr = ((tagHC) (-1));
  if (heapHC != ((void *)0))
    free(heapHC);
  heapHC = (struct nodeHC *) malloc(HCHEAPSIZE * sizeof(struct nodeHC));
  if (heapHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the heap for hash consing\n");
    exit(1);
  }
  heapHC[0].head = 0;
  heapHC[0].tail = ((tagHC) (-1));
  heapHC[0].ptr = ((tagHC) (-1));
  for (tagHC i = 1; i < HCHEAPSIZE-1; i++)
    heapHC[i].ptr = i+1;
  heapHC[HCHEAPSIZE-1].ptr = ((tagHC) (-1));
  entriesHC = 1;
  HCGCLIMIT = HCHEAPSIZE * 0.98 - MAXDIM;
  freeHC = 1;
  printf("HC memory: %u bytes\n", HCTABLESIZE * sizeof(struct bucketHC)
  + HCHEAPSIZE * sizeof(struct nodeHC));
}

canonical_original_code:
void initializeHC()
{
  if (tableHC != ((void *)0))
    free(tableHC);
  tableHC = (struct bucketHC *) malloc(HCTABLESIZE * sizeof(struct bucketHC));
  if (tableHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the table for hash consing\n");
    exit(1);
  }
  for (unsigned int i = 0; i < HCTABLESIZE; i++)
    tableHC[i].ptr = ((tagHC) (-1));
  if (heapHC != ((void *)0))
    free(heapHC);
  heapHC = (struct nodeHC *) malloc(HCHEAPSIZE * sizeof(struct nodeHC));
  if (heapHC == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the heap for hash consing\n");
    exit(1);
  }
  heapHC[0].head = 0;
  heapHC[0].tail = ((tagHC) (-1));
  heapHC[0].ptr = ((tagHC) (-1));
  for (unsigned int i = 1; i < HCHEAPSIZE-1; i++)
    heapHC[i].ptr = i+1;
  heapHC[HCHEAPSIZE-1].ptr = ((tagHC) (-1));
  entriesHC = 1;
  HCGCLIMIT = HCHEAPSIZE * 0.98 - MAXDIM;
  freeHC = 1;
  printf("HC memory: %u bytes\n", HCTABLESIZE * sizeof(struct bucketHC)
  + HCHEAPSIZE * sizeof(struct nodeHC));
}

variable_types:
i
unsigned int

return_type: void

user_defined_types: struct nodeHC { unsigned char head; unsigned int tail; unsigned int ptr; }


gcollectHC

decompiled_code:
__int64 __fastcall gcollectHC(_QWORD *a1)
{
_QWORD *v1; // r8
char v2; // r9
__int64 v3; // r10
unsigned int *v4; // rsi
unsigned int i; // eax
__int64 v6; // rax
char v7; // dl
_DWORD *v8; // rax
_DWORD *v9; // rsi
unsigned int v10; // edx
__int64 v11; // r9
__int64 v12; // r8
__int64 result; // rax
__int64 v14; // rdi
__int64 v15; // r8
unsigned int *v16; // rcx
__int64 v17; // r9
unsigned int *v18; // rdi
unsigned int v19; // edx
char *v20; // rsi

if ( a1 )
{
v1 = a1;
v2 = MAXDIM;
v3 = 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
{
v4 = (unsigned int *)(v1 + 1);
if ( v2 )
{
do
{
for ( i = *v4; i; i = *(_DWORD *)((char *)heapHC + v6 + 4) )
{
v6 = 12LL * i;
v7 = *((_BYTE *)heapHC + v6);
if ( v7 < 0 )
break;
*((_BYTE *)heapHC + v6) = v7 | 0x80;
}
++v4;
}
while ( v4 != (unsigned int *)((char *)v1 + v3) );
}
v1 = (_QWORD *)*v1;
}
while ( v1 );
}
if ( WHTABLESIZE )
{
v8 = (_DWORD *)tableWH;
while ( 1 )
{
v9 = v8;
v10 = *v8;
if ( *v8 != -1 )
break;
if ( ++v8 == (_DWORD *)(tableWH + 4LL * (unsigned int)(WHTABLESIZE - 1) + 4) )
goto LABEL_15;
}
result = v10;
v14 = 4 * v10 * (MAXDIM + 5LL);
v15 = rawHeapWH + v14;
if ( *(_DWORD *)(rawHeapWH + v14 + 4) != 0x80000000 )
{
result = *(unsigned __int8 *)(v15 + 16);
if ( (_BYTE)result )
{
v16 = (unsigned int *)(v15 + 20);
v17 = v15 + 4LL * (unsigned __int8)(result - 1) + 24;
while ( 1 )
{
result = *v16;
if ( (_DWORD)result )
{
result = 3LL * (unsigned int)result;
if ( *((char *)heapHC + 4 * result) >= 0 )
break;
}
if ( ++v16 == (unsigned int *)v17 )
return result;
}
*v9 = *(_DWORD *)(v15 + 12);
result = rawHeapWH;
*(_DWORD *)(rawHeapWH + v14 + 12) = freeWH;
freeWH = v10;
--entriesWH;
}
}
}
else
{
LABEL_15:
if ( HCTABLESIZE )
{
v11 = 4LL * HCTABLESIZE;
v12 = 0LL;
do
{
v18 = (unsigned int *)((char *)tableHC + v12);
v19 = *(_DWORD *)((char *)tableHC + v12);
if ( v19 != -1 )
{
do
{
v20 = (char *)heapHC + 12 * v19;
if ( *v20 < 0 )
{
*v20 &= 0x7Fu;
v18 = (unsigned int *)((char *)heapHC + 12 * *v18 + 8);
}
else
{
*v18 = *((_DWORD *)v20 + 2);
*((_DWORD *)heapHC + 3 * v19 + 2) = freeHC;
freeHC = v19;
--entriesHC;
}
v19 = *v18;
}
while ( *v18 != -1 );
}
v12 += 4LL;
}
while ( v11 != v12 );
}
result = HCHEAPSIZE - (unsigned int)MAXDIM;
if ( (unsigned int)result <= entriesHC )
{
fwrite("FATAL ERROR: Out of heap space for hash consing\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1)
{
_QWORD *v1; // r8
char v2; // r9
__int64 v3; // r10
unsigned int *v4; // rsi
unsigned int i; // eax
__int64 v6; // rax
char v7; // dl
_DWORD *v8; // rax
_DWORD *v9; // rsi
unsigned int v10; // edx
__int64 v11; // r9
__int64 v12; // r8
__int64 result; // rax
__int64 v14; // rdi
__int64 v15; // r8
unsigned int *v16; // rcx
__int64 v17; // r9
unsigned int *v18; // rdi
unsigned int v19; // edx
char *v20; // rsi

if ( a1 )
{
v1 = a1;
v2 = MAXDIM;
v3 = 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
{
v4 = (unsigned int *)(v1 + 1);
if ( v2 )
{
do
{
for ( i = *v4; i; i = *(_DWORD *)((char *)heapHC + v6 + 4) )
{
v6 = 12LL * i;
v7 = *((_BYTE *)heapHC + v6);
if ( v7 < 0 )
break;
*((_BYTE *)heapHC + v6) = v7 | 0x80;
}
++v4;
}
while ( v4 != (unsigned int *)((char *)v1 + v3) );
}
v1 = (_QWORD *)*v1;
}
while ( v1 );
}
if ( WHTABLESIZE )
{
v8 = (_DWORD *)tableWH;
while ( 1 )
{
v9 = v8;
v10 = *v8;
if ( *v8 != -1 )
break;
if ( ++v8 == (_DWORD *)(tableWH + 4LL * (unsigned int)(WHTABLESIZE - 1) + 4) )
goto LABEL_15;
}
result = v10;
v14 = 4 * v10 * (MAXDIM + 5LL);
v15 = rawHeapWH + v14;
if ( *(_DWORD *)(rawHeapWH + v14 + 4) != 0x80000000 )
{
result = *(unsigned __int8 *)(v15 + 16);
if ( (_BYTE)result )
{
v16 = (unsigned int *)(v15 + 20);
v17 = v15 + 4LL * (unsigned __int8)(result - 1) + 24;
while ( 1 )
{
result = *v16;
if ( (_DWORD)result )
{
result = 3LL * (unsigned int)result;
if ( *((char *)heapHC + 4 * result) >= 0 )
break;
}
if ( ++v16 == (unsigned int *)v17 )
return result;
}
*v9 = *(_DWORD *)(v15 + 12);
result = rawHeapWH;
*(_DWORD *)(rawHeapWH + v14 + 12) = freeWH;
freeWH = v10;
--entriesWH;
}
}
}
else
{
LABEL_15:
if ( HCTABLESIZE )
{
v11 = 4LL * HCTABLESIZE;
v12 = 0LL;
do
{
v18 = (unsigned int *)((char *)tableHC + v12);
v19 = *(_DWORD *)((char *)tableHC + v12);
if ( v19 != -1 )
{
do
{
v20 = (char *)heapHC + 12 * v19;
if ( *v20 < 0 )
{
*v20 &= 0x7Fu;
v18 = (unsigned int *)((char *)heapHC + 12 * *v18 + 8);
}
else
{
*v18 = *((_DWORD *)v20 + 2);
*((_DWORD *)heapHC + 3 * v19 + 2) = freeHC;
freeHC = v19;
--entriesHC;
}
v19 = *v18;
}
while ( *v18 != -1 );
}
v12 += 4LL;
}
while ( v11 != v12 );
}
result = HCHEAPSIZE - (unsigned int)MAXDIM;
if ( (unsigned int)result <= entriesHC )
{
fwrite("FATAL ERROR: Out of heap space for hash consing\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
}
return result;
}

original_code:
void gcollectHC (World *w)
{
  for (; w != ((void *)0); w = w->prev)
    for (dimension d = 0; d < MAXDIM; d++)
      for (list l = w->l[d];
    l != 0 && !(heapHC[l].head & ((tag) 1 << (8 * sizeof(tag) - 1)));
    l = heapHC[l].tail) {
 heapHC[l].head |= ((tag) 1 << (8 * sizeof(tag) - 1));
      }
  for (tagWH i = 0; i < WHTABLESIZE; i++)
    for (tagWH * ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1));) {
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((value) 1 << (8 * sizeof(value) - 1)))
        for (dimension d = 0; d < ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim; d++) {
          list l = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d];
          if (l != 0 && !(heapHC[l].head & ((tag) 1 << (8 * sizeof(tag) - 1)))) {
            tagWH prev = *ptr;
            *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
            ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
            freeWH = prev;
            entriesWH--;
            goto skipForwardingPtr;
          }
        }
      ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
skipForwardingPtr:
 return;
    }
  for (tagHC i = 0; i < HCTABLESIZE; i++)
    for (tagHC * ptr = &(tableHC[i].ptr); *ptr != ((tagHC) (-1)); )
      if (heapHC[*ptr].head & ((tag) 1 << (8 * sizeof(tag) - 1))) {
 heapHC[*ptr].head &= ~((tag) 1 << (8 * sizeof(tag) - 1));
 ptr = &(heapHC[*ptr].ptr);
      }
      else {
 tagHC prev = *ptr;
 *ptr = heapHC[*ptr].ptr;
 heapHC[prev].ptr = freeHC;
 freeHC = prev;
 entriesHC--;
      }
    if (entriesHC >= HCHEAPSIZE - MAXDIM) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for hash consing\n");
      exit(1);
    }
}

canonical_original_code:
void gcollectHC(struct world_tag *w)
{
  for (; w != ((void *)0); w = w->prev)
    for (unsigned char d = 0; d < MAXDIM; d++)
      for (unsigned int l = w->l[d];
    l != 0 && !(heapHC[l].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1)));
    l = heapHC[l].tail) {
 heapHC[l].head |= ((unsigned char) 1 << (8 * sizeof(tag) - 1));
      }
  for (unsigned int i = 0; i < WHTABLESIZE; i++)
    for (unsigned int *ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1));) {
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((int) 1 << (8 * sizeof(value) - 1)))
        for (unsigned char d = 0; d < ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim; d++) {
          unsigned int l = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d];
          if (l != 0 && !(heapHC[l].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1)))) {
            unsigned int prev = *ptr;
            *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
            ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
            freeWH = prev;
            entriesWH--;
            goto skipForwardingPtr;
          }
        }
      ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
skipForwardingPtr:
 return;
    }
  for (unsigned int i = 0; i < HCTABLESIZE; i++)
    for (unsigned int *ptr = &(tableHC[i].ptr); *ptr != ((tagHC) (-1)); )
      if (heapHC[*ptr].head & ((unsigned char) 1 << (8 * sizeof(tag) - 1))) {
 heapHC[*ptr].head &= ~((unsigned char) 1 << (8 * sizeof(tag) - 1));
 ptr = &(heapHC[*ptr].ptr);
      }
      else {
 unsigned int prev = *ptr;
 *ptr = heapHC[*ptr].ptr;
 heapHC[prev].ptr = freeHC;
 freeHC = prev;
 entriesHC--;
      }
    if (entriesHC >= HCHEAPSIZE - MAXDIM) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for hash consing\n");
      exit(1);
    }
}

variable_types: struct world_tag { struct world_tag *prev; unsigned int l[]; } *

variable_types:
d
unsigned char

variable_types:
ptr
unsigned int *

variable_types:
prev
unsigned int

user_defined_types: struct nodeWH { unsigned int id; int val; unsigned int age; unsigned int ptr; unsigned char depDim; unsigned int l[]; }


call

decompiled_code:
__int64 __fastcall call(unsigned __int8 a1, int a2)
{
return hashCons(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int8 a1, int a2)
{
return func1(a1, a2);
}

original_code:
list call (tag i, list l)
{
  return hashCons(i, l);
}

canonical_original_code:
unsigned int call(unsigned char i, unsigned int l)
{
  return hashCons(i, l);
}

variable_types:
i
unsigned char


actuals

decompiled_code:
__int64 __fastcall actuals(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 *v2; // rax

v2 = (unsigned __int8 *)heapHC + 12 * a2;
if ( *v2 != a1 )
{
fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n", *v2, a1);
exit(1);
}
return *((unsigned int *)v2 + 1);
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 *v2; // rax

v2 = (unsigned __int8 *)heapHC + 12 * a2;
if ( *v2 != a1 )
{
fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n", *v2, a1);
exit(1);
}
return *((unsigned int *)v2 + 1);
}

original_code:
list actuals (tag i, list l)
{
  if (heapHC[l].head == i)
    return heapHC[l].tail;
  fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n",
   heapHC[l].head, i);
  exit(1);
}

canonical_original_code:
unsigned int actuals(unsigned char i, unsigned int l)
{
  if (heapHC[l].head == i)
    return heapHC[l].tail;
  fprintf(stderr, "Internal error: wrong actuals (%u instead of %u)\n",
   heapHC[l].head, i);
  exit(1);
}


cases

decompiled_code:
__int64 __fastcall cases(unsigned int a1)
{
return *((unsigned __int8 *)heapHC + 12 * a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(unsigned int a1)
{
return *((unsigned __int8 *)heapHC + 12 * a1);
}

original_code:
tag cases (list l)
{
  return heapHC[l].head;
}

canonical_original_code:
unsigned char cases(unsigned int l)
{
  return heapHC[l].head;
}

return_type: unsigned char


statsHC

decompiled_code:
int statsHC()
{
return printf(
"\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
HCHEAPSIZE,
(double)(HCHEAPSIZE - entriesHC) / (double)HCHEAPSIZE * 100.0);
}

canonical_decompiled_code:
int func7()
{
return printf(
"\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
HCHEAPSIZE,
(double)(HCHEAPSIZE - entriesHC) / (double)HCHEAPSIZE * 100.0);
}

original_code:
void statsHC ()
{
  printf("\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
  HCHEAPSIZE, ((double) (HCHEAPSIZE - entriesHC) / HCHEAPSIZE) * 100);
}

canonical_original_code:
void statsHC()
{
  printf("\n\nHC heapsize:\t%u\nHC freerecs:\t%.2lf%%\n\n",
  HCHEAPSIZE, ((double) (HCHEAPSIZE - entriesHC) / HCHEAPSIZE) * 100);
}


printList

decompiled_code:
int __fastcall printList(unsigned int a1)
{
unsigned int v1; // ebx
__int64 v2; // rbx

v1 = a1;
putchar(91);
if ( a1 )
{
while ( 1 )
{
v2 = 12LL * v1;
printf("%d", *((unsigned __int8 *)heapHC + v2));
v1 = *(_DWORD *)((char *)heapHC + v2 + 4);
if ( !v1 )
break;
putchar(44);
}
}
return putchar(93);
}

canonical_decompiled_code:
int __fastcall func8(unsigned int a1)
{
unsigned int v1; // ebx
__int64 v2; // rbx

v1 = a1;
putchar(91);
if ( a1 )
{
while ( 1 )
{
v2 = 12LL * v1;
printf("%d", *((unsigned __int8 *)heapHC + v2));
v1 = *(_DWORD *)((char *)heapHC + v2 + 4);
if ( !v1 )
break;
putchar(44);
}
}
return putchar(93);
}

original_code:
void printList (list l)
{
   printf("[");
 while (l != 0) {
      printf("%d", heapHC[l].head);
      l = heapHC[l].tail;
      if (l != 0)
         printf(",");
   }
 printf("]");
}

canonical_original_code:
void printList(unsigned int l)
{
   printf("[");
 while (l != 0) {
      printf("%d", heapHC[l].head);
      l = heapHC[l].tail;
      if (l != 0)
         printf(",");
   }
 printf("]");
}


hashWH

decompiled_code:
__int64 __fastcall hashWH(int a1, char a2, __int64 a3)
{
unsigned __int8 *v4; // rdi
unsigned __int8 *v5; // rsi
__int64 v6; // r8
int v7; // eax
unsigned __int8 *v8; // rdx
void **v9; // rdx
int v11; // [rsp+0h] [rbp-4h] BYREF
void *retaddr; // [rsp+4h] [rbp+0h] BYREF

v11 = a1;
if ( a2 )
{
v4 = (unsigned __int8 *)(a3 + 8);
v5 = (unsigned __int8 *)(a3 + 12);
v6 = a3 + 4LL * (unsigned __int8)(a2 - 1) + 16;
v7 = -2128831035;
do
{
v8 = v4;
do
v7 = *v8++ ^ (16777619 * v7);
while ( v8 != v5 );
v4 += 4;
v5 += 4;
}
while ( v5 != (unsigned __int8 *)v6 );
}
else
{
v7 = -2128831035;
}
v9 = (void **)&v11;
do
{
v7 = *(unsigned __int8 *)v9 ^ (16777619 * v7);
v9 = (void **)((char *)v9 + 1);
}
while ( &retaddr != v9 );
return (WHTABLESIZE - 1) & (unsigned int)v7;
}

original_code:
static tagWH hashWH (identifier id, dimension depdim, World *w)
{
  register tagWH hash = 0x811c9dc5;
  for (register dimension d=0; d<depdim; d++)
    for (register int i=0; i<sizeof(list); ++i) {
       hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
       hash ^= *((unsigned char *) &(w->l[d]) + i);
    }
  for (register int i=0; i<sizeof(identifier); ++i) {
     hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
     hash ^= *((unsigned char *) &id + i);
  }
  return hash & ((tagWH) (WHTABLESIZE - 1));
}

canonical_original_code:
static unsigned int hashWH(unsigned int id, unsigned char depdim, struct world_tag *w)
{
  register unsigned int hash = 0x811c9dc5;
  for (register unsigned char d = 0; d<depdim; d++)
    for (register int i = 0; i<sizeof(list); ++i) {
       hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
       hash ^= *((unsigned char *) &(w->l[d]) + i);
    }
  for (register int i = 0; i<sizeof(identifier); ++i) {
     hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
     hash ^= *((unsigned char *) &id + i);
  }
  return hash & ((tagWH) (WHTABLESIZE - 1));
}

variable_types:
id
unsigned int

variable_types:
depdim
unsigned char

variable_types: i int

user_defined_types: struct world_tag { struct world_tag *prev; unsigned int l[]; }


match

decompiled_code:
__int64 __fastcall match(unsigned int a1, int a2, unsigned __int8 a3, __int64 a4)
{
unsigned __int8 v5; // r8
_DWORD *v7; // rdx
__int64 result; // rax
__int64 v9; // rax

v5 = a3;
v7 = (char *)rawHeapWH + 4 * a1 * (MAXDIM + 5LL);
result = 0LL;
if ( *v7 == a2 )
{
if ( v5 )
{
v9 = 0LL;
while ( v7[v9 + 5] == *(_DWORD *)(a4 + 4 * v9 + 8) )
{
if ( a3 <= (unsigned __int8)++v9 )
return 1LL;
}
result = 0LL;
}
else
{
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1, int a2, unsigned __int8 a3, __int64 a4)
{
unsigned __int8 v5; // r8
_DWORD *v7; // rdx
__int64 result; // rax
__int64 v9; // rax

v5 = a3;
v7 = (char *)rawHeapWH + 4 * a1 * (MAXDIM + 5LL);
result = 0LL;
if ( *v7 == a2 )
{
if ( v5 )
{
v9 = 0LL;
while ( v7[v9 + 5] == *(_DWORD *)(a4 + 4 * v9 + 8) )
{
if ( a3 <= (unsigned __int8)++v9 )
return 1LL;
}
result = 0LL;
}
else
{
result = 1LL;
}
}
return result;
}

original_code:
static _Bool match (tagWH hV, identifier id, dimension depdim, World *w)
{
  if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id != id)
    return 0;
  for (register dimension d = 0; d < depdim; d++)
    if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] != w->l[d])
      return 0;
  return 1;
}

canonical_original_code:
static _Bool match(unsigned int hV, unsigned int id, unsigned char depdim, struct world_tag *w)
{
  if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id != id)
    return 0;
  for (register unsigned char d = 0; d < depdim; d++)
    if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] != w->l[d])
      return 0;
  return 1;
}

variable_types:
hV
unsigned int


initializeWH

decompiled_code:
int initializeWH()
{
int v0; // ebp
size_t v1; // rbx
__int64 v2; // rax
__int64 v3; // r12
size_t v4; // rbp
_DWORD *v5; // rax
_DWORD *v6; // rdi
_DWORD *v7; // rdx
int v8; // eax
unsigned int v9; // ecx

if ( tableWH )
free(tableWH);
v0 = WHTABLESIZE;
v1 = 4LL * WHTABLESIZE;
tableWH = malloc(v1);
if ( !tableWH )
{
fwrite("Out of memory: allocating the warehouse table\n", 1uLL, 0x2EuLL, stderr);
exit(1);
}
v2 = 0LL;
if ( v0 )
{
do
{
*(_DWORD *)((char *)tableWH + v2) = -1;
v2 += 4LL;
}
while ( v2 != v1 );
}
if ( rawHeapWH )
free(rawHeapWH);
v3 = MAXDIM + 5LL;
v4 = 4 * v3 * WHHEAPSIZE;
v5 = malloc(v4);
v6 = v5;
rawHeapWH = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the warehouse heap\n", 1uLL, 0x2DuLL, stderr);
exit(1);
}
v7 = v5 + 3;
v8 = 0;
v9 = WHHEAPSIZE - 1;
if ( WHHEAPSIZE != 1 )
{
do
{
*v7 = ++v8;
v7 += v3;
}
while ( v8 != v9 );
}
v6[v9 * v3 + 3] = -1;
entriesWH = 0;
freeWH = 0;
hits = 0;
globalAge = 0;
return printf("WH memory: %u bytes\n", v1 + v4);
}

canonical_decompiled_code:
int func2()
{
int v0; // ebp
size_t v1; // rbx
__int64 v2; // rax
__int64 v3; // r12
size_t v4; // rbp
_DWORD *v5; // rax
_DWORD *v6; // rdi
_DWORD *v7; // rdx
int v8; // eax
unsigned int v9; // ecx

if ( tableWH )
free(tableWH);
v0 = WHTABLESIZE;
v1 = 4LL * WHTABLESIZE;
tableWH = malloc(v1);
if ( !tableWH )
{
fwrite("Out of memory: allocating the warehouse table\n", 1uLL, 0x2EuLL, stderr);
exit(1);
}
v2 = 0LL;
if ( v0 )
{
do
{
*(_DWORD *)((char *)tableWH + v2) = -1;
v2 += 4LL;
}
while ( v2 != v1 );
}
if ( rawHeapWH )
free(rawHeapWH);
v3 = MAXDIM + 5LL;
v4 = 4 * v3 * WHHEAPSIZE;
v5 = malloc(v4);
v6 = v5;
rawHeapWH = v5;
if ( !v5 )
{
fwrite("Out of memory: allocating the warehouse heap\n", 1uLL, 0x2DuLL, stderr);
exit(1);
}
v7 = v5 + 3;
v8 = 0;
v9 = WHHEAPSIZE - 1;
if ( WHHEAPSIZE != 1 )
{
do
{
*v7 = ++v8;
v7 += v3;
}
while ( v8 != v9 );
}
v6[v9 * v3 + 3] = -1;
entriesWH = 0;
freeWH = 0;
hits = 0;
globalAge = 0;
return printf("WH memory: %u bytes\n", v1 + v4);
}

original_code:
void initializeWH ()
{
  if (tableWH != ((void *)0))
    free(tableWH);
  tableWH = (struct bucketWH *) malloc(WHTABLESIZE * sizeof(struct bucketWH));
  if (tableWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse table\n");
    exit(1);
  }
  for (tagWH i = 0; i < WHTABLESIZE; i++)
    tableWH[i].ptr = ((tagWH) (-1));
  if (rawHeapWH != ((void *)0))
    free(rawHeapWH);
  sizeOfHeapWH = WHHEAPSIZE * (sizeof(struct nodeWH) + MAXDIM * sizeof(list));
  rawHeapWH = malloc(sizeOfHeapWH);
  if (rawHeapWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse heap\n");
    exit(1);
  }
  for (tagWH i = 0; i < WHHEAPSIZE-1; i++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (i) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = i+1;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (WHHEAPSIZE-1) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = ((tagWH) (-1));
  entriesWH = 0;
  freeWH = 0;
  hits = 0;
  globalAge = 0;
  printf("WH memory: %u bytes\n", WHTABLESIZE * sizeof(struct bucketWH)
  + sizeOfHeapWH);
}

canonical_original_code:
void initializeWH()
{
  if (tableWH != ((void *)0))
    free(tableWH);
  tableWH = (struct bucketWH *) malloc(WHTABLESIZE * sizeof(struct bucketWH));
  if (tableWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse table\n");
    exit(1);
  }
  for (unsigned int i = 0; i < WHTABLESIZE; i++)
    tableWH[i].ptr = ((tagWH) (-1));
  if (rawHeapWH != ((void *)0))
    free(rawHeapWH);
  sizeOfHeapWH = WHHEAPSIZE * (sizeof(struct nodeWH) + MAXDIM * sizeof(list));
  rawHeapWH = malloc(sizeOfHeapWH);
  if (rawHeapWH == ((void *)0)) {
    fprintf(stderr, "Out of memory: allocating the warehouse heap\n");
    exit(1);
  }
  for (unsigned int i = 0; i < WHHEAPSIZE-1; i++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (i) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = i+1;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (WHHEAPSIZE-1) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = ((tagWH) (-1));
  entriesWH = 0;
  freeWH = 0;
  hits = 0;
  globalAge = 0;
  printf("WH memory: %u bytes\n", WHTABLESIZE * sizeof(struct bucketWH)
  + sizeOfHeapWH);
}


getWH

decompiled_code:
__int64 __fastcall getWH(unsigned int a1)
{
return *((unsigned int *)rawHeapWH + a1 * (MAXDIM + 5LL) + 1);
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int a1)
{
return *((unsigned int *)rawHeapWH + a1 * (MAXDIM + 5LL) + 1);
}

original_code:
value getWH (tagWH hV)
{
  return ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val;
}

canonical_original_code:
int getWH(unsigned int hV)
{
  return ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val;
}

return_type: int


putWH

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

result = a1 * (MAXDIM + 5LL);
*((_DWORD *)rawHeapWH + result + 1) = a2;
return result;
}

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

result = a1 * (MAXDIM + 5LL);
*((_DWORD *)rawHeapWH + result + 1) = a2;
return result;
}

original_code:
void putWH (tagWH hV, value val)
{
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = val;
}

canonical_original_code:
void putWH(unsigned int hV, int val)
{
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (hV) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = val;
}

variable_types: val int


gcollectWH

decompiled_code:
__int64 gcollectWH()
{
unsigned int v0; // er12
__int64 result; // rax
unsigned int v2; // ebp
__int64 v3; // rbx
__int64 v4; // r11
__int64 v5; // r10
unsigned int *v6; // rdi
unsigned int v7; // ecx
char *v8; // r8
char *v9; // rsi
unsigned int v10; // edx

v0 = (int)((double)(globalAge - hits) * 0.5);
result = WHTABLESIZE;
if ( WHTABLESIZE )
{
v2 = (int)((double)WHHEAPSIZE * 0.0);
v3 = 4LL * WHTABLESIZE;
v4 = 0LL;
result = MAXDIM;
v5 = 4LL * MAXDIM + 20;
do
{
if ( v2 >= entriesWH )
break;
result = (__int64)tableWH + v4;
v6 = (unsigned int *)((char *)tableWH + v4);
v7 = *(_DWORD *)((char *)tableWH + v4);
if ( v7 != -1 )
{
do
{
v8 = (char *)rawHeapWH;
result = v5 * v7;
v9 = (char *)rawHeapWH + result;
v10 = *(_DWORD *)((char *)rawHeapWH + result + 8);
if ( v10 >= v0 || *((_DWORD *)v9 + 1) == 0x80000000 )
{
*((_DWORD *)v9 + 2) = v10 - v0;
result = v5 * *v6;
v6 = (unsigned int *)&v8[result + 12];
}
else
{
*v6 = *((_DWORD *)v9 + 3);
*(_DWORD *)((char *)rawHeapWH + result + 12) = freeWH;
freeWH = v7;
--entriesWH;
}
v7 = *v6;
}
while ( *v6 != -1 );
}
v4 += 4LL;
}
while ( v4 != v3 );
}
globalAge -= v0;
hits = 0;
return result;
}

canonical_decompiled_code:
__int64 func5()
{
unsigned int v0; // er12
__int64 result; // rax
unsigned int v2; // ebp
__int64 v3; // rbx
__int64 v4; // r11
__int64 v5; // r10
unsigned int *v6; // rdi
unsigned int v7; // ecx
char *v8; // r8
char *v9; // rsi
unsigned int v10; // edx

v0 = (int)((double)(globalAge - hits) * 0.5);
result = WHTABLESIZE;
if ( WHTABLESIZE )
{
v2 = (int)((double)WHHEAPSIZE * 0.0);
v3 = 4LL * WHTABLESIZE;
v4 = 0LL;
result = MAXDIM;
v5 = 4LL * MAXDIM + 20;
do
{
if ( v2 >= entriesWH )
break;
result = (__int64)tableWH + v4;
v6 = (unsigned int *)((char *)tableWH + v4);
v7 = *(_DWORD *)((char *)tableWH + v4);
if ( v7 != -1 )
{
do
{
v8 = (char *)rawHeapWH;
result = v5 * v7;
v9 = (char *)rawHeapWH + result;
v10 = *(_DWORD *)((char *)rawHeapWH + result + 8);
if ( v10 >= v0 || *((_DWORD *)v9 + 1) == 0x80000000 )
{
*((_DWORD *)v9 + 2) = v10 - v0;
result = v5 * *v6;
v6 = (unsigned int *)&v8[result + 12];
}
else
{
*v6 = *((_DWORD *)v9 + 3);
*(_DWORD *)((char *)rawHeapWH + result + 12) = freeWH;
freeWH = v7;
--entriesWH;
}
v7 = *v6;
}
while ( *v6 != -1 );
}
v4 += 4LL;
}
while ( v4 != v3 );
}
globalAge -= v0;
hits = 0;
return result;
}

original_code:
void gcollectWH ()
{
  tagAge ageLimit = (tagAge) ((globalAge - hits) * 0.5);
  for (tagWH i = 0; i < WHTABLESIZE && entriesWH > ((tagWH) (WHHEAPSIZE * 0.0)); i++)
    for (tagWH * ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1)); )
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age < ageLimit && ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((value) 1 << (8 * sizeof(value) - 1))) {
 tagWH prev = *ptr;
 *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
 freeWH = prev;
 entriesWH--;
      }
      else {
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age -= ageLimit;
 ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
      }
  globalAge -= ageLimit;
  hits = 0;
}

canonical_original_code:
void gcollectWH()
{
  unsigned int ageLimit = (tagAge) ((globalAge - hits) * 0.5);
  for (unsigned int i = 0; i < WHTABLESIZE && entriesWH > ((tagWH) (WHHEAPSIZE * 0.0)); i++)
    for (unsigned int *ptr = &(tableWH[i].ptr); *ptr != ((tagWH) (-1)); )
      if (((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age < ageLimit && ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val != ((int) 1 << (8 * sizeof(value) - 1))) {
 unsigned int prev = *ptr;
 *ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (prev) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = freeWH;
 freeWH = prev;
 entriesWH--;
      }
      else {
 ((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age -= ageLimit;
 ptr = &(((struct nodeWH *) ((unsigned char *) rawHeapWH + (*ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr);
      }
  globalAge -= ageLimit;
  hits = 0;
}

variable_types:
ageLimit
unsigned int


seekWH

decompiled_code:
__int64 __fastcall seekWH(int a1, unsigned __int8 a2, __int64 a3, _DWORD *a4)
{
unsigned int v6; // ebx
_DWORD *v7; // r15
__int64 v8; // r13
__int64 result; // rax
int v10; // edi
__int64 v11; // rcx
char *v12; // rsi
__int64 v13; // rax
_DWORD *v14; // rdx
unsigned __int8 v16; // [rsp+Ch] [rbp-4Ch]
__int64 v18; // [rsp+18h] [rbp-40h]

v16 = a2;
if ( (int)((double)WHHEAPSIZE * 0.98) <= (unsigned int)entriesWH )
{
gcollectWH();
if ( WHHEAPSIZE <= (unsigned int)entriesWH )
{
fwrite("FATAL ERROR: Out of heap space for the warehouse\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
}
v18 = (unsigned int)hashWH(a1, a2, a3);
v6 = *((_DWORD *)tableWH + v18);
if ( v6 == -1 )
{
LABEL_6:
v10 = freeWH;
v11 = 4 * (unsigned int)freeWH * (MAXDIM + 5LL);
freeWH = *(_DWORD *)((char *)rawHeapWH + v11 + 12);
++entriesWH;
*(_DWORD *)((char *)rawHeapWH + v11) = a1;
if ( a2 )
{
v12 = (char *)rawHeapWH + v11;
v13 = 0LL;
do
{
*(_DWORD *)&v12[4 * v13 + 20] = *(_DWORD *)(a3 + 4 * v13 + 8);
++v13;
}
while ( a2 > (unsigned __int8)v13 );
}
++globalAge;
v14 = (char *)rawHeapWH + v11;
v14[2] = globalAge;
v14[3] = *((_DWORD *)tableWH + v18);
v14[1] = 0x80000000;
*((_BYTE *)rawHeapWH + v11 + 16) = v16;
*((_DWORD *)tableWH + v18) = v10;
*a4 = v10;
result = 0LL;
}
else
{
v7 = rawHeapWH;
v8 = MAXDIM + 5LL;
while ( 1 )
{
result = match(v6, a1, a2, a3);
if ( (_BYTE)result )
break;
v6 = v7[v8 * v6 + 3];
if ( v6 == -1 )
goto LABEL_6;
}
++hits;
v7[v6 * v8 + 2] = ++globalAge;
*a4 = v6;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(int a1, unsigned __int8 a2, __int64 a3, _DWORD *a4)
{
unsigned int v6; // ebx
_DWORD *v7; // r15
__int64 v8; // r13
__int64 result; // rax
int v10; // edi
__int64 v11; // rcx
char *v12; // rsi
__int64 v13; // rax
_DWORD *v14; // rdx
unsigned __int8 v16; // [rsp+Ch] [rbp-4Ch]
__int64 v18; // [rsp+18h] [rbp-40h]

v16 = a2;
if ( (int)((double)WHHEAPSIZE * 0.98) <= (unsigned int)entriesWH )
{
func5();
if ( WHHEAPSIZE <= (unsigned int)entriesWH )
{
fwrite("FATAL ERROR: Out of heap space for the warehouse\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
}
v18 = (unsigned int)func0(a1, a2, a3);
v6 = *((_DWORD *)tableWH + v18);
if ( v6 == -1 )
{
LABEL_6:
v10 = freeWH;
v11 = 4 * (unsigned int)freeWH * (MAXDIM + 5LL);
freeWH = *(_DWORD *)((char *)rawHeapWH + v11 + 12);
++entriesWH;
*(_DWORD *)((char *)rawHeapWH + v11) = a1;
if ( a2 )
{
v12 = (char *)rawHeapWH + v11;
v13 = 0LL;
do
{
*(_DWORD *)&v12[4 * v13 + 20] = *(_DWORD *)(a3 + 4 * v13 + 8);
++v13;
}
while ( a2 > (unsigned __int8)v13 );
}
++globalAge;
v14 = (char *)rawHeapWH + v11;
v14[2] = globalAge;
v14[3] = *((_DWORD *)tableWH + v18);
v14[1] = 0x80000000;
*((_BYTE *)rawHeapWH + v11 + 16) = v16;
*((_DWORD *)tableWH + v18) = v10;
*a4 = v10;
result = 0LL;
}
else
{
v7 = rawHeapWH;
v8 = MAXDIM + 5LL;
while ( 1 )
{
result = func1(v6, a1, a2, a3);
if ( (_BYTE)result )
break;
v6 = v7[v8 * v6 + 3];
if ( v6 == -1 )
goto LABEL_6;
}
++hits;
v7[v6 * v8 + 2] = ++globalAge;
*a4 = v6;
}
return result;
}

original_code:
_Bool seekWH (identifier id, dimension depdim, World *w, tagWH *hV)
{
  if (entriesWH >= ((tagWH) (WHHEAPSIZE * 0.98))) {
    gcollectWH();
    if (entriesWH >= WHHEAPSIZE) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for the warehouse\n");
      exit(1);
    }
  }
  tagWH hashval = hashWH(id, depdim, w);
  tagWH ptr;
  for (ptr = tableWH[hashval].ptr; ptr != ((tagWH) (-1)); ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr)
    if (match(ptr, id, depdim, w)) {
      hits++;
      ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
      *hV = ptr;
      return 1;
    }
    else {
      ;
    }
  ptr = freeWH;
  freeWH = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (freeWH) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
  entriesWH++;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id = id;
  for (register dimension d = 0; d < depdim; d++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] = w->l[d];
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = tableWH[hashval].ptr;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = ((value) 1 << (8 * sizeof(value) - 1));
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim = depdim;
  tableWH[hashval].ptr = ptr;
  *hV=ptr;
  return 0;
}

canonical_original_code:
_Bool seekWH(unsigned int id, unsigned char depdim, struct world_tag *w, unsigned int *hV)
{
  if (entriesWH >= ((tagWH) (WHHEAPSIZE * 0.98))) {
    gcollectWH();
    if (entriesWH >= WHHEAPSIZE) {
      fprintf(stderr, "FATAL ERROR: Out of heap space for the warehouse\n");
      exit(1);
    }
  }
  unsigned int hashval = hashWH(id, depdim, w);
  unsigned int ptr;
  for (ptr = tableWH[hashval].ptr; ptr != ((tagWH) (-1)); ptr = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr)
    if (match(ptr, id, depdim, w)) {
      hits++;
      ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
      *hV = ptr;
      return 1;
    }
    else {
      ;
    }
  ptr = freeWH;
  freeWH = ((struct nodeWH *) ((unsigned char *) rawHeapWH + (freeWH) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr;
  entriesWH++;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->id = id;
  for (register unsigned char d = 0; d < depdim; d++)
    ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->l[d] = w->l[d];
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->age = ++globalAge;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->ptr = tableWH[hashval].ptr;
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->val = ((int) 1 << (8 * sizeof(value) - 1));
  ((struct nodeWH *) ((unsigned char *) rawHeapWH + (ptr) * (sizeof(struct nodeWH) + MAXDIM * sizeof(list))))->depDim = depdim;
  tableWH[hashval].ptr = ptr;
  *hV=ptr;
  return 0;
}

variable_types:
hV
unsigned int *


statsWH

decompiled_code:
int statsWH()
{
return printf(
"\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
WHHEAPSIZE,
(double)(WHHEAPSIZE - entriesWH) / (double)WHHEAPSIZE * 100.0);
}

canonical_decompiled_code:
int func7()
{
return printf(
"\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
WHHEAPSIZE,
(double)(WHHEAPSIZE - entriesWH) / (double)WHHEAPSIZE * 100.0);
}

original_code:
void statsWH ()
{
  printf("\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
  WHHEAPSIZE, ((double) (WHHEAPSIZE - entriesWH) / WHHEAPSIZE) * 100);
}

canonical_original_code:
void statsWH()
{
  printf("\n\nWH heapsize:\t%u\nWH freerecs:\t%.2lf%%\n\n",
  WHHEAPSIZE, ((double) (WHHEAPSIZE - entriesWH) / WHHEAPSIZE) * 100);
}


printWorld

decompiled_code:
__int64 __fastcall printWorld(__int64 a1)
{
__int64 result; // rax
unsigned int *v2; // rbx
__int64 v3; // rbp

result = MAXDIM;
if ( MAXDIM )
{
v2 = (unsigned int *)(a1 + 8);
v3 = a1 + 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
result = printList(*v2++);
while ( v2 != (unsigned int *)v3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 result; // rax
unsigned int *v2; // rbx
__int64 v3; // rbp

result = MAXDIM;
if ( MAXDIM )
{
v2 = (unsigned int *)(a1 + 8);
v3 = a1 + 4LL * (unsigned __int8)(MAXDIM - 1) + 12;
do
result = printList(*v2++);
while ( v2 != (unsigned int *)v3 );
}
return result;
}

original_code:
void printWorld (World *w)
{
   for (register dimension d = 0; d < MAXDIM; d++)
      printList(w->l[d]);
}

canonical_original_code:
void printWorld(struct world_tag *w)
{
   for (register unsigned char d = 0; d < MAXDIM; d++)
      printList(w->l[d]);
}


repo: aconbere/c-PID

decompiled_code:
_BOOL8 __fastcall PID_should_compute(__int64 a1, double a2)
{
unsigned __int64 v2; // rax
double v3; // xmm1_8

getCurrentMilliseconds();
v2 = *(_QWORD *)a1;
if ( *(__int64 *)a1 < 0 )
v3 = (double)(int)(*(_DWORD *)a1 & 1 | (v2 >> 1)) + (double)(int)(*(_DWORD *)a1 & 1 | (v2 >> 1));
else
v3 = (double)(int)v2;
return *(double *)(a1 + 48) <= a2 - v3;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(__int64 a1, double a2)
{
unsigned __int64 v2; // rax
double v3; // xmm1_8

getCurrentMilliseconds();
v2 = *(_QWORD *)a1;
if ( *(__int64 *)a1 < 0 )
v3 = (double)(int)(*(_DWORD *)a1 & 1 | (v2 >> 1)) + (double)(int)(*(_DWORD *)a1 & 1 | (v2 >> 1));
else
v3 = (double)(int)v2;
return *(double *)(a1 + 48) <= a2 - v3;
}

original_code:
bool_t PID_should_compute(PID *pid) {
  if (getCurrentMilliseconds() - pid->last_computed < pid->sample_time) {
    return false_t;
  }
  return true_t;
}

canonical_original_code:
int PID_should_compute(struct PID *pid) {
  if (getCurrentMilliseconds() - pid->last_computed < pid->sample_time) {
    return false_t;
  }
  return true_t;
}

variable_types: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; } *


decompiled_code:
double __fastcall PID_clamp_output(__int64 a1, double a2)
{
double result; // xmm0_8

result = *(double *)(a1 + 24);
if ( a2 <= result )
result = fmax(*(double *)(a1 + 16), a2);
return result;
}

canonical_decompiled_code:
double __fastcall func1(__int64 a1, double a2)
{
double result; // xmm0_8

result = *(double *)(a1 + 24);
if ( a2 <= result )
result = fmax(*(double *)(a1 + 16), a2);
return result;
}

original_code:
double PID_clamp_output(PID *pid, double output) {
  if (output > pid->out_max) {
    return pid->out_max;
  } else if (output < pid->out_min) {
    return pid->out_min;
  } else {
    return output;
  }
}

canonical_original_code:
double PID_clamp_output(struct PID *pid, double output) {
  if (output > pid->out_max) {
    return pid->out_max;
  } else if (output < pid->out_min) {
    return pid->out_min;
  } else {
    return output;
  }
}

variable_types: output double

return_type: double

user_defined_types: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; }


decompiled_code:
__int64 __fastcall PID_create(double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8)
{
double *v10; // rax
__int64 v11; // rbx
int *v13; // rbp
const char *v14; // r8

v10 = (double *)calloc(1uLL, 0x50uLL);
v11 = (__int64)v10;
if ( v10 )
{
v10[1] = a2;
v10[6] = a3;
v10[3] = a5;
v10[2] = a4;
v10[7] = a6;
v10[8] = a7;
v10[9] = a8;
v10[4] = PID_clamp_output((__int64)v10, 0.0);
*(double *)(v11 + 40) = PID_clamp_output(v11, a1);
*(_QWORD *)(v11 + 48) = LC5;
}
else
{
v13 = _errno_location();
v14 = "None";
if ( *v13 )
v14 = "ERR:";
fprintf(stderr, "[ERROR] (%s:%d: errno: %s) Out of memory.\n", "src/pid.c", 25LL, v14);
*v13 = 0;
}
return v11;
}

original_code:
PID *PID_create(
    double current_input,
    double setpoint,
    double sample_time,
    double out_min,
    double out_max,
    double Kp,
    double Ki,
    double Kd
) {
  PID *pid = (PID *)calloc(1, sizeof(PID));
  if(!((pid))) { fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " "Out of memory." "\n", "src/pid.c", 25, ((*__errno_location ()) == 0 ? "None" : "ERR:")); (*__errno_location ())=0; goto error; };
  pid->setpoint = setpoint;
  pid->sample_time = sample_time;
  pid->out_max = out_max;
  pid->out_min = out_min;
  pid->Kp = Kp;
  pid->Ki = Ki;
  pid->Kd = Kd;
  pid->current_integral_value = PID_clamp_output(pid, 0);
  pid->last_process_value = PID_clamp_output(pid, current_input);
  pid->sample_time = 300;
  return pid;
error:
  return ((void *)0);
}

canonical_original_code:
struct PID *PID_create(double current_input, double setpoint, double sample_time, double out_min, double out_max, double Kp, double Ki, double Kd) {
  struct PID *pid = (PID *)calloc(1, sizeof(PID));
  if(!((pid))) { fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " "Out of memory." "\n", "src/pid.c", 25, ((*__errno_location ()) == 0 ? "None" : "ERR:")); (*__errno_location ())=0; goto error; };
  pid->setpoint = setpoint;
  pid->sample_time = sample_time;
  pid->out_max = out_max;
  pid->out_min = out_min;
  pid->Kp = Kp;
  pid->Ki = Ki;
  pid->Kd = Kd;
  pid->current_integral_value = PID_clamp_output(pid, 0);
  pid->last_process_value = PID_clamp_output(pid, current_input);
  pid->sample_time = 300;
  return pid;
error:
  return ((void *)0);
}

variable_types: setpoint double

variable_types: Kp double

variable_types: Ki double

variable_types: Kd double

return_type: struct PID { unsigned long last_computed; double setpoint; double out_min; double out_max; double current_integral_value; double last_process_value; double sample_time; double Kp; double Ki; double Kd; } *


decompiled_code:
void __fastcall PID_tune(double *a1, double a2, double a3, double a4)
{
double v5; // xmm0_8

v5 = a1[6] / 1000.0;
a1[7] = a2;
a1[8] = a3 * v5;
a1[9] = a4 / v5;
}

canonical_decompiled_code:
void __fastcall func3(double *a1, double a2, double a3, double a4)
{
double v5; // xmm0_8

v5 = a1[6] / 1000.0;
a1[7] = a2;
a1[8] = a3 * v5;
a1[9] = a4 / v5;
}

original_code:
void PID_tune(PID *pid, double Kp, double Ki, double Kd) {
  double sample_time = (double)(pid->sample_time / 1000);
  pid->Kp = Kp;
  pid->Ki = Ki * sample_time;
  pid->Kd = Kd / sample_time;
}

canonical_original_code:
void PID_tune(struct PID *pid, double Kp, double Ki, double Kd) {
  double sample_time = (double)(pid->sample_time / 1000);
  pid->Kp = Kp;
  pid->Ki = Ki * sample_time;
  pid->Kd = Kd / sample_time;
}


original_code:
double PID_next(PID *pid, double process_value) {
  double error = pid->setpoint - process_value;
  pid->current_integral_value = PID_clamp_output( pid,
    pid->current_integral_value + (pid->Ki * error)
  );
  double input_derivative = pid->last_process_value - process_value;
  double output = PID_clamp_output( pid,
    (pid->Kp * error) + pid->current_integral_value - (pid->Kd * input_derivative)
  );
  pid->last_process_value = process_value;
  pid->last_computed = getCurrentMilliseconds();
  return output;
}

canonical_original_code:
double PID_next(struct PID *pid, double process_value) {
  double error = pid->setpoint - process_value;
  pid->current_integral_value = PID_clamp_output( pid,
    pid->current_integral_value + (pid->Ki * error)
  );
  double input_derivative = pid->last_process_value - process_value;
  double output = PID_clamp_output( pid,
    (pid->Kp * error) + pid->current_integral_value - (pid->Kd * input_derivative)
  );
  pid->last_process_value = process_value;
  pid->last_computed = getCurrentMilliseconds();
  return output;
}

variable_types: error double


repo: acourt/OS-Assignments

decompiled_code:
int *load_FAT_from_disk()
{
int *result; // rax
_BYTE v1[4104]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(1LL, 1LL, v1);
result = &FAT;
qmemcpy(&FAT, v1, 0x7E8uLL);
return result;
}

canonical_decompiled_code:
int *func0()
{
int *result; // rax
_BYTE v1[4104]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(1LL, 1LL, v1);
result = &FAT;
qmemcpy(&FAT, v1, 0x7E8uLL);
return result;
}

original_code:
void load_FAT_from_disk()
{
 char disk_FAT[4096];
 memset(disk_FAT, 0, 4096);
 read_blocks(1, 1, disk_FAT);
 memcpy(FAT, disk_FAT, (256 - 3)*sizeof(FAT_entry));
}


decompiled_code:
__int64 write_FAT_to_disk()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &FAT, 0x7E8uLL);
return write_blocks(1LL, 1LL);
}

canonical_decompiled_code:
__int64 func1()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &FAT, 0x7E8uLL);
return write_blocks(1LL, 1LL);
}

original_code:
void write_FAT_to_disk()
{
 char disk_FAT[4096];
 memset(disk_FAT, 0, 4096);
 memcpy(disk_FAT, FAT, (256 - 3)*sizeof(FAT_entry));
 write_blocks(1, 1, disk_FAT);
}


decompiled_code:
__int64 load_directory_from_disk()
{
__int64 result; // rax
int v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(0LL, 1LL, v1);
file_count = v1[0];
qmemcpy(&directory, &v1[1], 0xFF8uLL);
result = (unsigned int)v1[1023];
*((_DWORD *)&directory + 1022) = v1[1023];
return result;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 result; // rax
int v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(0LL, 1LL, v1);
file_count = v1[0];
qmemcpy(&directory, &v1[1], 0xFF8uLL);
result = (unsigned int)v1[1023];
*((_DWORD *)&directory + 1022) = v1[1023];
return result;
}

original_code:
void load_directory_from_disk()
{
 char disk_directory[4096];
 memset(disk_directory,0, 4096);
 read_blocks(0, 1, disk_directory);
 memcpy(&file_count, disk_directory, sizeof(int));
 memcpy(directory, disk_directory+4, 93*sizeof(dir_entry));
}


decompiled_code:
__int64 write_directory_to_disk()
{
return write_blocks(0LL, 1LL);
}

canonical_decompiled_code:
__int64 func3()
{
return write_blocks(0LL, 1LL);
}

original_code:
void write_directory_to_disk()
{
 char disk_directory[4096];
 memset(disk_directory,0, 4096);
 memcpy(disk_directory, &file_count, sizeof(int));
 memcpy(disk_directory+4, directory, 93*sizeof(dir_entry));
 write_blocks(0, 1, directory);
}


decompiled_code:
__int64 load_free_list_from_disk()
{
__int64 result; // rax
_DWORD v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(2LL, 1LL, v1);
qmemcpy(&free_list, v1, 0xF8uLL);
*(&free_list + 62) = v1[62];
result = LOBYTE(v1[63]);
*((_BYTE *)&free_list + 252) = v1[63];
return result;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 result; // rax
_DWORD v1[1026]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, 0x1000uLL);
read_blocks(2LL, 1LL, v1);
qmemcpy(&free_list, v1, 0xF8uLL);
*(&free_list + 62) = v1[62];
result = LOBYTE(v1[63]);
*((_BYTE *)&free_list + 252) = v1[63];
return result;
}

original_code:
void load_free_list_from_disk()
{
 char disk_free_list[4096];
 memset(disk_free_list,0, 4096);
 read_blocks(2, 1, disk_free_list);
 memcpy(free_list, disk_free_list, 256 - 3);
}


decompiled_code:
__int64 write_free_list_to_disk()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &free_list, 0xFDuLL);
return write_blocks(2LL, 1LL);
}

canonical_decompiled_code:
__int64 func5()
{
_BYTE v1[4096]; // [rsp+0h] [rbp-1008h] BYREF

memset(v1, 0, sizeof(v1));
qmemcpy(v1, &free_list, 0xFDuLL);
return write_blocks(2LL, 1LL);
}

original_code:
void write_free_list_to_disk()
{
 char disk_free_list[4096];
 memset(disk_free_list,0, 4096);
 memcpy(disk_free_list, free_list, 256 - 3);
 write_blocks(2, 1, disk_free_list);
}


decompiled_code:
_BOOL8 __fastcall dir_entry_is_null(int a1)
{
return *((_BYTE *)&directory + 44 * a1) == 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func6(int a1)
{
return *((_BYTE *)&directory + 44 * a1) == 0;
}

original_code:
int dir_entry_is_null(int entry)
{
 return directory[entry].fname[0] == '\0';
}

variable_types: entry int


decompiled_code:
__int64 get_current_time()
{
time_t timer; // [rsp+8h] [rbp-10h] BYREF

time(&timer);
return (unsigned int)timer;
}

canonical_decompiled_code:
__int64 func7()
{
time_t timer; // [rsp+8h] [rbp-10h] BYREF

time(&timer);
return (unsigned int)timer;
}

original_code:
int get_current_time()
{
 time_t current_time;
 time(&current_time);
 return (int)current_time;
}

canonical_original_code:
int get_current_time()
{
 long current_time;
 time(&current_time);
 return (int)current_time;
}


decompiled_code:
__int64 get_free_block()
{
__int64 i; // rax
unsigned int v1; // edx

for ( i = 0LL; i != 253; ++i )
{
v1 = i;
if ( free_list[i] )
{
free_list[(int)i] = 0;
return v1;
}
}
return (unsigned int)-1;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 i; // rax
unsigned int v1; // edx

for ( i = 0LL; i != 253; ++i )
{
v1 = i;
if ( free_list[i] )
{
free_list[(int)i] = 0;
return v1;
}
}
return (unsigned int)-1;
}

original_code:
int get_free_block()
{
 int i=0, found_free_block = 0, free_block_index = -1;
 for (i=0; i < 256 -3 && !found_free_block; i++) {
  if (free_list[i]) {
   free_list[i] = 0;
   found_free_block = 1;
   free_block_index = i;
  }
 }
 return free_block_index;
}

canonical_original_code:
int get_free_block()
{
 int i = 0; int found_free_block = 0; int free_block_index = -1;
 for (i=0; i < 256 -3 && !found_free_block; i++) {
  if (free_list[i]) {
   free_list[i] = 0;
   found_free_block = 1;
   free_block_index = i;
  }
 }
 return free_block_index;
}


decompiled_code:
__int64 get_free_dir_index()
{
unsigned int v0; // ebx

v0 = 0;
while ( !dir_entry_is_null(v0) )
{
if ( ++v0 == 93 )
return (unsigned int)-1;
}
return v0;
}

canonical_decompiled_code:
__int64 func9()
{
unsigned int v0; // ebx

v0 = 0;
while ( !func6(v0) )
{
if ( ++v0 == 93 )
return (unsigned int)-1;
}
return v0;
}

original_code:
int get_free_dir_index()
{
 int i, index = -1, found_free_index = 0;
 for ( i=0; i < 93 && !found_free_index; i++) {
  if (dir_entry_is_null(i)) {
   found_free_index = 1;
   index = i;
  }
 }
 return index;
}

canonical_original_code:
int get_free_dir_index()
{
 int i; int index = -1; int found_free_index = 0;
 for ( i=0; i < 93 && !found_free_index; i++) {
  if (dir_entry_is_null(i)) {
   found_free_index = 1;
   index = i;
  }
 }
 return index;
}

variable_types: index int


mksfs

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

if ( a1 )
{
memset(&FAT, 0, 0x7E8uLL);
memset(free_list, 1u, 0x3F0uLL);
free_list[252] = 16843009;
memset(&directory, 0, 0xFF8uLL);
*((_DWORD *)&directory + 1022) = 0;
init_fresh_disk("DISK_FILE.txt", 4096LL, 256LL);
}
else
{
init_disk("DISK_FILE.txt", 4096LL, 256LL);
load_FAT_from_disk();
load_directory_from_disk();
load_free_list_from_disk();
}
result = -1LL;
memset(file_descriptors, 0xFFu, 0x740uLL);
file_descriptors[464] = -1;
return result;
}

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

if ( a1 )
{
memset(&FAT, 0, 0x7E8uLL);
memset(free_list, 1u, 0x3F0uLL);
free_list[252] = 16843009;
memset(&directory, 0, 0xFF8uLL);
*((_DWORD *)&directory + 1022) = 0;
init_fresh_disk("DISK_FILE.txt", 4096LL, 256LL);
}
else
{
init_disk("DISK_FILE.txt", 4096LL, 256LL);
func0();
func2();
func4();
}
result = -1LL;
memset(file_descriptors, 0xFFu, 0x740uLL);
file_descriptors[464] = -1;
return result;
}

original_code:
void mksfs(int fresh)
{
 if (fresh) {
  memset(FAT,0, sizeof(FAT_entry)*(256 -3));
  memset(free_list,1, sizeof(int)*(256 -3));
  memset(directory, 0, sizeof(dir_entry)*93);
  init_fresh_disk("DISK_FILE.txt", 4096, 256);
 }
 else
 {
  init_disk("DISK_FILE.txt", 4096, 256);
  load_FAT_from_disk();
  load_directory_from_disk();
  load_free_list_from_disk();
 }
 memset(file_descriptors, -1, sizeof(fd_entry)*93);
}

variable_types: fresh int


decompiled_code:
int sfs_ls()
{
const time_t *v0; // rbp
int i; // ebx
int result; // eax

v0 = (const time_t *)(unsigned int)((_DWORD)&directory + 36);
for ( i = 0; i != 93; ++i )
{
result = dir_entry_is_null(i);
if ( !result )
{
ctime(v0);
result = printf("Name: %s\tSize: %d\t\n", (const char *)v0 - 36, *((unsigned int *)v0 - 1));
}
v0 = (const time_t *)((char *)v0 + 44);
}
return result;
}

canonical_decompiled_code:
int func11()
{
const time_t *v0; // rbp
int i; // ebx
int result; // eax

v0 = (const time_t *)(unsigned int)((_DWORD)&directory + 36);
for ( i = 0; i != 93; ++i )
{
result = func6(i);
if ( !result )
{
ctime(v0);
result = printf("Name: %s\tSize: %d\t\n", (const char *)v0 - 36, *((unsigned int *)v0 - 1));
}
v0 = (const time_t *)((char *)v0 + 44);
}
return result;
}

original_code:
void sfs_ls()
{
 int i=0;
 for (i=0; i < 93; i++) {
  if(!dir_entry_is_null(i))
  {
   char* time = ctime((time_t*)&(directory[i].time));
   printf("Name: %s\tSize: %d\t\n", directory[i].fname, directory[i].size);
  }
 }
}

canonical_original_code:
void sfs_ls()
{
 int i = 0;
 for (i=0; i < 93; i++) {
  if(!dir_entry_is_null(i))
  {
   char *time = ctime((time_t*)&(directory[i].time));
   printf("Name: %s\tSize: %d\t\n", directory[i].fname, directory[i].size);
  }
 }
}

variable_types:
time
char *


decompiled_code:
__int64 __fastcall get_block_count(int a1)
{
int v1; // eax
unsigned int v2; // edx

v1 = FAT[2 * file_descriptors[5 * a1] + 1];
if ( v1 == -1 )
return 0;
v2 = 0;
do
{
++v2;
v1 = FAT[2 * v1 + 1];
}
while ( v1 != -1 );
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func12(int a1)
{
int v1; // eax
unsigned int v2; // edx

v1 = FAT[2 * file_descriptors[5 * a1] + 1];
if ( v1 == -1 )
return 0;
v2 = 0;
do
{
++v2;
v1 = FAT[2 * v1 + 1];
}
while ( v1 != -1 );
return v2;
}

original_code:
int get_block_count(int dir_index)
{
 int block_count=0;
 int next_FAT_index = file_descriptors[dir_index].root;
 while (FAT[next_FAT_index].next != -1) {
  next_FAT_index = FAT[next_FAT_index].next;
  block_count++;
 }
 return block_count;
}

canonical_original_code:
int get_block_count(int dir_index)
{
 int block_count = 0;
 int next_FAT_index = file_descriptors[dir_index].root;
 while (FAT[next_FAT_index].next != -1) {
  next_FAT_index = FAT[next_FAT_index].next;
  block_count++;
 }
 return block_count;
}


decompiled_code:
__int64 __fastcall create_file_in_mem(char *src, int *a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // eax
int v5; // ebx

v2 = get_free_block();
v3 = v2;
if ( v2 == -1 )
{
puts("Error: No more free blocks");
}
else
{
FAT[2 * v2] = v2;
FAT[2 * v2 + 1] = -1;
v4 = get_free_dir_index();
*a2 = v4;
if ( v4 == -1 )
{
puts("No more space in the directory for more files");
return (unsigned int)-1;
}
strncpy((char *)&directory + 44 * v4, src, 0x20uLL);
*((_DWORD *)&directory + 11 * *a2 + 10) = v3;
*((_DWORD *)&directory + 11 * *a2 + 8) = 0;
v5 = *a2;
*((_DWORD *)&directory + 11 * v5 + 9) = get_current_time();
v3 = 1;
}
write_directory_to_disk();
write_FAT_to_disk();
write_free_list_to_disk();
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func13(char *src, int *a2)
{
int v2; // eax
unsigned int v3; // ebx
int v4; // eax
int v5; // ebx

v2 = func8();
v3 = v2;
if ( v2 == -1 )
{
puts("Error: No more free blocks");
}
else
{
FAT[2 * v2] = v2;
FAT[2 * v2 + 1] = -1;
v4 = func9();
*a2 = v4;
if ( v4 == -1 )
{
puts("No more space in the directory for more files");
return (unsigned int)-1;
}
strncpy((char *)&directory + 44 * v4, src, 0x20uLL);
*((_DWORD *)&directory + 11 * *a2 + 10) = v3;
*((_DWORD *)&directory + 11 * *a2 + 8) = 0;
v5 = *a2;
*((_DWORD *)&directory + 11 * v5 + 9) = func7();
v3 = 1;
}
func3();
func1();
func5();
return v3;
}

original_code:
int create_file_in_mem(char* name, int* dir_index )
{
 int block_index = get_free_block();
 int errorcode = 1;
 if (block_index == -1) {
  printf("Error: No more free blocks\n");
  errorcode = -1;
 }
 else
 {
  FAT[block_index].start = block_index;
  FAT[block_index].next = -1;
  *dir_index = get_free_dir_index();
  if (*dir_index == -1) {
   printf("No more space in the directory for more files\n");
   return -1;
  }
  strncpy(directory[*dir_index].fname, name, 32);
  directory[*dir_index].FAT_index = block_index;
  directory[*dir_index].size = 0;
  directory[*dir_index].time = get_current_time();
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
 return errorcode;
}

canonical_original_code:
int create_file_in_mem(char *name, int *dir_index)
{
 int block_index = get_free_block();
 int errorcode = 1;
 if (block_index == -1) {
  printf("Error: No more free blocks\n");
  errorcode = -1;
 }
 else
 {
  FAT[block_index].start = block_index;
  FAT[block_index].next = -1;
  *dir_index = get_free_dir_index();
  if (*dir_index == -1) {
   printf("No more space in the directory for more files\n");
   return -1;
  }
  strncpy(directory[*dir_index].fname, name, 32);
  directory[*dir_index].FAT_index = block_index;
  directory[*dir_index].size = 0;
  directory[*dir_index].time = get_current_time();
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
 return errorcode;
}

variable_types:
name
char *

variable_types: errorcode int


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

result = 0xFFFFFFFFLL;
if ( a1 <= 0x5D )
result = file_descriptors[5 * a1] != -1;
return result;
}

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

result = 0xFFFFFFFFLL;
if ( a1 <= 0x5D )
result = file_descriptors[5 * a1] != -1;
return result;
}

original_code:
int is_file_open(int dir_index)
{
 if (dir_index > 93 ||
  dir_index < 0) {
  return -1;
 }
 return (file_descriptors[dir_index].root != -1);
}


decompiled_code:
__int64 __fastcall sfs_fopen(char *src)
{
const char *v1; // rbp
unsigned int i; // ebx
unsigned int v4[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4[0] = -1;
v1 = (const char *)&directory;
for ( i = 0; i != 93; ++i )
{
if ( !strcmp(v1, src) )
{
v4[0] = i;
return get_fd(v4[0]);
}
v1 += 44;
}
create_file_in_mem(src, (int *)v4);
return get_fd(v4[0]);
}

canonical_decompiled_code:
__int64 __fastcall func17(char *src)
{
const char *v1; // rbp
unsigned int i; // ebx
unsigned int v4[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4[0] = -1;
v1 = (const char *)&directory;
for ( i = 0; i != 93; ++i )
{
if ( !strcmp(v1, src) )
{
v4[0] = i;
return func16(v4[0]);
}
v1 += 44;
}
func13(src, (int *)v4);
return func16(v4[0]);
}

original_code:
int sfs_fopen(char *name)
{
 int i=0;
 int dir_index = -1;
 int file_exists = 0;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, name))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (!file_exists) {
  create_file_in_mem(name, &dir_index);
 }
 dir_index = get_fd(dir_index);
 return dir_index;
}

canonical_original_code:
int sfs_fopen(char *name)
{
 int i = 0;
 int dir_index = -1;
 int file_exists = 0;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, name))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (!file_exists) {
  create_file_in_mem(name, &dir_index);
 }
 dir_index = get_fd(dir_index);
 return dir_index;
}

variable_types: i int


decompiled_code:
int __fastcall sfs_fwrite(unsigned int a1, __int64 a2, int a3)
{
int v5; // er12
int *v6; // rbp
int v8; // edi
int v9; // ebx
int v10; // ebx
int v11; // eax
int v12; // eax
int v13; // eax
int v14; // [rsp+4h] [rbp-1044h]
int v15; // [rsp+8h] [rbp-1040h]
int v16; // [rsp+Ch] [rbp-103Ch]
char v17[4152]; // [rsp+10h] [rbp-1038h] BYREF

if ( !(unsigned int)is_file_open(a1) )
return puts("Error: Tried to write to a file without having it opened");
v16 = file_descriptors[5 * a1 + 4];
v15 = get_block_count(a1);
if ( a3 > 0 )
{
v5 = a3;
v14 = 0;
v6 = &file_descriptors[5 * a1];
do
{
read_blocks((unsigned int)(FAT[2 * v6[3]] + 3), 1LL, v17);
v8 = v6[4];
v9 = 4096 - v8;
if ( 4096 - v8 > v5 )
v9 = v5;
memcpy(&v17[v8], (const void *)(a2 + a3 - v5), v9);
write_blocks((unsigned int)(FAT[2 * v6[3]] + 3), 1LL);
v5 -= v9;
v10 = v6[4] + v9;
v6[4] = v10 % 4096;
if ( (v10 & 0xFFF) == 0 )
{
v11 = FAT[2 * v6[3] + 1];
if ( v11 == -1 )
{
v12 = get_free_block();
if ( v12 == -1 )
return puts("Error: No more free blocks!!");
FAT[2 * v6[3] + 1] = v12;
FAT[2 * v12] = v12;
FAT[2 * v12 + 1] = -1;
v6[3] = v12;
v14 = 1;
}
else
{
v6[3] = v11;
}
}
}
while ( v5 > 0 );
v13 = get_block_count(a1);
if ( v14 || v15 == v13 && file_descriptors[5 * a1 + 4] > v16 )
*((_DWORD *)&directory + 11 * (int)a1 + 8) = file_descriptors[5 * a1 + 4] + (v13 << 12);
}
write_directory_to_disk();
write_FAT_to_disk();
return write_free_list_to_disk();
}

canonical_decompiled_code:
int __fastcall func18(unsigned int a1, __int64 a2, int a3)
{
int v5; // er12
int *v6; // rbp
int v8; // edi
int v9; // ebx
int v10; // ebx
int v11; // eax
int v12; // eax
int v13; // eax
int v14; // [rsp+4h] [rbp-1044h]
int v15; // [rsp+8h] [rbp-1040h]
int v16; // [rsp+Ch] [rbp-103Ch]
char v17[4152]; // [rsp+10h] [rbp-1038h] BYREF

if ( !(unsigned int)func15(a1) )
return puts("Error: Tried to write to a file without having it opened");
v16 = file_descriptors[5 * a1 + 4];
v15 = func12(a1);
if ( a3 > 0 )
{
v5 = a3;
v14 = 0;
v6 = &file_descriptors[5 * a1];
do
{
read_blocks((unsigned int)(FAT[2 * v6[3]] + 3), 1LL, v17);
v8 = v6[4];
v9 = 4096 - v8;
if ( 4096 - v8 > v5 )
v9 = v5;
memcpy(&v17[v8], (const void *)(a2 + a3 - v5), v9);
write_blocks((unsigned int)(FAT[2 * v6[3]] + 3), 1LL);
v5 -= v9;
v10 = v6[4] + v9;
v6[4] = v10 % 4096;
if ( (v10 & 0xFFF) == 0 )
{
v11 = FAT[2 * v6[3] + 1];
if ( v11 == -1 )
{
v12 = func8();
if ( v12 == -1 )
return puts("Error: No more free blocks!!");
FAT[2 * v6[3] + 1] = v12;
FAT[2 * v12] = v12;
FAT[2 * v12 + 1] = -1;
v6[3] = v12;
v14 = 1;
}
else
{
v6[3] = v11;
}
}
}
while ( v5 > 0 );
v13 = func12(a1);
if ( v14 || v15 == v13 && file_descriptors[5 * a1 + 4] > v16 )
*((_DWORD *)&directory + 11 * (int)a1 + 8) = file_descriptors[5 * a1 + 4] + (v13 << 12);
}
func3();
func1();
return func5();
}

original_code:
void sfs_fwrite(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to write to a file without having it opened\n");
  return;
 }
 fd_entry* fd = &file_descriptors[fileID];
 int total_length = length;
 int file_has_new_blocks = 0;
 int old_write_offset = fd->write_offset;
 int old_block_offset = get_block_count(fileID);
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->write_block].start + 3, 1, current_block);
  int available_space = 4096 - fd->write_offset;
  int min = available_space > length ? length : available_space;
  memcpy(current_block+fd->write_offset , buf+(total_length-length) , min);
  write_blocks(FAT[fd->write_block].start + 3, 1,current_block);
  length -= min;
  fd->write_offset = (fd->write_offset +min ) % 4096;
  if (fd->write_offset == 0) {
   int next_write_block = FAT[fd->write_block].next;
   if (next_write_block != -1) {
    fd->write_block = next_write_block;
   }
   else
   {
    int next_free_block = get_free_block();
    if (next_free_block ==-1) {
     printf("Error: No more free blocks!!\n");
     return ;
    }
    FAT[fd->write_block].next = next_free_block;
    FAT[next_free_block].start = next_free_block;
    FAT[next_free_block].next = -1;
    fd->write_block = next_free_block;
    file_has_new_blocks = 1;
   }
  }
 }
 int current_block_count = get_block_count(fileID);
 if (file_has_new_blocks
  || (old_block_offset == current_block_count && old_write_offset < fd->write_offset))
 {
  directory[fileID].size = (current_block_count * 4096) + fd->write_offset;
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
}

canonical_original_code:
void sfs_fwrite(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to write to a file without having it opened\n");
  return;
 }
 struct fd_entry *fd = &file_descriptors[fileID];
 int total_length = length;
 int file_has_new_blocks = 0;
 int old_write_offset = fd->write_offset;
 int old_block_offset = get_block_count(fileID);
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->write_block].start + 3, 1, current_block);
  int available_space = 4096 - fd->write_offset;
  int min = available_space > length ? length : available_space;
  memcpy(current_block+fd->write_offset , buf+(total_length-length) , min);
  write_blocks(FAT[fd->write_block].start + 3, 1,current_block);
  length -= min;
  fd->write_offset = (fd->write_offset +min ) % 4096;
  if (fd->write_offset == 0) {
   int next_write_block = FAT[fd->write_block].next;
   if (next_write_block != -1) {
    fd->write_block = next_write_block;
   }
   else
   {
    int next_free_block = get_free_block();
    if (next_free_block ==-1) {
     printf("Error: No more free blocks!!\n");
     return ;
    }
    FAT[fd->write_block].next = next_free_block;
    FAT[next_free_block].start = next_free_block;
    FAT[next_free_block].next = -1;
    fd->write_block = next_free_block;
    file_has_new_blocks = 1;
   }
  }
 }
 int current_block_count = get_block_count(fileID);
 if (file_has_new_blocks
  || (old_block_offset == current_block_count && old_write_offset < fd->write_offset))
 {
  directory[fileID].size = (current_block_count * 4096) + fd->write_offset;
 }
 write_directory_to_disk();
 write_FAT_to_disk();
 write_free_list_to_disk();
}

variable_types: fileID int

variable_types:
buf
char *

variable_types: length int

variable_types: struct fd_entry { int root; int read_block; int read_offset; int write_block; int write_offset; } *

variable_types: min int


decompiled_code:
int __fastcall sfs_fread(unsigned int a1, __int64 a2, int a3)
{
int result; // eax
int v6; // ebp
int *v7; // r12
int v8; // esi
int v9; // ebx
int v10; // ebx
_BYTE v11[4136]; // [rsp+0h] [rbp-1028h] BYREF

if ( !(unsigned int)is_file_open(a1) )
return puts("Error: Tried to read a file without having it opened");
result = get_fd(a1);
if ( a3 > 0 )
{
v6 = a3;
v7 = &file_descriptors[5 * result];
do
{
read_blocks((unsigned int)(FAT[2 * v7[1]] + 3), 1LL, v11);
v8 = v7[2];
v9 = 4096 - v8;
if ( 4096 - v8 > v6 )
v9 = v6;
memcpy((void *)(a2 + a3 - v6), &v11[v8], v9);
v6 -= v9;
v10 = v7[2] + v9;
result = v10 % 4096;
v7[2] = v10 % 4096;
if ( (v10 & 0xFFF) == 0 )
{
result = FAT[2 * v7[1] + 1];
if ( result == -1 )
return puts("ERROR: No more blocks");
v7[1] = result;
}
}
while ( v6 > 0 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func19(unsigned int a1, __int64 a2, int a3)
{
int result; // eax
int v6; // ebp
int *v7; // r12
int v8; // esi
int v9; // ebx
int v10; // ebx
_BYTE v11[4136]; // [rsp+0h] [rbp-1028h] BYREF

if ( !(unsigned int)func15(a1) )
return puts("Error: Tried to read a file without having it opened");
result = func16(a1);
if ( a3 > 0 )
{
v6 = a3;
v7 = &file_descriptors[5 * result];
do
{
read_blocks((unsigned int)(FAT[2 * v7[1]] + 3), 1LL, v11);
v8 = v7[2];
v9 = 4096 - v8;
if ( 4096 - v8 > v6 )
v9 = v6;
memcpy((void *)(a2 + a3 - v6), &v11[v8], v9);
v6 -= v9;
v10 = v7[2] + v9;
result = v10 % 4096;
v7[2] = v10 % 4096;
if ( (v10 & 0xFFF) == 0 )
{
result = FAT[2 * v7[1] + 1];
if ( result == -1 )
return puts("ERROR: No more blocks");
v7[1] = result;
}
}
while ( v6 > 0 );
}
return result;
}

original_code:
void sfs_fread(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to read a file without having it opened\n");
  return;
 }
 fd_entry* fd = &file_descriptors[get_fd(fileID)];
 int total_length = length;
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->read_block].start + 3, 1, current_block);
  int min = 4096 - fd->read_offset > length ? length : 4096 - fd->read_offset;
  memcpy(buf+(total_length-length), current_block+fd->read_offset, min);
  length -= min;
  fd->read_offset = (fd->read_offset + min) % 4096;
  if (fd->read_offset == 0) {
   int next_read_block = FAT[fd->read_block].next;
   if (next_read_block == -1) {
    printf("ERROR: No more blocks\n");
    return;
   }
   fd->read_block = next_read_block;
  }
 }
}

canonical_original_code:
void sfs_fread(int fileID, char *buf, int length)
{
 if (!is_file_open(fileID)) {
  printf("Error: Tried to read a file without having it opened\n");
  return;
 }
 struct fd_entry *fd = &file_descriptors[get_fd(fileID)];
 int total_length = length;
 while (length > 0)
 {
  char current_block[4096];
  read_blocks(FAT[fd->read_block].start + 3, 1, current_block);
  int min = 4096 - fd->read_offset > length ? length : 4096 - fd->read_offset;
  memcpy(buf+(total_length-length), current_block+fd->read_offset, min);
  length -= min;
  fd->read_offset = (fd->read_offset + min) % 4096;
  if (fd->read_offset == 0) {
   int next_read_block = FAT[fd->read_block].next;
   if (next_read_block == -1) {
    printf("ERROR: No more blocks\n");
    return;
   }
   fd->read_block = next_read_block;
  }
 }
}

user_defined_types: struct fd_entry { int root; int read_block; int read_offset; int write_block; int write_offset; }


decompiled_code:
int __fastcall sfs_fseek(int a1, int a2)
{
int result; // eax
__int64 v3; // r9
int v4; // edx
__int64 v5; // rcx

result = file_descriptors[5 * a1];
if ( result != -1 )
{
v3 = 5LL * a1;
file_descriptors[v3 + 4] = a2 % 4096;
file_descriptors[v3 + 2] = a2 % 4096;
v4 = a2 / 4096;
if ( a2 / 4096 )
{
while ( 1 )
{
result = FAT[2 * result + 1];
if ( result == -1 )
break;
if ( !--v4 )
goto LABEL_5;
}
result = puts("Tried to seek past the end of file");
}
else
{
LABEL_5:
v5 = 5LL * a1;
file_descriptors[v5 + 1] = result;
file_descriptors[v5 + 3] = result;
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func20(int a1, int a2)
{
int result; // eax
__int64 v3; // r9
int v4; // edx
__int64 v5; // rcx

result = file_descriptors[5 * a1];
if ( result != -1 )
{
v3 = 5LL * a1;
file_descriptors[v3 + 4] = a2 % 4096;
file_descriptors[v3 + 2] = a2 % 4096;
v4 = a2 / 4096;
if ( a2 / 4096 )
{
while ( 1 )
{
result = FAT[2 * result + 1];
if ( result == -1 )
break;
if ( !--v4 )
goto LABEL_5;
}
result = puts("Tried to seek past the end of file");
}
else
{
LABEL_5:
v5 = 5LL * a1;
file_descriptors[v5 + 1] = result;
file_descriptors[v5 + 3] = result;
}
}
return result;
}

original_code:
void sfs_fseek(int fileID, int loc)
{
 if (file_descriptors[fileID].root == -1) {
  return;
 }
 file_descriptors[fileID].write_offset = loc%4096;
 file_descriptors[fileID].read_offset = loc%4096;
 int block_number = loc/4096;
 int current_block_index = file_descriptors[fileID].root;
 while (block_number != 0) {
  current_block_index = FAT[current_block_index].next;
  if (current_block_index == -1) {
   printf("Tried to seek past the end of file\n");
   return;
  }
  block_number--;
 }
 file_descriptors[fileID].read_block = current_block_index;
 file_descriptors[fileID].write_block = current_block_index;
}

variable_types: loc int


decompiled_code:
__int64 __fastcall sfs_remove(char *s2)
{
const char *v1; // rbp
int v2; // ebx
int i; // eax
__int64 v4; // rax

v1 = (const char *)&directory;
v2 = 0;
while ( strcmp(v1, s2) )
{
++v2;
v1 += 44;
if ( v2 == 93 )
return 0LL;
}
for ( i = *((_DWORD *)&directory + 11 * v2 + 10); i != -1; i = FAT[2 * i + 1] )
free_list[i] = 0;
v4 = 44LL * v2;
*(time_t *)((char *)&directory + v4) = 0LL;
*(time_t *)((char *)&directory + v4 + 8) = 0LL;
*(time_t *)((char *)&directory + v4 + 16) = 0LL;
*(time_t *)((char *)&directory + v4 + 24) = 0LL;
*(time_t *)((char *)&directory + v4 + 32) = 0LL;
*(_DWORD *)((char *)&directory + v4 + 40) = 0;
write_free_list_to_disk();
write_directory_to_disk();
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func21(char *s2)
{
const char *v1; // rbp
int v2; // ebx
int i; // eax
__int64 v4; // rax

v1 = (const char *)&directory;
v2 = 0;
while ( strcmp(v1, s2) )
{
++v2;
v1 += 44;
if ( v2 == 93 )
return 0LL;
}
for ( i = *((_DWORD *)&directory + 11 * v2 + 10); i != -1; i = FAT[2 * i + 1] )
free_list[i] = 0;
v4 = 44LL * v2;
*(time_t *)((char *)&directory + v4) = 0LL;
*(time_t *)((char *)&directory + v4 + 8) = 0LL;
*(time_t *)((char *)&directory + v4 + 16) = 0LL;
*(time_t *)((char *)&directory + v4 + 24) = 0LL;
*(time_t *)((char *)&directory + v4 + 32) = 0LL;
*(_DWORD *)((char *)&directory + v4 + 40) = 0;
func5();
func3();
return 0LL;
}

original_code:
int sfs_remove(char *file)
{
 int dir_index, file_exists = 0, i;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, file))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (file_exists) {
  int block_index = directory[dir_index].FAT_index;
  while (block_index != -1) {
   free_list[block_index] = 0;
   block_index = FAT[block_index].next;
  }
  memset(directory+dir_index, 0, sizeof(dir_entry));
  write_free_list_to_disk();
  write_directory_to_disk();
 }
 return 0;
}

canonical_original_code:
int sfs_remove(char *file)
{
 int dir_index; int file_exists = 0; int i;
 for (i=0; i < 93 && !file_exists; i++) {
  if(!strcmp(directory[i].fname, file))
  {
   dir_index = i;
   file_exists = 1;
  }
 }
 if (file_exists) {
  int block_index = directory[dir_index].FAT_index;
  while (block_index != -1) {
   free_list[block_index] = 0;
   block_index = FAT[block_index].next;
  }
  memset(directory+dir_index, 0, sizeof(dir_entry));
  write_free_list_to_disk();
  write_directory_to_disk();
 }
 return 0;
}

variable_types:
file
char *


decompiled_code:
__int64 close_disk()
{
if ( fp )
fclose(fp);
return 0LL;
}

canonical_decompiled_code:
__int64 func0()
{
if ( fp )
fclose(fp);
return 0LL;
}

original_code:
int close_disk()
{
    if(((void *)0) != fp)
    {
        fclose(fp);
    }
    return 0;
}


decompiled_code:
__int64 __fastcall init_fresh_disk(char *filename, int a2, int a3)
{
unsigned int v3; // eax
int v4; // ebp
__int64 result; // rax
int i; // ebx

L = 0LL;
p = LC1;
MAX_RETRY = 3;
BLOCK_SIZE = a2;
MAX_BLOCK = a3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "w+b");
if ( fp )
{
v4 = 0;
result = 0LL;
if ( MAX_BLOCK > 0 )
{
do
{
for ( i = 0; BLOCK_SIZE > i; ++i )
fputc(0, fp);
++v4;
}
while ( MAX_BLOCK > v4 );
result = 0LL;
}
}
else
{
printf("Could not create new disk file %s\n\n", filename);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *filename, int a2, int a3)
{
unsigned int v3; // eax
int v4; // ebp
__int64 result; // rax
int i; // ebx

L = 0LL;
p = LC1;
MAX_RETRY = 3;
BLOCK_SIZE = a2;
MAX_BLOCK = a3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "w+b");
if ( fp )
{
v4 = 0;
result = 0LL;
if ( MAX_BLOCK > 0 )
{
do
{
for ( i = 0; BLOCK_SIZE > i; ++i )
fputc(0, fp);
++v4;
}
while ( MAX_BLOCK > v4 );
result = 0LL;
}
}
else
{
printf("Could not create new disk file %s\n\n", filename);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int init_fresh_disk(char *filename, int block_size, int num_blocks)
{
    int i, j;
    L = 00000.f;
    p = -1.f;
    MAX_RETRY = 3;
    BLOCK_SIZE = block_size;
    MAX_BLOCK = num_blocks;
    srand((unsigned int)(time( 0 )) );
    fp = fopen (filename, "w+b");
    if (fp == ((void *)0))
    {
        printf("Could not create new disk file %s\n\n", filename);
        return -1;
    }
    for (i = 0; i < MAX_BLOCK; i++)
    {
        for (j = 0; j < BLOCK_SIZE; j++)
        {
            fputc(0, fp);
        }
    }
    return 0;
}

canonical_original_code:
int init_fresh_disk(char *filename, int block_size, int num_blocks)
{
    int i; int j;
    L = 00000.f;
    p = -1.f;
    MAX_RETRY = 3;
    BLOCK_SIZE = block_size;
    MAX_BLOCK = num_blocks;
    srand((unsigned int)(time( 0 )) );
    fp = fopen (filename, "w+b");
    if (fp == ((void *)0))
    {
        printf("Could not create new disk file %s\n\n", filename);
        return -1;
    }
    for (i = 0; i < MAX_BLOCK; i++)
    {
        for (j = 0; j < BLOCK_SIZE; j++)
        {
            fputc(0, fp);
        }
    }
    return 0;
}

variable_types:
filename
char *

variable_types: j int


decompiled_code:
__int64 __fastcall init_disk(char *filename, int a2, int a3)
{
unsigned int v3; // eax

L = 0LL;
p = LC1;
MAX_RETRY = 3;
BLOCK_SIZE = a2;
MAX_BLOCK = a3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "r+b");
if ( fp )
return 0LL;
printf("Could not open %s\n\n", filename);
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *filename, int a2, int a3)
{
unsigned int v3; // eax

L = 0LL;
p = LC1;
MAX_RETRY = 3;
BLOCK_SIZE = a2;
MAX_BLOCK = a3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "r+b");
if ( fp )
return 0LL;
printf("Could not open %s\n\n", filename);
return 0xFFFFFFFFLL;
}

original_code:
int init_disk(char *filename, int block_size, int num_blocks)
{
    L = 00000.f;
    p = -1.f;
    MAX_RETRY = 3;
    BLOCK_SIZE = block_size;
    MAX_BLOCK = num_blocks;
    srand((unsigned int)(time( 0 )) );
    fp = fopen (filename, "r+b");
    if (fp == ((void *)0))
    {
        printf("Could not open %s\n\n", filename);
        return -1;
    }
    return 0;
}


decompiled_code:
__int64 __fastcall read_blocks(int a1, int a2, __int64 a3)
{
unsigned int v3; // er14
int v5; // ebx
void *v6; // r12
int i; // ebp
int v8; // edx
int v9; // ebx
__int64 result; // rax

v3 = a2;
v5 = BLOCK_SIZE;
v6 = malloc(BLOCK_SIZE);
if ( a1 + a2 > MAX_BLOCK )
{
puts("out of bound error");
result = 0xFFFFFFFFLL;
}
else
{
fseek(fp, a1 * v5, 0);
if ( a2 <= 0 )
{
v3 = 0;
}
else
{
for ( i = 0; i != a2; ++i )
{
usleep((int)*(double *)&L);
fread(v6, BLOCK_SIZE, 1uLL, fp);
v8 = BLOCK_SIZE;
if ( BLOCK_SIZE > 0 )
{
v9 = 0;
do
{
memcpy((void *)(a3 + i * v8), v6, v8);
++v9;
v8 = BLOCK_SIZE;
}
while ( BLOCK_SIZE > v9 );
}
}
}
free(v6);
result = v3;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1, int a2, __int64 a3)
{
unsigned int v3; // er14
int v5; // ebx
void *v6; // r12
int i; // ebp
int v8; // edx
int v9; // ebx
__int64 result; // rax

v3 = a2;
v5 = BLOCK_SIZE;
v6 = malloc(BLOCK_SIZE);
if ( a1 + a2 > MAX_BLOCK )
{
puts("out of bound error");
result = 0xFFFFFFFFLL;
}
else
{
fseek(fp, a1 * v5, 0);
if ( a2 <= 0 )
{
v3 = 0;
}
else
{
for ( i = 0; i != a2; ++i )
{
usleep((int)*(double *)&L);
fread(v6, BLOCK_SIZE, 1uLL, fp);
v8 = BLOCK_SIZE;
if ( BLOCK_SIZE > 0 )
{
v9 = 0;
do
{
memcpy((void *)(a3 + i * v8), v6, v8);
++v9;
v8 = BLOCK_SIZE;
}
while ( BLOCK_SIZE > v9 );
}
}
}
free(v6);
result = v3;
}
return result;
}

original_code:
int read_blocks(int start_address, int nblocks, void *buffer)
{
    int i, j, e, s;
    e = 0;
    s = 0;
    void* blockRead = (void*) malloc(BLOCK_SIZE);
    if (start_address + nblocks > MAX_BLOCK)
    {
        printf("out of bound error\n");
        return -1;
    }
    fseek(fp, start_address * BLOCK_SIZE, 0);
    for (i = 0; i < nblocks; ++i)
    {
        usleep(L);
        s++;
        fread(blockRead, BLOCK_SIZE, 1, fp);
        for (j = 0; j < BLOCK_SIZE; j++)
        {
            memcpy(buffer+(i*BLOCK_SIZE), blockRead, BLOCK_SIZE);
        }
    }
    free(blockRead);
    if (e == 0)
        return s;
    else
        return e;
}

canonical_original_code:
int read_blocks(int start_address, int nblocks, void *buffer)
{
    int i; int j; int e; int s;
    e = 0;
    s = 0;
    void *blockRead = (void*) malloc(BLOCK_SIZE);
    if (start_address + nblocks > MAX_BLOCK)
    {
        printf("out of bound error\n");
        return -1;
    }
    fseek(fp, start_address * BLOCK_SIZE, 0);
    for (i = 0; i < nblocks; ++i)
    {
        usleep(L);
        s++;
        fread(blockRead, BLOCK_SIZE, 1, fp);
        for (j = 0; j < BLOCK_SIZE; j++)
        {
            memcpy(buffer+(i*BLOCK_SIZE), blockRead, BLOCK_SIZE);
        }
    }
    free(blockRead);
    if (e == 0)
        return s;
    else
        return e;
}

variable_types: nblocks int

variable_types:
buffer
void *

variable_types: e int

variable_types: s int

variable_types:
blockRead
void *


decompiled_code:
__int64 __fastcall write_blocks(int a1, int a2, __int64 a3)
{
unsigned int v3; // er13
int v5; // ebx
void *v6; // r12
int i; // ebx
size_t v8; // rbp
__int64 result; // rax

v3 = a2;
v5 = BLOCK_SIZE;
v6 = malloc(BLOCK_SIZE);
if ( a1 + a2 > MAX_BLOCK )
{
puts("out of bound error");
result = 0xFFFFFFFFLL;
}
else
{
fseek(fp, a1 * v5, 0);
if ( a2 <= 0 )
{
v3 = 0;
}
else
{
for ( i = 0; i != a2; ++i )
{
usleep((int)*(double *)&L);
v8 = BLOCK_SIZE;
memcpy(v6, (const void *)(a3 + i * BLOCK_SIZE), BLOCK_SIZE);
fwrite(v6, v8, 1uLL, fp);
}
}
free(v6);
result = v3;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, int a2, __int64 a3)
{
unsigned int v3; // er13
int v5; // ebx
void *v6; // r12
int i; // ebx
size_t v8; // rbp
__int64 result; // rax

v3 = a2;
v5 = BLOCK_SIZE;
v6 = malloc(BLOCK_SIZE);
if ( a1 + a2 > MAX_BLOCK )
{
puts("out of bound error");
result = 0xFFFFFFFFLL;
}
else
{
fseek(fp, a1 * v5, 0);
if ( a2 <= 0 )
{
v3 = 0;
}
else
{
for ( i = 0; i != a2; ++i )
{
usleep((int)*(double *)&L);
v8 = BLOCK_SIZE;
memcpy(v6, (const void *)(a3 + i * BLOCK_SIZE), BLOCK_SIZE);
fwrite(v6, v8, 1uLL, fp);
}
}
free(v6);
result = v3;
}
return result;
}

original_code:
int write_blocks(int start_address, int nblocks, void *buffer)
{
    int i, e, s;
    e = 0;
    s = 0;
    void* blockWrite = (void*) malloc(BLOCK_SIZE);
    if (start_address + nblocks > MAX_BLOCK)
    {
        printf("out of bound error\n");
        return -1;
    }
    fseek(fp, start_address * BLOCK_SIZE, 0);
    for (i = 0; i < nblocks; ++i)
    {
        usleep(L);
        memcpy(blockWrite, buffer+(i*BLOCK_SIZE), BLOCK_SIZE);
        fwrite(blockWrite, BLOCK_SIZE, 1, fp);
        s++;
    }
    free(blockWrite);
    if (e == 0)
        return s;
    else
        return e;
}

canonical_original_code:
int write_blocks(int start_address, int nblocks, void *buffer)
{
    int i; int e; int s;
    e = 0;
    s = 0;
    void *blockWrite = (void*) malloc(BLOCK_SIZE);
    if (start_address + nblocks > MAX_BLOCK)
    {
        printf("out of bound error\n");
        return -1;
    }
    fseek(fp, start_address * BLOCK_SIZE, 0);
    for (i = 0; i < nblocks; ++i)
    {
        usleep(L);
        memcpy(blockWrite, buffer+(i*BLOCK_SIZE), BLOCK_SIZE);
        fwrite(blockWrite, BLOCK_SIZE, 1, fp);
        s++;
    }
    free(blockWrite);
    if (e == 0)
        return s;
    else
        return e;
}

variable_types:
blockWrite
void *


repo: adamdunkels/ubasic

decompiled_code:
void index_free()
{
void *v0; // rdi

if ( line_index_head )
{
line_index_current = (void *)line_index_head;
do
{
v0 = line_index_current;
line_index_head = (__int64)line_index_current;
line_index_current = (void *)*((_QWORD *)line_index_current + 2);
free(v0);
}
while ( line_index_current );
line_index_head = 0LL;
}
}

canonical_decompiled_code:
void func1()
{
void *v0; // rdi

if ( line_index_head )
{
line_index_current = (void *)line_index_head;
do
{
v0 = line_index_current;
line_index_head = (__int64)line_index_current;
line_index_current = (void *)*((_QWORD *)line_index_current + 2);
free(v0);
}
while ( line_index_current );
line_index_head = 0LL;
}
}

original_code:
static void
index_free(void) {
  if(line_index_head != ((void *)0)) {
    line_index_current = line_index_head;
    do {
      ;
      line_index_head = line_index_current;
      line_index_current = line_index_current->next;
      free(line_index_head);
    } while (line_index_current != ((void *)0));
    line_index_head = ((void *)0);
  }
}

canonical_original_code:
static void index_free() {
  if(line_index_head != ((void *)0)) {
    line_index_current = line_index_head;
    do {
      ;
      line_index_head = line_index_current;
      line_index_current = line_index_current->next;
      free(line_index_head);
    } while (line_index_current != ((void *)0));
    line_index_head = ((void *)0);
  }
}


accept

decompiled_code:
__int64 __fastcall accept(int a1)
{
if ( (unsigned int)tokenizer_token() != a1 )
{
tokenizer_error_print();
exit(1);
}
return tokenizer_next();
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1)
{
if ( (unsigned int)tokenizer_token() != a1 )
{
tokenizer_error_print();
exit(1);
}
return tokenizer_next();
}

original_code:
static void
accept(int token)
{
  if(token != tokenizer_token()) {
    ;
    tokenizer_error_print();
    exit(1);
  }
  ;
  tokenizer_next();
}

variable_types: token int


decompiled_code:
__int64 end_statement()
{
__int64 result; // rax

result = accept(20);
ended = 1;
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 result; // rax

result = func2(20);
ended = 1;
return result;
}

original_code:
static void
end_statement(void)
{
  accept(TOKENIZER_END);
  ended = 1;
}

canonical_original_code:
static void end_statement()
{
  accept(TOKENIZER_END);
  ended = 1;
}


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

tokenizer_init(program_ptr);
while ( 1 )
{
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result == a1 )
break;
do
{
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 36 && (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
}
while ( (unsigned int)tokenizer_token() != 2 );
}
return result;
}

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

tokenizer_init(program_ptr);
while ( 1 )
{
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result == a1 )
break;
do
{
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 36 && (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
}
while ( (unsigned int)tokenizer_token() != 2 );
}
return result;
}

original_code:
static void
jump_linenum_slow(int linenum)
{
  tokenizer_init(program_ptr);
  while(tokenizer_num() != linenum) {
    do {
      do {
        tokenizer_next();
      } while(tokenizer_token() != TOKENIZER_CR &&
          tokenizer_token() != TOKENIZER_ENDOFINPUT);
      if(tokenizer_token() == TOKENIZER_CR) {
        tokenizer_next();
      }
    } while(tokenizer_token() != TOKENIZER_NUMBER);
    ;
  }
}

variable_types: linenum int


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

v1 = index_find(a1);
if ( v1 )
result = tokenizer_goto(v1);
else
result = jump_linenum_slow(a1);
return result;
}

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

v1 = func0(a1);
if ( v1 )
result = tokenizer_goto(v1);
else
result = func4(a1);
return result;
}

original_code:
static void
jump_linenum(int linenum)
{
  char const* pos = index_find(linenum);
  if(pos != ((void *)0)) {
    ;
    tokenizer_goto(pos);
  } else {
    ;
    jump_linenum_slow(linenum);
  }
}

canonical_original_code:
static void jump_linenum(int linenum)
{
  char *pos = index_find(linenum);
  if(pos != ((void *)0)) {
    ;
    tokenizer_goto(pos);
  } else {
    ;
    jump_linenum_slow(linenum);
  }
}

variable_types:
pos
char *


decompiled_code:
__int64 goto_statement()
{
char v0; // al

accept(13);
v0 = tokenizer_num();
return jump_linenum(v0);
}

canonical_decompiled_code:
__int64 func6()
{
char v0; // al

func2(13);
v0 = tokenizer_num();
return func5(v0);
}

original_code:
static void
goto_statement(void)
{
  accept(TOKENIZER_GOTO);
  jump_linenum(tokenizer_num());
}

canonical_original_code:
static void goto_statement()
{
  accept(TOKENIZER_GOTO);
  jump_linenum(tokenizer_num());
}


decompiled_code:
__int64 gosub_statement()
{
char v0; // bl
__int64 result; // rax
char v2; // dl
int v3; // eax

accept(14);
v0 = tokenizer_num();
accept(2);
result = accept(36);
if ( gosub_stack_ptr <= 9 )
{
v2 = tokenizer_num();
v3 = gosub_stack_ptr;
gosub_stack[gosub_stack_ptr] = v2;
gosub_stack_ptr = v3 + 1;
result = jump_linenum(v0);
}
return result;
}

canonical_decompiled_code:
__int64 func7()
{
char v0; // bl
__int64 result; // rax
char v2; // dl
int v3; // eax

func2(14);
v0 = tokenizer_num();
func2(2);
result = func2(36);
if ( gosub_stack_ptr <= 9 )
{
v2 = tokenizer_num();
v3 = gosub_stack_ptr;
gosub_stack[gosub_stack_ptr] = v2;
gosub_stack_ptr = v3 + 1;
result = func5(v0);
}
return result;
}

original_code:
static void
gosub_statement(void)
{
  int linenum;
  accept(TOKENIZER_GOSUB);
  linenum = tokenizer_num();
  accept(TOKENIZER_NUMBER);
  accept(TOKENIZER_CR);
  if(gosub_stack_ptr < 10) {
    gosub_stack[gosub_stack_ptr] = tokenizer_num();
    gosub_stack_ptr++;
    jump_linenum(linenum);
  } else {
    ;
  }
}

canonical_original_code:
static void gosub_statement()
{
  int linenum;
  accept(TOKENIZER_GOSUB);
  linenum = tokenizer_num();
  accept(TOKENIZER_NUMBER);
  accept(TOKENIZER_CR);
  if(gosub_stack_ptr < 10) {
    gosub_stack[gosub_stack_ptr] = tokenizer_num();
    gosub_stack_ptr++;
    jump_linenum(linenum);
  } else {
    ;
  }
}


decompiled_code:
__int64 return_statement()
{
__int64 result; // rax

accept(15);
result = (unsigned int)gosub_stack_ptr;
if ( gosub_stack_ptr > 0 )
{
--gosub_stack_ptr;
result = jump_linenum(gosub_stack[(int)result - 1]);
}
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 result; // rax

func2(15);
result = (unsigned int)gosub_stack_ptr;
if ( gosub_stack_ptr > 0 )
{
--gosub_stack_ptr;
result = func5(gosub_stack[(int)result - 1]);
}
return result;
}

original_code:
static void
return_statement(void)
{
  accept(TOKENIZER_RETURN);
  if(gosub_stack_ptr > 0) {
    gosub_stack_ptr--;
    jump_linenum(gosub_stack[gosub_stack_ptr]);
  } else {
    ;
  }
}

canonical_original_code:
static void return_statement()
{
  accept(TOKENIZER_RETURN);
  if(gosub_stack_ptr > 0) {
    gosub_stack_ptr--;
    jump_linenum(gosub_stack[gosub_stack_ptr]);
  } else {
    ;
  }
}


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

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
index_free();
result = tokenizer_init(a1);
ended = 0;
return result;
}

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

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
func1();
result = tokenizer_init(a1);
ended = 0;
return result;
}

original_code:
void
ubasic_init(const char *program)
{
  program_ptr = program;
  for_stack_ptr = gosub_stack_ptr = 0;
  index_free();
  tokenizer_init(program);
  ended = 0;
}

canonical_original_code:
void ubasic_init(char *program)
{
  program_ptr = program;
  for_stack_ptr = gosub_stack_ptr = 0;
  index_free();
  tokenizer_init(program);
  ended = 0;
}

variable_types:
program
char *


decompiled_code:
__int64 __fastcall ubasic_init_peek_poke(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
index_free();
peek_function = a2;
poke_function = a3;
result = tokenizer_init(a1);
ended = 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
func1();
peek_function = a2;
poke_function = a3;
result = tokenizer_init(a1);
ended = 0;
return result;
}

original_code:
void
ubasic_init_peek_poke(const char *program, peek_func peek, poke_func poke)
{
  program_ptr = program;
  for_stack_ptr = gosub_stack_ptr = 0;
  index_free();
  peek_function = peek;
  poke_function = poke;
  tokenizer_init(program);
  ended = 0;
}

canonical_original_code:
void ubasic_init_peek_poke(char *program, char (*peek)(char), void (*poke)(char, char))
{
  program_ptr = program;
  for_stack_ptr = gosub_stack_ptr = 0;
  index_free();
  peek_function = peek;
  poke_function = poke;
  tokenizer_init(program);
  ended = 0;
}

variable_types:
peek
char (*)(char)

variable_types:
poke
void (*)(char, char)


decompiled_code:
_BOOL8 ubasic_finished()
{
_BOOL8 result; // rax

result = 1LL;
if ( !ended )
result = (unsigned int)tokenizer_finished() != 0;
return result;
}

canonical_decompiled_code:
_BOOL8 func11()
{
_BOOL8 result; // rax

result = 1LL;
if ( !ended )
result = (unsigned int)tokenizer_finished() != 0;
return result;
}

original_code:
int
ubasic_finished(void)
{
  return ended || tokenizer_finished();
}

canonical_original_code:
int ubasic_finished()
{
  return ended || tokenizer_finished();
}


decompiled_code:
void __fastcall ubasic_set_variable(unsigned int a1, char a2)
{
if ( a1 <= 0x1A )
variables[a1] = a2;
}

canonical_decompiled_code:
void __fastcall func12(unsigned int a1, char a2)
{
if ( a1 <= 0x1A )
variables[a1] = a2;
}

original_code:
void
ubasic_set_variable(int varnum, char value)
{
  if(varnum >= 0 && varnum <= 26) {
    variables[varnum] = value;
  }
}

variable_types: varnum int

variable_types: value char