// File: /workspace/github_c_makefile_star2_O3/ryvnf[P]czc/parse.c
// Function: parse_type
static struct ast *parse_type(struct parse *parse)
{
    struct loc *line = get_linenr(parse);
    switch (peek_tok(parse)->type) {
        case '^': {
            parse->pos++;

	    struct ast *type = parse_type(parse);
            if (type == NULL)
                return type;

            return ast_new_ast(line, PTR_EXPR, 1, type);
        }
        case '[': {
            struct ast *expr = parse_enclosed(parse, '[', parse_expr, ']', false);
            if (expr == NULL)
                return NULL;

            struct ast *type = parse_type(parse);
            if (type == NULL) {
                ast_unref(expr);
                return type;
            }

            return ast_new_ast(line, ARRAY_EXPR, 2, type, expr);
        }
        case '(': {
            struct ast *param_list = parse_enclosed(parse, '(',
                    parse_param_list, ')', false);

            struct ast *type = parse_type(parse);
            if (type == NULL) {
                ast_unref(param_list);
                return NULL;
            }

            return ast_new_ast(line, FUNC_EXPR, 2, param_list, type);
        }
        case IDENT_TOK: {
            char *s = parse->tokens[parse->pos++].val.u.s;
            return ast_new_s(line, NAME, s);
        }
        case '{': {
            struct ast *field_list = parse_enclosed(parse, '{',
                    parse_decl_list, '}', false);
            return field_list;
        }
    }

    return NULL;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %r14
movq (%rdi), %rdx
movslq 0x14(%rdi), %rax
movq %rax, %rsi
shlq $0x5, %rsi
movq 0x8(%rdx,%rsi), %rbx
movl (%rdx,%rsi), %ecx
cmpl $0x5d, %ecx
jle 0x9b96
cmpl $0x120, %ecx            # imm = 0x120
je 0x9c08
cmpl $0x7b, %ecx
je 0x9c25
cmpl $0x5e, %ecx
jne 0x9c99
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
callq 0x9b22
testq %rax, %rax
je 0x9c99
movl $0x1, %edx
movq %rbx, %rdi
movl $0x4300, %esi           # imm = 0x4300
movq %rax, %rcx
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
jmp 0x2552
cmpl $0x28, %ecx
je 0x9c46
cmpl $0x5b, %ecx
jne 0x9c99
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
xorl %esi, %esi
callq 0x9ef1
testq %rax, %rax
je 0x9c99
movq %rax, %r15
movq (%r14), %rcx
movslq 0x14(%r14), %rax
movq %rax, %rdx
shlq $0x5, %rdx
cmpl $0x5d, (%rcx,%rdx)
jne 0x9c91
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
callq 0x9b22
testq %rax, %rax
je 0x9c91
movl $0x2, %edx
movq %rbx, %rdi
movl $0x4301, %esi           # imm = 0x4301
movq %rax, %rcx
movq %r15, %r8
jmp 0x9c85
incl %eax
movl %eax, 0x14(%r14)
movq 0x10(%rdx,%rsi), %rdx
movq %rbx, %rdi
movl $0x1000, %esi           # imm = 0x1000
popq %rbx
popq %r14
popq %r15
jmp 0x247d
leaq 0x292(%rip), %rdx       # 0x9ebe
movq %r14, %rdi
movl $0x7b, %esi
movl $0x7d, %ecx
xorl %r8d, %r8d
popq %rbx
popq %r14
popq %r15
jmp 0x9cd5
leaq 0x10f(%rip), %rdx       # 0x9d5c
movq %r14, %rdi
movl $0x28, %esi
movl $0x29, %ecx
xorl %r8d, %r8d
callq 0x9cd5
movq %rax, %r15
movq %r14, %rdi
callq 0x9b22
testq %rax, %rax
je 0x9c91
movl $0x2, %edx
movq %rbx, %rdi
movl $0x4302, %esi           # imm = 0x4302
movq %r15, %rcx
movq %rax, %r8
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
jmp 0x2552
movq %r15, %rdi
callq 0x26ef
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
retq