// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x448, %rsp            # imm = 0x448
movq %rdi, 0x440(%rsp)
movq 0x440(%rsp), %rdi
callq 0x17050
movq 0x440(%rsp), %rdi
movl $0x47, %esi
leaq 0x1341b(%rip), %rdx     # 0x2b33b
callq 0x160a0
movq 0x440(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x438(%rsp)
movq 0x440(%rsp), %rax
movl 0x40(%rax), %eax
movl %eax, 0x434(%rsp)
movq 0x440(%rsp), %rax
movl 0x44(%rax), %eax
movl %eax, 0x430(%rsp)
movq 0x440(%rsp), %rdi
movl $0x37, %esi
leaq 0x133e5(%rip), %rdx     # 0x2b356
callq 0x160a0
movq 0x440(%rsp), %rdi
movl 0x430(%rsp), %ecx
leaq 0x133ed(%rip), %rsi     # 0x2b379
movl $0x9, %edx
callq 0x17070
movq 0x440(%rsp), %rdi
callq 0x17be0
movq 0x440(%rsp), %rdi
movl 0x430(%rsp), %ecx
leaq 0x133ca(%rip), %rsi     # 0x2b383
movl $0x9, %edx
callq 0x17070
movq 0x440(%rsp), %rdi
movl $0x2, %esi
callq 0x16650
movq 0x440(%rsp), %rdi
movq 0x438(%rsp), %rsi
movl 0x434(%rsp), %edx
movl 0x430(%rsp), %ecx
callq 0x17070
movq 0x440(%rsp), %rdi
movl $0x1, %esi
callq 0x16650
movq 0x440(%rsp), %rdi
movl $0x29, %esi
callq 0x16650
movq 0x440(%rsp), %rax
movq 0x18c0(%rax), %rax
movq 0x8(%rax), %rax
movq 0x38(%rax), %rax
movl 0x8(%rax), %eax
movl %eax, 0x10(%rsp)
movl $0x0, 0x418(%rsp)
movq 0x440(%rsp), %rax
movq 0x18b8(%rax), %rax
movq %rax, 0x420(%rsp)
movq 0x440(%rsp), %rax
movl 0xa0(%rax), %eax
movl %eax, 0x428(%rsp)
movq 0x440(%rsp), %rax
leaq 0x10(%rsp), %rcx
movq %rcx, 0x18b8(%rax)
movq 0x440(%rsp), %rdi
movl $0x2a, %esi
callq 0x16650
movq 0x440(%rsp), %rdi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x16690
movl %eax, 0xc(%rsp)
movq 0x440(%rsp), %rdi
movl $0x1, %esi
callq 0x171e0
movq 0x440(%rsp), %rdi
callq 0x17ae0
movq 0x440(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0x18270
movl $0x0, 0x8(%rsp)
movl 0x8(%rsp), %eax
movq 0x440(%rsp), %rcx
movq 0x18b8(%rcx), %rcx
cmpl 0x408(%rcx), %eax
jge 0x18132
movq 0x440(%rsp), %rdi
movq 0x440(%rsp), %rax
movq 0x18b8(%rax), %rax
movslq 0x8(%rsp), %rcx
movl 0x8(%rax,%rcx,4), %esi
callq 0x18270
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0x180e5
movq 0x420(%rsp), %rcx
movq 0x440(%rsp), %rax
movq %rcx, 0x18b8(%rax)
movq 0x440(%rsp), %rdi
callq 0x15f40
movq 0x440(%rsp), %rdi
movl $0x35, %esi
leaq 0x1317e(%rip), %rdx     # 0x2b2e8
callq 0x160a0
movq 0x440(%rsp), %rdi
callq 0x17300
addq $0x448, %rsp            # imm = 0x448
retq
nopw %cs:(%rax,%rax)