// File: /workspace/github_c_makefile_star2_O0/atomlang[P]atomlang/cli/main.c
// Function: main
int main(int argc, const char** argv) {

  // Parse command line arguments.

  const char* usage[] = {
    "atomlang ... [-c cmd | file] ...",
    NULL,
  };

  const char* cmd = NULL;
  int debug = false, help = false, quiet = false, version = false;
  struct argparse_option cli_opts[] = {
      OPT_STRING('c', "cmd", (void*)&cmd,
        "Evaluate and run the passed string.", NULL, 0, 0),

      OPT_BOOLEAN('d', "debug", (void*)&debug,
        "Compile and run the debug version.", NULL, 0, 0),

      OPT_BOOLEAN('h', "help",  (void*)&help,
        "Prints this help message and exit.", NULL, 0, 0),

      OPT_BOOLEAN('q', "quiet", (void*)&quiet,
        "Don't print version and copyright statement on REPL startup.",
        NULL, 0, 0),

      OPT_BOOLEAN('v', "version", &version,
        "Prints the atomlang version and exit.", NULL, 0, 0),
      OPT_END(),
  };

  // Parse the options.
  struct argparse argparse;
  argparse_init(&argparse, cli_opts, usage, 0);
  argc = argparse_parse(&argparse, argc, argv);

  if (help) { // atomlang --help.
    argparse_usage(&argparse);
    return 0;
  }

  if (version) { // atomlang --version
    fprintf(stdout, "atomlang %s\n", PK_VERSION_STRING);
    return 0;
  }

  int exitcode = 0;

  // Create and initialize atomlang VM.
  PKVM* vm = intializeatomlangVM();
  VmUserData user_data;
  user_data.repl_mode = false;
  pkSetUserData(vm, &user_data);

  registerModules(vm);

  PkCompileOptions options = pkNewCompilerOptions();
  options.debug = debug;

  if (cmd != NULL) { // atomlang -c "print('foo')"

    PkStringPtr source = { cmd, NULL, NULL, 0, 0 };
    PkStringPtr path = { "$(Source)", NULL, NULL, 0, 0 };
    PkResult result = pkInterpretSource(vm, source, path, NULL);
    exitcode = (int)result;

  } else if (argc == 0) { // Run on REPL mode.

   // Print the copyright and license notice, if --quiet not set.
    if (!quiet) {
      printf("%s", CLI_NOTICE);
    }

    options.repl_mode = true;
    exitcode = repl(vm, &options);

  } else { // atomlang file.pk ...

    PkStringPtr resolved = resolvePath(vm, ".", argv[0]);
    PkStringPtr source = loadScript(vm, resolved.string);

    if (source.string != NULL) {
      PkResult result = pkInterpretSource(vm, source, resolved, &options);
      exitcode = (int)result;
    } else {
      fprintf(stderr, "Error: cannot open file at \"%s\"\n", resolved.string);
      if (resolved.on_done != NULL) resolved.on_done(vm, resolved);
      if (source.on_done != NULL) source.on_done(vm, source);
    }
  }

  // Cleanup the VM and exit.
  pkFreeVM(vm);
  return exitcode;
}

