decompiled_code:
int __fastcall sfs_fseek(int a1, int a2)
{
__int64 v3; // rax
int v4; // esi
int v5; // esi
int *v6; // rdx

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

canonical_decompiled_code:
int __fastcall func20(int a1, int a2)
{
__int64 v3; // rax
int v4; // esi
int v5; // esi
int *v6; // rdx

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

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


repo: acourt/OS-Assignments

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

v1 = (const char *)&directory;
v2 = 0;
while ( strcmp(v1, s2) )
{
++v2;
v1 += 44;
if ( v2 == 93 )
return 0LL;
}
for ( i = *((int *)&directory + 11 * v2 + 10); (_DWORD)i != -1; i = FAT[2 * i + 1] )
free_list[i] = 0;
v4 = 44LL * v2;
*(time_t *)((char *)&directory + v4 + 32) = 0LL;
*(_DWORD *)((char *)&directory + v4 + 40) = 0;
*(_OWORD *)((char *)&directory + v4) = 0LL;
*(_OWORD *)((char *)&directory + v4 + 16) = 0LL;
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
__int64 i; // rax
__int64 v4; // rax

v1 = (const char *)&directory;
v2 = 0;
while ( strcmp(v1, s2) )
{
++v2;
v1 += 44;
if ( v2 == 93 )
return 0LL;
}
for ( i = *((int *)&directory + 11 * v2 + 10); (_DWORD)i != -1; i = FAT[2 * i + 1] )
free_list[i] = 0;
v4 = 44LL * v2;
*(time_t *)((char *)&directory + v4 + 32) = 0LL;
*(_DWORD *)((char *)&directory + v4 + 40) = 0;
*(_OWORD *)((char *)&directory + v4) = 0LL;
*(_OWORD *)((char *)&directory + v4 + 16) = 0LL;
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 *

variable_types: i int

return_type: int


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 i; // ebp
int j; // ebx
__int64 result; // rax

BLOCK_SIZE = a2;
MAX_BLOCK = a3;
L = 0LL;
p = LC1;
MAX_RETRY = 3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "w+b");
if ( fp )
{
for ( i = 0; MAX_BLOCK > i; ++i )
{
for ( j = 0; BLOCK_SIZE > j; ++j )
fputc(0, fp);
}
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 i; // ebp
int j; // ebx
__int64 result; // rax

BLOCK_SIZE = a2;
MAX_BLOCK = a3;
L = 0LL;
p = LC1;
MAX_RETRY = 3;
v3 = time(0LL);
srand(v3);
fp = fopen(filename, "w+b");
if ( fp )
{
for ( i = 0; MAX_BLOCK > i; ++i )
{
for ( j = 0; BLOCK_SIZE > j; ++j )
fputc(0, fp);
}
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

BLOCK_SIZE = a2;
MAX_BLOCK = a3;
L = 0LL;
p = LC1;
MAX_RETRY = 3;
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

BLOCK_SIZE = a2;
MAX_BLOCK = a3;
L = 0LL;
p = LC1;
MAX_RETRY = 3;
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; // rbp
int v7; // er13
int v8; // ebx
size_t v9; // rdx
int v10; // er15
__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
{
v7 = 0;
do
{
v8 = v7++;
usleep((int)*(double *)&L);
fread(v6, BLOCK_SIZE, 1uLL, fp);
v9 = BLOCK_SIZE;
if ( BLOCK_SIZE > 0 )
{
v10 = 0;
do
{
++v10;
memcpy((void *)(a3 + v8 * (int)v9), v6, v9);
v9 = BLOCK_SIZE;
}
while ( BLOCK_SIZE > v10 );
}
}
while ( a2 != v7 );
}
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; // rbp
int v7; // er13
int v8; // ebx
size_t v9; // rdx
int v10; // er15
__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
{
v7 = 0;
do
{
v8 = v7++;
usleep((int)*(double *)&L);
fread(v6, BLOCK_SIZE, 1uLL, fp);
v9 = BLOCK_SIZE;
if ( BLOCK_SIZE > 0 )
{
v10 = 0;
do
{
++v10;
memcpy((void *)(a3 + v8 * (int)v9), v6, v9);
v9 = BLOCK_SIZE;
}
while ( BLOCK_SIZE > v10 );
}
}
while ( a2 != v7 );
}
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 v4; // er12
int v5; // ebx
void *v6; // rbp
int v7; // ebx
size_t v8; // r14
int v9; // esi
__int64 result; // rax

v4 = 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 )
{
v4 = 0;
}
else
{
v7 = 0;
do
{
usleep((int)*(double *)&L);
v8 = BLOCK_SIZE;
v9 = v7 * BLOCK_SIZE;
++v7;
memcpy(v6, (const void *)(a3 + v9), BLOCK_SIZE);
fwrite(v6, v8, 1uLL, fp);
}
while ( v4 != v7 );
}
free(v6);
result = v4;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, int a2, __int64 a3)
{
unsigned int v4; // er12
int v5; // ebx
void *v6; // rbp
int v7; // ebx
size_t v8; // r14
int v9; // esi
__int64 result; // rax

v4 = 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 )
{
v4 = 0;
}
else
{
v7 = 0;
do
{
usleep((int)*(double *)&L);
v8 = BLOCK_SIZE;
v9 = v7 * BLOCK_SIZE;
++v7;
memcpy(v6, (const void *)(a3 + v9), BLOCK_SIZE);
fwrite(v6, v8, 1uLL, fp);
}
while ( v4 != v7 );
}
free(v6);
result = v4;
}
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()
{
_QWORD *v0; // rdi
__int64 v1; // rax

v0 = line_index_head;
if ( line_index_head )
{
do
{
v1 = v0[2];
line_index_head = v0;
line_index_current = v1;
free(v0);
v0 = (_QWORD *)line_index_current;
}
while ( line_index_current );
line_index_head = 0LL;
}
}

canonical_decompiled_code:
void func0()
{
_QWORD *v0; // rdi
__int64 v1; // rax

v0 = line_index_head;
if ( line_index_head )
{
do
{
v1 = v0[2];
line_index_head = v0;
line_index_current = v1;
free(v0);
v0 = (_QWORD *)line_index_current;
}
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);
  }
}

return_type: void


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 func1(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 func2()
{
__int64 result; // rax

result = func1(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);
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result != a1 )
{
while ( 1 )
{
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 36 && (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
if ( (unsigned int)tokenizer_token() == 2 )
{
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result == a1 )
break;
}
}
}
return result;
}

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

tokenizer_init(program_ptr);
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result != a1 )
{
while ( 1 )
{
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 36 && (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
if ( (unsigned int)tokenizer_token() == 2 )
{
result = (unsigned int)(char)tokenizer_num();
if ( (_DWORD)result == a1 )
break;
}
}
}
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)
{
_QWORD *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 func4(int a1)
{
_QWORD *v1; // rax
__int64 result; // rax

v1 = index_find(a1);
if ( v1 )
result = tokenizer_goto(v1);
else
result = func3(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 func5()
{
char v0; // al

func1(13);
v0 = tokenizer_num();
return func4(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
int v2; // edx
int v3; // eax

accept(14);
v0 = tokenizer_num();
accept(2);
result = accept(36);
if ( gosub_stack_ptr <= 9 )
{
v2 = (char)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 func6()
{
char v0; // bl
__int64 result; // rax
int v2; // edx
int v3; // eax

func1(14);
v0 = tokenizer_num();
func1(2);
result = func1(36);
if ( gosub_stack_ptr <= 9 )
{
v2 = (char)tokenizer_num();
v3 = gosub_stack_ptr;
gosub_stack[gosub_stack_ptr] = v2;
gosub_stack_ptr = v3 + 1;
result = func4(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 func7()
{
__int64 result; // rax

func1(15);
result = (unsigned int)gosub_stack_ptr;
if ( gosub_stack_ptr > 0 )
{
--gosub_stack_ptr;
result = func4(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 func8(__int64 a1)
{
__int64 result; // rax

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
func0();
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 func9(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

program_ptr = a1;
gosub_stack_ptr = 0;
for_stack_ptr = 0;
func0();
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

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

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

if ( ended )
result = 1LL;
else
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 func11(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


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

result = 0LL;
if ( a1 <= 0x1A )
result = (unsigned __int8)variables[a1];
return result;
}

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

result = 0LL;
if ( a1 <= 0x1A )
result = (unsigned __int8)variables[a1];
return result;
}

original_code:
char
ubasic_get_variable(int varnum)
{
  if(varnum >= 0 && varnum <= 26) {
    return variables[varnum];
  }
  return 0;
}

return_type: char


varfactor

decompiled_code:
__int64 varfactor()
{
unsigned int v0; // eax
char v1; // bl

v0 = tokenizer_variable_num();
v1 = ubasic_get_variable(v0);
accept(4);
return (unsigned int)v1;
}

canonical_decompiled_code:
__int64 func13()
{
unsigned int v0; // eax
char v1; // bl

v0 = tokenizer_variable_num();
v1 = func12(v0);
func1(4);
return (unsigned int)v1;
}

original_code:
static int
varfactor(void)
{
  int r;
  ;
  r = ubasic_get_variable(tokenizer_variable_num());
  accept(TOKENIZER_VARIABLE);
  return r;
}

canonical_original_code:
static int varfactor()
{
  int r;
  ;
  r = ubasic_get_variable(tokenizer_variable_num());
  accept(TOKENIZER_VARIABLE);
  return r;
}

variable_types: r int


factor

decompiled_code:
__int64 factor()
{
int v0; // eax
__int64 result; // rax
unsigned int v2; // er12
unsigned int v3; // er12

v0 = tokenizer_token();
if ( v0 == 2 )
{
v2 = (char)tokenizer_num();
accept(2);
result = v2;
}
else if ( v0 == 31 )
{
accept(31);
v3 = (char)expr();
accept(32);
result = v3;
}
else
{
result = varfactor();
}
return result;
}

canonical_decompiled_code:
__int64 func14()
{
int v0; // eax
__int64 result; // rax
unsigned int v2; // er12
unsigned int v3; // er12

v0 = tokenizer_token();
if ( v0 == 2 )
{
v2 = (char)tokenizer_num();
func1(2);
result = v2;
}
else if ( v0 == 31 )
{
func1(31);
v3 = (char)func16();
func1(32);
result = v3;
}
else
{
result = func13();
}
return result;
}

original_code:
static int
factor(void)
{
  int r;
  ;
  switch(tokenizer_token()) {
  case TOKENIZER_NUMBER:
    r = tokenizer_num();
    ;
    accept(TOKENIZER_NUMBER);
    break;
  case TOKENIZER_LEFTPAREN:
    accept(TOKENIZER_LEFTPAREN);
    r = expr();
    accept(TOKENIZER_RIGHTPAREN);
    break;
  default:
    r = varfactor();
    break;
  }
  return r;
}

canonical_original_code:
static int factor()
{
  int r;
  ;
  switch(tokenizer_token()) {
  case TOKENIZER_NUMBER:
    r = tokenizer_num();
    ;
    accept(TOKENIZER_NUMBER);
    break;
  case TOKENIZER_LEFTPAREN:
    accept(TOKENIZER_LEFTPAREN);
    r = expr();
    accept(TOKENIZER_RIGHTPAREN);
    break;
  default:
    r = varfactor();
    break;
  }
  return r;
}


term

decompiled_code:
__int64 term()
{
unsigned int v0; // er12
int v1; // ebx
int v2; // eax

v0 = factor();
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) <= 2 )
{
while ( 1 )
{
tokenizer_next();
v2 = factor();
if ( v1 == 28 )
break;
if ( v1 == 29 )
{
v0 = (int)v0 % v2;
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) > 2 )
return v0;
}
else
{
v0 *= v2;
LABEL_4:
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) > 2 )
return v0;
}
}
v0 = (int)v0 / v2;
goto LABEL_4;
}
return v0;
}

canonical_decompiled_code:
__int64 func15()
{
unsigned int v0; // er12
int v1; // ebx
int v2; // eax

v0 = func14();
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) <= 2 )
{
while ( 1 )
{
tokenizer_next();
v2 = func14();
if ( v1 == 28 )
break;
if ( v1 == 29 )
{
v0 = (int)v0 % v2;
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) > 2 )
return v0;
}
else
{
v0 *= v2;
LABEL_4:
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 27) > 2 )
return v0;
}
}
v0 = (int)v0 / v2;
goto LABEL_4;
}
return v0;
}

original_code:
static int
term(void)
{
  int f1, f2;
  int op;
  f1 = factor();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_ASTR ||
       op == TOKENIZER_SLASH ||
       op == TOKENIZER_MOD) {
    tokenizer_next();
    f2 = factor();
    ;
    switch(op) {
    case TOKENIZER_ASTR:
      f1 = f1 * f2;
      break;
    case TOKENIZER_SLASH:
      f1 = f1 / f2;
      break;
    case TOKENIZER_MOD:
      f1 = f1 % f2;
      break;
    }
    op = tokenizer_token();
  }
  ;
  return f1;
}

