// File: /workspace/github_c_makefile_star2_O3/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
cmpl $0x19, %esi
jg 0x3d3f
leal -0x1(%rsi), %eax
cmpl $0xb, %eax
ja 0x3e9c
leaq 0x161f(%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 0x3c0c
cmpl $0x25, %esi
jg 0x3d6f
cmpl $0x1a, %esi
je 0x3e15
cmpl $0x1c, %esi
je 0x3e72
cmpl $0x22, %esi
jne 0x3e9c
movq %r14, %rdi
movq %rbx, %rsi
callq 0x380d
jmp 0x3e56
cmpl $0x26, %esi
je 0x3e3a
cmpl $0x27, %esi
je 0x3e87
cmpl $0x2f, %esi
jne 0x3e9c
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3eaf
movq %r14, %rdi
movl $0x6, %esi
jmp 0x3e1d
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3688
movq %r14, %rdi
movl $0x5, %esi
jmp 0x3e1d
movq %r14, %rdi
movl $0x3, %esi
callq 0x3652
movq 0x8(%r15), %rsi
movq %r15, %rdi
callq 0x165c
jmp 0x3e56
movq %r14, %rdi
movl $0xc, %esi
callq 0x3652
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3740
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x12cb
movq %r14, %rdi
movl $0xd, %esi
callq 0x3652
jmp 0x3e64
movq %r14, %rdi
movl $0x1a, %esi
callq 0x3652
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3cf2
movq %r15, %rdi
movq %rax, %rsi
callq 0x168c
jmp 0x3e56
movq %r14, %rdi
movl $0x26, %esi
callq 0x3652
movq 0x8(%r15), %rax
movsbl (%rax), %esi
movq %r15, %rdi
callq 0x1370
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x12cb
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 0x3c50
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3899
leaq 0x152f(%rip), %rdi      # 0x53d2
xorl %r15d, %r15d
xorl %eax, %eax
callq 0x10a0
jmp 0x3e64