// Assembly:
subq $0x2d8, %rsp            # imm = 0x2D8
movl $0x0, 0x2d4(%rsp)
movl %edi, 0x2d0(%rsp)
movq %rsi, 0x2c8(%rsp)
movq 0xe5c8(%rip), %rax      # 0x32da0
movq %rax, 0x2b0(%rsp)
movq 0xe5c1(%rip), %rax      # 0x32da8
movq %rax, 0x2b8(%rsp)
movq $0x0, 0x2a8(%rsp)
movl $0x0, 0x2a4(%rsp)
movl $0x0, 0x2a0(%rsp)
movl $0x0, 0x29c(%rsp)
movl $0x0, 0x298(%rsp)
movl $0x6, 0x140(%rsp)
movb $0x63, 0x144(%rsp)
leaq 0x8e01(%rip), %rax      # 0x2d642
movq %rax, 0x148(%rsp)
leaq 0x2a8(%rsp), %rax
movq %rax, 0x150(%rsp)
leaq 0x8de6(%rip), %rax      # 0x2d646
movq %rax, 0x158(%rsp)
movq $0x0, 0x160(%rsp)
movq $0x0, 0x168(%rsp)
movl $0x0, 0x170(%rsp)
movl $0x2, 0x178(%rsp)
movb $0x64, 0x17c(%rsp)
leaq 0x8dc5(%rip), %rax      # 0x2d66a
movq %rax, 0x180(%rsp)
leaq 0x2a4(%rsp), %rax
movq %rax, 0x188(%rsp)
leaq 0x8dac(%rip), %rax      # 0x2d670
movq %rax, 0x190(%rsp)
movq $0x0, 0x198(%rsp)
movq $0x0, 0x1a0(%rsp)
movl $0x0, 0x1a8(%rsp)
movl $0x2, 0x1b0(%rsp)
movb $0x68, 0x1b4(%rsp)
leaq 0x73d6(%rip), %rax      # 0x2bcdf
movq %rax, 0x1b8(%rsp)
leaq 0x2a0(%rsp), %rax
movq %rax, 0x1c0(%rsp)
leaq 0x8d6b(%rip), %rax      # 0x2d693
movq %rax, 0x1c8(%rsp)
movq $0x0, 0x1d0(%rsp)
movq $0x0, 0x1d8(%rsp)
movl $0x0, 0x1e0(%rsp)
movl $0x2, 0x1e8(%rsp)
movb $0x71, 0x1ec(%rsp)
leaq 0x8d49(%rip), %rax      # 0x2d6b6
movq %rax, 0x1f0(%rsp)
leaq 0x29c(%rsp), %rax
movq %rax, 0x1f8(%rsp)
leaq 0x8d30(%rip), %rax      # 0x2d6bc
movq %rax, 0x200(%rsp)
movq $0x0, 0x208(%rsp)
movq $0x0, 0x210(%rsp)
movl $0x0, 0x218(%rsp)
movl $0x2, 0x220(%rsp)
movb $0x76, 0x224(%rsp)
leaq 0x8d28(%rip), %rax      # 0x2d6f9
movq %rax, 0x228(%rsp)
leaq 0x298(%rsp), %rax
movq %rax, 0x230(%rsp)
leaq 0x8d11(%rip), %rax      # 0x2d701
movq %rax, 0x238(%rsp)
movq $0x0, 0x240(%rsp)
movq $0x0, 0x248(%rsp)
movl $0x0, 0x250(%rsp)
leaq 0x140(%rsp), %rdi
addq $0x118, %rdi            # imm = 0x118
xorl %esi, %esi
movl $0x38, %edx
callq 0x2180
movl $0x0, 0x258(%rsp)
leaq 0x140(%rsp), %rsi
leaq 0x2b0(%rsp), %rdx
leaq 0xf0(%rsp), %rdi
xorl %ecx, %ecx
callq 0x28600
movl 0x2d0(%rsp), %esi
movq 0x2c8(%rsp), %rdx
leaq 0xf0(%rsp), %rdi
callq 0x286a0
movl %eax, 0x2d0(%rsp)
cmpl $0x0, 0x2a0(%rsp)
je 0x24aaa
leaq 0xf0(%rsp), %rdi
callq 0x28b80
movl $0x0, 0x2d4(%rsp)
jmp 0x24dfc
cmpl $0x0, 0x298(%rsp)
je 0x24ae3
movq 0xe515(%rip), %rax      # 0x32fd0
movq (%rax), %rdi
leaq 0x8c62(%rip), %rsi      # 0x2d727
leaq 0x8c68(%rip), %rdx      # 0x2d734
movb $0x0, %al
callq 0x2240
movl $0x0, 0x2d4(%rsp)
jmp 0x24dfc
movl $0x0, 0xec(%rsp)
callq 0x24e10
movq %rax, 0xe0(%rsp)
movb $0x0, 0xdf(%rsp)
movq 0xe0(%rsp), %rdi
leaq 0xdf(%rsp), %rsi
callq 0x9030
movq 0xe0(%rsp), %rdi
callq 0x25e10
callq 0x8d70
movw %ax, 0xdd(%rsp)
cmpl $0x0, 0x2a4(%rsp)
setne %al
andb $0x1, %al
movb %al, 0xdd(%rsp)
cmpq $0x0, 0x2a8(%rsp)
je 0x24c35
leaq 0xb8(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x2180
movq 0x2a8(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xe230(%rip), %rax      # 0x32db0
movq %rax, 0x98(%rsp)
movq 0xe229(%rip), %rax      # 0x32db8
movq %rax, 0xa0(%rsp)
movq 0xe222(%rip), %rax      # 0x32dc0
movq %rax, 0xa8(%rsp)
movq 0xe21b(%rip), %rax      # 0x32dc8
movq %rax, 0xb0(%rsp)
movq 0xe0(%rsp), %rdi
leaq 0xb8(%rsp), %rcx
leaq 0x98(%rsp), %rax
xorl %edx, %edx
movl %edx, %esi
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq (%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x28(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x30(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x38(%rsp)
callq 0x9200
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
movl %eax, 0xec(%rsp)
jmp 0x24de1
cmpl $0x0, 0x2d0(%rsp)
jne 0x24c87
cmpl $0x0, 0x29c(%rsp)
jne 0x24c5e
leaq 0x8e8f(%rip), %rdi      # 0x2dadf
leaq 0x8aed(%rip), %rsi      # 0x2d744
movb $0x0, %al
callq 0x2140
movb $0x1, 0xde(%rsp)
movq 0xe0(%rsp), %rdi
leaq 0xdd(%rsp), %rsi
callq 0x26000
movl %eax, 0xec(%rsp)
jmp 0x24ddf
movq 0xe0(%rsp), %rsi
movq 0x2c8(%rsp), %rax
movq (%rax), %rcx
leaq 0x70(%rsp), %rdi
leaq 0x6f88(%rip), %rdx      # 0x2bc2e
callq 0x24540
movq 0xe0(%rsp), %rsi
movq 0x70(%rsp), %rdx
leaq 0x50(%rsp), %rdi
callq 0x246c0
cmpq $0x0, 0x50(%rsp)
je 0x24d42
movq 0xe0(%rsp), %rdi
leaq 0x50(%rsp), %rcx
leaq 0x70(%rsp), %rax
leaq 0xdd(%rsp), %rsi
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq (%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x28(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x30(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x38(%rsp)
callq 0x9200
movl %eax, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0xec(%rsp)
jmp 0x24ddd
movq 0xe2af(%rip), %rax      # 0x32ff8
movq (%rax), %rdi
movq 0x70(%rsp), %rdx
leaq 0x8a91(%rip), %rsi      # 0x2d7e9
movb $0x0, %al
callq 0x2240
cmpq $0x0, 0x78(%rsp)
je 0x24d9d
movq 0x78(%rsp), %rax
movq 0xe0(%rsp), %rdi
leaq 0x70(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
callq *%rax
cmpq $0x0, 0x58(%rsp)
je 0x24ddb
movq 0x58(%rsp), %rax
movq 0xe0(%rsp), %rdi
leaq 0x50(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
callq *%rax
jmp 0x24ddd
jmp 0x24ddf
jmp 0x24de1
movq 0xe0(%rsp), %rdi
callq 0x8eb0
movl 0xec(%rsp), %eax
movl %eax, 0x2d4(%rsp)
movl 0x2d4(%rsp), %eax
addq $0x2d8, %rsp            # imm = 0x2D8
retq
nopl (%rax,%rax)