// File: /workspace/github_c_makefile_star2_O3/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 0x7829(%rip), %rdi      # 0x13158
callq 0xaff5
testl %eax, %eax
je 0xb96f
callq 0xbeb2
movq %rax, %rbx
leaq 0x39dc(%rip), %rdi      # 0xf323
callq 0xa09f
testq %rax, %rax
jne 0xba11
movq 0x77fc(%rip), %rbx      # 0x13158
leaq 0x26ed(%rip), %rdi      # 0xe050
leaq 0x3968(%rip), %rsi      # 0xf2d2
jmp 0xbe4f
leaq 0x3c86(%rip), %rdi      # 0xf5fc
callq 0xa09f
testq %rax, %rax
je 0xb9db
movl $0x1d, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
movq 0x77c1(%rip), %rdi      # 0x13158
leaq 0x3985(%rip), %rsi      # 0xf323
callq 0xdab0
testb %al, %al
jne 0xb9b0
callq 0xb86a
movq %rax, 0x38(%rbx)
leaq 0x396c(%rip), %rdi      # 0xf323
callq 0xa09f
testq %rax, %rax
jne 0xba11
movq 0x7790(%rip), %rbx      # 0x13158
leaq 0x2681(%rip), %rdi      # 0xe050
leaq 0x391a(%rip), %rsi      # 0xf2f0
jmp 0xbe4f
leaq 0x2e88(%rip), %rdi      # 0xe86a
callq 0xa09f
testq %rax, %rax
je 0xba20
movl $0x27, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
leaq 0x3920(%rip), %rdi      # 0xf323
callq 0xa09f
testq %rax, %rax
je 0xbe0c
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x260f(%rip), %rdi      # 0xe036
callq 0xa09f
testq %rax, %rax
je 0xbaac
movq %rax, %rbx
leaq 0x3df3(%rip), %rdi      # 0xf82e
callq 0xa09f
testq %rax, %rax
je 0xbe3a
callq 0xb86a
movq %rax, %r14
leaq 0x3874(%rip), %rdi      # 0xf2cc
callq 0xa09f
testq %rax, %rax
je 0xbe23
callq 0xb920
movq %rax, %r15
leaq 0x2d72(%rip), %rdi      # 0xe7e7
callq 0xa09f
testq %rax, %rax
je 0xbb11
callq 0xb920
movq %rax, %r12
movl $0x1f, %edi
movq %rbx, %rsi
callq 0x9bd0
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
movq %r12, 0x68(%rax)
jmp 0xba11
leaq 0x3850(%rip), %rdi      # 0xf303
callq 0xa09f
testq %rax, %rax
je 0xbb2e
movl $0x20, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
leaq 0x3d5a(%rip), %rdi      # 0xf82e
callq 0xa09f
testq %rax, %rax
je 0xbe3a
callq 0xb86a
movq %rax, 0x58(%rbx)
leaq 0x37da(%rip), %rdi      # 0xf2cc
callq 0xa09f
testq %rax, %rax
je 0xbe23
callq 0xb920
movq %rax, 0x80(%rbx)
jmp 0xba11
movl $0x1e, %edi
movq %rbx, %rsi
callq 0x9bd0
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
jmp 0xba11
leaq 0x37d4(%rip), %rdi      # 0xf309
callq 0xa09f
testq %rax, %rax
je 0xbba7
movl $0x21, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
movq 0x762a(%rip), %r15      # 0x13180
leaq 0x3cd1(%rip), %rdi      # 0xf82e
callq 0xa09f
movq 0x75ef(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbe61
leaq 0x37aa(%rip), %rsi      # 0xf323
movq %r14, %rdi
callq 0xdab0
testb %al, %al
jne 0xbc50
movq 0x75c8(%rip), %rdi      # 0x13158
callq 0xaff5
testl %eax, %eax
je 0xbc47
callq 0xbeb2
jmp 0xbc4c
leaq 0x3777(%rip), %rdi      # 0xf325
callq 0xa09f
testq %rax, %rax
je 0xbc11
movq %rax, %r14
movl $0x24, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
leaq 0x3c5c(%rip), %rdi      # 0xf82e
callq 0xa09f
testq %rax, %rax
je 0xbe61
callq 0xb86a
movq %rax, 0x38(%rbx)
leaq 0x36dc(%rip), %rdi      # 0xf2cc
callq 0xa09f
testq %rax, %rax
jne 0xbb00
leaq 0x244b(%rip), %rdi      # 0xe050
leaq 0x36c0(%rip), %rsi      # 0xf2cc
jmp 0xbe8f
leaq 0x3714(%rip), %rdi      # 0xf32c
callq 0xa09f
testq %rax, %rax
je 0xbd13
movq %rax, %r14
movl $0x25, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
callq 0xab15
movq %rax, 0x38(%rbx)
jmp 0xbd37
callq 0xb86a
movq %rax, 0x70(%rbx)
leaq 0x36cc(%rip), %rdi      # 0xf323
callq 0xa09f
movq 0x74f5(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbe71
leaq 0x36b0(%rip), %rsi      # 0xf323
movq %r14, %rdi
callq 0xdab0
testb %al, %al
je 0xbca2
movq 0x74d2(%rip), %rsi      # 0x13158
xorl %edi, %edi
callq 0x9bd0
movq %rax, %r14
movl $0x1, 0x28(%rax)
callq 0x9cac
movq %rax, 0x10(%r14)
jmp 0xbcaa
callq 0xb86a
movq %rax, %r14
movq %r14, 0x58(%rbx)
leaq 0x366e(%rip), %rdi      # 0xf323
callq 0xa09f
movq 0x7497(%rip), %r14      # 0x13158
testq %rax, %rax
je 0xbe81
leaq 0x35fb(%rip), %rsi      # 0xf2cc
movq %r14, %rdi
callq 0xdab0
testb %al, %al
jne 0xbce6
callq 0xb86a
movq %rax, 0x78(%rbx)
leaq 0x35df(%rip), %rdi      # 0xf2cc
callq 0xa09f
testq %rax, %rax
je 0xbe23
callq 0xb920
movq %rax, 0x80(%rbx)
movq %r15, 0x7472(%rip)      # 0x13180
jmp 0xba11
leaq 0x3617(%rip), %rdi      # 0xf331
callq 0xa09f
testq %rax, %rax
je 0xbd5f
movq %rax, %r14
movl $0x26, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
leaq 0x36f0(%rip), %rdi      # 0xf42e
callq 0xa09f
testq %rax, %rax
jne 0xbb00
leaq 0x22fd(%rip), %rdi      # 0xe050
leaq 0x36d4(%rip), %rsi      # 0xf42e
jmp 0xbe8f
leaq 0x34bd(%rip), %rdi      # 0xf223
callq 0xa09f
testq %rax, %rax
je 0xbdfc
movl $0x22, %edi
movq %rax, %rsi
callq 0x9bd0
movq %rax, %rbx
xorl %eax, %eax
callq 0x307c
movq %rax, 0x30(%rbx)
movq 0x73ea(%rip), %r12      # 0x13180
movq 0x73bb(%rip), %rdi      # 0x13158
leaq 0x33bd(%rip), %rsi      # 0xf161
callq 0xdab0
testb %al, %al
jne 0xbddb
leaq 0x33ad(%rip), %r14      # 0xf161
movq 0x30(%rbx), %r15
callq 0xb920
movq %r15, %rdi
movq %rax, %rsi
callq 0x30ae
movq 0x7389(%rip), %rdi      # 0x13158
movq %r14, %rsi
callq 0xdab0
testb %al, %al
je 0xbdb4
leaq 0x337f(%rip), %rdi      # 0xf161
callq 0xa09f
testq %rax, %rax
je 0xbe9b
movq %r12, 0x7389(%rip)      # 0x13180
jmp 0xba11
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0xc0b9
movq 0x7345(%rip), %rbx      # 0x13158
leaq 0x2236(%rip), %rdi      # 0xe050
leaq 0x34d9(%rip), %rsi      # 0xf2fa
jmp 0xbe4f
movq 0x732e(%rip), %rbx      # 0x13158
leaq 0x221f(%rip), %rdi      # 0xe050
leaq 0x3494(%rip), %rsi      # 0xf2cc
jmp 0xbe4f
movq 0x7317(%rip), %rbx      # 0x13158
leaq 0x2208(%rip), %rdi      # 0xe050
leaq 0x39df(%rip), %rsi      # 0xf82e
xorl %eax, %eax
callq 0xd86a
movq %rbx, %rdi
movq %rax, %rsi
callq 0xcd01
leaq 0x21e8(%rip), %rdi      # 0xe050
leaq 0x39bf(%rip), %rsi      # 0xf82e
jmp 0xbe8f
leaq 0x21d8(%rip), %rdi      # 0xe050
leaq 0x348e(%rip), %rsi      # 0xf30d
jmp 0xbe8f
leaq 0x21c8(%rip), %rdi      # 0xe050
leaq 0x348a(%rip), %rsi      # 0xf319
xorl %eax, %eax
callq 0xd86a
movq %r14, %rdi
jmp 0xbe59
movq 0x72b6(%rip), %rbx      # 0x13158
leaq 0x21a7(%rip), %rdi      # 0xe050
leaq 0x32b1(%rip), %rsi      # 0xf161
jmp 0xbe4f