// File: /workspace/github_c_makefile_star2_O0/masyagin1998[P]GCI/src/parser/parser.c
// Function: stmt_ast_read
static enum PARSER_CODES stmt_ast_read(struct PARSER*parser, struct STMT_AST**stmt)
{
    enum PARSER_CODES r;
    
    switch ((parser->tok)->token_type) {
    case TOKEN_TYPE_LET: {
        struct DECL_STMT_AST*decl_stmt;
        r = decl_stmt_ast_read(parser, &decl_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(decl_stmt, AST_STMT_TYPE_DECL);
        break;
    }
    case TOKEN_TYPE_IDENT: {
        struct IDENT_AST*ident = create_ident_ast((parser->tok)->str_val,
                                                  (parser->tok)->frag.starting.line,
                                                  (parser->tok)->frag.starting.pos);
        token_free((parser->tok));
        lexer_next_token(parser->lexer, &(parser->tok));
        /* check, if name is part of variable or name is function name. */
        switch ((parser->tok)->token_type) {
        case TOKEN_TYPE_LPAREN: {
            struct FUNCTION_CALL_AST*function_call;    
            struct FUNCTION_CALL_STMT_AST*function_call_stmt;

            r = function_call_ast_read(parser, &function_call, ident);
            if (r != PARSER_OK) {
                ident_ast_free(ident);
                goto err0;
            }

            function_call_stmt = create_function_call_stmt_ast(function_call,
                                                               (parser->tok)->frag.starting.line,
                                                               (parser->tok)->frag.starting.pos);
            (*stmt) = create_stmt_ast(function_call_stmt, AST_STMT_TYPE_FUNCTION_CALL);
            break;
        }
        default: {
            struct ASSIGN_STMT_AST*assign_stmt;
            struct VARIABLE_AST*var_name;
            struct ASSIGNMENT_EXPR_AST*assignment_expr;

            r = variable_ast_read(parser, &var_name, ident);
            if (r != PARSER_OK) {
                ident_ast_free(ident);
                goto err0;
            }

            if ((parser->tok)->token_type != TOKEN_TYPE_EQ) {
                ident_ast_free(ident);
                variable_ast_free(var_name);
                r = PARSER_INVALID_TOKEN;
                set_parser_error(parser, 1, TOKEN_TYPE_EQ);
                goto err0;
            }            
            token_free((parser->tok));
            lexer_next_token(parser->lexer, &(parser->tok));

            /* reading assignment expr. */
            r = assignment_expr_ast_read(parser, &assignment_expr);
            if (r != PARSER_OK) {
                ident_ast_free(ident);
                variable_ast_free(var_name);
                goto err0;
            }

            assign_stmt = create_assign_stmt_ast(var_name, assignment_expr,
                                                 (parser->tok)->frag.starting.line,
                                                 (parser->tok)->frag.starting.pos);
            (*stmt) = create_stmt_ast(assign_stmt, AST_STMT_TYPE_ASSIGN);
        }
        }

        if ((parser->tok)->token_type != TOKEN_TYPE_SEMI) {
            stmt_ast_free(*stmt);
            r = PARSER_INVALID_TOKEN;
            set_parser_error(parser, 1, TOKEN_TYPE_SEMI);
            goto err0;
        }
        token_free((parser->tok));
        lexer_next_token(parser->lexer, &(parser->tok));
        
        break;
    }
    case TOKEN_TYPE_IF: {
        struct IF_STMT_AST*if_stmt;
        r = if_stmt_ast_read(parser, &if_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(if_stmt, AST_STMT_TYPE_IF);
        break;
    }
    case TOKEN_TYPE_WHILE: {
        struct WHILE_STMT_AST*while_stmt;
        r = while_stmt_ast_read(parser, &while_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(while_stmt, AST_STMT_TYPE_WHILE);
        break;
    }
    case TOKEN_TYPE_BREAK: {
        struct BREAK_STMT_AST*break_stmt;
        r = break_stmt_ast_read(parser, &break_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(break_stmt, AST_STMT_TYPE_BREAK);
        break;
    }
    case TOKEN_TYPE_CONTINUE: {
        struct CONTINUE_STMT_AST*continue_stmt;
        r = continue_stmt_ast_read(parser, &continue_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(continue_stmt, AST_STMT_TYPE_CONTINUE);        
        break;
    }
    case TOKEN_TYPE_APPEND: {
        struct APPEND_STMT_AST*append_stmt;
        r = append_stmt_ast_read(parser, &append_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(append_stmt, AST_STMT_TYPE_APPEND);
        break;
    }
    case TOKEN_TYPE_DELETE: {
        struct DELETE_STMT_AST*delete_stmt;
        r = delete_stmt_ast_read(parser, &delete_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(delete_stmt, AST_STMT_TYPE_DELETE);
        break;
    }
    case TOKEN_TYPE_RETURN: {
        struct RETURN_STMT_AST*return_stmt;
        r = return_stmt_ast_read(parser, &return_stmt);
        if (r != PARSER_OK) {
            goto err0;
        }
        (*stmt) = create_stmt_ast(return_stmt, AST_STMT_TYPE_RETURN);
        break;
    }
    default: {
        r = PARSER_INVALID_TOKEN;
        set_parser_error(parser, 9, TOKEN_TYPE_LET, TOKEN_TYPE_IDENT, TOKEN_TYPE_IF,
                         TOKEN_TYPE_WHILE, TOKEN_TYPE_BREAK, TOKEN_TYPE_CONTINUE,
                         TOKEN_TYPE_APPEND, TOKEN_TYPE_DELETE,
                         TOKEN_TYPE_RETURN);
        goto err0;
        break;
    }
    }

    return PARSER_OK;

 err0:
    (*stmt) = NULL;
    return r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x98(%rbp)
subl $0xb, %eax
ja 0x4c0a
movq -0x98(%rbp), %rax
leaq 0x13fb5(%rip), %rcx     # 0x187e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x4c90
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4853
jmp 0x4c69
movq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, %rdi
addq $0x58, %rdi
movq 0x18(%rax), %rsi
movq 0x20(%rax), %rdx
callq 0xd670
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x31b0
movq -0x10(%rbp), %rsi
movq (%rsi), %rdi
addq $0x8, %rsi
callq 0x1fd0
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movl (%rax), %eax
subl $0x1b, %eax
jne 0x4925
jmp 0x48bb
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x38(%rbp), %rsi
callq 0x4e30
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x48e3
movq -0x30(%rbp), %rdi
callq 0x8b30
jmp 0x4c69
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdx
callq 0x9b10
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4a1c
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x50(%rbp), %rsi
callq 0x4f80
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x494d
movq -0x30(%rbp), %rdi
callq 0x8b30
jmp 0x4c69
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x15, (%rax)
je 0x498d
movq -0x30(%rbp), %rdi
callq 0x8b30
movq -0x50(%rbp), %rdi
callq 0x9a80
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rdi
movl $0x1, %esi
movl $0x15, %edx
movb $0x0, %al
callq 0x4030
jmp 0x4c69
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x31b0
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x8, %rsi
callq 0x1fd0
movq -0x10(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x5190
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x49db
movq -0x30(%rbp), %rdi
callq 0x8b30
movq -0x50(%rbp), %rdi
callq 0x9a80
jmp 0x4c69
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rcx
callq 0x98b0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movl $0x1, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x23, (%rax)
je 0x4a56
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x8fe0
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rdi
movl $0x1, %esi
movl $0x23, %edx
movb $0x0, %al
callq 0x4030
jmp 0x4c69
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x31b0
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x8, %rsi
callq 0x1fd0
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x5280
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4a97
jmp 0x4c69
movq -0x60(%rbp), %rdi
movl $0x3, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x5660
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4acf
jmp 0x4c69
movq -0x68(%rbp), %rdi
movl $0x4, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x57f0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4b07
jmp 0x4c69
movq -0x70(%rbp), %rdi
movl $0x5, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x5900
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4b3f
jmp 0x4c69
movq -0x78(%rbp), %rdi
movl $0x6, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x5a10
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4b77
jmp 0x4c69
movq -0x80(%rbp), %rdi
movl $0x7, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x5c90
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4bb2
jmp 0x4c69
movq -0x88(%rbp), %rdi
movl $0x8, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x5f10
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x4bed
jmp 0x4c69
movq -0x90(%rbp), %rdi
movl $0x9, %esi
callq 0x90f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x4c60
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rdi
movl $0x9, %esi
movl $0x1, %edx
movl $0xc, %ecx
movl $0x2, %r8d
movl $0x4, %r9d
movl $0x5, (%rsp)
movl $0x6, 0x8(%rsp)
movl $0x7, 0x10(%rsp)
movl $0x8, 0x18(%rsp)
movl $0xb, 0x20(%rsp)
movb $0x0, %al
callq 0x4030
jmp 0x4c69
movl $0x0, -0x4(%rbp)
jmp 0x4c7a
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)