canonical_original_code:
static int term()
{
  int f1; int f2;
  int op;
  f1 = factor();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_ASTR ||
       op == TOKENIZER_SLASH ||
       op == TOKENIZER_MOD) {
    tokenizer_next();
    f2 = factor();
    ;
    switch(op) {
    case TOKENIZER_ASTR:
      f1 = f1 * f2;
      break;
    case TOKENIZER_SLASH:
      f1 = f1 / f2;
      break;
    case TOKENIZER_MOD:
      f1 = f1 % f2;
      break;
    }
    op = tokenizer_token();
  }
  ;
  return f1;
}

variable_types: op int


expr

decompiled_code:
__int64 expr()
{
unsigned int v0; // ebp
int i; // ebx
unsigned int v2; // ecx
int v3; // eax

v0 = term();
for ( i = tokenizer_token(); (unsigned int)(i - 23) <= 3; i = tokenizer_token() )
{
while ( 1 )
{
tokenizer_next();
v3 = term();
if ( i != 25 )
break;
v0 &= v3;
LABEL_5:
i = tokenizer_token();
if ( (unsigned int)(i - 23) > 3 )
return v0;
}
if ( i != 26 )
{
v2 = v0 + v3;
v0 -= v3;
if ( i != 24 )
v0 = v2;
goto LABEL_5;
}
v0 |= v3;
}
return v0;
}

canonical_decompiled_code:
__int64 func16()
{
unsigned int v0; // ebp
int i; // ebx
unsigned int v2; // ecx
int v3; // eax

v0 = func15();
for ( i = tokenizer_token(); (unsigned int)(i - 23) <= 3; i = tokenizer_token() )
{
while ( 1 )
{
tokenizer_next();
v3 = func15();
if ( i != 25 )
break;
v0 &= v3;
LABEL_5:
i = tokenizer_token();
if ( (unsigned int)(i - 23) > 3 )
return v0;
}
if ( i != 26 )
{
v2 = v0 + v3;
v0 -= v3;
if ( i != 24 )
v0 = v2;
goto LABEL_5;
}
v0 |= v3;
}
return v0;
}

original_code:
static char
expr(void)
{
  int t1, t2;
  int op;
  t1 = term();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_PLUS ||
       op == TOKENIZER_MINUS ||
       op == TOKENIZER_AND ||
       op == TOKENIZER_OR) {
    tokenizer_next();
    t2 = term();
    ;
    switch(op) {
    case TOKENIZER_PLUS:
      t1 = t1 + t2;
      break;
    case TOKENIZER_MINUS:
      t1 = t1 - t2;
      break;
    case TOKENIZER_AND:
      t1 = t1 & t2;
      break;
    case TOKENIZER_OR:
      t1 = t1 | t2;
      break;
    }
    op = tokenizer_token();
  }
  ;
  return t1;
}

canonical_original_code:
static char expr()
{
  int t1; int t2;
  int op;
  t1 = term();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_PLUS ||
       op == TOKENIZER_MINUS ||
       op == TOKENIZER_AND ||
       op == TOKENIZER_OR) {
    tokenizer_next();
    t2 = term();
    ;
    switch(op) {
    case TOKENIZER_PLUS:
      t1 = t1 + t2;
      break;
    case TOKENIZER_MINUS:
      t1 = t1 - t2;
      break;
    case TOKENIZER_AND:
      t1 = t1 & t2;
      break;
    case TOKENIZER_OR:
      t1 = t1 | t2;
      break;
    }
    op = tokenizer_token();
  }
  ;
  return t1;
}


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

accept(6);
while ( (unsigned int)tokenizer_token() == 3 )
{
tokenizer_string(string, 40LL);
printf("%s", string);
tokenizer_next();
if ( (unsigned int)tokenizer_token() == 36 )
goto LABEL_11;
LABEL_8:
if ( (unsigned int)tokenizer_token() == 1 )
goto LABEL_11;
}
if ( (unsigned int)tokenizer_token() == 21 )
{
putchar(32);
tokenizer_next();
goto LABEL_7;
}
if ( (unsigned int)tokenizer_token() == 22 )
{
tokenizer_next();
LABEL_7:
if ( (unsigned int)tokenizer_token() == 36 )
goto LABEL_11;
goto LABEL_8;
}
if ( (unsigned int)tokenizer_token() == 4 || (unsigned int)tokenizer_token() == 2 )
{
v0 = expr();
printf("%d", (unsigned int)v0);
goto LABEL_7;
}
LABEL_11:
putchar(10);
return tokenizer_next();
}

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

func1(6);
while ( (unsigned int)tokenizer_token() == 3 )
{
tokenizer_string(string, 40LL);
printf("%s", string);
tokenizer_next();
if ( (unsigned int)tokenizer_token() == 36 )
goto LABEL_11;
LABEL_8:
if ( (unsigned int)tokenizer_token() == 1 )
goto LABEL_11;
}
if ( (unsigned int)tokenizer_token() == 21 )
{
putchar(32);
tokenizer_next();
goto LABEL_7;
}
if ( (unsigned int)tokenizer_token() == 22 )
{
tokenizer_next();
LABEL_7:
if ( (unsigned int)tokenizer_token() == 36 )
goto LABEL_11;
goto LABEL_8;
}
if ( (unsigned int)tokenizer_token() == 4 || (unsigned int)tokenizer_token() == 2 )
{
v0 = func16();
printf("%d", (unsigned int)v0);
goto LABEL_7;
}
LABEL_11:
putchar(10);
return tokenizer_next();
}

original_code:
static void
print_statement(void)
{
  accept(TOKENIZER_PRINT);
  do {
    ;
    if(tokenizer_token() == TOKENIZER_STRING) {
      tokenizer_string(string, sizeof(string));
      printf("%s", string);
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_COMMA) {
      printf(" ");
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_SEMICOLON) {
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_VARIABLE ||
          tokenizer_token() == TOKENIZER_NUMBER) {
      printf("%d", expr());
    } else {
      break;
    }
  } while(tokenizer_token() != TOKENIZER_CR &&
      tokenizer_token() != TOKENIZER_ENDOFINPUT);
  printf("\n");
  ;
  tokenizer_next();
}

canonical_original_code:
static void print_statement()
{
  accept(TOKENIZER_PRINT);
  do {
    ;
    if(tokenizer_token() == TOKENIZER_STRING) {
      tokenizer_string(string, sizeof(string));
      printf("%s", string);
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_COMMA) {
      printf(" ");
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_SEMICOLON) {
      tokenizer_next();
    } else if(tokenizer_token() == TOKENIZER_VARIABLE ||
          tokenizer_token() == TOKENIZER_NUMBER) {
      printf("%d", expr());
    } else {
      break;
    }
  } while(tokenizer_token() != TOKENIZER_CR &&
      tokenizer_token() != TOKENIZER_ENDOFINPUT);
  printf("\n");
  ;
  tokenizer_next();
}


relation

decompiled_code:
__int64 relation()
{
unsigned int v0; // er12
int v1; // ebx
int v2; // eax

v0 = (char)expr();
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) <= 2 )
{
while ( 1 )
{
tokenizer_next();
v2 = (char)expr();
if ( v1 == 34 )
break;
if ( v1 == 35 )
{
v0 = v2 == v0;
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) > 2 )
return v0;
}
else
{
v0 = v2 > (int)v0;
LABEL_4:
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) > 2 )
return v0;
}
}
v0 = v2 < (int)v0;
goto LABEL_4;
}
return v0;
}

canonical_decompiled_code:
__int64 func18()
{
unsigned int v0; // er12
int v1; // ebx
int v2; // eax

v0 = (char)func16();
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) <= 2 )
{
while ( 1 )
{
tokenizer_next();
v2 = (char)func16();
if ( v1 == 34 )
break;
if ( v1 == 35 )
{
v0 = v2 == v0;
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) > 2 )
return v0;
}
else
{
v0 = v2 > (int)v0;
LABEL_4:
v1 = tokenizer_token();
if ( (unsigned int)(v1 - 33) > 2 )
return v0;
}
}
v0 = v2 < (int)v0;
goto LABEL_4;
}
return v0;
}

original_code:
static int
relation(void)
{
  int r1, r2;
  int op;
  r1 = expr();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_LT ||
       op == TOKENIZER_GT ||
       op == TOKENIZER_EQ) {
    tokenizer_next();
    r2 = expr();
    ;
    switch(op) {
    case TOKENIZER_LT:
      r1 = r1 < r2;
      break;
    case TOKENIZER_GT:
      r1 = r1 > r2;
      break;
    case TOKENIZER_EQ:
      r1 = r1 == r2;
      break;
    }
    op = tokenizer_token();
  }
  return r1;
}

canonical_original_code:
static int relation()
{
  int r1; int r2;
  int op;
  r1 = expr();
  op = tokenizer_token();
  ;
  while(op == TOKENIZER_LT ||
       op == TOKENIZER_GT ||
       op == TOKENIZER_EQ) {
    tokenizer_next();
    r2 = expr();
    ;
    switch(op) {
    case TOKENIZER_LT:
      r1 = r1 < r2;
      break;
    case TOKENIZER_GT:
      r1 = r1 > r2;
      break;
    case TOKENIZER_EQ:
      r1 = r1 == r2;
      break;
    }
    op = tokenizer_token();
  }
  return r1;
}


decompiled_code:
__int64 for_statement()
{
unsigned int v0; // ebx
char v1; // al
int v2; // ebp
__int64 result; // rax
int v4; // ecx
int v5; // edx

accept(10);
v0 = tokenizer_variable_num();
accept(4);
accept(35);
v1 = expr();
ubasic_set_variable(v0, v1);
accept(11);
v2 = (char)expr();
result = accept(36);
if ( for_stack_ptr <= 3 )
{
v4 = (char)tokenizer_num();
result = 12LL * for_stack_ptr;
v5 = for_stack_ptr + 1;
*(int *)((char *)&dword_B24 + result) = v0;
*(int *)((char *)&dword_B28 + result) = v2;
*(int *)((char *)&for_stack + result) = v4;
for_stack_ptr = v5;
}
return result;
}

canonical_decompiled_code:
__int64 func19()
{
unsigned int v0; // ebx
char v1; // al
int v2; // ebp
__int64 result; // rax
int v4; // ecx
int v5; // edx

func1(10);
v0 = tokenizer_variable_num();
func1(4);
func1(35);
v1 = func16();
func11(v0, v1);
func1(11);
v2 = (char)func16();
result = func1(36);
if ( for_stack_ptr <= 3 )
{
v4 = (char)tokenizer_num();
result = 12LL * for_stack_ptr;
v5 = for_stack_ptr + 1;
*(int *)((char *)&dword_B24 + result) = v0;
*(int *)((char *)&dword_B28 + result) = v2;
*(int *)((char *)&for_stack + result) = v4;
for_stack_ptr = v5;
}
return result;
}

original_code:
static void
for_statement(void)
{
  int for_variable, to;
  accept(TOKENIZER_FOR);
  for_variable = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_EQ);
  ubasic_set_variable(for_variable, expr());
  accept(TOKENIZER_TO);
  to = expr();
  accept(TOKENIZER_CR);
  if(for_stack_ptr < 4) {
    for_stack[for_stack_ptr].line_after_for = tokenizer_num();
    for_stack[for_stack_ptr].for_variable = for_variable;
    for_stack[for_stack_ptr].to = to;
    ;
    for_stack_ptr++;
  } else {
    ;
  }
}

