// File: /workspace/github_c_makefile_star2_O2/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 0x922f(%rip), %rdi      # 0x12158
callq 0x876f
testl %eax, %eax
je 0x8f62
callq 0x9457
movq %rax, %rbx
leaq 0x4408(%rip), %rdi      # 0xd349
callq 0x7967
testq %rax, %rax
jne 0x8ff9
movq 0x9202(%rip), %rsi      # 0x12158
leaq 0x439b(%rip), %rdi      # 0xd2f8
callq 0x7d21
leaq 0x46ba(%rip), %rdi      # 0xd623
callq 0x7967
testq %rax, %rax
je 0x8fc5
pushq $0x1d
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
movq 0x91d0(%rip), %rdi      # 0x12158
leaq 0x43ba(%rip), %rsi      # 0xd349
callq 0xab1d
testb %al, %al
jne 0x8fa1
callq 0x8e75
movq %rax, 0x38(%rbx)
leaq 0x43a1(%rip), %rdi      # 0xd349
callq 0x7967
testq %rax, %rax
jne 0x8ff9
movq 0x919f(%rip), %rsi      # 0x12158
leaq 0x4356(%rip), %rdi      # 0xd316
callq 0x7d21
leaq 0x389e(%rip), %rdi      # 0xc86a
callq 0x7967
testq %rax, %rax
je 0x9008
pushq $0x27
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
leaq 0x435e(%rip), %rdi      # 0xd349
callq 0x7967
testq %rax, %rax
je 0x93db
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x3027(%rip), %rdi      # 0xc036
callq 0x7967
testq %rax, %rax
je 0x9092
movq %rax, %rbx
leaq 0x482f(%rip), %rdi      # 0xd852
callq 0x7967
testq %rax, %rax
je 0x9401
callq 0x8e75
movq %rax, %r14
leaq 0x42b2(%rip), %rdi      # 0xd2f2
callq 0x7967
testq %rax, %rax
je 0x93ee
callq 0x8f1a
movq %rax, %r15
leaq 0x378a(%rip), %rdi      # 0xc7e7
callq 0x7967
testq %rax, %rax
je 0x90f5
callq 0x8f1a
movq %rax, %r12
pushq $0x1f
popq %rdi
movq %rbx, %rsi
callq 0x75dc
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
movq %r12, 0x68(%rax)
jmp 0x8ff9
leaq 0x4290(%rip), %rdi      # 0xd329
callq 0x7967
testq %rax, %rax
je 0x9110
pushq $0x20
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
leaq 0x479a(%rip), %rdi      # 0xd852
callq 0x7967
testq %rax, %rax
je 0x9401
callq 0x8e75
movq %rax, 0x58(%rbx)
leaq 0x421c(%rip), %rdi      # 0xd2f2
callq 0x7967
testq %rax, %rax
je 0x93ee
callq 0x8f1a
movq %rax, 0x80(%rbx)
jmp 0x8ff9
pushq $0x1e
popq %rdi
movq %rbx, %rsi
callq 0x75dc
movq %rax, %rbx
movq %r14, 0x58(%rax)
movq %r15, 0x60(%rax)
jmp 0x8ff9
leaq 0x4218(%rip), %rdi      # 0xd32f
callq 0x7967
testq %rax, %rax
je 0x9187
pushq $0x21
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
movq 0x904a(%rip), %r14      # 0x12180
leaq 0x4715(%rip), %rdi      # 0xd852
callq 0x7967
movq 0x900f(%rip), %rcx      # 0x12158
testq %rax, %rax
je 0x9414
leaq 0x41f0(%rip), %rsi      # 0xd349
movq %rcx, %rdi
callq 0xab1d
testb %al, %al
jne 0x9225
movq 0x8fe8(%rip), %rdi      # 0x12158
callq 0x876f
testl %eax, %eax
je 0x921c
callq 0x9457
jmp 0x9221
leaq 0x41bd(%rip), %rdi      # 0xd34b
callq 0x7967
testq %rax, %rax
je 0x91e8
movq %rax, %r14
pushq $0x24
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
leaq 0x46a2(%rip), %rdi      # 0xd852
callq 0x7967
testq %rax, %rax
je 0x9435
callq 0x8e75
movq %rax, 0x38(%rbx)
leaq 0x4124(%rip), %rdi      # 0xd2f2
callq 0x7967
testq %rax, %rax
jne 0x90e4
leaq 0x410f(%rip), %rdi      # 0xd2f2
jmp 0x943c
leaq 0x4163(%rip), %rdi      # 0xd352
callq 0x7967
testq %rax, %rax
je 0x92d3
movq %rax, %r14
pushq $0x25
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
callq 0x82f2
movq %rax, 0x38(%rbx)
jmp 0x92f5
callq 0x8e75
movq %rax, 0x70(%rbx)
leaq 0x411d(%rip), %rdi      # 0xd349
callq 0x7967
movq 0x8f20(%rip), %rcx      # 0x12158
testq %rax, %rax
je 0x941d
leaq 0x4101(%rip), %rsi      # 0xd349
movq %rcx, %rdi
callq 0xab1d
testb %al, %al
je 0x9265
movq 0x8efd(%rip), %rdi      # 0x12158
pushq $0x1
popq %rsi
callq 0x8183
jmp 0x926a
callq 0x8e75
movq %rax, 0x58(%rbx)
leaq 0x40d4(%rip), %rdi      # 0xd349
callq 0x7967
movq 0x8ed7(%rip), %rcx      # 0x12158
testq %rax, %rax
je 0x9426
leaq 0x4061(%rip), %rsi      # 0xd2f2
movq %rcx, %rdi
callq 0xab1d
testb %al, %al
jne 0x92a6
callq 0x8e75
movq %rax, 0x78(%rbx)
leaq 0x4045(%rip), %rdi      # 0xd2f2
callq 0x7967
testq %rax, %rax
je 0x93ee
callq 0x8f1a
movq %rax, 0x80(%rbx)
movq %r14, 0x8eb2(%rip)      # 0x12180
jmp 0x8ff9
leaq 0x407d(%rip), %rdi      # 0xd357
callq 0x7967
testq %rax, %rax
je 0x9316
movq %rax, %r14
pushq $0x26
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
leaq 0x4156(%rip), %rdi      # 0xd452
callq 0x7967
testq %rax, %rax
jne 0x90e4
leaq 0x4141(%rip), %rdi      # 0xd452
jmp 0x943c
leaq 0x3f2e(%rip), %rdi      # 0xd24b
callq 0x7967
testq %rax, %rax
je 0x9398
pushq $0x22
popq %rdi
movq %rax, %rsi
callq 0x75dc
movq %rax, %rbx
xorl %eax, %eax
callq 0x229c
movq %rax, 0x30(%rbx)
movq 0x8e39(%rip), %r12      # 0x12180
leaq 0x3e3b(%rip), %r14      # 0xd189
movq 0x8e03(%rip), %rdi      # 0x12158
movq %r14, %rsi
callq 0xab1d
testb %al, %al
jne 0x9377
movq 0x30(%rbx), %r15
callq 0x8f1a
movq %r15, %rdi
movq %rax, %rsi
callq 0x22c6
jmp 0x934e
leaq 0x3e0b(%rip), %rdi      # 0xd189
callq 0x7967
testq %rax, %rax
je 0x9444
movq %r12, 0x8ded(%rip)      # 0x12180
jmp 0x8ff9
movq 0x8db9(%rip), %rsi      # 0x12158
pushq $0x1c
popq %rdi
callq 0x75dc
movq %rax, %rbx
callq 0x8e75
movq %rax, 0x38(%rbx)
leaq 0x3f8f(%rip), %rdi      # 0xd349
callq 0x7967
testq %rax, %rax
jne 0x8ff9
movq 0x8d89(%rip), %rsi      # 0x12158
leaq 0x3f89(%rip), %rdi      # 0xd35f
callq 0x7d21
movq 0x8d76(%rip), %rsi      # 0x12158
leaq 0x3f37(%rip), %rdi      # 0xd320
callq 0x7d21
movq 0x8d63(%rip), %rsi      # 0x12158
leaq 0x3ef6(%rip), %rdi      # 0xd2f2
callq 0x7d21
movq 0x8d50(%rip), %rsi      # 0x12158
leaq 0x4443(%rip), %rdi      # 0xd852
callq 0x7d21
leaq 0x4437(%rip), %rdi      # 0xd852
jmp 0x942d
leaq 0x3f0f(%rip), %rdi      # 0xd333
jmp 0x942d
leaq 0x3f12(%rip), %rdi      # 0xd33f
movq %rcx, %rsi
callq 0x7d21
leaq 0x4416(%rip), %rdi      # 0xd852
movq %r14, %rsi
callq 0x7d21
movq 0x8d0d(%rip), %rsi      # 0x12158
leaq 0x3d37(%rip), %rdi      # 0xd189
callq 0x7d21