// File: /workspace/github_c_makefile_star2_O0/tstword[P]MIPSAssemblerC/src/assembler.c
// Function: execute_assembler
astatus_t execute_assembler(struct assembler *assembler, const char **files, size_t size) {
    /* Setup Tokenizer List */
    assembler->tokenizer_list = create_list();
    for(size_t i = 0; i < size; ++i) {
        struct tokenizer *tokenizer = create_tokenizer(files[i]);
        if(tokenizer == NULL) {
            fprintf(stderr, "%s: Error: ", files[i]);
            perror(NULL);
            assembler->status = ASSEMBLER_STATUS_FAIL;
            destroy_tokenizer_list(assembler);
            return assembler->status;
        }
        insert_rear(assembler->tokenizer_list, (void *)tokenizer);
    }

    /* Setup initial tokenizer structure */
    if(assembler->tokenizer_list->front == NULL) {
        fprintf(stderr, "Input: No source files to assemble\n");
        assembler->status = ASSEMBLER_STATUS_FAIL;
        destroy_tokenizer_list(assembler);
        return assembler->status;
    }

    /* Setup tokenizer */
    assembler->tokenizer = (struct tokenizer *)assembler->tokenizer_list->front->value;

    /* Setup lookahead */
    assembler->lookahead = get_next_token(assembler->tokenizer);

    /* Setup Symbol Table */
    assembler->symbol_table = create_symbol_table();

    /* Setup declared symbol list */
    assembler->decl_symlist = create_list();

    /* Default segment is SEGMENT_TEXT */
    assembler->segment = SEGMENT_TEXT;

    /* Setup segment / memory offsets */
    for(segment_t segment = 0; segment < MAX_SEGMENTS; ++segment) {
        assembler->segment_offset[segment] = SEGMENT_OFFSET_BASE[segment];
        assembler->segment_memory_offset[segment] = 0;
    }

    /* Default is ASSEMBLER_STATUS_OK */
    assembler->status = ASSEMBLER_STATUS_OK;

    /* Start grammar recognization... */
    program_cfg(assembler);

    #ifdef DEBUG
    if(assembler->status == ASSEMBLER_STATUS_OK) {
        for(segment_t segment = 0; segment < MAX_SEGMENTS; ++segment) {
            if(assembler->segment_memory_offset[segment] == 0) continue;
            printf("[ * Memory Segment %-4s * ]", segment_string[segment]);
            for(unsigned int i = 0; i < assembler->segment_memory_offset[segment]; i++) {
                if((i & (0x3)) == 0) printf("\n0x%08X  ", SEGMENT_OFFSET_BASE[segment] + i);
                unsigned char c = *((unsigned char *)assembler->segment_memory[segment] + i);
                printf("\\%02X ", c);
            }
            printf("\n\n");
        }
    }
    print_symbol_table(assembler->symbol_table);
    #endif

    /* Destory tokenizer list */
    destroy_tokenizer_list(assembler);

    /* Destroy symbol table */
    destroy_symbol_table(&assembler->symbol_table);

    /* Destroy declared symbol list */
    delete_linked_list(&assembler->decl_symlist, LN_VSTATIC);

    return assembler->status;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movb $0x0, %al
callq 0x71c0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x6fd7
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x8e60
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x6fb5
movq 0x7089(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
leaq 0x3c82(%rip), %rsi      # 0xac07
movb $0x0, %al
callq 0x30c0
xorl %eax, %eax
movl %eax, %edi
callq 0x3120
movq -0x10(%rbp), %rax
movb $0x2, 0x44(%rax)
movq -0x10(%rbp), %rdi
callq 0x6da0
movq -0x10(%rbp), %rax
movb 0x44(%rax), %al
movb %al, -0x1(%rbp)
jmp 0x70f8
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x7290
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x6f3e
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpq $0x0, (%rax)
jne 0x701d
movq 0x700c(%rip), %rax      # 0xdff8
movq (%rax), %rdi
leaq 0x387d(%rip), %rsi      # 0xa873
movb $0x0, %al
callq 0x30c0
movq -0x10(%rbp), %rax
movb $0x2, 0x44(%rax)
movq -0x10(%rbp), %rdi
callq 0x6da0
movq -0x10(%rbp), %rax
movb 0x44(%rax), %al
movb %al, -0x1(%rbp)
jmp 0x70f8
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x8f90
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x40(%rax)
movb $0x0, %al
callq 0x7bc0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
movb $0x0, %al
callq 0x71c0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0x45(%rax)
movb $0x0, -0x31(%rbp)
movzbl -0x31(%rbp), %eax
cmpl $0x4, %eax
jge 0x70b8
movzbl -0x31(%rbp), %eax
movl %eax, %ecx
leaq 0x33d2(%rip), %rax      # 0xa460
movl (%rax,%rcx,4), %edx
movq -0x10(%rbp), %rax
movzbl -0x31(%rbp), %ecx
movl %edx, 0x48(%rax,%rcx,4)
movq -0x10(%rbp), %rax
movzbl -0x31(%rbp), %ecx
movq $0x0, 0x58(%rax,%rcx,8)
movb -0x31(%rbp), %al
addb $0x1, %al
movb %al, -0x31(%rbp)
jmp 0x7078
movq -0x10(%rbp), %rax
movb $0x1, 0x44(%rax)
movq -0x10(%rbp), %rdi
callq 0x6bf0
movq -0x10(%rbp), %rdi
callq 0x6da0
movq -0x10(%rbp), %rdi
addq $0x10, %rdi
callq 0x7f70
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
xorl %esi, %esi
callq 0x7470
movq -0x10(%rbp), %rax
movb 0x44(%rax), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)