canonical_original_code:
static void for_statement()
{
  int for_variable; int to;
  accept(TOKENIZER_FOR);
  for_variable = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_EQ);
  ubasic_set_variable(for_variable, expr());
  accept(TOKENIZER_TO);
  to = expr();
  accept(TOKENIZER_CR);
  if(for_stack_ptr < 4) {
    for_stack[for_stack_ptr].line_after_for = tokenizer_num();
    for_stack[for_stack_ptr].for_variable = for_variable;
    for_stack[for_stack_ptr].to = to;
    ;
    for_stack_ptr++;
  } else {
    ;
  }
}

variable_types: to int


decompiled_code:
void peek_statement()
{
char v0; // bl
unsigned int v1; // ebp
char v2; // al

accept(18);
v0 = expr();
accept(21);
v1 = tokenizer_variable_num();
accept(4);
accept(36);
v2 = peek_function((unsigned int)v0);
ubasic_set_variable(v1, v2);
}

canonical_decompiled_code:
void func20()
{
char v0; // bl
unsigned int v1; // ebp
char v2; // al

func1(18);
v0 = func16();
func1(21);
v1 = tokenizer_variable_num();
func1(4);
func1(36);
v2 = peek_function((unsigned int)v0);
func11(v1, v2);
}

original_code:
static void
peek_statement(void)
{
  char peek_addr;
  int var;
  accept(TOKENIZER_PEEK);
  peek_addr = expr();
  accept(TOKENIZER_COMMA);
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_CR);
  ubasic_set_variable(var, peek_function(peek_addr));
}

canonical_original_code:
static void peek_statement()
{
  char peek_addr;
  int var;
  accept(TOKENIZER_PEEK);
  peek_addr = expr();
  accept(TOKENIZER_COMMA);
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_CR);
  ubasic_set_variable(var, peek_function(peek_addr));
}

variable_types: var int


decompiled_code:
__int64 poke_statement()
{
char v0; // bl
char v1; // bp

accept(19);
v0 = expr();
accept(21);
v1 = expr();
accept(36);
return poke_function((unsigned int)v0, (unsigned int)v1);
}

canonical_decompiled_code:
__int64 func21()
{
char v0; // bl
char v1; // bp

func1(19);
v0 = func16();
func1(21);
v1 = func16();
func1(36);
return poke_function((unsigned int)v0, (unsigned int)v1);
}

original_code:
static void
poke_statement(void)
{
  char poke_addr;
  char value;
  accept(TOKENIZER_POKE);
  poke_addr = expr();
  accept(TOKENIZER_COMMA);
  value = expr();
  accept(TOKENIZER_CR);
  poke_function(poke_addr, value);
}

canonical_original_code:
static void poke_statement()
{
  char poke_addr;
  char value;
  accept(TOKENIZER_POKE);
  poke_addr = expr();
  accept(TOKENIZER_COMMA);
  value = expr();
  accept(TOKENIZER_CR);
  poke_function(poke_addr, value);
}


decompiled_code:
__int64 let_statement()
{
unsigned int v0; // ebp
char v1; // al

v0 = tokenizer_variable_num();
accept(4);
accept(35);
v1 = expr();
ubasic_set_variable(v0, v1);
return accept(36);
}

canonical_decompiled_code:
__int64 func22()
{
unsigned int v0; // ebp
char v1; // al

v0 = tokenizer_variable_num();
func1(4);
func1(35);
v1 = func16();
func11(v0, v1);
return func1(36);
}

original_code:
static void
let_statement(void)
{
  int var;
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_EQ);
  ubasic_set_variable(var, expr());
  ;
  accept(TOKENIZER_CR);
}

canonical_original_code:
static void let_statement()
{
  int var;
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  accept(TOKENIZER_EQ);
  ubasic_set_variable(var, expr());
  ;
  accept(TOKENIZER_CR);
}


decompiled_code:
__int64 next_statement()
{
unsigned int v0; // ebp
char v2; // al
char v3; // al
int v4; // edx
__int64 v5; // rcx

accept(12);
v0 = tokenizer_variable_num();
accept(4);
if ( for_stack_ptr <= 0 || dword_B24[3 * for_stack_ptr - 3] != v0 )
return accept(36);
v2 = ubasic_get_variable(v0);
ubasic_set_variable(v0, v2 + 1);
v3 = ubasic_get_variable(v0);
if ( v3 <= *(int *)((char *)&dword_B28 + v5) )
return jump_linenum(*(int *)((char *)&for_stack + v5));
for_stack_ptr = v4;
return accept(36);
}

canonical_decompiled_code:
__int64 func23()
{
unsigned int v0; // ebp
char v2; // al
char v3; // al
int v4; // edx
__int64 v5; // rcx

func1(12);
v0 = tokenizer_variable_num();
func1(4);
if ( for_stack_ptr <= 0 || dword_B24[3 * for_stack_ptr - 3] != v0 )
return func1(36);
v2 = func12(v0);
func11(v0, v2 + 1);
v3 = func12(v0);
if ( v3 <= *(int *)((char *)&dword_B28 + v5) )
return func4(*(int *)((char *)&for_stack + v5));
for_stack_ptr = v4;
return func1(36);
}

original_code:
static void
next_statement(void)
{
  int var;
  accept(TOKENIZER_NEXT);
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  if(for_stack_ptr > 0 &&
     var == for_stack[for_stack_ptr - 1].for_variable) {
    ubasic_set_variable(var,
                       ubasic_get_variable(var) + 1);
    if(ubasic_get_variable(var) <= for_stack[for_stack_ptr - 1].to) {
      jump_linenum(for_stack[for_stack_ptr - 1].line_after_for);
    } else {
      for_stack_ptr--;
      accept(TOKENIZER_CR);
    }
  } else {
    ;
    accept(TOKENIZER_CR);
  }
}

canonical_original_code:
static void next_statement()
{
  int var;
  accept(TOKENIZER_NEXT);
  var = tokenizer_variable_num();
  accept(TOKENIZER_VARIABLE);
  if(for_stack_ptr > 0 &&
     var == for_stack[for_stack_ptr - 1].for_variable) {
    ubasic_set_variable(var,
                       ubasic_get_variable(var) + 1);
    if(ubasic_get_variable(var) <= for_stack[for_stack_ptr - 1].to) {
      jump_linenum(for_stack[for_stack_ptr - 1].line_after_for);
    } else {
      for_stack_ptr--;
      accept(TOKENIZER_CR);
    }
  } else {
    ;
    accept(TOKENIZER_CR);
  }
}


statement

decompiled_code:
void statement()
{
switch ( (unsigned int)tokenizer_token() )
{
case 4u:
goto LABEL_3;
case 5u:
accept(5);
LABEL_3:
let_statement();
break;
case 6u:
print_statement();
break;
case 7u:
if_statement();
break;
case 0xAu:
for_statement();
break;
case 0xCu:
next_statement();
break;
case 0xDu:
goto_statement();
break;
case 0xEu:
gosub_statement();
break;
case 0xFu:
return_statement();
break;
case 0x12u:
peek_statement();
break;
case 0x13u:
poke_statement();
break;
case 0x14u:
end_statement();
break;
default:
exit(1);
}
}

canonical_decompiled_code:
void func24()
{
switch ( (unsigned int)tokenizer_token() )
{
case 4u:
goto LABEL_3;
case 5u:
func1(5);
LABEL_3:
func22();
break;
case 6u:
func17();
break;
case 7u:
func27();
break;
case 0xAu:
func19();
break;
case 0xCu:
func23();
break;
case 0xDu:
func5();
break;
case 0xEu:
func6();
break;
case 0xFu:
func7();
break;
case 0x12u:
func20();
break;
case 0x13u:
func21();
break;
case 0x14u:
func2();
break;
default:
exit(1);
}
}

original_code:
static void
statement(void)
{
  int token;
  token = tokenizer_token();
  switch(token) {
  case TOKENIZER_PRINT:
    print_statement();
    break;
  case TOKENIZER_IF:
    if_statement();
    break;
  case TOKENIZER_GOTO:
    goto_statement();
    break;
  case TOKENIZER_GOSUB:
    gosub_statement();
    break;
  case TOKENIZER_RETURN:
    return_statement();
    break;
  case TOKENIZER_FOR:
    for_statement();
    break;
  case TOKENIZER_PEEK:
    peek_statement();
    break;
  case TOKENIZER_POKE:
    poke_statement();
    break;
  case TOKENIZER_NEXT:
    next_statement();
    break;
  case TOKENIZER_END:
    end_statement();
    break;
  case TOKENIZER_LET:
    accept(TOKENIZER_LET);
  case TOKENIZER_VARIABLE:
    let_statement();
    break;
  default:
    ;
    exit(1);
  }
}

canonical_original_code:
static void statement()
{
  int token;
  token = tokenizer_token();
  switch(token) {
  case TOKENIZER_PRINT:
    print_statement();
    break;
  case TOKENIZER_IF:
    if_statement();
    break;
  case TOKENIZER_GOTO:
    goto_statement();
    break;
  case TOKENIZER_GOSUB:
    gosub_statement();
    break;
  case TOKENIZER_RETURN:
    return_statement();
    break;
  case TOKENIZER_FOR:
    for_statement();
    break;
  case TOKENIZER_PEEK:
    peek_statement();
    break;
  case TOKENIZER_POKE:
    poke_statement();
    break;
  case TOKENIZER_NEXT:
    next_statement();
    break;
  case TOKENIZER_END:
    end_statement();
    break;
  case TOKENIZER_LET:
    accept(TOKENIZER_LET);
  case TOKENIZER_VARIABLE:
    let_statement();
    break;
  default:
    ;
    exit(1);
  }
}


decompiled_code:
void line_statement()
{
__int64 v0; // rbp
char v1; // al

v0 = tokenizer_pos();
v1 = tokenizer_num();
index_add(v1, v0);
accept(2);
statement();
}

canonical_decompiled_code:
void func25()
{
__int64 v0; // rbp
char v1; // al

v0 = tokenizer_pos();
v1 = tokenizer_num();
index_add(v1, v0);
func1(2);
func24();
}

original_code:
static void
line_statement(void)
{
  ;
  index_add(tokenizer_num(), tokenizer_pos());
  accept(TOKENIZER_NUMBER);
  statement();
  return;
}

canonical_original_code:
static void line_statement()
{
  ;
  index_add(tokenizer_num(), tokenizer_pos());
  accept(TOKENIZER_NUMBER);
  statement();
  return;
}


decompiled_code:
void ubasic_run()
{
if ( !(unsigned int)tokenizer_finished() )
line_statement();
}

canonical_decompiled_code:
void func26()
{
if ( !(unsigned int)tokenizer_finished() )
func25();
}

original_code:
void
ubasic_run(void)
{
  if(tokenizer_finished()) {
    ;
    return;
  }
  line_statement();
}

canonical_original_code:
void ubasic_run()
{
  if(tokenizer_finished()) {
    ;
    return;
  }
  line_statement();
}


decompiled_code:
void if_statement()
{
int v0; // ebx

accept(7);
v0 = relation();
accept(8);
if ( v0 )
goto LABEL_10;
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 9
&& (unsigned int)tokenizer_token() != 36
&& (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 9 )
{
tokenizer_next();
LABEL_10:
statement();
return;
}
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
}

canonical_decompiled_code:
void func27()
{
int v0; // ebx

func1(7);
v0 = func18();
func1(8);
if ( v0 )
goto LABEL_10;
do
tokenizer_next();
while ( (unsigned int)tokenizer_token() != 9
&& (unsigned int)tokenizer_token() != 36
&& (unsigned int)tokenizer_token() != 1 );
if ( (unsigned int)tokenizer_token() == 9 )
{
tokenizer_next();
LABEL_10:
func24();
return;
}
if ( (unsigned int)tokenizer_token() == 36 )
tokenizer_next();
}

original_code:
static void
if_statement(void)
{
  int r;
  accept(TOKENIZER_IF);
  r = relation();
  ;
  accept(TOKENIZER_THEN);
  if(r) {
    statement();
  } else {
    do {
      tokenizer_next();
    } while(tokenizer_token() != TOKENIZER_ELSE &&
        tokenizer_token() != TOKENIZER_CR &&
        tokenizer_token() != TOKENIZER_ENDOFINPUT);
    if(tokenizer_token() == TOKENIZER_ELSE) {
      tokenizer_next();
      statement();
    } else if(tokenizer_token() == TOKENIZER_CR) {
      tokenizer_next();
    }
  }
}

