// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x5470
movq %rax, 0x8(%rbx)
cmpq %r12, %r15
je 0x533d
movq (%r14,%r12,8), %rdi
callq 0x64bd
testq %rax, %rax
je 0x53db
movq 0x8(%rbx), %rdi
movq %rax, %rsi
callq 0x54c6
incq %r12
jmp 0x5315
movq 0x8(%rbx), %rax
movq (%rax), %rax
testq %rax, %rax
je 0x5400
movq 0x8(%rax), %rdi
movq %rdi, (%rbx)
callq 0x654d
movl %eax, 0x40(%rbx)
xorl %eax, %eax
callq 0x5a6e
leaq 0x10(%rbx), %r14
movq %rax, 0x10(%rbx)
xorl %eax, %eax
callq 0x5470
leaq 0x18(%rbx), %r15
movq %rax, 0x18(%rbx)
movb $0x0, 0x45(%rbx)
pushq $0x2c
popq %rax
leaq 0x1ef8(%rip), %rcx      # 0x7280
cmpq $0x3c, %rax
je 0x53a1
movl -0x2c(%rax,%rcx), %edx
movl %edx, 0x1c(%rbx,%rax)
andq $0x0, (%rbx,%rax,2)
addq $0x4, %rax
jmp 0x5388
leaq 0x44(%rbx), %r12
movb $0x1, 0x44(%rbx)
movq %rbx, %rdi
callq 0x5188
movq %rbx, %rdi
callq 0x525a
movq %r14, %rdi
callq 0x5c63
movq %r15, %rdi
xorl %esi, %esi
callq 0x5588
movb (%r12), %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x5c16(%rip), %rax      # 0xaff8
movq (%rax), %rdi
movq (%r14,%r12,8), %rdx
leaq 0x25e4(%rip), %rsi      # 0x79d4
xorl %eax, %eax
callq 0x30d0
xorl %edi, %edi
callq 0x3130
jmp 0x541c
movq 0x5bf1(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x2282(%rip), %rdi      # 0x7693
pushq $0x23
popq %rsi
pushq $0x1
popq %rdx
callq 0x3160
leaq 0x44(%rbx), %r12
movb $0x2, 0x44(%rbx)
movq %rbx, %rdi
callq 0x525a
jmp 0x53cb