// File: /workspace/github_c_makefile_star2_O0/sebbekarlsson[P]cola/src/interpret.c
// Function: interpret_visit_component
ast_node* interpret_visit_component(ast_node_component* node) {
    save_component((scope*)ast_node_get_scope((ast_node*)node), node);
    
    if (node->deps->size == 0) {
        free(node->deps);
    } else {
        for (int i = 0; i < node->deps->size; i++) {
            ast_node_component* component = get_component(
                (scope*)ast_node_get_scope((ast_node*)node),
                ((token*)node->deps->items[i])->value
            );

            if (!component) {
                char msg[32];
                sprintf(msg, "could not find definition for: %s", ((token*)node->deps->items[i])->value);
                error_in_interpreter(msg);
            }

            interpret_visit((ast_node*)component->body);
            scope* tmp_scope = (scope*)ast_node_get_scope((ast_node*) component->body);

            for (int ii = 0; ii < tmp_scope->functions->size; ii++) {
                save_function_definition(
                    (scope*)ast_node_get_scope((ast_node*)node->body),
                    (ast_node_function_definition*)tmp_scope->functions->items[ii]
                );   
            }

            // look for yields function
            ast_node_function_definition* yields_definition = get_function_definition(
                tmp_scope,
                "yields"
            );

            if (yields_definition) {
                // lets create a variable definition in the currently visited
                // component and assign whatever the yields method returns
                // to it.
                ast_node_variable_definition* var_definition = init_ast_node_variable_definition(
                    (token*)node->deps->items[i],
                    yields_definition->data_type,
                    interpret_visit((ast_node*)yields_definition->body)
                );
                ast_node_set_scope(
                    (ast_node*) var_definition,
                    (struct scope*)tmp_scope // should use same scope as the-
                    // - component it came from
                );

                // save whatever the yields method returns as a variable
                // in the currently visited component.
                save_variable_definition(
                    (scope*)ast_node_get_scope((ast_node*)node->body),
                    var_definition 
                );
            }
        }
    }

    // check if main component
    if (strcmp(node->name->value, "main") == 0)
        interpret_visit((ast_node*)node->body);


    // look for run method
    ast_node_function_definition* run_definition = get_function_definition(
        (scope*)ast_node_get_scope((ast_node*)node->body),
        "run"
    );

    if (run_definition)
        interpret_visit((ast_node*)run_definition->body);

    return (ast_node*) node;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x12b0
movq %rax, %rdi
movq -0x8(%rbp), %rsi
callq 0x5e10
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
cmpq $0x0, (%rax)
jne 0x3284
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x1030
jmp 0x3406
movl $0x0, -0xc(%rbp)
movslq -0xc(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x30(%rcx), %rcx
cmpq (%rcx), %rax
jae 0x3404
movq -0x8(%rbp), %rdi
callq 0x12b0
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x8(%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rsi
callq 0x5f80
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x3307
leaq -0x40(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x8(%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdx
leaq 0x3eb3(%rip), %rsi      # 0x71aa
movb $0x0, %al
callq 0x1130
leaq -0x40(%rbp), %rdi
callq 0x2040
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x2110
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x12b0
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movslq -0x4c(%rbp), %rax
movq -0x48(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpq (%rcx), %rax
jae 0x3371
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x12b0
movq %rax, %rdi
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movslq -0x4c(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x5de0
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x332c
movq -0x48(%rbp), %rdi
leaq 0x3e50(%rip), %rsi      # 0x71cc
callq 0x5ed0
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x33f4
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x8(%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x78(%rbp)
movq -0x58(%rbp), %rax
movl 0x20(%rax), %eax
movl %eax, -0x6c(%rbp)
movq -0x58(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x2110
movq -0x78(%rbp), %rdi
movl -0x6c(%rbp), %esi
movq %rax, %rdx
callq 0x1990
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x12f0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x12b0
movq %rax, %rdi
movq -0x60(%rbp), %rsi
callq 0x5d00
jmp 0x33f6
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x328b
jmp 0x3406
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x3dba(%rip), %rsi      # 0x71d3
callq 0x10a0
cmpl $0x0, %eax
jne 0x3430
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x2110
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x12b0
movq %rax, %rdi
leaq 0x3d91(%rip), %rsi      # 0x71d8
callq 0x5ed0
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x3464
movq -0x68(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x2110
movq -0x8(%rbp), %rax
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)