canonical_original_code:
static void if_statement()
{
  int r;
  accept(TOKENIZER_IF);
  r = relation();
  ;
  accept(TOKENIZER_THEN);
  if(r) {
    statement();
  } else {
    do {
      tokenizer_next();
    } while(tokenizer_token() != TOKENIZER_ELSE &&
        tokenizer_token() != TOKENIZER_CR &&
        tokenizer_token() != TOKENIZER_ENDOFINPUT);
    if(tokenizer_token() == TOKENIZER_ELSE) {
      tokenizer_next();
      statement();
    } else if(tokenizer_token() == TOKENIZER_CR) {
      tokenizer_next();
    }
  }
}


singlechar

decompiled_code:
__int64 singlechar()
{
char v0; // al
bool v1; // zf
__int64 result; // rax

v0 = *ptr;
if ( *ptr == 10 )
return 36LL;
switch ( v0 )
{
case ',':
return 21LL;
case ';':
return 22LL;
case '+':
return 23LL;
case '-':
return 24LL;
case '&':
return 25LL;
case '|':
return 26LL;
case '*':
return 27LL;
case '/':
return 28LL;
case '%':
return 29LL;
case '(':
return 31LL;
case '#':
return 30LL;
case ')':
return 32LL;
case '<':
return 33LL;
case '>':
return 34LL;
}
v1 = v0 == 61;
result = 0LL;
if ( v1 )
result = 35LL;
return result;
}

canonical_decompiled_code:
__int64 func0()
{
char v0; // al
bool v1; // zf
__int64 result; // rax

v0 = *ptr;
if ( *ptr == 10 )
return 36LL;
switch ( v0 )
{
case ',':
return 21LL;
case ';':
return 22LL;
case '+':
return 23LL;
case '-':
return 24LL;
case '&':
return 25LL;
case '|':
return 26LL;
case '*':
return 27LL;
case '/':
return 28LL;
case '%':
return 29LL;
case '(':
return 31LL;
case '#':
return 30LL;
case ')':
return 32LL;
case '<':
return 33LL;
case '>':
return 34LL;
}
v1 = v0 == 61;
result = 0LL;
if ( v1 )
result = 35LL;
return result;
}

original_code:
static int
singlechar(void)
{
  if(*ptr == '\n') {
    return TOKENIZER_CR;
  } else if(*ptr == ',') {
    return TOKENIZER_COMMA;
  } else if(*ptr == ';') {
    return TOKENIZER_SEMICOLON;
  } else if(*ptr == '+') {
    return TOKENIZER_PLUS;
  } else if(*ptr == '-') {
    return TOKENIZER_MINUS;
  } else if(*ptr == '&') {
    return TOKENIZER_AND;
  } else if(*ptr == '|') {
    return TOKENIZER_OR;
  } else if(*ptr == '*') {
    return TOKENIZER_ASTR;
  } else if(*ptr == '/') {
    return TOKENIZER_SLASH;
  } else if(*ptr == '%') {
    return TOKENIZER_MOD;
  } else if(*ptr == '(') {
    return TOKENIZER_LEFTPAREN;
  } else if(*ptr == '#') {
    return TOKENIZER_HASH;
  } else if(*ptr == ')') {
    return TOKENIZER_RIGHTPAREN;
  } else if(*ptr == '<') {
    return TOKENIZER_LT;
  } else if(*ptr == '>') {
    return TOKENIZER_GT;
  } else if(*ptr == '=') {
    return TOKENIZER_EQ;
  }
  return 0;
}

canonical_original_code:
static int singlechar()
{
  if(*ptr == '\n') {
    return TOKENIZER_CR;
  } else if(*ptr == ',') {
    return TOKENIZER_COMMA;
  } else if(*ptr == ';') {
    return TOKENIZER_SEMICOLON;
  } else if(*ptr == '+') {
    return TOKENIZER_PLUS;
  } else if(*ptr == '-') {
    return TOKENIZER_MINUS;
  } else if(*ptr == '&') {
    return TOKENIZER_AND;
  } else if(*ptr == '|') {
    return TOKENIZER_OR;
  } else if(*ptr == '*') {
    return TOKENIZER_ASTR;
  } else if(*ptr == '/') {
    return TOKENIZER_SLASH;
  } else if(*ptr == '%') {
    return TOKENIZER_MOD;
  } else if(*ptr == '(') {
    return TOKENIZER_LEFTPAREN;
  } else if(*ptr == '#') {
    return TOKENIZER_HASH;
  } else if(*ptr == ')') {
    return TOKENIZER_RIGHTPAREN;
  } else if(*ptr == '<') {
    return TOKENIZER_LT;
  } else if(*ptr == '>') {
    return TOKENIZER_GT;
  } else if(*ptr == '=') {
    return TOKENIZER_EQ;
  }
  return 0;
}


decompiled_code:
__int64 get_next_token()
{
char *v0; // rbx
char v1; // r13
const unsigned __int16 *v2; // rdx
char *v3; // rax
char *v4; // rbx
char *v5; // rcx
unsigned int v6; // er14
size_t v7; // rbp
char **v8; // r12
const char *i; // r15
char *v10; // rax

v0 = ptr;
v1 = *ptr;
if ( !*ptr )
return 1;
v2 = *_ctype_b_loc();
if ( (v2[v1] & 0x800) != 0 )
{
v3 = v0 + 1;
v4 = v0 + 6;
while ( v3 != v4 )
{
v5 = v3++;
if ( (v2[*v5] & 0x800) == 0 )
{
nextptr = (__int64)v5;
return 2;
}
}
return 0;
}
v6 = singlechar();
if ( !v6 )
{
if ( v1 == 34 )
{
do
v10 = v0++;
while ( *v0 != 34 );
v6 = 3;
nextptr = (__int64)(v10 + 2);
}
else
{
v7 = 3LL;
v8 = &keywords;
for ( i = "let"; ; v7 = strlen(i) )
{
if ( !strncmp(v0, i, v7) )
{
v6 = *((_DWORD *)v8 + 2);
nextptr = (__int64)&v0[v7];
return v6;
}
i = v8[2];
v8 += 2;
if ( !i )
break;
}
if ( (unsigned __int8)(v1 - 97) <= 0x19u )
{
v6 = 4;
nextptr = (__int64)(v0 + 1);
}
}
return v6;
}
nextptr = (__int64)(v0 + 1);
return singlechar();
}

original_code:
static int
get_next_token(void)
{
  struct keyword_token const *kt;
  int i;
  ;
  if(*ptr == 0) {
    return TOKENIZER_ENDOFINPUT;
  }
  if(((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short int) _ISdigit)) {
    for(i = 0; i < 6; ++i) {
      if(!((*__ctype_b_loc ())[(int) ((ptr[i]))] & (unsigned short int) _ISdigit)) {
        if(i > 0) {
          nextptr = ptr + i;
          return TOKENIZER_NUMBER;
        } else {
          ;
          return TOKENIZER_ERROR;
        }
      }
      if(!((*__ctype_b_loc ())[(int) ((ptr[i]))] & (unsigned short int) _ISdigit)) {
        ;
        return TOKENIZER_ERROR;
      }
    }
    ;
    return TOKENIZER_ERROR;
  } else if(singlechar()) {
    nextptr = ptr + 1;
    return singlechar();
  } else if(*ptr == '"') {
    nextptr = ptr;
    do {
      ++nextptr;
    } while(*nextptr != '"');
    ++nextptr;
    return TOKENIZER_STRING;
  } else {
    for(kt = keywords; kt->keyword != ((void *)0); ++kt) {
      if(strncmp(ptr, kt->keyword, strlen(kt->keyword)) == 0) {
        nextptr = ptr + strlen(kt->keyword);
        return kt->token;
      }
    }
  }
  if(*ptr >= 'a' && *ptr <= 'z') {
    nextptr = ptr + 1;
    return TOKENIZER_VARIABLE;
  }
  return TOKENIZER_ERROR;
}

canonical_original_code:
static int get_next_token()
{
  struct keyword_token *kt;
  int i;
  ;
  if(*ptr == 0) {
    return TOKENIZER_ENDOFINPUT;
  }
  if(((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short) _ISdigit)) {
    for(i = 0; i < 6; ++i) {
      if(!((*__ctype_b_loc ())[(int) ((ptr[i]))] & (unsigned short) _ISdigit)) {
        if(i > 0) {
          nextptr = ptr + i;
          return TOKENIZER_NUMBER;
        } else {
          ;
          return TOKENIZER_ERROR;
        }
      }
      if(!((*__ctype_b_loc ())[(int) ((ptr[i]))] & (unsigned short) _ISdigit)) {
        ;
        return TOKENIZER_ERROR;
      }
    }
    ;
    return TOKENIZER_ERROR;
  } else if(singlechar()) {
    nextptr = ptr + 1;
    return singlechar();
  } else if(*ptr == '"') {
    nextptr = ptr;
    do {
      ++nextptr;
    } while(*nextptr != '"');
    ++nextptr;
    return TOKENIZER_STRING;
  } else {
    for(kt = keywords; kt->keyword != ((void *)0); ++kt) {
      if(strncmp(ptr, kt->keyword, strlen(kt->keyword)) == 0) {
        nextptr = ptr + strlen(kt->keyword);
        return kt->token;
      }
    }
  }
  if(*ptr >= 'a' && *ptr <= 'z') {
    nextptr = ptr + 1;
    return TOKENIZER_VARIABLE;
  }
  return TOKENIZER_ERROR;
}

variable_types: struct keyword_token { char *keyword; int token; } *

variable_types: i int


decompiled_code:
__int64 __fastcall tokenizer_goto(char *a1)
{
__int64 result; // rax

ptr = a1;
result = get_next_token();
current_token = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *a1)
{
__int64 result; // rax

ptr = a1;
result = func1();
current_token = result;
return result;
}

original_code:
void
tokenizer_goto(const char *program)
{
  ptr = program;
  current_token = get_next_token();
}

canonical_original_code:
void tokenizer_goto(char *program)
{
  ptr = program;
  current_token = get_next_token();
}


decompiled_code:
__int64 __fastcall tokenizer_init(char *a1)
{
__int64 result; // rax

tokenizer_goto(a1);
result = get_next_token();
current_token = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *a1)
{
__int64 result; // rax

func2(a1);
result = func1();
current_token = result;
return result;
}

original_code:
void
tokenizer_init(const char *program)
{
  tokenizer_goto(program);
  current_token = get_next_token();
}

canonical_original_code:
void tokenizer_init(char *program)
{
  tokenizer_goto(program);
  current_token = get_next_token();
}


decompiled_code:
__int64 tokenizer_token()
{
return (unsigned int)current_token;
}

canonical_decompiled_code:
__int64 func4()
{
return (unsigned int)current_token;
}

original_code:
int
tokenizer_token(void)
{
  return current_token;
}

canonical_original_code:
int tokenizer_token()
{
  return current_token;
}


decompiled_code:
int tokenizer_num()
{
return atoi(ptr);
}

canonical_decompiled_code:
int func5()
{
return atoi(ptr);
}

original_code:
char
tokenizer_num(void)
{
  return atoi(ptr);
}

canonical_original_code:
char tokenizer_num()
{
  return atoi(ptr);
}


decompiled_code:
void *__fastcall tokenizer_string(void *dest, int a2)
{
void *result; // rax
int v3; // er13
char *v4; // r12
int v5; // eax
__int64 v6; // rbx

result = (void *)tokenizer_token(dest);
if ( (_DWORD)result == 3 )
{
v3 = (int)ptr;
v4 = ptr + 1;
result = strchr(ptr + 1, 34);
if ( result )
{
v5 = (_DWORD)result - v3 - 1;
if ( v5 > a2 )
v5 = a2;
v6 = v5;
result = memcpy(dest, v4, v5);
*((_BYTE *)dest + v6) = 0;
}
}
return result;
}

canonical_decompiled_code:
void *__fastcall func6(void *dest, int a2)
{
void *result; // rax
int v3; // er13
char *v4; // r12
int v5; // eax
__int64 v6; // rbx

result = (void *)func4(dest);
if ( (_DWORD)result == 3 )
{
v3 = (int)ptr;
v4 = ptr + 1;
result = strchr(ptr + 1, 34);
if ( result )
{
v5 = (_DWORD)result - v3 - 1;
if ( v5 > a2 )
v5 = a2;
v6 = v5;
result = memcpy(dest, v4, v5);
*((_BYTE *)dest + v6) = 0;
}
}
return result;
}

