// File: /workspace/github_c_makefile_star2_O0/atomlang[P]atomlang/cli/repl.c
// Function: repl
int repl(PKVM* vm, const PkCompileOptions* options) {

  // Set repl_mode of the user_data.
  VmUserData* user_data = (VmUserData*)pkGetUserData(vm);
  user_data->repl_mode = true;

  // The main module that'll be used to compile and execute the input source.
  PkHandle* module = pkNewModule(vm, "$(REPL)");

  // A buffer to store lines read from stdin.
  ByteBuffer lines;
  byteBufferInit(&lines);

  // A buffer to store a line read from stdin.
  ByteBuffer line;
  byteBufferInit(&line);

  // Will be set to true if the compilation failed with unexpected EOF to add
  // more lines to the [lines] buffer.
  bool need_more_lines = false;

  bool done = false;
  do {

    // Print the input listening line.
    if (!need_more_lines) {
      printf(">>> ");
    } else {
      printf("... ");
    }

    // Read a line from stdin and add the line to the lines buffer.
    readLine(&line);
    bool is_empty = is_str_empty((const char*)line.data);

    // If the line is empty, we don't have to compile it.
    if (is_empty && !need_more_lines) {
      byteBufferClear(&line);
      ASSERT(lines.count == 0, OOPS);
      continue;
    }

    if (lines.count != 0) byteBufferWrite(&lines, '\n');
    byteBufferAddString(&lines, (const char*)line.data, line.count - 1);
    byteBufferClear(&line);
    byteBufferWrite(&lines, '\0');

    // Compile the buffer to the module.
    PkStringPtr source_ptr = { (const char*)lines.data, NULL, NULL };
    PkResult result = pkCompileModule(vm, module, source_ptr, options);

    if (result == PK_RESULT_UNEXPECTED_EOF) {
      ASSERT(lines.count > 0 && lines.data[lines.count - 1] == '\0', OOPS);
      lines.count -= 1; // Remove the null byte to append a new string.
      need_more_lines = true;
      continue;
    }

    // We're buffering the lines for unexpected EOF, if we reached here that
    // means it's either successfully compiled or compilation error. Clean the
    // buffer for the next iteration.
    need_more_lines = false;
    byteBufferClear(&lines);

    if (result != PK_RESULT_SUCCESS) continue;

    // Compiled source would be the "main" function of the module. Run it.
    PkHandle* _main = pkGetFunction(vm, module, PK_IMPLICIT_MAIN_NAME);
    PkHandle* fiber = pkNewFiber(vm, _main);
    result = pkRunFiber(vm, fiber, 0, NULL);
    pkReleaseHandle(vm, _main);
    pkReleaseHandle(vm, fiber);

  } while (!done);

  byteBufferClear(&lines);
  pkReleaseHandle(vm, module);

  return 0;
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movq %rsi, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x9010
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
movb $0x1, (%rax)
movq 0xa0(%rsp), %rdi
leaq 0x7945(%rip), %rsi      # 0x2d98b
callq 0x1aa40
movq %rax, 0x88(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x26420
leaq 0x68(%rsp), %rdi
callq 0x26420
movb $0x0, 0x67(%rsp)
movb $0x0, 0x66(%rsp)
testb $0x1, 0x67(%rsp)
jne 0x26088
leaq 0x7914(%rip), %rdi      # 0x2d993
movb $0x0, %al
callq 0x2140
jmp 0x26096
leaq 0x7909(%rip), %rdi      # 0x2d998
movb $0x0, %al
callq 0x2140
leaq 0x68(%rsp), %rdi
callq 0x26310
movq 0x68(%rsp), %rdi
callq 0x26370
andb $0x1, %al
movb %al, 0x65(%rsp)
testb $0x1, 0x65(%rsp)
je 0x26113
testb $0x1, 0x67(%rsp)
jne 0x26113
leaq 0x68(%rsp), %rdi
callq 0x26450
cmpl $0x0, 0x80(%rsp)
je 0x2610c
movq 0xcf1f(%rip), %rax      # 0x32ff8
movq (%rax), %rdi
leaq 0x406d(%rip), %rsi      # 0x2a150
leaq 0x417a(%rip), %rdx      # 0x2a264
leaq 0x78ac(%rip), %rcx      # 0x2d99d
leaq 0x78aa(%rip), %r8       # 0x2d9a2
movl $0x61, %r9d
movb $0x0, %al
callq 0x2240
ud2
callq 0x2040
jmp 0x2610e
jmp 0x262cf
cmpl $0x0, 0x80(%rsp)
je 0x2612c
leaq 0x78(%rsp), %rdi
movl $0xa, %esi
callq 0x265f0
movq 0x68(%rsp), %rsi
movl 0x70(%rsp), %edx
subl $0x1, %edx
leaq 0x78(%rsp), %rdi
callq 0x26620
leaq 0x68(%rsp), %rdi
callq 0x26450
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
callq 0x265f0
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x2180
movq 0x78(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x98(%rsp), %rdx
leaq 0x40(%rsp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x16390
movl %eax, 0x3c(%rsp)
cmpl $0x1, 0x3c(%rsp)
jne 0x2623f
jmp 0x261c4
cmpl $0x0, 0x80(%rsp)
jbe 0x261e8
movq 0x78(%rsp), %rax
movl 0x80(%rsp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x26222
movq 0xce09(%rip), %rax      # 0x32ff8
movq (%rax), %rdi
leaq 0x3f57(%rip), %rsi      # 0x2a150
leaq 0x4064(%rip), %rdx      # 0x2a264
leaq 0x7796(%rip), %rcx      # 0x2d99d
leaq 0x7794(%rip), %r8       # 0x2d9a2
movl $0x6f, %r9d
movb $0x0, %al
callq 0x2240
ud2
callq 0x2040
jmp 0x26224
movl 0x80(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x80(%rsp)
movb $0x1, 0x67(%rsp)
jmp 0x262cf
movb $0x0, 0x67(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x26450
cmpl $0x0, 0x3c(%rsp)
je 0x26257
jmp 0x262cf
movq 0xa0(%rsp), %rdi
movq 0x88(%rsp), %rsi
leaq 0x4079(%rip), %rdx      # 0x2a2e7
callq 0x1af90
movq %rax, 0x30(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x2a60
movq %rax, 0x28(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x28(%rsp), %rsi
xorl %edx, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x10970
movl %eax, 0x3c(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x9120
movq 0xa0(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x9120
movb 0x66(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x26071
leaq 0x78(%rsp), %rdi
callq 0x26450
movq 0xa0(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x9120
xorl %eax, %eax
addq $0xa8, %rsp
retq
nopw %cs:(%rax,%rax)