// File: /workspace/github_c_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, 0x48(%rsp)
movq %rdi, %rbx
callq 0xb6b2
movb $0x1, (%rax)
leaq 0x5ed8(%rip), %rsi      # 0x207fa
movq %rbx, 0x40(%rsp)
movq %rbx, %rdi
callq 0x131a0
movq %rax, 0x38(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x1abac
leaq 0x50(%rsp), %r13
movq %r13, %rdi
callq 0x1abac
xorl %r12d, %r12d
movq 0xf683(%rip), %r15      # 0x29fd8
testb $0x1, %r12b
leaq 0x5ea2(%rip), %rbp      # 0x20802
leaq 0x5ea0(%rip), %rax      # 0x20807
cmovneq %rax, %rbp
movq %rbp, %rdi
xorl %eax, %eax
callq 0x2150
movq (%r15), %rdi
callq 0x21c0
cmpb $0xa, %al
je 0x1a996
movzbl %al, %esi
cmpl $0xff, %esi
je 0x1a996
movq %r13, %rdi
callq 0x1ac58
jmp 0x1a975
movq %r13, %rdi
xorl %esi, %esi
callq 0x1ac58
movq 0x50(%rsp), %rbx
testq %rbx, %rbx
je 0x1ab19
movsbq (%rbx), %r14
testq %r14, %r14
sete %al
je 0x1a9e7
callq 0x23c0
movq (%rax), %rcx
testb $0x20, 0x1(%rcx,%r14,2)
jne 0x1a9ce
xorl %eax, %eax
jmp 0x1a9e7
incq %rbx
movsbq (%rbx), %rdx
testq %rdx, %rdx
sete %al
je 0x1a9e7
incq %rbx
testb $0x20, 0x1(%rcx,%rdx,2)
jne 0x1a9d1
notb %al
orb %r12b, %al
testb $0x1, %al
jne 0x1aa08
movq %r13, %rdi
callq 0x1abb3
cmpl $0x0, 0x30(%rsp)
je 0x1a96b
jmp 0x1ab47
cmpl $0x0, 0x30(%rsp)
leaq 0x28(%rsp), %rbx
je 0x1aa21
movq %rbx, %rdi
movl $0xa, %esi
callq 0x1ac58
movq 0x50(%rsp), %rsi
movl 0x58(%rsp), %edx
decl %edx
movq %rbx, %rdi
callq 0x1ac84
movq %r13, %rdi
callq 0x1abb3
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1ac58
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x70(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x60(%rsp)
movaps 0x60(%rsp), %xmm0
movaps 0x70(%rsp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x48(%rsp), %rdx
callq 0x11290
cmpl $0x1, %eax
sete %r12b
jne 0x1aab3
movl 0x30(%rsp), %eax
testl %eax, %eax
je 0x1ab7c
movq 0x28(%rsp), %rcx
decl %eax
cmpb $0x0, (%rcx,%rax)
jne 0x1ab7c
movl %eax, 0x30(%rsp)
jmp 0x1a955
movl %eax, %ebp
movq %rbx, %rdi
callq 0x1abb3
testl %ebp, %ebp
jne 0x1a955
movq 0x40(%rsp), %r14
movq %r14, %rdi
movq 0x38(%rsp), %rsi
leaq 0x279e(%rip), %rdx      # 0x1d277
callq 0x1339b
movq %rax, %rbp
movq %r14, %rdi
movq %rax, %rsi
callq 0x8218
movq %rax, %rbx
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xdfa9
movq %r14, %rdi
movq %rbp, %rsi
callq 0xb734
movq %r14, %rdi
movq %rbx, %rsi
callq 0xb734
jmp 0x1a955
movq 0xf4d8(%rip), %rax      # 0x29ff8
movq (%rax), %rdi
leaq 0x25b6(%rip), %rsi      # 0x1d0e0
leaq 0x26c3(%rip), %rdx      # 0x1d1f4
leaq 0x5ce4(%rip), %rcx      # 0x2081c
leaq 0x5cd2(%rip), %r8       # 0x20811
movl $0x32, %r9d
jmp 0x1ab73
movq 0xf4aa(%rip), %rax      # 0x29ff8
movq (%rax), %rdi
leaq 0x2588(%rip), %rsi      # 0x1d0e0
leaq 0x2695(%rip), %rdx      # 0x1d1f4
leaq 0x5ca6(%rip), %rcx      # 0x2080c
leaq 0x5ca4(%rip), %r8       # 0x20811
movl $0x61, %r9d
xorl %eax, %eax
callq 0x2250
ud2
movq 0xf475(%rip), %rax      # 0x29ff8
movq (%rax), %rdi
leaq 0x2553(%rip), %rsi      # 0x1d0e0
leaq 0x2660(%rip), %rdx      # 0x1d1f4
leaq 0x5c71(%rip), %rcx      # 0x2080c
leaq 0x5c6f(%rip), %r8       # 0x20811
movl $0x6f, %r9d
jmp 0x1ab73
nop