original_code:
void
tokenizer_string(char *dest, int len)
{
  char *string_end;
  int string_len;
  if(tokenizer_token() != TOKENIZER_STRING) {
    return;
  }
  string_end = strchr(ptr + 1, '"');
  if(string_end == ((void *)0)) {
    return;
  }
  string_len = string_end - ptr - 1;
  if(len < string_len) {
    string_len = len;
  }
  memcpy(dest, ptr + 1, string_len);
  dest[string_len] = 0;
}

variable_types:
dest
char *

variable_types: len int


decompiled_code:
void tokenizer_error_print()
{
;
}

canonical_decompiled_code:
void func7()
{
;
}

original_code:
void
tokenizer_error_print(void)
{
  ;
}

canonical_original_code:
void tokenizer_error_print()
{
  ;
}


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

result = 1LL;
if ( *ptr )
result = current_token == 1;
return result;
}

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

result = 1LL;
if ( *ptr )
result = current_token == 1;
return result;
}

original_code:
int
tokenizer_finished(void)
{
  return *ptr == 0 || current_token == TOKENIZER_ENDOFINPUT;
}

canonical_original_code:
int tokenizer_finished()
{
  return *ptr == 0 || current_token == TOKENIZER_ENDOFINPUT;
}


decompiled_code:
__int64 tokenizer_next()
{
__int64 result; // rax
bool v1; // zf
__int64 v2; // rax
char *v3; // rdx
__int64 v4; // rax
_BYTE *v5; // rcx

while ( 1 )
{
result = tokenizer_finished();
if ( (_DWORD)result )
return result;
v1 = *(_BYTE *)nextptr == 32;
ptr = (char *)nextptr;
if ( v1 )
{
v2 = nextptr + 1;
do
v3 = (char *)v2++;
while ( *(_BYTE *)(v2 - 1) == 32 );
ptr = v3;
}
result = get_next_token();
current_token = result;
if ( (_DWORD)result != 17 )
return result;
v4 = nextptr;
if ( *(_BYTE *)nextptr != 10 )
{
do
{
result = tokenizer_finished();
if ( (_DWORD)result )
return result;
nextptr = (__int64)v5;
v4 = (__int64)v5;
}
while ( *v5 != 10 );
}
nextptr = v4 + 1;
}
}

canonical_decompiled_code:
__int64 func9()
{
__int64 result; // rax
bool v1; // zf
__int64 v2; // rax
char *v3; // rdx
__int64 v4; // rax
_BYTE *v5; // rcx

while ( 1 )
{
result = func8();
if ( (_DWORD)result )
return result;
v1 = *(_BYTE *)nextptr == 32;
ptr = (char *)nextptr;
if ( v1 )
{
v2 = nextptr + 1;
do
v3 = (char *)v2++;
while ( *(_BYTE *)(v2 - 1) == 32 );
ptr = v3;
}
result = func1();
current_token = result;
if ( (_DWORD)result != 17 )
return result;
v4 = nextptr;
if ( *(_BYTE *)nextptr != 10 )
{
do
{
result = func8();
if ( (_DWORD)result )
return result;
nextptr = (__int64)v5;
v4 = (__int64)v5;
}
while ( *v5 != 10 );
}
nextptr = v4 + 1;
}
}

original_code:
void
tokenizer_next(void)
{
  if(tokenizer_finished()) {
    return;
  }
  ;
  ptr = nextptr;
  while(*ptr == ' ') {
    ++ptr;
  }
  current_token = get_next_token();
  if(current_token == TOKENIZER_REM) {
      while(!(*nextptr == '\n' || tokenizer_finished())) {
        ++nextptr;
      }
      if(*nextptr == '\n') {
        ++nextptr;
      }
      tokenizer_next();
  }
  ;
  return;
}

canonical_original_code:
void tokenizer_next()
{
  if(tokenizer_finished()) {
    return;
  }
  ;
  ptr = nextptr;
  while(*ptr == ' ') {
    ++ptr;
  }
  current_token = get_next_token();
  if(current_token == TOKENIZER_REM) {
      while(!(*nextptr == '\n' || tokenizer_finished())) {
        ++nextptr;
      }
      if(*nextptr == '\n') {
        ++nextptr;
      }
      tokenizer_next();
  }
  ;
  return;
}


decompiled_code:
__int64 tokenizer_variable_num()
{
return (unsigned int)(*ptr - 97);
}

canonical_decompiled_code:
__int64 func10()
{
return (unsigned int)(*ptr - 97);
}

original_code:
int
tokenizer_variable_num(void)
{
  return *ptr - 'a';
}

canonical_original_code:
int tokenizer_variable_num()
{
  return *ptr - 'a';
}


decompiled_code:
char *tokenizer_pos()
{
return ptr;
}

canonical_decompiled_code:
char *func11()
{
return ptr;
}

original_code:
char const *
tokenizer_pos(void)
{
    return ptr;
}

canonical_original_code:
char *tokenizer_pos()
{
    return ptr;
}

return_type: char *


peek

decompiled_code:
__int64 __fastcall peek(unsigned int a1)
{
return a1;
}

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

original_code:
char peek(char arg) {
    return arg;
}

canonical_original_code:
char peek(char arg) {
    return arg;
}

variable_types: arg char


poke

decompiled_code:
void __fastcall poke(char a1, char a2)
{
if ( a1 != a2 )
_assert_fail("arg == value", "tests.c", 0x55u, "poke");
}

canonical_decompiled_code:
void __fastcall func1(char a1, char a2)
{
if ( a1 != a2 )
_assert_fail("arg == value", "tests.c", 0x55u, "poke");
}

original_code:
void poke(char arg, char value) {
    ((void) sizeof ((arg == value) ? 1 : 0), __extension__ ({ if (arg == value) ; else __assert_fail ("arg == value", "tests.c", 85, __extension__ __PRETTY_FUNCTION__); }));
}


run

decompiled_code:
int __fastcall run(__int64 a1)
{
int v1; // ebx
int v2; // eax

printf("Running test #%u... ", (unsigned int)++test_num_1);
fflush(stdout);
v1 = clock();
ubasic_init_peek_poke(a1, peek, poke);
do
ubasic_run();
while ( !(unsigned int)ubasic_finished() );
v2 = clock();
return printf("done. Run time: %.3f s\n", (double)(v2 - v1) / 1000000.0);
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
int v1; // ebx
int v2; // eax

printf("Running test #%u... ", (unsigned int)++test_num_1);
fflush(stdout);
v1 = clock();
ubasic_init_peek_poke(a1, peek, poke);
do
ubasic_run();
while ( !(unsigned int)ubasic_finished() );
v2 = clock();
return printf("done. Run time: %.3f s\n", (double)(v2 - v1) / 1000000.0);
}

original_code:
void run(const char program[]) {
  static int test_num = 0;
  test_num++;
  printf("Running test #%u... ", test_num);
  fflush(stdout);
  clock_t start_t, end_t;
  double delta_t;
  start_t = clock();
  ubasic_init_peek_poke(program, &peek, &poke);
  do {
    ubasic_run();
  } while(!ubasic_finished());
  end_t = clock();
  delta_t = (double)(end_t - start_t) / ((__clock_t) 1000000);
  printf("done. Run time: %.3f s\n", delta_t);
}

canonical_original_code:
void run(char program[]) {
  static int test_num = 0;
  test_num++;
  printf("Running test #%u... ", test_num);
  fflush(stdout);
  long start_t; long end_t;
  double delta_t;
  start_t = clock();
  ubasic_init_peek_poke(program, &peek, &poke);
  do {
    ubasic_run();
  } while(!ubasic_finished());
  end_t = clock();
  delta_t = (double)(end_t - start_t) / ((long) 1000000);
  printf("done. Run time: %.3f s\n", delta_t);
}

variable_types:
program
char []


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
run((__int64)"10 let a = 42\n20 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 42 )
_assert_fail("ubasic_get_variable(0) == 42", "tests.c", 0x75u, "main");
run((__int64)"10 goto 50\n20 goto 40\n30 goto 60\n40 goto 30\n50 goto 20\n60 let c = 108\n70 end\n");
if ( (unsigned __int8)ubasic_get_variable(2LL, argv) != 108 )
_assert_fail("ubasic_get_variable(2) == 108", "tests.c", 0x78u, "main");
run((__int64)"10 for i = 0 to 126\n"
"20 for j = 0 to 126\n"
"30 for k = 0 to 10\n"
"40 let a = i * j * k\n"
"rem 45 print a, i, j, k\n"
"50 next k\n"
"60 next j\n"
"70 next i\n"
"80 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 40 )
_assert_fail("ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10)", "tests.c", 0x7Bu, "main");
run((__int64)"20 let a = 1\n"
"40 let b = 1\n"
"60 for i = 0 to 8\n"
"80 let b = a + b\n"
"100 let a = b - a\n"
"rem 120 print a, b\n"
"140 next i\n"
"160 end\n");
if ( (unsigned __int8)ubasic_get_variable(1LL, argv) != 89 )
_assert_fail("ubasic_get_variable(1) == 89", "tests.c", 0x7Eu, "main");
run((__int64)"10 peek 100 + 20 + 3, a\n20 peek 123, z\n30 poke 100 - 1, 99\n40 poke 0, 0\n50 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 123 )
_assert_fail("ubasic_get_variable(0) == 123", "tests.c", 0x81u, "main");
if ( (unsigned __int8)ubasic_get_variable(25LL, argv) != 123 )
_assert_fail("ubasic_get_variable(25) == 123", "tests.c", 0x82u, "main");
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
func2((__int64)"10 let a = 42\n20 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 42 )
_assert_fail("ubasic_get_variable(0) == 42", "tests.c", 0x75u, "main");
func2((__int64)"10 goto 50\n20 goto 40\n30 goto 60\n40 goto 30\n50 goto 20\n60 let c = 108\n70 end\n");
if ( (unsigned __int8)ubasic_get_variable(2LL, argv) != 108 )
_assert_fail("ubasic_get_variable(2) == 108", "tests.c", 0x78u, "main");
func2((__int64)"10 for i = 0 to 126\n"
"20 for j = 0 to 126\n"
"30 for k = 0 to 10\n"
"40 let a = i * j * k\n"
"rem 45 print a, i, j, k\n"
"50 next k\n"
"60 next j\n"
"70 next i\n"
"80 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 40 )
_assert_fail("ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10)", "tests.c", 0x7Bu, "main");
func2((__int64)"20 let a = 1\n"
"40 let b = 1\n"
"60 for i = 0 to 8\n"
"80 let b = a + b\n"
"100 let a = b - a\n"
"rem 120 print a, b\n"
"140 next i\n"
"160 end\n");
if ( (unsigned __int8)ubasic_get_variable(1LL, argv) != 89 )
_assert_fail("ubasic_get_variable(1) == 89", "tests.c", 0x7Eu, "main");
func2((__int64)"10 peek 100 + 20 + 3, a\n20 peek 123, z\n30 poke 100 - 1, 99\n40 poke 0, 0\n50 end\n");
if ( (unsigned __int8)ubasic_get_variable(0LL, argv) != 123 )
_assert_fail("ubasic_get_variable(0) == 123", "tests.c", 0x81u, "main");
if ( (unsigned __int8)ubasic_get_variable(25LL, argv) != 123 )
_assert_fail("ubasic_get_variable(25) == 123", "tests.c", 0x82u, "main");
return 0;
}

original_code:
int
main(void)
{
  run(program_let);
  ((void) sizeof ((ubasic_get_variable(0) == 42) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == 42) ; else __assert_fail ("ubasic_get_variable(0) == 42", "tests.c", 117, __extension__ __PRETTY_FUNCTION__); }));
  run(program_goto);
  ((void) sizeof ((ubasic_get_variable(2) == 108) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(2) == 108) ; else __assert_fail ("ubasic_get_variable(2) == 108", "tests.c", 120, __extension__ __PRETTY_FUNCTION__); }));
  run(program_loop);
  ((void) sizeof ((ubasic_get_variable(0) == (char)(126 * 126 * 10)) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == (char)(126 * 126 * 10)) ; else __assert_fail ("ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10)", "tests.c", 123, __extension__ __PRETTY_FUNCTION__); }));
  run(program_fibs);
  ((void) sizeof ((ubasic_get_variable(1) == 89) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(1) == 89) ; else __assert_fail ("ubasic_get_variable(1) == 89", "tests.c", 126, __extension__ __PRETTY_FUNCTION__); }));
  run(program_peek_poke);
  ((void) sizeof ((ubasic_get_variable(0) == 123) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == 123) ; else __assert_fail ("ubasic_get_variable(0) == 123", "tests.c", 129, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((ubasic_get_variable(25) == 123) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(25) == 123) ; else __assert_fail ("ubasic_get_variable(25) == 123", "tests.c", 130, __extension__ __PRETTY_FUNCTION__); }));
  return 0;
}

