// File: /workspace/github_c_makefile_star2_O1/atomlang[P]atomlang/src/pk_compiler.c
// Function: compileForStatement
static void compileForStatement(Compiler* compiler) {
  compilerEnterBlock(compiler);
  consume(compiler, TK_NAME, "Expected an iterator name.");

  // Unlike functions local variable could shadow a name.
  const char* iter_name = compiler->previous.start;
  int iter_len = compiler->previous.length;
  int iter_line = compiler->previous.line;

  consume(compiler, TK_IN, "Expected 'in' after iterator name.");

  // Compile and store sequence.
  compilerAddVariable(compiler, "@Sequence", 9, iter_line); // Sequence
  compileExpression(compiler);

  // Add iterator to locals. It's an increasing integer indicating that the
  // current loop is nth starting from 0.
  compilerAddVariable(compiler, "@iterator", 9, iter_line); // Iterator.
  emitOpcode(compiler, OP_PUSH_0);

  // Add the iteration value. It'll be updated to each element in an array of
  // each character in a string etc.
  compilerAddVariable(compiler, iter_name, iter_len, iter_line); // Iter value.
  emitOpcode(compiler, OP_PUSH_NULL);

  // Start the iteration, and check if the sequence is iterable.
  emitOpcode(compiler, OP_ITER_TEST);

  Loop loop;
  loop.start = (int)_FN->opcodes.count;
  loop.patch_count = 0;
  loop.outer_loop = compiler->loop;
  loop.depth = compiler->scope_depth;
  compiler->loop = &loop;

  // Compile next iteration.
  emitOpcode(compiler, OP_ITER);
  int forpatch = emitShort(compiler, 0xffff);

  compileBlockBody(compiler, BLOCK_LOOP);

  emitLoopJump(compiler); //< Loop back to iteration.
  patchJump(compiler, forpatch); //< Patch exit iteration address.

  // Patch break statement.
  for (int i = 0; i < compiler->loop->patch_count; i++) {
    patchJump(compiler, compiler->loop->patches[i]);
  }
  compiler->loop = loop.outer_loop;

  skipNewLines(compiler);
  consume(compiler, TK_END, "Expected 'end' after statement end.");
  compilerExitBlock(compiler); //< Iterator scope.
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
movq %rdi, %rbx
incl 0xa0(%rdi)
leaq 0xc04f(%rip), %rdx      # 0x1e1ab
movl $0x47, %esi
callq 0x11171
movq 0x38(%rbx), %r14
movl 0x40(%rbx), %ebp
movl 0x44(%rbx), %r15d
leaq 0xc04e(%rip), %rdx      # 0x1e1c6
movq %rbx, %rdi
movl $0x37, %esi
callq 0x11171
leaq 0xc05d(%rip), %rsi      # 0x1e1e9
movq %rbx, %rdi
movl $0x9, %edx
movl %r15d, %ecx
callq 0x11846
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12323
leaq 0xc043(%rip), %rsi      # 0x1e1f3
movq %rbx, %rdi
movl $0x9, %edx
movl %r15d, %ecx
callq 0x11846
movq %rbx, %rdi
movl $0x2, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
movq %rbx, %rdi
movq %r14, %rsi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x11846
movq %rbx, %rdi
movl $0x1, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
movq %rbx, %rdi
movl $0x29, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
movq 0x18c0(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x38(%rax), %rax
movl 0x8(%rax), %eax
leaq 0x8(%rsp), %rcx
movl %eax, (%rcx)
movl $0x0, 0x408(%rcx)
movq 0x18b8(%rbx), %rax
movq %rax, 0x410(%rcx)
movl 0xa0(%rbx), %eax
movl %eax, 0x418(%rcx)
movq %rcx, 0x18b8(%rbx)
movq %rbx, %rdi
movl $0x2a, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
movq %rbx, %rdi
movl $0xff, %esi
callq 0x1135b
movq %rbx, %rdi
movl $0xff, %esi
callq 0x1135b
leal -0x1(%rax), %ebp
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11919
movq %rbx, %rdi
callq 0x11f23
movq %rbx, %rdi
movl %ebp, %esi
callq 0x123a2
movq 0x18b8(%rbx), %rax
cmpl $0x0, 0x408(%rax)
jle 0x122e2
xorl %r14d, %r14d
movl 0x8(%rax,%r14,4), %esi
movq %rbx, %rdi
callq 0x123a2
incq %r14
movq 0x18b8(%rbx), %rax
movslq 0x408(%rax), %rcx
cmpq %rcx, %r14
jl 0x122bf
movq 0x418(%rsp), %rax
movq %rax, 0x18b8(%rbx)
movq %rbx, %rdi
callq 0x11e66
leaq 0xbe58(%rip), %rdx      # 0x1e158
movq %rbx, %rdi
movl $0x35, %esi
callq 0x11171
movq %rbx, %rdi
callq 0x11986
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r14
popq %r15
popq %rbp
retq