// File: /workspace/github_c_makefile_star2_O2/pocari[P]compilerbook-9cc/parser.c
// Function: stmt
static Node *stmt() {
  Token *tk;
  Node *node = NULL;

  if (tk = consume(";")) {
    node = new_node(ND_NULL, tk);
  } else if (tk = consume_kind(TK_RETURN)) {
    node = new_node(ND_RETURN, tk);
    if (!consume(";")) {
      node->lhs = expr();
      expect(";");
    }
  } else if (tk = consume_kind(TK_IF)) {
    node = new_node(ND_IF, tk);

    expect("(");
    node->cond = expr();
    expect(")");
    node->then = stmt();

    // elseがあればパース
    if (consume_kind(TK_ELSE)) {
      node->els = stmt();
    } else {
      node->els = NULL;
    }
  } else if (tk = consume_kind(TK_WHILE)) {
    node = new_node(ND_WHILE, tk);

    expect("(");
    node->cond = expr();
    expect(")");
    node->body = stmt();
  } else if (tk = consume_kind(TK_DO)) {
    node = new_node(ND_WHILE, tk);
    node->is_do_while = true;
    node->body = stmt();
    expect_kind(TK_WHILE);
    expect("(");
    node->cond = expr();
    expect(")");
    expect(";");
  } else if (tk = consume_kind(TK_FOR)) {
    node = new_node(ND_FOR, tk);
    Scope *sc = enter_scope();
    expect("(");
    if (consume(";")) {
      //次が";"なら初期化式なしなのでNULL入れる
      node->init = NULL;
    } else {
      // ";"でないなら初期化式かまたは辺宣言あるのでパース
      if (is_type(token)) {
        node->init = var_decl();
      } else {
        node->init = read_expr_stmt();
        expect(";");
      }
    }
    if (consume(";")) {
      //次が";"なら条件式なしなのでNULL入れる
      node->cond = NULL;
    } else {
      // ";"でないなら条件式があるのでパース
      node->cond = expr();
      expect(";");
    }
    if (consume(")")) {
      //次が")"なら継続式なしなのでNULL入れる
      node->inc = NULL;
    } else {
      // ")"でないなら継続式があるのでパース
      node->inc = read_expr_stmt();
      expect(")");
    }
    node->body = stmt();
    leave_scope(sc);
  } else if (tk = consume("{")) {
    node = new_node(ND_BLOCK, tk);
    Scope *sc = enter_scope();
    int i = 0;
    Node head = {};
    Node *cur = &head;
    while (!consume("}")) {
      cur->next = stmt();
      cur = cur->next;
    }
    node->body = head.next;
    leave_scope(sc);
  } else if (tk = consume_kind(TK_BREAK)) {
    expect(";");
    node = new_node(ND_BREAK, tk);
  } else if (tk = consume_kind(TK_CONTINUE)) {
    expect(";");
    node = new_node(ND_CONTINUE, tk);
  } else if (tk = consume_kind(TK_GOTO)) {
    char *ident = expect_ident();
    expect(";");
    node = new_node(ND_GOTO, tk);
    node->label_name = ident;
  } else if (tk = consume_kind(TK_SWITCH)) {
    expect("(");
    Node *switch_condition = expr();
    expect(")");
    node = new_unary_node(ND_SWITCH, switch_condition, tk);

    // 今のswitchを保存して現在のswitchに切り替える
    Node *tmp = current_switch;
    current_switch = node;
    node->body = stmt();
    // もとのswitchに戻す
    current_switch = tmp;
  } else if (tk = consume_kind(TK_CASE)) {
    if (!current_switch) {
      error(tk->str, "対応するswitchがありません");
    }
    int case_cond_val = const_expr();
    expect(":");
    node = new_unary_node(ND_CASE, stmt(), tk);
    node->case_cond_val = case_cond_val;
    node->is_default_case = false;
    node->case_next = current_switch->case_next;
    current_switch->case_next = node;
  } else if (tk = consume_kind(TK_DEFAULT)) {
    if (!current_switch) {
      error(tk->str, "対応するswitchがありません");
    }
    expect(":");
    node = new_unary_node(ND_CASE, stmt(), tk);
    node->is_default_case = true;
    current_switch->default_case = node;
  } else {
    Token *tmp = token;
    Token *tk = consume_ident();
    if (consume(":")) {
      // identの次に":" が来てたらラベル
      node = new_unary_node(ND_LABEL, stmt(), tk);
      node->label_name = my_strndup(tk->str, tk->len);
    } else {
      // ラベルじゃなかったので、もとに戻す
      token = tmp;
      // キーワードじゃなかったら 変数宣言かどうかチェック
      node = var_decl();
      if (!node) {
        // 変数宣言でなかったら式文
        node = read_expr_stmt();
        expect(";");
      }
    }
  }

  add_type(node);
  return node;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xc8, %rsp
leaq 0x307c(%rip), %rdi      # 0xa6ba
callq 0x498f
testq %rax, %rax
je 0x7670
pushq $0x31
popq %rdi
movq %rax, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %rbx, %rdi
callq 0x8a4d
movq %rbx, %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x7e09(%rip), %r15      # 0xf480
movq (%r15), %rsi
movl (%rsi), %eax
addl $-0x4, %eax
cmpl $0x5, %eax
ja 0x76c5
leaq 0x2fc9(%rip), %rcx      # 0xa654
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%rsi), %rax
movq %rax, (%r15)
pushq $0x18
popq %rdi
callq 0x4e7e
movq %rax, %rbx
leaq 0x300d(%rip), %rdi      # 0xa6ba
callq 0x498f
testq %rax, %rax
jne 0x7656
callq 0x7590
movq %rax, 0x18(%rbx)
jmp 0x777b
leaq 0x2c4a(%rip), %rdi      # 0xa316
callq 0x498f
testq %rax, %rax
je 0x7878
pushq $0x1a
popq %rdi
movq %rax, %rsi
callq 0x4e7e
movq %rax, %rbx
callq 0x7600
movq %rax, %r14
movq %rsp, %r15
movl $0xc8, %edx
movq %r15, %rdi
xorl %esi, %esi
callq 0x20e0
leaq 0x2fa4(%rip), %r12      # 0xa6ad
movq %r12, %rdi
callq 0x498f
testq %rax, %rax
jne 0x7864
callq 0x7629
movq %rax, 0x30(%r15)
movq %rax, %r15
jmp 0x7709
movq 0x8(%rsi), %rax
movq %rax, (%r15)
pushq $0x19
popq %rdi
callq 0x4e7e
movq %rax, %rbx
movb $0x1, 0x50(%rax)
callq 0x7629
movq %rax, 0x28(%rbx)
movq (%r15), %rax
cmpl $0x5, (%rax)
jne 0x7b5f
movq 0x8(%rax), %rax
movq %rax, (%r15)
leaq 0x2e15(%rip), %rdi      # 0xa576
callq 0x5644
callq 0x7590
movq %rax, 0x38(%rbx)
leaq 0x2e13(%rip), %rdi      # 0xa589
callq 0x5644
leaq 0x2f38(%rip), %rdi      # 0xa6ba
callq 0x5644
jmp 0x7656
movq 0x8(%rsi), %rax
movq %rax, (%r15)
pushq $0x19
popq %rdi
callq 0x4e7e
movq %rax, %rbx
leaq 0x2dd1(%rip), %rdi      # 0xa576
callq 0x5644
callq 0x7590
movq %rax, 0x38(%rbx)
leaq 0x2dcf(%rip), %rdi      # 0xa589
callq 0x5644
callq 0x7629
movq %rax, 0x28(%rbx)
jmp 0x7656
movq 0x8(%rsi), %rax
movq %rax, (%r15)
pushq $0x1b
popq %rdi
callq 0x4e7e
movq %rax, %rbx
leaq 0x2d90(%rip), %rdi      # 0xa576
callq 0x5644
callq 0x7590
movq %rax, 0x38(%rbx)
leaq 0x2d8e(%rip), %rdi      # 0xa589
callq 0x5644
callq 0x7629
movq %rax, 0x40(%rbx)
movq (%r15), %rax
cmpl $0x8, (%rax)
jne 0x786e
movq 0x8(%rax), %rax
movq %rax, (%r15)
callq 0x7629
movq %rax, 0x48(%rbx)
jmp 0x7656
movq 0x8(%rsi), %rax
movq %rax, (%r15)
pushq $0x1c
popq %rdi
callq 0x4e7e
movq %rax, %rbx
callq 0x7600
movq %rax, %r14
leaq 0x2d2f(%rip), %rdi      # 0xa576
callq 0x5644
leaq 0x2e67(%rip), %rdi      # 0xa6ba
callq 0x498f
testq %rax, %rax
je 0x78b3
andq $0x0, 0x58(%rbx)
jmp 0x78df
movq 0x30(%rsp), %rax
jmp 0x793e
andq $0x0, 0x48(%rbx)
jmp 0x7656
movq (%r15), %rbx
movl (%rbx), %ecx
leal -0x18(%rcx), %eax
cmpl $0x5, %eax
ja 0x7962
leaq 0x2ddc(%rip), %rcx      # 0xa66c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%rbx), %rax
movq %rax, (%r15)
leaq 0x2e13(%rip), %rdi      # 0xa6ba
callq 0x5644
pushq $0x2a
jmp 0x7ae0
movq (%r15), %rdi
callq 0x54e7
testb %al, %al
je 0x78ca
callq 0x7b91
movq %rax, 0x58(%rbx)
jmp 0x78df
callq 0x7e9b
movq %rax, 0x58(%rbx)
leaq 0x2de0(%rip), %rdi      # 0xa6ba
callq 0x5644
leaq 0x2dd4(%rip), %rdi      # 0xa6ba
callq 0x498f
testq %rax, %rax
je 0x78f7
andq $0x0, 0x38(%rbx)
jmp 0x790c
callq 0x7590
movq %rax, 0x38(%rbx)
leaq 0x2db3(%rip), %rdi      # 0xa6ba
callq 0x5644
leaq 0x2c76(%rip), %rdi      # 0xa589
callq 0x498f
testq %rax, %rax
je 0x7924
andq $0x0, 0x60(%rbx)
jmp 0x7939
callq 0x7e9b
movq %rax, 0x60(%rbx)
leaq 0x2c55(%rip), %rdi      # 0xa589
callq 0x5644
callq 0x7629
movq %rax, 0x28(%rbx)
movq (%r14), %rax
movq %rax, 0x7af4(%rip)      # 0xf440
movq 0x8(%r14), %rax
movq %rax, 0x7ae1(%rip)      # 0xf438
decl 0x7ad3(%rip)            # 0xf430
jmp 0x7656
cmpl $0x2, %ecx
jne 0x7a24
movq 0x8(%rbx), %rax
movq %rax, (%r15)
movq %rbx, %r14
jmp 0x7a27
movq 0x8(%rbx), %rax
movq %rax, (%r15)
cmpq $0x0, 0x7acf(%rip)      # 0xf458
je 0x7b7f
callq 0x56fc
movq %rax, %r14
leaq 0x1b83(%rip), %rdi      # 0x9521
callq 0x5644
callq 0x7629
movq %rax, %r15
pushq $0x2f
popq %rdi
movq %rbx, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %r15, 0x18(%rax)
movslq %r14d, %rax
movq %rax, 0xa8(%rbx)
movb $0x0, 0xb0(%rbx)
movq 0x7a83(%rip), %rax      # 0xf458
movq 0xc0(%rax), %rcx
movq %rcx, 0xc0(%rbx)
movq %rbx, 0xc0(%rax)
jmp 0x7656
movq 0x8(%rbx), %rax
movq %rax, (%r15)
callq 0x56c6
movq %rax, %r14
leaq 0x2cb5(%rip), %rdi      # 0xa6ba
callq 0x5644
pushq $0x2c
popq %rdi
movq %rbx, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %r14, 0xa0(%rax)
jmp 0x7656
xorl %r14d, %r14d
leaq 0x1af3(%rip), %rdi      # 0x9521
callq 0x498f
testq %rax, %rax
je 0x7b3e
callq 0x7629
movq %rax, %r15
pushq $0x2d
popq %rdi
movq %r14, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %r15, 0x18(%rax)
movq 0x18(%r14), %rdi
movl 0x20(%r14), %esi
callq 0x4903
movq %rax, 0xa0(%rbx)
jmp 0x7656
movq 0x8(%rbx), %rax
movq %rax, (%r15)
leaq 0x2af9(%rip), %rdi      # 0xa576
callq 0x5644
callq 0x7590
movq %rax, %r14
leaq 0x2af8(%rip), %rdi      # 0xa589
callq 0x5644
pushq $0x2e
popq %rdi
movq %rbx, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %r14, 0x18(%rax)
movq 0x79a9(%rip), %r14      # 0xf458
movq %rax, 0x79a2(%rip)      # 0xf458
callq 0x7629
movq %rax, 0x28(%rbx)
movq %r14, 0x7992(%rip)      # 0xf458
jmp 0x7656
movq 0x8(%rbx), %rax
movq %rax, (%r15)
leaq 0x2be1(%rip), %rdi      # 0xa6ba
callq 0x5644
pushq $0x2b
popq %rdi
movq %rbx, %rsi
jmp 0x764e
movq 0x8(%rbx), %rax
movq %rax, (%r15)
cmpq $0x0, 0x7960(%rip)      # 0xf458
je 0x7b7f
leaq 0x1a1c(%rip), %rdi      # 0x9521
callq 0x5644
callq 0x7629
movq %rax, %r14
pushq $0x2f
popq %rdi
movq %rbx, %rsi
callq 0x4e7e
movq %rax, %rbx
movq %r14, 0x18(%rax)
movb $0x1, 0xb0(%rax)
movq 0x7926(%rip), %rax      # 0xf458
movq %rbx, 0xb8(%rax)
jmp 0x7656
movq %rbx, (%r15)
callq 0x7b91
movq %rax, %rbx
testq %rax, %rax
jne 0x7656
callq 0x7e9b
movq %rax, %rbx
jmp 0x777b
movq 0x18(%rax), %rbx
pushq $0x5
popq %rdi
callq 0x8148
leaq 0x303b(%rip), %rsi      # 0xabad
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x46f0
movq 0x18(%rbx), %rdi
leaq 0x2ffe(%rip), %rsi      # 0xab88
xorl %eax, %eax
callq 0x485f