canonical_original_code:
int main()
{
  run(program_let);
  ((void) sizeof ((ubasic_get_variable(0) == 42) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == 42) ; else __assert_fail ("ubasic_get_variable(0) == 42", "tests.c", 117, __extension__ __PRETTY_FUNCTION__); }));
  run(program_goto);
  ((void) sizeof ((ubasic_get_variable(2) == 108) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(2) == 108) ; else __assert_fail ("ubasic_get_variable(2) == 108", "tests.c", 120, __extension__ __PRETTY_FUNCTION__); }));
  run(program_loop);
  ((void) sizeof ((ubasic_get_variable(0) == (char)(126 * 126 * 10)) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == (char)(126 * 126 * 10)) ; else __assert_fail ("ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10)", "tests.c", 123, __extension__ __PRETTY_FUNCTION__); }));
  run(program_fibs);
  ((void) sizeof ((ubasic_get_variable(1) == 89) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(1) == 89) ; else __assert_fail ("ubasic_get_variable(1) == 89", "tests.c", 126, __extension__ __PRETTY_FUNCTION__); }));
  run(program_peek_poke);
  ((void) sizeof ((ubasic_get_variable(0) == 123) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(0) == 123) ; else __assert_fail ("ubasic_get_variable(0) == 123", "tests.c", 129, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((ubasic_get_variable(25) == 123) ? 1 : 0), __extension__ ({ if (ubasic_get_variable(25) == 123) ; else __assert_fail ("ubasic_get_variable(25) == 123", "tests.c", 130, __extension__ __PRETTY_FUNCTION__); }));
  return 0;
}


