// File: /workspace/github_c_makefile_star2_O0/chgzm[P]minic/parser.c
// Function: create_direct_declarator_node
static DirectDeclaratorNode* create_direct_declarator_node(const Vector* vec, int* index) {
    DirectDeclaratorNode* direct_declarator_node = calloc(1, sizeof(DirectDeclaratorNode));

    direct_declarator_node->identifier_list = create_vector();

    const Token* token = vec->elements[*index];
    switch (token->type) {
    case TK_IDENT: {
        direct_declarator_node->identifier = strdup(token->str);
        ++(*index);
        break;
    }
    case TK_LPAREN: {
        ++(*index);
        // @todo
        break;
    }
    default: {
        break;
    }
    }

    DirectDeclaratorNode* current = direct_declarator_node;
    token = vec->elements[*index];
    while (token->type == TK_LSQUARE || token->type == TK_LPAREN) {
        ++(*index);
   
        DirectDeclaratorNode* p_direct_declarator_node = calloc(1, sizeof(DirectDeclaratorNode));
        
        p_direct_declarator_node->direct_declarator_node = current;
        p_direct_declarator_node->identifier_list        = create_vector();

        switch (token->type) {
        case TK_LSQUARE: {
            token = vec->elements[*index];
            if (token->type == TK_RSQUARE) {
                ++(*index);
                break;
            }

            p_direct_declarator_node->conditional_expr_node = create_conditional_expr_node(vec, index);
            if (p_direct_declarator_node->conditional_expr_node == NULL) {
                error("Failed to create constant-expression node.\n");
                return NULL;
            }

            token = vec->elements[*index];
            if (token->type != TK_RSQUARE) {
                error("Invalid token[%d]=\"%s\".\n", *index, decode_token_type(token->type));
                return NULL;
            }
            ++(*index);

            break;
        }
        case TK_LPAREN: {
            if (is_declaration_specifier(vec, *index)) {
                p_direct_declarator_node->param_type_list_node = create_param_type_list_node(vec, index);
                if (p_direct_declarator_node->param_type_list_node == NULL) {
                    error("Failed to create parameter-type-list node.\n");
                    return NULL;
                } 

                token = vec->elements[*index];
                if (token->type != TK_RPAREN) {
                    error("Invalid token[%d]=\"%s\".\n", *index, decode_token_type(token->type));
                    return NULL;
                }
                ++(*index);
            } 
            else {
                token = vec->elements[*index];
                while (token->type == TK_IDENT) {
                    char* identifier = strdup(token->str);
                    vector_push_back(p_direct_declarator_node->identifier_list, identifier);

                    ++(*index);
                    token = vec->elements[*index];
                }

                if (token->type != TK_RPAREN) {
                    error("Invalid token[%d]=\"%s\".\n", *index, decode_token_type(token->type));
                    return NULL;
                }
                ++(*index);
            }
              
            break;
        }
        default: {
            break;
        }
        }

        token = vec->elements[*index];
        current = p_direct_declarator_node;
    }

    return current;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl $0x1, %edi
movl $0x30, %esi
callq 0x10b0
movq %rax, -0x20(%rbp)
xorl %eax, %eax
callq 0xe5c0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x44(%rbp)
subl $0x3, %eax
je 0x8aa5
jmp 0x8a9b
movl -0x44(%rbp), %eax
subl $0x21, %eax
je 0x8ac9
jmp 0x8ad6
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x1170
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8ad8
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8ad8
jmp 0x8ad8
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
movb $0x1, %al
cmpl $0x25, (%rcx)
movb %al, -0x45(%rbp)
je 0x8b11
movq -0x28(%rbp), %rax
cmpl $0x21, (%rax)
sete %al
movb %al, -0x45(%rbp)
movb -0x45(%rbp), %al
testb $0x1, %al
jne 0x8b1d
jmp 0x8dd6
movq -0x18(%rbp), %rax
movl (%rax), %ecx
incl %ecx
movl %ecx, (%rax)
movl $0x1, %edi
movl $0x30, %esi
callq 0x10b0
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
xorl %eax, %eax
callq 0xe5c0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x28(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x4c(%rbp)
subl $0x21, %eax
je 0x8c4b
jmp 0x8b6c
movl -0x4c(%rbp), %eax
subl $0x25, %eax
jne 0x8db1
jmp 0x8b7a
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x26, (%rax)
jne 0x8ba9
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8db3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x8df0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x8be7
leaq 0x7595(%rip), %rdi      # 0x10168
movb $0x0, %al
callq 0xe4e0
movq $0x0, -0x8(%rbp)
jmp 0x8dde
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x26, (%rax)
je 0x8c3b
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %edi
callq 0xe050
movl -0x50(%rbp), %esi
movq %rax, %rdx
leaq 0x7309(%rip), %rdi      # 0xff30
movb $0x0, %al
callq 0xe4e0
movq $0x0, -0x8(%rbp)
jmp 0x8dde
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8db3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %esi
callq 0x7eb0
testb $0x1, %al
jne 0x8c63
jmp 0x8d05
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x8f70
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jne 0x8ca1
leaq 0x7507(%rip), %rdi      # 0x10194
movb $0x0, %al
callq 0xe4e0
movq $0x0, -0x8(%rbp)
jmp 0x8dde
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x22, (%rax)
je 0x8cf5
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x54(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %edi
callq 0xe050
movl -0x54(%rbp), %esi
movq %rax, %rdx
leaq 0x724f(%rip), %rdi      # 0xff30
movb $0x0, %al
callq 0xe4e0
movq $0x0, -0x8(%rbp)
jmp 0x8dde
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8daf
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x3, (%rax)
jne 0x8d69
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x1170
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0xe610
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
jmp 0x8d1b
movq -0x28(%rbp), %rax
cmpl $0x22, (%rax)
je 0x8da4
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x58(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %edi
callq 0xe050
movl -0x58(%rbp), %esi
movq %rax, %rdx
leaq 0x719d(%rip), %rdi      # 0xff30
movb $0x0, %al
callq 0xe4e0
movq $0x0, -0x8(%rbp)
jmp 0x8dde
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8db3
jmp 0x8db3
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x8af6
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)