// File: /workspace/github_c_makefile_star2_O1/takoeight0821[P]hoc_nyan/src/parse.c
// Function: statement
static Node *statement() {
  Token *tok;
  if (is_typename(peek(0))) {
    Node *node = declaration();
    if (!match(";")) {
      parse_error("local variable declaration: ;", peek(0));
    }
    return node;
  } else if ((tok = match("return"))) {
    Node *node = new_node(NRETURN, tok);
    if (!eq_reserved(peek(0), ";")) {
      node->expr = expr();
    }
    if (!match(";")) {
      parse_error("return: ;", peek(0));
    }
    return node;
  } else if ((tok = match("break"))) {
    Node *node = new_node(NBREAK, tok);
    if (!match(";")) {
      parse_error("break: ;", peek(0));
    }
    return node;
  } else if ((tok = match("if"))) {
    if (!match("(")) {
      parse_error("(", peek(0));
    }
    Node *cond = expr();
    if (!match(")")) {
      parse_error(")", peek(0));
    }

    Node *then = statement();

    if (match("else")) {
      Node *els = statement();
      Node *node = new_node(NIFELSE, tok);
      node->cond = cond;
      node->then = then;
      node->els = els;
      return node;
    } else {
      Node *node = new_node(NIF, tok);
      node->cond = cond;
      node->then = then;
      return node;
    }
  } else if ((tok = match("while"))) {
    Node *node = new_node(NWHILE, tok);

    if (!match("(")) {
      parse_error("(", peek(0));
    }
    node->cond = expr();
    if (!match(")")) {
      parse_error(")", peek(0));
    }

    node->body = statement();

    return node;
  } else if ((tok = match("for"))) {
    Node *node = new_node(NFOR, tok);

    LVar *tmp = local_env;
    if (!match("(")) {
      parse_error("(", peek(0));
    }

    if (!(eq_reserved(peek(0), ";"))) {
      if (is_typename(peek(0))) {
        node->init = declaration();
      } else {
        node->init = expr();
      }
    }
    if (!match(";")) {
      parse_error("for init: ;", peek(0));
    }

    if (!(eq_reserved(peek(0), ";"))) {
      node->cond = expr();
    } else {
      node->cond = new_int_node(peek(0), 1);
    }
    if (!match(";")) {
      parse_error("for cond: ;", peek(0));
    }

    if (!(eq_reserved(peek(0), ")"))) {
      node->step = expr();
    }
    if (!match(")")) {
      parse_error(")", peek(0));
    }

    node->body = statement();

    local_env = tmp;

    return node;
  } else if ((tok = match("switch"))) {
    Node *node = new_node(NSWITCH, tok);

    if (!match("(")) {
      parse_error("(", tok);
    }
    node->expr = expr();
    if (!match(")")) {
      parse_error(")", tok);
    }

    node->body = statement();

    return node;
  } else if ((tok = match("case"))) {
    Node *node = new_node(NCASE, tok);
    node->expr = logical_or(); // TODO: support conditional expression
    if (!match(":")) {
      parse_error(":", tok);
    }
    node->body = statement();
    return node;
  } else if ((tok = match("default"))) {
    Node *node = new_node(NDEFAULT, tok);
    if (!match(":")) {
      parse_error(":", tok);
    }
    node->body = statement();
    return node;
  } else if ((tok = match("{"))) {
    Node *node = new_node(NBLOCK, tok);
    node->stmts = new_vec();

    LVar *tmp = local_env; // start scope

    while (!eq_reserved(peek(0), "}")) {
      vec_push(node->stmts, statement());
    }

    if (!match("}")) {
      parse_error("}", peek(0));
    }

    local_env = tmp; // end scope

    return node;
  } else {
    return expr_stmt();
  }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq 0x76ad(%rip), %rdi      # 0x13158
callq 0xb115
testl %eax, %eax
je 0xbaeb
callq 0xc02e
movq %rax, %rbx
leaq 0x3886(%rip), %rdi      # 0xf349
callq 0xa184
testq %rax, %rax
jne 0xbb8d
movq 0x7680(%rip), %rbx      # 0x13158
leaq 0x2571(%rip), %rdi      # 0xe050
leaq 0x3812(%rip), %rsi      # 0xf2f8
jmp 0xbfcb
leaq 0x3b31(%rip), %rdi      # 0xf623
callq 0xa184
testq %rax, %rax
je 0xbb57
movl $0x1d, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
movq 0x7645(%rip), %rdi      # 0x13158
leaq 0x382f(%rip), %rsi      # 0xf349
callq 0xda40
testb %al, %al
jne 0xbb2c
callq 0xb9e6
movq %rax, 0x38(%rbx)
leaq 0x3816(%rip), %rdi      # 0xf349
callq 0xa184
testq %rax, %rax
jne 0xbb8d
movq 0x7614(%rip), %rbx      # 0x13158
leaq 0x2505(%rip), %rdi      # 0xe050
leaq 0x37c4(%rip), %rsi      # 0xf316
jmp 0xbfcb
leaq 0x2d0c(%rip), %rdi      # 0xe86a
callq 0xa184
testq %rax, %rax
je 0xbb9c
movl $0x27, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
leaq 0x37ca(%rip), %rdi      # 0xf349
callq 0xa184
testq %rax, %rax
je 0xbf88
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x2493(%rip), %rdi      # 0xe036
callq 0xa184
testq %rax, %rax
je 0xbc28
movq %rax, %rbx
leaq 0x3c9b(%rip), %rdi      # 0xf852
callq 0xa184
testq %rax, %rax
je 0xbfb6
callq 0xb9e6
movq %rax, %r14
leaq 0x371e(%rip), %rdi      # 0xf2f2
callq 0xa184
testq %rax, %rax
je 0xbf9f
callq 0xba9c
movq %rax, %r15
leaq 0x2bf6(%rip), %rdi      # 0xe7e7
callq 0xa184
testq %rax, %rax
je 0xbc8d
callq 0xba9c
movq %rax, %r12
movl $0x1f, %edi
movq %rbx, %rsi
callq 0x9c68
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
movq %r12, 0x68(%rax)
jmp 0xbb8d
leaq 0x36fa(%rip), %rdi      # 0xf329
callq 0xa184
testq %rax, %rax
je 0xbcaa
movl $0x20, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
leaq 0x3c02(%rip), %rdi      # 0xf852
callq 0xa184
testq %rax, %rax
je 0xbfb6
callq 0xb9e6
movq %rax, 0x58(%rbx)
leaq 0x3684(%rip), %rdi      # 0xf2f2
callq 0xa184
testq %rax, %rax
je 0xbf9f
callq 0xba9c
movq %rax, 0x80(%rbx)
jmp 0xbb8d
movl $0x1e, %edi
movq %rbx, %rsi
callq 0x9c68
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
jmp 0xbb8d
leaq 0x367e(%rip), %rdi      # 0xf32f
callq 0xa184
testq %rax, %rax
je 0xbd23
movl $0x21, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
movq 0x74ae(%rip), %r15      # 0x13180
leaq 0x3b79(%rip), %rdi      # 0xf852
callq 0xa184
movq 0x7473(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbfdd
leaq 0x3654(%rip), %rsi      # 0xf349
movq %r14, %rdi
callq 0xda40
testb %al, %al
jne 0xbdcc
movq 0x744c(%rip), %rdi      # 0x13158
callq 0xb115
testl %eax, %eax
je 0xbdc3
callq 0xc02e
jmp 0xbdc8
leaq 0x3621(%rip), %rdi      # 0xf34b
callq 0xa184
testq %rax, %rax
je 0xbd8d
movq %rax, %r14
movl $0x24, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
leaq 0x3b04(%rip), %rdi      # 0xf852
callq 0xa184
testq %rax, %rax
je 0xbfdd
callq 0xb9e6
movq %rax, 0x38(%rbx)
leaq 0x3586(%rip), %rdi      # 0xf2f2
callq 0xa184
testq %rax, %rax
jne 0xbc7c
leaq 0x22cf(%rip), %rdi      # 0xe050
leaq 0x356a(%rip), %rsi      # 0xf2f2
jmp 0xc00b
leaq 0x35be(%rip), %rdi      # 0xf352
callq 0xa184
testq %rax, %rax
je 0xbe8f
movq %rax, %r14
movl $0x25, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
callq 0xac2d
movq %rax, 0x38(%rbx)
jmp 0xbeb3
callq 0xb9e6
movq %rax, 0x70(%rbx)
leaq 0x3576(%rip), %rdi      # 0xf349
callq 0xa184
movq 0x7379(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbfed
leaq 0x355a(%rip), %rsi      # 0xf349
movq %r14, %rdi
callq 0xda40
testb %al, %al
je 0xbe1e
movq 0x7356(%rip), %rsi      # 0x13158
xorl %edi, %edi
callq 0x9c68
movq %rax, %r14
movl $0x1, 0x28(%rax)
callq 0x9d54
movq %rax, 0x10(%r14)
jmp 0xbe26
callq 0xb9e6
movq %rax, %r14
movq %r14, 0x58(%rbx)
leaq 0x3518(%rip), %rdi      # 0xf349
callq 0xa184
movq 0x731b(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbffd
leaq 0x34a5(%rip), %rsi      # 0xf2f2
movq %r14, %rdi
callq 0xda40
testb %al, %al
jne 0xbe62
callq 0xb9e6
movq %rax, 0x78(%rbx)
leaq 0x3489(%rip), %rdi      # 0xf2f2
callq 0xa184
testq %rax, %rax
je 0xbf9f
callq 0xba9c
movq %rax, 0x80(%rbx)
movq %r15, 0x72f6(%rip)      # 0x13180
jmp 0xbb8d
leaq 0x34c1(%rip), %rdi      # 0xf357
callq 0xa184
testq %rax, %rax
je 0xbedb
movq %rax, %r14
movl $0x26, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
leaq 0x3598(%rip), %rdi      # 0xf452
callq 0xa184
testq %rax, %rax
jne 0xbc7c
leaq 0x2181(%rip), %rdi      # 0xe050
leaq 0x357c(%rip), %rsi      # 0xf452
jmp 0xc00b
leaq 0x3369(%rip), %rdi      # 0xf24b
callq 0xa184
testq %rax, %rax
je 0xbf78
movl $0x22, %edi
movq %rax, %rsi
callq 0x9c68
movq %rax, %rbx
xorl %eax, %eax
callq 0x307c
movq %rax, 0x30(%rbx)
movq 0x726e(%rip), %r12      # 0x13180
movq 0x723f(%rip), %rdi      # 0x13158
leaq 0x3269(%rip), %rsi      # 0xf189
callq 0xda40
testb %al, %al
jne 0xbf57
leaq 0x3259(%rip), %r14      # 0xf189
movq 0x30(%rbx), %r15
callq 0xba9c
movq %r15, %rdi
movq %rax, %rsi
callq 0x30b6
movq 0x720d(%rip), %rdi      # 0x13158
movq %r14, %rsi
callq 0xda40
testb %al, %al
je 0xbf30
leaq 0x322b(%rip), %rdi      # 0xf189
callq 0xa184
testq %rax, %rax
je 0xc017
movq %r12, 0x720d(%rip)      # 0x13180
jmp 0xbb8d
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0xc235
movq 0x71c9(%rip), %rbx      # 0x13158
leaq 0x20ba(%rip), %rdi      # 0xe050
leaq 0x3383(%rip), %rsi      # 0xf320
jmp 0xbfcb
movq 0x71b2(%rip), %rbx      # 0x13158
leaq 0x20a3(%rip), %rdi      # 0xe050
leaq 0x333e(%rip), %rsi      # 0xf2f2
jmp 0xbfcb
movq 0x719b(%rip), %rbx      # 0x13158
leaq 0x208c(%rip), %rdi      # 0xe050
leaq 0x3887(%rip), %rsi      # 0xf852
xorl %eax, %eax
callq 0xd7f2
movq %rbx, %rdi
movq %rax, %rsi
callq 0xce4d
leaq 0x206c(%rip), %rdi      # 0xe050
leaq 0x3867(%rip), %rsi      # 0xf852
jmp 0xc00b
leaq 0x205c(%rip), %rdi      # 0xe050
leaq 0x3338(%rip), %rsi      # 0xf333
jmp 0xc00b
leaq 0x204c(%rip), %rdi      # 0xe050
leaq 0x3334(%rip), %rsi      # 0xf33f
xorl %eax, %eax
callq 0xd7f2
movq %r14, %rdi
jmp 0xbfd5
movq 0x713a(%rip), %rbx      # 0x13158
leaq 0x202b(%rip), %rdi      # 0xe050
leaq 0x315d(%rip), %rsi      # 0xf189
jmp 0xbfcb