decompiled_code:
__int64 __fastcall get_token_symbol(int a1)
{
return (__int64)*(&token_symbols + a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
return (__int64)*(&token_symbols + a1);
}

original_code:
const char *get_token_symbol(token_type t) {
  return token_symbols[(int)t];
}

canonical_original_code:
char *get_token_symbol(enum token_type t) {
  return token_symbols[(int)t];
}

variable_types: enum token_type { nulsym=1, identsym=2, numbersym=3, plussym=4, minussym=5, multsym=6, slashsym=7, oddsym=8, eqsym=9, neqsym=10, lessym=11, leqsym=12, gtrsym=13, geqsym=14, lparentsym=15, rparentsym=16, commasym=17, semicolonsym=18, periodsym=19, becomessym=20, beginsym=21, endsym=22, ifsym=23, thensym=24, whilesym=25, dosym=26, callsym=27, constsym=28, intsym=29, procsym=30, outsym=31, insym=32, elsesym=33 }


canonical_original_code:
enum token_type get_reserved_word_sym(char *str) {
  if(strcmp(str, "begin")==0) {
    return beginsym;
  } else if(strcmp(str, "end")==0) {
    return endsym;
  } else if(strcmp(str, "if")==0) {
    return ifsym;
  } else if(strcmp(str, "then")==0) {
    return thensym;
  } else if(strcmp(str, "while")==0) {
    return whilesym;
  } else if(strcmp(str, "do")==0) {
    return dosym;
  } else if(strcmp(str, "call")==0) {
    return callsym;
  } else if(strcmp(str, "const")==0) {
    return constsym;
  } else if(strcmp(str, "int")==0) {
    return intsym;
  } else if(strcmp(str, "procedure")==0) {
    return procsym;
  } else if(strcmp(str, "out")==0) {
    return outsym;
  } else if(strcmp(str, "in")==0) {
    return insym;
  } else if(strcmp(str, "else")==0) {
    return elsesym;
  } else if(strcmp(str, "odd")==0) {
    return oddsym;
  } else {
    return identsym;
  }
}

variable_types:
str
char *

return_type: enum token_type { nulsym=1, identsym=2, numbersym=3, plussym=4, minussym=5, multsym=6, slashsym=7, oddsym=8, eqsym=9, neqsym=10, lessym=11, leqsym=12, gtrsym=13, geqsym=14, lparentsym=15, rparentsym=16, commasym=17, semicolonsym=18, periodsym=19, becomessym=20, beginsym=21, endsym=22, ifsym=23, thensym=24, whilesym=25, dosym=26, callsym=27, constsym=28, intsym=29, procsym=30, outsym=31, insym=32, elsesym=33 }


original_code:
token_type get_special_symbol_sym (char *str) {
  if(strcmp(str, "+")==0) {
    return plussym;
  } else if(strcmp(str, "-")==0) {
    return minussym;
  } else if(strcmp(str, "*")==0) {
    return multsym;
  } else if(strcmp(str, "/")==0) {
    return slashsym;
  } else if(strcmp(str, "=")==0) {
    return eqsym;
  } else if(strcmp(str, "<>")==0) {
    return neqsym;
  } else if(strcmp(str, "<")==0) {
    return lessym;
  } else if(strcmp(str, "<=")==0) {
    return leqsym;
  } else if(strcmp(str, ">")==0) {
    return gtrsym;
  } else if(strcmp(str, ">=")==0) {
    return geqsym;
  } else if(strcmp(str, "(")==0) {
    return lparentsym;
  } else if(strcmp(str, ")")==0) {
    return rparentsym;
  } else if(strcmp(str, ",")==0) {
    return commasym;
  } else if(strcmp(str, ";")==0) {
    return semicolonsym;
  } else if(strcmp(str, ".")==0) {
    return periodsym;
  } else if(strcmp(str, ":=")==0) {
    return becomessym;
  } else {
    return nulsym;
  }
}

canonical_original_code:
enum token_type get_special_symbol_sym(char *str) {
  if(strcmp(str, "+")==0) {
    return plussym;
  } else if(strcmp(str, "-")==0) {
    return minussym;
  } else if(strcmp(str, "*")==0) {
    return multsym;
  } else if(strcmp(str, "/")==0) {
    return slashsym;
  } else if(strcmp(str, "=")==0) {
    return eqsym;
  } else if(strcmp(str, "<>")==0) {
    return neqsym;
  } else if(strcmp(str, "<")==0) {
    return lessym;
  } else if(strcmp(str, "<=")==0) {
    return leqsym;
  } else if(strcmp(str, ">")==0) {
    return gtrsym;
  } else if(strcmp(str, ">=")==0) {
    return geqsym;
  } else if(strcmp(str, "(")==0) {
    return lparentsym;
  } else if(strcmp(str, ")")==0) {
    return rparentsym;
  } else if(strcmp(str, ",")==0) {
    return commasym;
  } else if(strcmp(str, ";")==0) {
    return semicolonsym;
  } else if(strcmp(str, ".")==0) {
    return periodsym;
  } else if(strcmp(str, ":=")==0) {
    return becomessym;
  } else {
    return nulsym;
  }
}

user_defined_types: enum token_type { nulsym=1, identsym=2, numbersym=3, plussym=4, minussym=5, multsym=6, slashsym=7, oddsym=8, eqsym=9, neqsym=10, lessym=11, leqsym=12, gtrsym=13, geqsym=14, lparentsym=15, rparentsym=16, commasym=17, semicolonsym=18, periodsym=19, becomessym=20, beginsym=21, endsym=22, ifsym=23, thensym=24, whilesym=25, dosym=26, callsym=27, constsym=28, intsym=29, procsym=30, outsym=31, insym=32, elsesym=33 }


decompiled_code:
__int64 __fastcall is_reserved_word(char *s1)
{
char **v1; // rbx

v1 = reserved_words;
while ( strcmp(s1, *v1) )
{
if ( ++v1 == &reserved_words[13] )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1)
{
char **v1; // rbx

v1 = reserved_words;
while ( strcmp(s1, *v1) )
{
if ( ++v1 == &reserved_words[13] )
return 0LL;
}
return 1LL;
}

original_code:
int is_reserved_word(char *str) {
  int i;
  for(i = 0; i < 13; i++) {
    if(strcmp(str, reserved_words[i])==0) {
      return 1;
    }
  }
  return 0;
}


decompiled_code:
_BOOL8 __fastcall is_letter(char a1)
{
return (unsigned __int8)((a1 & 0xDF) - 65) <= 0x19u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(char a1)
{
return (unsigned __int8)((a1 & 0xDF) - 65) <= 0x19u;
}

original_code:
int is_letter(char c) {
  if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
    return 1;
  return 0;
}

variable_types: c char


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

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

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


decompiled_code:
__int64 __fastcall is_special_symbol(char a1)
{
char *v1; // rax
char i; // dl

v1 = (char *)(unsigned int)((_DWORD)&special_symbols + 1);
for ( i = 43; a1 != i; i = *v1++ )
{
if ( v1 == (char *)&special_symbols + 13 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(char a1)
{
char *v1; // rax
char i; // dl

v1 = (char *)(unsigned int)((_DWORD)&special_symbols + 1);
for ( i = 43; a1 != i; i = *v1++ )
{
if ( v1 == (char *)&special_symbols + 13 )
return 0LL;
}
return 1LL;
}

original_code:
int is_special_symbol(char c) {
  int i;
  for(i = 0; i < 13; i++)
    if(c == special_symbols[i]) {
      return 1;
    }
  return 0;
}


decompiled_code:
unsigned __int64 __fastcall is_invisible_character(char a1)
{
unsigned __int64 result; // rax

result = 0LL;
if ( (unsigned __int8)(a1 + 1) <= 0x21u )
result = (0x200004C01uLL >> (a1 + 1)) & 1;
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func7(char a1)
{
unsigned __int64 result; // rax

result = 0LL;
if ( (unsigned __int8)(a1 + 1) <= 0x21u )
result = (0x200004C01uLL >> (a1 + 1)) & 1;
return result;
}

original_code:
int is_invisible_character(char c) {
  int i;
  for(i = 0; i < 4; i++) {
    if(c == invisible_characters[i]) {
      return 1;
    }
  }
  if(c == (-1))
    return 1;
  return 0;
}


decompiled_code:
_BOOL8 __fastcall is_relation(int a1)
{
return (unsigned int)(a1 - 9) <= 5;
}

canonical_decompiled_code:
_BOOL8 __fastcall func8(int a1)
{
return (unsigned int)(a1 - 9) <= 5;
}

original_code:
int is_relation(token_type token) {
  switch(token) {
    case eqsym:
    case neqsym:
    case lessym:
    case leqsym:
    case gtrsym:
    case geqsym:
      return 1;
      break;
    default:
      return 0;
  }
}

canonical_original_code:
int is_relation(enum token_type token) {
  switch(token) {
    case eqsym:
    case neqsym:
    case lessym:
    case leqsym:
    case gtrsym:
    case geqsym:
      return 1;
      break;
    default:
      return 0;
  }
}


decompiled_code:
void *__fastcall add_lexeme(_QWORD *a1, const char *a2, int a3)
{
_QWORD *v3; // rax
void *v5; // r12
_QWORD *v6; // rbx
_DWORD *v7; // rax
_DWORD *v8; // rbp
size_t v9; // r15
void *v10; // rax
void *v12; // rax

v3 = a1;
v5 = a1;
if ( !a1 )
{
v12 = malloc(0x18uLL);
v5 = v12;
if ( !v12 )
return v5;
v8 = v12;
goto LABEL_4;
}
do
{
v6 = v3;
v3 = (_QWORD *)v3[2];
}
while ( v3 );
v7 = malloc(0x18uLL);
v6[2] = v7;
v8 = v7;
if ( v7 )
{
LABEL_4:
v9 = strlen(a2) + 1;
v10 = malloc(v9);
*(_QWORD *)v8 = v10;
memcpy(v10, a2, v9);
v8[2] = a3;
*((_QWORD *)v8 + 2) = 0LL;
}
return v5;
}

canonical_decompiled_code:
void *__fastcall func0(_QWORD *a1, const char *a2, int a3)
{
_QWORD *v3; // rax
void *v5; // r12
_QWORD *v6; // rbx
_DWORD *v7; // rax
_DWORD *v8; // rbp
size_t v9; // r15
void *v10; // rax
void *v12; // rax

v3 = a1;
v5 = a1;
if ( !a1 )
{
v12 = malloc(0x18uLL);
v5 = v12;
if ( !v12 )
return v5;
v8 = v12;
goto LABEL_4;
}
do
{
v6 = v3;
v3 = (_QWORD *)v3[2];
}
while ( v3 );
v7 = malloc(0x18uLL);
v6[2] = v7;
v8 = v7;
if ( v7 )
{
LABEL_4:
v9 = strlen(a2) + 1;
v10 = malloc(v9);
*(_QWORD *)v8 = v10;
memcpy(v10, a2, v9);
v8[2] = a3;
*((_QWORD *)v8 + 2) = 0LL;
}
return v5;
}

original_code:
lexeme_list *add_lexeme(lexeme_list *lexemes, char *lex, token_type t) {
  lexeme_list *pos = lexemes;
  if(!lexemes) {
    lexemes = (lexeme_list *)malloc(sizeof(lexeme_list));
    if(!lexemes) return ((void *)0);
    pos = lexemes;
  } else {
    while(pos->next) pos = pos->next;
    pos->next = (lexeme_list *)malloc(sizeof(lexeme_list));
    if(!pos->next) {
      pos->next = ((void *)0);
      return lexemes;
    }
    pos = pos->next;
  }
  pos->lex = (char *)malloc((strlen(lex) + 1) * sizeof(char));
  strcpy(pos->lex, lex);
  pos->t = t;
  pos->next = ((void *)0);
  return lexemes;
}

canonical_original_code:
struct lexeme_list *add_lexeme(struct lexeme_list *lexemes, char *lex, enum token_type t) {
  struct lexeme_list *pos = lexemes;
  if(!lexemes) {
    lexemes = (struct lexeme_list *)malloc(sizeof(lexeme_list));
    if(!lexemes) return ((void *)0);
    pos = lexemes;
  } else {
    while(pos->next) pos = pos->next;
    pos->next = (struct lexeme_list *)malloc(sizeof(lexeme_list));
    if(!pos->next) {
      pos->next = ((void *)0);
      return lexemes;
    }
    pos = pos->next;
  }
  pos->lex = (char *)malloc((strlen(lex) + 1) * sizeof(char));
  strcpy(pos->lex, lex);
  pos->t = t;
  pos->next = ((void *)0);
  return lexemes;
}

variable_types:
lexemes
struct lexeme_list *

variable_types:
lex
char *

variable_types: struct lexeme_list { char *lex; enum token_type { nulsym=1, identsym=2, numbersym=3, plussym=4, minussym=5, multsym=6, slashsym=7, oddsym=8, eqsym=9, neqsym=10, lessym=11, leqsym=12, gtrsym=13, geqsym=14, lparentsym=15, rparentsym=16, commasym=17, semicolonsym=18, periodsym=19, becomessym=20, beginsym=21, endsym=22, ifsym=23, thensym=24, whilesym=25, dosym=26, callsym=27, constsym=28, intsym=29, procsym=30, outsym=31, insym=32, elsesym=33 } t; struct lexeme_list *next; } *

user_defined_types: struct lexeme_list { char *lex; enum token_type t; struct lexeme_list *next; }


decompiled_code:
void __fastcall destroy_lexemes(void *ptr)
{
void **v1; // rbx
void **v2; // rbp

if ( ptr )
{
v1 = (void **)ptr;
do
{
v2 = v1;
v1 = (void **)v1[2];
free(*v2);
free(v2);
}
while ( v1 );
}
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
void **v1; // rbx
void **v2; // rbp

if ( ptr )
{
v1 = (void **)ptr;
do
{
v2 = v1;
v1 = (void **)v1[2];
free(*v2);
free(v2);
}
while ( v1 );
}
}

original_code:
void destroy_lexemes(lexeme_list *lexemes) {
  lexeme_list *del;
  while(lexemes) {
    del = lexemes;
    lexemes = lexemes->next;
    free(del->lex);
    free(del);
  }
}

canonical_original_code:
void destroy_lexemes(struct lexeme_list *lexemes) {
  struct lexeme_list *del;
  while(lexemes) {
    del = lexemes;
    lexemes = lexemes->next;
    free(del->lex);
    free(del);
  }
}


decompiled_code:
int __fastcall print_lexeme_table(__int64 a1)
{
__int64 v1; // rbx
int result; // eax

v1 = a1;
puts("Lexeme Table:");
puts("----------------------");
puts("lexeme token type");
result = puts("----------------------");
if ( a1 )
{
do
{
result = printf("%-11s %d\n", *(const char **)v1, *(unsigned int *)(v1 + 8));
v1 = *(_QWORD *)(v1 + 16);
}
while ( v1 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
__int64 v1; // rbx
int result; // eax

v1 = a1;
puts("Lexeme Table:");
puts("----------------------");
puts("lexeme token type");
result = puts("----------------------");
if ( a1 )
{
do
{
result = printf("%-11s %d\n", *(const char **)v1, *(unsigned int *)(v1 + 8));
v1 = *(_QWORD *)(v1 + 16);
}
while ( v1 );
}
return result;
}

original_code:
void print_lexeme_table(lexeme_list *lexemes) {
  lexeme_list *pos = lexemes;
  printf("Lexeme Table:\n");
  printf("----------------------\n");
  printf("lexeme      token type\n");
  printf("----------------------\n");
  while(pos) {
    printf("%-11s %d\n", pos->lex, pos->t);
    pos = pos->next;
  }
}

canonical_original_code:
void print_lexeme_table(struct lexeme_list *lexemes) {
  struct lexeme_list *pos = lexemes;
  printf("Lexeme Table:\n");
  printf("----------------------\n");
  printf("lexeme      token type\n");
  printf("----------------------\n");
  while(pos) {
    printf("%-11s %d\n", pos->lex, pos->t);
    pos = pos->next;
  }
}


decompiled_code:
int __fastcall print_lexeme_list(__int64 a1)
{
__int64 v1; // rbx

v1 = a1;
puts("Lexeme List:");
puts("------------");
if ( a1 )
{
do
{
printf("%d", *(unsigned int *)(v1 + 8));
if ( (unsigned int)(*(_DWORD *)(v1 + 8) - 2) <= 1 )
{
if ( *(_QWORD *)(v1 + 16) )
putchar(32);
printf("%s", *(const char **)v1);
}
if ( !*(_QWORD *)(v1 + 16) )
break;
printf(" | ");
v1 = *(_QWORD *)(v1 + 16);
}
while ( v1 );
}
return putchar(10);
}

original_code:
void print_lexeme_list(lexeme_list *lexemes) {
  lexeme_list *pos = lexemes;
  printf("Lexeme List:\n");
  printf("------------\n");
  while(pos) {
    printf("%d", pos->t);
    if(pos->t == identsym || pos->t == numbersym) {
      if(pos->next) printf(" ");
      printf("%s", pos->lex);
    }
    if(pos->next) printf(" | ");
    pos = pos->next;
  }
  printf("\n");
}

canonical_original_code:
void print_lexeme_list(struct lexeme_list *lexemes) {
  struct lexeme_list *pos = lexemes;
  printf("Lexeme List:\n");
  printf("------------\n");
  while(pos) {
    printf("%d", pos->t);
    if(pos->t == identsym || pos->t == numbersym) {
      if(pos->next) printf(" ");
      printf("%s", pos->lex);
    }
    if(pos->next) printf(" | ");
    pos = pos->next;
  }
  printf("\n");
}


decompiled_code:
__int64 __fastcall get_lexeme_list_str(__int64 a1)
{
__int64 *v1; // rbp
__int64 v2; // rbx
__int64 v3; // rax
__int64 v4; // r12
char s[27]; // [rsp+1h] [rbp-1Bh] BYREF

if ( !a1 )
get_lexeme_list_str_cold();
v1 = 0LL;
v2 = a1;
do
{
sprintf(s, "%d", *(unsigned int *)(v2 + 8));
v1 = (__int64 *)fancy_append(v1, s);
if ( (unsigned int)(*(_DWORD *)(v2 + 8) - 2) <= 1 )
{
if ( *(_QWORD *)(v2 + 16) )
v1 = (__int64 *)fancy_push(v1, 32LL);
v1 = (__int64 *)fancy_append(v1, *(_QWORD *)v2);
}
if ( !*(_QWORD *)(v2 + 16) )
break;
v3 = fancy_push(v1, 32LL);
v2 = *(_QWORD *)(v2 + 16);
v1 = (__int64 *)v3;
}
while ( v2 );
v4 = *v1;
free(v1);
return v4;
}

original_code:
char *get_lexeme_list_str(lexeme_list *lexemes) {
  lexeme_list *pos = lexemes;
  char tmp_t[3];
  fancy_string *lexeme_list_str = ((void *)0);
  while(pos) {
    sprintf(tmp_t, "%d", pos->t);
    lexeme_list_str = fancy_append(lexeme_list_str, tmp_t);
    if(pos->t == 2 || pos->t == 3) {
      if(pos->next)
        lexeme_list_str = fancy_push(lexeme_list_str, ' ');
      lexeme_list_str = fancy_append(lexeme_list_str, pos->lex);
    }
    if(pos->next) {
      lexeme_list_str = fancy_push(lexeme_list_str, ' ');
    }
    pos = pos->next;
  }
  char *return_str = lexeme_list_str->value;
  free(lexeme_list_str);
  return return_str;
}

canonical_original_code:
char *get_lexeme_list_str(struct lexeme_list *lexemes) {
  struct lexeme_list *pos = lexemes;
  char tmp_t[3];
  struct fancy_string *lexeme_list_str = ((void *)0);
  while(pos) {
    sprintf(tmp_t, "%d", pos->t);
    lexeme_list_str = fancy_append(lexeme_list_str, tmp_t);
    if(pos->t == 2 || pos->t == 3) {
      if(pos->next)
        lexeme_list_str = fancy_push(lexeme_list_str, ' ');
      lexeme_list_str = fancy_append(lexeme_list_str, pos->lex);
    }
    if(pos->next) {
      lexeme_list_str = fancy_push(lexeme_list_str, ' ');
    }
    pos = pos->next;
  }
  char *return_str = lexeme_list_str->value;
  free(lexeme_list_str);
  return return_str;
}

variable_types: struct fancy_string { char *value; unsigned int size; } *


decompiled_code:
_DWORD *fancy_initialize()
{
_DWORD *v0; // r12
_BYTE *v1; // rax

v0 = malloc(0x10uLL);
v1 = malloc(1uLL);
v0[2] = 0;
*(_QWORD *)v0 = v1;
*v1 = 0;
return v0;
}

canonical_decompiled_code:
_DWORD *func0()
{
_DWORD *v0; // r12
_BYTE *v1; // rax

v0 = malloc(0x10uLL);
v1 = malloc(1uLL);
v0[2] = 0;
*(_QWORD *)v0 = v1;
*v1 = 0;
return v0;
}

original_code:
fancy_string *fancy_initialize(fancy_string *str) {
  str = (fancy_string *)malloc(sizeof(fancy_string));
  str->value = (char *)malloc(sizeof(char));
  str->value[0] = 0;
  str->size = 0;
  return str;
}

canonical_original_code:
struct fancy_string *fancy_initialize(struct fancy_string *str) {
  str = (struct fancy_string *)malloc(sizeof(fancy_string));
  str->value = (char *)malloc(sizeof(char));
  str->value[0] = 0;
  str->size = 0;
  return str;
}

variable_types:
str
struct fancy_string *

return_type: struct fancy_string { char *value; unsigned int size; } *


decompiled_code:
__int64 __fastcall fancy_pop(__int64 a1)
{
__int64 v1; // rax
_BYTE *v2; // rax
unsigned int v3; // er12

if ( !a1 )
return (unsigned int)-1;
v1 = (unsigned int)(*(_DWORD *)(a1 + 8) - 1);
*(_DWORD *)(a1 + 8) = v1;
v2 = (_BYTE *)(*(_QWORD *)a1 + v1);
v3 = (unsigned __int8)*v2;
*v2 = 0;
*(_QWORD *)a1 = realloc(*(void **)a1, (unsigned int)(*(_DWORD *)(a1 + 8) + 1));
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 v1; // rax
_BYTE *v2; // rax
unsigned int v3; // er12

if ( !a1 )
return (unsigned int)-1;
v1 = (unsigned int)(*(_DWORD *)(a1 + 8) - 1);
*(_DWORD *)(a1 + 8) = v1;
v2 = (_BYTE *)(*(_QWORD *)a1 + v1);
v3 = (unsigned __int8)*v2;
*v2 = 0;
*(_QWORD *)a1 = realloc(*(void **)a1, (unsigned int)(*(_DWORD *)(a1 + 8) + 1));
return v3;
}

original_code:
char fancy_pop(fancy_string *dst) {
  if(!dst) {
    return -1;
  }
  dst->size--;
  char c = dst->value[dst->size];
  dst->value[dst->size] = 0;
  dst->value = (char *)realloc(dst->value, (dst->size + 1) * sizeof(char));
  return c;
}

canonical_original_code:
char fancy_pop(struct fancy_string *dst) {
  if(!dst) {
    return -1;
  }
  dst->size--;
  char c = dst->value[dst->size];
  dst->value[dst->size] = 0;
  dst->value = (char *)realloc(dst->value, (dst->size + 1) * sizeof(char));
  return c;
}

user_defined_types: struct fancy_string { char *value; unsigned int size; }


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

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

original_code:
void fancy_free(fancy_string *str) {
  if(str) {
    free(str->value);
    free(str);
  }
}

canonical_original_code:
void fancy_free(struct fancy_string *str) {
  if(str) {
    free(str->value);
    free(str);
  }
}


decompiled_code:
char *__fastcall get_op_code_symbol(int a1)
{
__int64 v1; // rdi
char *result; // rax

v1 = (unsigned int)(a1 - 1);
result = (char *)&unk_D02;
if ( (unsigned int)v1 <= 9 )
result = CSWTCH_4[v1];
return result;
}

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

v1 = (unsigned int)(a1 - 1);
result = (char *)&unk_D02;
if ( (unsigned int)v1 <= 9 )
result = CSWTCH_4[v1];
return result;
}

original_code:
const char *get_op_code_symbol(int op) {
  switch(op) {
    case 1:
      return "LIT";
      break;
    case 2:
      return "OPR";
      break;
    case 3:
      return "LOD";
      break;
    case 4:
      return "STO";
      break;
    case 5:
      return "CAL";
      break;
    case 6:
      return "INC";
      break;
    case 7:
      return "JMP";
      break;
    case 8:
      return "JPC";
      break;
    case 9:
      return "SIO";
      break;
    case 10:
      return "SIO";
      break;
  }
  return "ERR";
}

variable_types: op int


decompiled_code:
char *__fastcall get_opr_symbol(unsigned int a1)
{
char *result; // rax

result = (char *)&unk_D02;
if ( a1 <= 0xD )
result = CSWTCH_6[a1];
return result;
}

canonical_decompiled_code:
char *__fastcall func1(unsigned int a1)
{
char *result; // rax

result = (char *)&unk_D02;
if ( a1 <= 0xD )
result = CSWTCH_6[a1];
return result;
}

original_code:
const char *get_opr_symbol(int op) {
  switch(op) {
    case 0:
      return "OPR_RET";
      break;
    case 1:
      return "OPR_NEG";
      break;
    case 2:
      return "OPR_ADD";
      break;
    case 3:
      return "OPR_SUB";
      break;
    case 4:
      return "OPR_MUL";
      break;
    case 5:
      return "OPR_DIV";
      break;
    case 6:
      return "OPR_ODD";
      break;
    case 7:
      return "OPR_MOD";
      break;
    case 8:
      return "OPR_EQL";
      break;
    case 9:
      return "OPR_NEQ";
      break;
    case 10:
      return "OPR_LSS";
      break;
    case 11:
      return "OPR_LEQ";
      break;
    case 12:
      return "OPR_GTR";
      break;
    case 13:
      return "OPR_GEQ";
      break;
  }
  return "ERR";
}


base

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

result = a3;
if ( a2 > 0 )
{
do
{
result = *(int *)(a1 + 4 * result - 4);
--a2;
}
while ( a2 );
}
return result;
}

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

result = a3;
if ( a2 > 0 )
{
do
{
result = *(int *)(a1 + 4 * result - 4);
--a2;
}
while ( a2 );
}
return result;
}

original_code:
int base(int *stack, int l, int bp) {
  int base = bp;
  while(l > 0) {
    base = stack[base - 1];
    l--;
  }
  return base;
}

variable_types:
stack
int *

variable_types: l int

variable_types: bp int

variable_types: base int


decompiled_code:
int __fastcall print_stack(__int64 a1, int a2, _DWORD *a3, int a4)
{
int v4; // er12
int v6; // er13
int result; // eax
int v8; // ebx
__int64 v9; // r15
unsigned int *v10; // rbx
int v11; // [rsp+8h] [rbp-40h]

v4 = a4;
if ( !a4 )
{
result = a2;
if ( a2 <= 0 )
return result;
goto LABEL_12;
}
if ( a4 < 0 )
{
v6 = 0;
}
else
{
v11 = 0;
v6 = 0;
do
{
v8 = 0;
v9 = v6 + 1;
while ( v8 < *a3 )
{
v6 = v9;
++v8;
printf("%2d", *(unsigned int *)(a1 + 4 * v9 - 4));
if ( v8 >= *a3 )
break;
++v9;
putchar(32);
}
if ( v4 > v11 )
printf(" | ");
result = ++v11;
++a3;
}
while ( v4 >= v11 );
}
if ( a2 > v6 )
{
v4 = v6;
putchar(32);
LABEL_12:
v10 = (unsigned int *)(a1 + 4LL * v4);
do
{
while ( 1 )
{
++v4;
result = printf("%2d", *v10);
if ( a2 <= v4 )
break;
++v10;
putchar(32);
}
++v10;
}
while ( a2 != v4 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, int a2, _DWORD *a3, int a4)
{
int v4; // er12
int v6; // er13
int result; // eax
int v8; // ebx
__int64 v9; // r15
unsigned int *v10; // rbx
int v11; // [rsp+8h] [rbp-40h]

v4 = a4;
if ( !a4 )
{
result = a2;
if ( a2 <= 0 )
return result;
goto LABEL_12;
}
if ( a4 < 0 )
{
v6 = 0;
}
else
{
v11 = 0;
v6 = 0;
do
{
v8 = 0;
v9 = v6 + 1;
while ( v8 < *a3 )
{
v6 = v9;
++v8;
printf("%2d", *(unsigned int *)(a1 + 4 * v9 - 4));
if ( v8 >= *a3 )
break;
++v9;
putchar(32);
}
if ( v4 > v11 )
printf(" | ");
result = ++v11;
++a3;
}
while ( v4 >= v11 );
}
if ( a2 > v6 )
{
v4 = v6;
putchar(32);
LABEL_12:
v10 = (unsigned int *)(a1 + 4LL * v4);
do
{
while ( 1 )
{
++v4;
result = printf("%2d", *v10);
if ( a2 <= v4 )
break;
++v10;
putchar(32);
}
++v10;
}
while ( a2 != v4 );
}
return result;
}

original_code:
void print_stack(int *stack, int sp, int *activation_records, int ar) {
  int i, j, s = 0;
  if(ar != 0) {
    for(i = 0; i <= ar; i++) {
      for(j = 0; j < activation_records[i]; j++) {
        printf("%2d", stack[s++]);
        if(j + 1 < activation_records[i])
          printf(" ");
      }
      if(i + 1 <= ar)
        printf("  | ");
    }
  }
  if(s < sp && ar != 0)
    printf(" ");
  while(s < sp) {
    printf("%2d", stack[s++]);
    if(s < sp)
      printf(" ");
  }
}

canonical_original_code:
void print_stack(int *stack, int sp, int *activation_records, int ar) {
  int i; int j; int s = 0;
  if(ar != 0) {
    for(i = 0; i <= ar; i++) {
      for(j = 0; j < activation_records[i]; j++) {
        printf("%2d", stack[s++]);
        if(j + 1 < activation_records[i])
          printf(" ");
      }
      if(i + 1 <= ar)
        printf("  | ");
    }
  }
  if(s < sp && ar != 0)
    printf(" ");
  while(s < sp) {
    printf("%2d", stack[s++]);
    if(s < sp)
      printf(" ");
  }
}

variable_types: sp int

variable_types: ar int

variable_types: i int

variable_types: j int

variable_types: s int


decompiled_code:
const char *__fastcall get_parse_error(unsigned int a1)
{
const char *result; // rax

result = "Invalid error code.";
if ( a1 <= 0x1E )
result = (&parse_errors)[a1];
return result;
}

canonical_decompiled_code:
const char *__fastcall func3(unsigned int a1)
{
const char *result; // rax

result = "Invalid error code.";
if ( a1 <= 0x1E )
result = (&parse_errors)[a1];
return result;
}

original_code:
const char *get_parse_error(int e) {
  if(e < 0 || e > 30)
    return "Invalid error code.";
  return parse_errors[e];
}

variable_types: e int


emit

decompiled_code:
__int64 __fastcall emit(int a1, int a2, int a3)
{
int v4; // edx
__int64 result; // rax
__int64 v6; // rax

v4 = dword_1650;
result = 25LL;
if ( dword_1650 <= 999 )
{
++dword_1650;
v6 = 12LL * v4;
*(_DWORD *)((char *)&code + v6) = a1;
*(_DWORD *)((char *)&code + v6 + 4) = a2;
*(_DWORD *)((char *)&code + v6 + 8) = a3;
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, int a2, int a3)
{
int v4; // edx
__int64 result; // rax
__int64 v6; // rax

v4 = dword_1650;
result = 25LL;
if ( dword_1650 <= 999 )
{
++dword_1650;
v6 = 12LL * v4;
*(_DWORD *)((char *)&code + v6) = a1;
*(_DWORD *)((char *)&code + v6 + 4) = a2;
*(_DWORD *)((char *)&code + v6 + 8) = a3;
result = 0LL;
}
return result;
}

original_code:
int emit(int op, int l, int m) {
  if(cx >= 1000)
    return 25;
  else {
    if(0) {
      printf("DEBUG: cx = %d, op = %d (%s), l = %d, m = %d", cx, op, get_op_code_symbol(op), l, m);
      if(op == OPR)
        printf(" (%s)", get_opr_symbol(m));
      printf("\n");
    }
    code[cx].op = op;
    code[cx].l = l;
    code[cx].m = m;
    cx++;
  }
  return 0;
}

variable_types: m int


decompiled_code:
char *proc_cleanup()
{
int v0; // edx
__m128i v1; // xmm0
char *result; // rax
__int64 v3; // rsi
int v4; // ecx

v0 = curr_l;
v1 = _mm_loadu_si128((const __m128i *)&EMPTY_SYMBOL);
result = (char *)&symbol_table;
v3 = *((_QWORD *)&EMPTY_SYMBOL + 2);
v4 = *((_DWORD *)&EMPTY_SYMBOL + 6);
do
{
if ( *((_DWORD *)result + 5) == v0 )
{
*((_QWORD *)result + 2) = v3;
*((_DWORD *)result + 6) = v4;
*(__m128i *)result = v1;
}
result += 28;
}
while ( result != (char *)&symbol_table + 2800 );
curr_l = v0 - 1;
return result;
}

canonical_decompiled_code:
char *func10()
{
int v0; // edx
__m128i v1; // xmm0
char *result; // rax
__int64 v3; // rsi
int v4; // ecx

v0 = curr_l;
v1 = _mm_loadu_si128((const __m128i *)&EMPTY_SYMBOL);
result = (char *)&symbol_table;
v3 = *((_QWORD *)&EMPTY_SYMBOL + 2);
v4 = *((_DWORD *)&EMPTY_SYMBOL + 6);
do
{
if ( *((_DWORD *)result + 5) == v0 )
{
*((_QWORD *)result + 2) = v3;
*((_DWORD *)result + 6) = v4;
*(__m128i *)result = v1;
}
result += 28;
}
while ( result != (char *)&symbol_table + 2800 );
curr_l = v0 - 1;
return result;
}

original_code:
void proc_cleanup() {
  int i;
  for(i = 0; i < 100; i++) {
    if(symbol_table[i].level == curr_l) {
      if(0) printf("Clearing symbol \"%s\" at level %d\n", symbol_table[i].name, symbol_table[i].level);
      symbol_table[i] = EMPTY_SYMBOL;
    }
  }
  curr_l--;
}