// File: AgathokakologicalBit[P]wit/src/main.cpp
// Function: main
int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    char const *name = (argc > 0 ? argv[0] : "witcc");
    std::cerr << "Usage: " << name << ' ' << "<filename>" << std::endl;
    return EXIT_FAILURE;
  }
  
  std::ifstream ifs(argv[1]);
  if (!ifs)
  {
    std::cerr << "File could not be opened!\n";
    std::cerr << "Reason: " << strerror(errno) << std::endl;
    return EXIT_FAILURE;
  }
  std::string source((std::istreambuf_iterator<char>(ifs)),
                     (std::istreambuf_iterator<char>()   ));
  
  auto tokens = akbit::system::parsing::tokenize(source);
  // for (auto t : tokens)
  //   std::cout << t << std::endl;

  auto ast = akbit::system::parsing::parse(tokens);
  if (!ast) return EXIT_FAILURE;
  
  akbit::system::annotation::preprocess_ast(ast);
  akbit::system::annotation::generate_context(ast);

  dump_ast(ast, -1u, 0ul);
  std::cout << "\n\x1b[39mResult: "
    << (std::get<akbit::system::Node::module_t>(ast->value).has_errors ? "\x1b[01;41mFAILURE" : "\x1b[01;44mSUCCESS")
    << "\x1b[49m\x1b[00;39m" << std::endl;
  
  std::fstream js_output_file;
	js_output_file.open("program.out.js", std::ios::out);
  if (js_output_file)
  {
    js_output_file << akbit::system::code_generation::generate(ast, akbit::system::code_generation::GenerationTarget::Javascript, nullptr);
    js_output_file.close();
  }

  return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x590, %rsp            # imm = 0x590
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x5c9a
cmpl $0x0, -0x8(%rbp)
jle 0x5c29
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x518(%rbp)
jmp 0x5c39
leaq 0x30412(%rip), %rax     # 0x36042
movq %rax, -0x518(%rbp)
jmp 0x5c39
movq -0x518(%rbp), %rax
movq %rax, -0x18(%rbp)
movq 0x4f3a5(%rip), %rdi     # 0x54ff0
leaq 0x303f6(%rip), %rsi     # 0x36048
callq 0x42e0
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x42e0
movq %rax, %rdi
movl $0x20, %esi
callq 0x43c0
movq %rax, %rdi
leaq 0x303d6(%rip), %rsi     # 0x36050
callq 0x42e0
movq %rax, %rdi
movq 0x4f31f(%rip), %rsi     # 0x54fa8
callq 0x4330
movl $0x1, -0x4(%rbp)
jmp 0x6225
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x220(%rbp), %rdi
movl $0x8, %edx
callq 0x4590
movq -0x220(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x220(%rbp,%rax), %rdi
callq 0x41a0
movb %al, -0x519(%rbp)
jmp 0x5cd3
movb -0x519(%rbp), %al
testb $0x1, %al
jne 0x5ce2
jmp 0x5d79
movq 0x4f307(%rip), %rdi     # 0x54ff0
leaq 0x3036b(%rip), %rsi     # 0x3605b
callq 0x42e0
jmp 0x5cf7
movq 0x4f2f2(%rip), %rdi     # 0x54ff0
leaq 0x30371(%rip), %rsi     # 0x36076
callq 0x42e0
movq %rax, -0x528(%rbp)
jmp 0x5d13
callq 0x4050
movl (%rax), %edi
callq 0x4110
movq -0x528(%rbp), %rdi
movq %rax, %rsi
callq 0x42e0
movq %rax, -0x530(%rbp)
jmp 0x5d37
movq -0x530(%rbp), %rdi
movq 0x4f263(%rip), %rsi     # 0x54fa8
callq 0x4330
jmp 0x5d4c
movl $0x1, -0x4(%rbp)
movl $0x1, -0x230(%rbp)
jmp 0x6209
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x6217
leaq -0x260(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x99e0
leaq -0x270(%rbp), %rdi
callq 0x9a40
leaq -0x271(%rbp), %rdi
movq %rdi, -0x538(%rbp)
callq 0x4570
movq -0x538(%rbp), %r9
movq -0x260(%rbp), %rsi
movl -0x258(%rbp), %edx
movq -0x270(%rbp), %rcx
movl -0x268(%rbp), %r8d
leaq -0x250(%rbp), %rdi
callq 0x9a70
jmp 0x5ddb
leaq -0x271(%rbp), %rdi
callq 0x4370
leaq -0x290(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0x11870
jmp 0x5dfc
leaq -0x2a0(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x12ed0
jmp 0x5e11
leaq -0x2a0(%rbp), %rdi
callq 0x9b00
testb $0x1, %al
jne 0x5e88
movl $0x1, -0x4(%rbp)
movl $0x1, -0x230(%rbp)
jmp 0x61bd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x271(%rbp), %rdi
callq 0x4370
jmp 0x6217
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x61fb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x61ef
leaq -0x2b0(%rbp), %rdi
movq %rdi, -0x540(%rbp)
leaq -0x2a0(%rbp), %rsi
callq 0x9b20
movq -0x540(%rbp), %rdi
callq 0x20b10
jmp 0x5eb0
leaq -0x2b0(%rbp), %rdi
callq 0x9b50
leaq -0x2c0(%rbp), %rdi
movq %rdi, -0x548(%rbp)
leaq -0x2a0(%rbp), %rsi
callq 0x9b20
movq -0x548(%rbp), %rdi
callq 0x29fb0
jmp 0x5ee4
leaq -0x2c0(%rbp), %rdi
callq 0x9b50
leaq -0x2d0(%rbp), %rdi
movq %rdi, -0x550(%rbp)
leaq -0x2a0(%rbp), %rsi
callq 0x9b20
movq -0x550(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x57b0
jmp 0x5f21
leaq -0x2d0(%rbp), %rdi
callq 0x9b50
movq 0x4f094(%rip), %rdi     # 0x54fc8
leaq 0x30144(%rip), %rsi     # 0x3607f
callq 0x42e0
movq %rax, -0x558(%rbp)
jmp 0x5f49
leaq -0x2a0(%rbp), %rdi
callq 0x9b90
movq %rax, %rdi
addq $0x10, %rdi
callq 0x9b70
movq %rax, -0x560(%rbp)
jmp 0x5f6a
movq -0x560(%rbp), %rax
testb $0x1, 0x28(%rax)
je 0x5f87
leaq 0x30110(%rip), %rax     # 0x3608e
movq %rax, -0x568(%rbp)
jmp 0x5f97
leaq 0x30110(%rip), %rax     # 0x3609e
movq %rax, -0x568(%rbp)
jmp 0x5f97
movq -0x558(%rbp), %rdi
movq -0x568(%rbp), %rsi
callq 0x42e0
movq %rax, -0x570(%rbp)
jmp 0x5fb3
movq -0x570(%rbp), %rdi
leaq 0x300ed(%rip), %rsi     # 0x360ae
callq 0x42e0
movq %rax, -0x578(%rbp)
jmp 0x5fcf
movq -0x578(%rbp), %rdi
movq 0x4efcb(%rip), %rsi     # 0x54fa8
callq 0x4330
jmp 0x5fe4
leaq -0x4e0(%rbp), %rdi
callq 0x43d0
jmp 0x5ff2
leaq 0x300c3(%rip), %rsi     # 0x360bc
leaq -0x4e0(%rbp), %rdi
movl $0x10, %edx
callq 0x42c0
jmp 0x600c
movq -0x4e0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x4e0(%rbp,%rax), %rdi
callq 0x4400
movb %al, -0x579(%rbp)
jmp 0x602c
movb -0x579(%rbp), %al
testb $0x1, %al
jne 0x603b
jmp 0x6190
leaq -0x4d0(%rbp), %rax
movq %rax, -0x590(%rbp)
leaq -0x510(%rbp), %rdi
movq %rdi, -0x588(%rbp)
leaq -0x2a0(%rbp), %rsi
callq 0x9b20
movq -0x588(%rbp), %rsi
xorl %edx, %edx
movl %edx, %ecx
leaq -0x500(%rbp), %rdi
callq 0x9bb0
jmp 0x607c
movq -0x590(%rbp), %rdi
leaq -0x500(%rbp), %rsi
callq 0x42a0
jmp 0x6091
leaq -0x500(%rbp), %rdi
callq 0x4210
leaq -0x510(%rbp), %rdi
callq 0x9b50
leaq -0x4e0(%rbp), %rdi
callq 0x4060
jmp 0x60b7
jmp 0x6190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x9b50
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0x9b50
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x9b50
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x61af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x6182
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x500(%rbp), %rdi
callq 0x4210
leaq -0x510(%rbp), %rdi
callq 0x9b50
jmp 0x61af
movl $0x0, -0x4(%rbp)
movl $0x1, -0x230(%rbp)
leaq -0x4e0(%rbp), %rdi
callq 0x40b0
jmp 0x61bd
leaq -0x4e0(%rbp), %rdi
callq 0x40b0
jmp 0x61e3
leaq -0x2a0(%rbp), %rdi
callq 0x9b50
leaq -0x290(%rbp), %rdi
callq 0x9c90
leaq -0x250(%rbp), %rdi
callq 0x4210
jmp 0x6209
leaq -0x2a0(%rbp), %rdi
callq 0x9b50
leaq -0x290(%rbp), %rdi
callq 0x9c90
leaq -0x250(%rbp), %rdi
callq 0x4210
jmp 0x6217
leaq -0x220(%rbp), %rdi
callq 0x40e0
jmp 0x6225
leaq -0x220(%rbp), %rdi
callq 0x40e0
jmp 0x6231
movl -0x4(%rbp), %eax
addq $0x590, %rsp            # imm = 0x590
popq %rbp
retq
movq -0x228(%rbp), %rdi
callq 0x4560
nopl (%rax)