// File: /workspace/github_c_makefile_star2_O2/sebbekarlsson[P]cola/src/parse.c
// Function: parse_factor
ast_node* parse_factor(parse_state* state, scope* sc) {
    token* tok = state->current_token;

    if (tok->type == _OP_PLUS) {
        parse_eat(state, _OP_PLUS);
        ast_node_unaryop* node = init_ast_node_unaryop(tok, parse_factor(state, sc));
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        // invalid pointer type
        return (ast_node*) node;

    } else if (tok->type == _OP_SUBTRACT) {
        parse_eat(state, _OP_SUBTRACT);
        ast_node_unaryop* node = init_ast_node_unaryop(tok, parse_factor(state, sc));
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        // invalid pointer type
        return (ast_node*) node;

    } else if (tok->type == _NOT_EQUALS) {
        parse_eat(state, _NOT_EQUALS);
        ast_node_unaryop* node = init_ast_node_unaryop(tok, parse_factor(state, sc));
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        // invalid pointer type
        return (ast_node*) node;

    } else if (tok->type == _INTEGER) {
        return (ast_node*) parse_integer(state, sc);
    } else if (tok->type == _FLOAT) {
        return (ast_node*) parse_float(state, sc);
    } else if (tok->type == _CHAR) {
        parse_eat(state, _CHAR);
        ast_node_char* node = init_ast_node_char(tok, tok->value[0]);
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        // invalid pointer type
        return (ast_node*) node;

    } else if (tok->type == _STRING) {
        parse_eat(state, _STRING);
        ast_node_string* node = init_ast_node_string(tok, tok->value);
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        // invalid pointer type
        return (ast_node*) node;
    
    } else if (tok->type == _TYPE_COMPONENT) {
        return (ast_node*) parse_component(state, sc);
    } else if (tok->type == _ID) {
        return (ast_node*) parse_variable(state, sc);
    } else if (tok->type == _FUNCTION_CALL) {
        return (ast_node*) parse_function_call(state, sc);
    } else if (tok->type == _LPAREN) {
        parse_eat(state, _LPAREN);
        ast_node* node = parse_expr(state, sc);
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        parse_eat(state, _RPAREN);
        return node;
    } else if (tok->type == _LBRACKET) {
        ast_node_vector* node = parse_vector(state, sc);
        ast_node_set_scope((ast_node*) node, (struct scope*) sc);
        return (ast_node*) node;
    } else {
        printf("Unexpected token_type: `%d`\n", tok->type);
        return (void*)0;
    }

    return (ast_node*) parse_expr(state,sc );
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movq 0x8(%rdi), %r15
movl (%r15), %esi
leal -0x1(%rsi), %eax
cmpl $0xb, %eax
ja 0x37de
leaq 0x1b80(%rip), %rcx      # 0x5340
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x36b3
cmpl $0x1a, %esi
je 0x38af
cmpl $0x1c, %esi
je 0x391d
cmpl $0x22, %esi
je 0x38a2
cmpl $0x26, %esi
je 0x38d2
cmpl $0x27, %esi
je 0x3908
cmpl $0x2f, %esi
jne 0x3822
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3932
leaq 0x1ba9(%rip), %rdi      # 0x53d2
xorl %r15d, %r15d
xorl %eax, %eax
callq 0x10a0
jmp 0x38fa
pushq $0x5
jmp 0x38b1
pushq $0xc
popq %rsi
movq %r14, %rdi
callq 0x315c
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3244
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x12d2
pushq $0xd
popq %rsi
movq %r14, %rdi
callq 0x315c
jmp 0x38fa
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3192
pushq $0x3
popq %rsi
movq %r14, %rdi
callq 0x315c
movq 0x8(%r15), %rsi
movq %r15, %rdi
callq 0x1624
jmp 0x38ec
pushq $0x6
jmp 0x38b1
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3305
jmp 0x38ec
pushq $0x1a
popq %rsi
movq %r14, %rdi
callq 0x315c
movq %r14, %rdi
movq %rbx, %rsi
callq 0x379a
movq %r15, %rdi
movq %rax, %rsi
callq 0x1650
jmp 0x38ec
pushq $0x26
popq %rsi
movq %r14, %rdi
callq 0x315c
movq 0x8(%r15), %rax
movsbl (%rax), %esi
movq %r15, %rdi
callq 0x136c
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x12d2
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x33a2
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x36f5