// File: /workspace/github_c_makefile_star2_O0/johnvtan[P]ccccc/parse.c
// Function: parse_stmt
static stmt_t *parse_stmt(list_t *tokens, env_t *env) {
    if (!tokens || !env)
        return NULL;
    stmt_t *ret = malloc(sizeof(stmt_t));
    token_t *curr = list_peek(tokens);

    if (curr->type == TOK_OPEN_BRACE) {
        ret->block = parse_block(tokens, env);
        ret->type = STMT_BLOCK;
        return ret;
    }

    if (curr->type == TOK_RETURN) {
        debug("parse_stmt: Found return statement\n");
        return_stmt_t *ret_stmt = parse_return_stmt(tokens, env);
        if (!ret_stmt)
            return NULL;
        ret->type = STMT_RETURN;
        ret->ret = ret_stmt;
        return ret;
    }

    if (curr->type == TOK_IF) {
        if_stmt_t *if_stmt = parse_if_stmt(tokens, env);
        ret->type = STMT_IF;
        ret->if_stmt = if_stmt;
        return ret;
    }

    if (curr->type == TOK_FOR) {
        ret->for_stmt = parse_for_stmt(tokens, env);
        ret->type = STMT_FOR;
        return ret;
    }

    if (curr->type == TOK_WHILE) {
        ret->while_stmt = parse_while_stmt(tokens, env);
        ret->type = STMT_WHILE;
        return ret;
    }

    if (curr->type == TOK_DO) {
        debug("Found do stmt\n");
        ret->do_stmt = parse_do_stmt(tokens, env);
        ret->type = STMT_DO;
        return ret;
    }

    if (match(tokens, TOK_BREAK)) {
        debug("parse_stmt: Found break\n");
        expect_next(tokens, TOK_SEMICOLON);
        ret->type = STMT_BREAK;
        return ret;
    }

    if (match(tokens, TOK_CONTINUE)) {
        debug("parse_stmt: Found continue\n");
        expect_next(tokens, TOK_SEMICOLON);
        ret->type = STMT_CONTINUE;
        return ret;
    }

    // The first token in a declaration is a type
    if (is_type(curr->type)) {
        debug("parse_stmt: Found declaration statement\n");
        declare_stmt_t *declare = parse_declare_stmt(tokens, env);
        if (!declare)
            return NULL;
        ret->type = STMT_DECLARE;
        ret->declare = declare;
        return ret;
    }

    // Otherwise, try to parse an expression
    if (match(tokens, TOK_SEMICOLON)) {
        debug("parse_stmt: Found null expr stmt\n");
        ret->type = STMT_NULL;
        return ret;
    }

    debug("parse_stmt: Found nonnull expr stmt\n");
    expr_t *expr = parse_expr(tokens, env);
    ret->type = STMT_EXPR;
    ret->expr = expr; 
    expect_next(tokens, TOK_SEMICOLON);
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x58fe
cmpq $0x0, -0x18(%rbp)
jne 0x590b
movq $0x0, -0x8(%rbp)
jmp 0x5bdd
movl $0x10, %edi
callq 0x10e0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x48b0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0xc, (%rax)
jne 0x595e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5bf0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movl $0x3, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
cmpl $0x4, (%rax)
jne 0x59b3
jmp 0x5969
jmp 0x596b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5c50
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x5990
movq $0x0, -0x8(%rbp)
jmp 0x5bdd
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movq -0x30(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
cmpl $0x24, (%rax)
jne 0x59f0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5cb0
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movl $0x2, (%rax)
movq -0x38(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
cmpl $0x28, (%rax)
jne 0x5a28
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5da0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movl $0x6, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
cmpl $0x29, (%rax)
jne 0x5a60
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5ec0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movl $0x7, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
cmpl $0x2a, (%rax)
jne 0x5a9c
jmp 0x5a6b
jmp 0x5a6d
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5f50
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movl $0x8, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x10(%rbp), %rdi
movl $0x2b, %esi
callq 0x56a0
testb $0x1, %al
jne 0x5ab0
jmp 0x5ad9
jmp 0x5ab2
jmp 0x5ab4
movq -0x10(%rbp), %rdi
movl $0x12, %esi
callq 0x5800
movq -0x20(%rbp), %rax
movl $0x9, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x10(%rbp), %rdi
movl $0x2c, %esi
callq 0x56a0
testb $0x1, %al
jne 0x5aed
jmp 0x5b16
jmp 0x5aef
jmp 0x5af1
movq -0x10(%rbp), %rdi
movl $0x12, %esi
callq 0x5800
movq -0x20(%rbp), %rax
movl $0xa, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x28(%rbp), %rax
movl (%rax), %edi
callq 0x6000
testb $0x1, %al
jne 0x5b27
jmp 0x5b70
jmp 0x5b29
jmp 0x5b2b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x6030
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x5b50
movq $0x0, -0x8(%rbp)
jmp 0x5bdd
movq -0x20(%rbp), %rax
movl $0x1, (%rax)
movq -0x40(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
movq -0x10(%rbp), %rdi
movl $0x12, %esi
callq 0x56a0
testb $0x1, %al
jne 0x5b84
jmp 0x5b9c
jmp 0x5b86
jmp 0x5b88
movq -0x20(%rbp), %rax
movl $0x5, (%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5bdd
jmp 0x5b9e
jmp 0x5ba0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x6180
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
movl $0x4, (%rax)
movq -0x48(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rdi
movl $0x12, %esi
callq 0x5800
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)