// File: ghallak[P]regex-to-dfa/src/DFA.cpp
// Function: DFA::CreateDotFile(std::basic_string_view<char, std::char_traits<char>>) const
void DFA::CreateDotFile(std::string_view filename) const {
  std::ofstream out(filename.data());
  out << "digraph finite_state_machine {" << '\n'
      << "  rankdir=LR;" << '\n'
      << "  size=\"8,5\"" << '\n'
      << "  node [shape = circle]; q0" << '\n';

  std::unordered_map<const State*, std::size_t> state_id;
  for (std::size_t i = 0; i < states.size(); ++i) {
    auto p = states[i].get();
    for (const auto& trans : p->Transitions()) {
      state_id.try_emplace(p, state_id.size());
      state_id.try_emplace(trans.state, state_id.size());
      auto start_state = "q" + std::to_string(state_id[p]);
      auto end_state = "q" + std::to_string(state_id[trans.state]);
      auto edge_label = trans.character;

      if (trans.state->IsAcceptState()) {
        out << "node [shape = doublecircle];" << '\n';
      } else {
        out << "node [shape = circle];" << '\n';
      }
      out << "  " << start_state << " -> " << end_state << " [ label = \""
          << edge_label << "\" ];" << '\n';
    }
  }
  out << "}" << '\n';
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x440, %rsp            # imm = 0x440
movq %rsi, -0x10(%rbp)
movq %rdx, -0x8(%rbp)
movq %rdi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x360(%rbp)
leaq -0x10(%rbp), %rdi
callq 0x5130
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
movq %rdi, -0x358(%rbp)
movl $0x10, %edx
callq 0x2190
movq -0x358(%rbp), %rdi
leaq 0x10134(%rip), %rsi     # 0x13018
callq 0x2140
movq %rax, -0x350(%rbp)
jmp 0x2ef2
movq -0x350(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
movq %rax, -0x368(%rbp)
jmp 0x2f0c
movq -0x368(%rbp), %rdi
leaq 0x1011d(%rip), %rsi     # 0x13037
callq 0x2140
movq %rax, -0x370(%rbp)
jmp 0x2f28
movq -0x370(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
movq %rax, -0x378(%rbp)
jmp 0x2f42
movq -0x378(%rbp), %rdi
leaq 0x100f5(%rip), %rsi     # 0x13045
callq 0x2140
movq %rax, -0x380(%rbp)
jmp 0x2f5e
movq -0x380(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
movq %rax, -0x388(%rbp)
jmp 0x2f78
movq -0x388(%rbp), %rdi
leaq 0x100cc(%rip), %rsi     # 0x13052
callq 0x2140
movq %rax, -0x390(%rbp)
jmp 0x2f94
movq -0x390(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
jmp 0x2fa7
leaq -0x260(%rbp), %rdi
callq 0x5150
movq $0x0, -0x268(%rbp)
movq -0x360(%rbp), %rdi
movq -0x268(%rbp), %rax
movq %rax, -0x398(%rbp)
callq 0x5170
movq %rax, %rcx
movq -0x398(%rbp), %rax
cmpq %rcx, %rax
jae 0x3475
movq -0x360(%rbp), %rdi
movq -0x268(%rbp), %rsi
callq 0x5190
movq %rax, %rdi
callq 0x4ff0
movq %rax, -0x270(%rbp)
movq -0x270(%rbp), %rdi
callq 0x51b0
movq %rax, -0x3a0(%rbp)
jmp 0x3022
movq -0x3a0(%rbp), %rax
movq %rax, -0x278(%rbp)
movq -0x278(%rbp), %rdi
callq 0x51c0
movq %rax, -0x280(%rbp)
movq -0x278(%rbp), %rdi
callq 0x51f0
movq %rax, -0x288(%rbp)
leaq -0x280(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x5220
testb $0x1, %al
jne 0x3072
jmp 0x345c
leaq -0x280(%rbp), %rdi
callq 0x5260
movq %rax, -0x290(%rbp)
leaq -0x260(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x52e0
movq -0x3b8(%rbp), %rdi
movq %rax, -0x298(%rbp)
leaq -0x270(%rbp), %rsi
leaq -0x298(%rbp), %rdx
callq 0x5280
movb %dl, -0x3a9(%rbp)
movq %rax, -0x3a8(%rbp)
jmp 0x30c8
movb -0x3a9(%rbp), %al
movq -0x3a8(%rbp), %rcx
movq %rcx, -0x2a8(%rbp)
movb %al, -0x2a0(%rbp)
movq -0x290(%rbp), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x260(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x52e0
movq -0x3d8(%rbp), %rdi
movq -0x3d0(%rbp), %rsi
movq %rax, -0x2b0(%rbp)
leaq -0x2b0(%rbp), %rdx
callq 0x5280
movb %dl, -0x3c1(%rbp)
movq %rax, -0x3c0(%rbp)
jmp 0x3133
movb -0x3c1(%rbp), %al
movq -0x3c0(%rbp), %rcx
movq %rcx, -0x2c0(%rbp)
movb %al, -0x2b8(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x5430
movq %rax, -0x3e0(%rbp)
jmp 0x3169
movq -0x3e0(%rbp), %rax
movq (%rax), %rsi
leaq -0x300(%rbp), %rdi
callq 0x5350
jmp 0x3181
leaq 0xfee6(%rip), %rsi      # 0x1306e
leaq -0x2e0(%rbp), %rdi
leaq -0x300(%rbp), %rdx
callq 0x5300
jmp 0x319d
leaq -0x300(%rbp), %rdi
callq 0x20d0
movq -0x290(%rbp), %rsi
leaq -0x260(%rbp), %rdi
callq 0x5430
movq %rax, -0x3e8(%rbp)
jmp 0x31c5
movq -0x3e8(%rbp), %rax
movq (%rax), %rsi
leaq -0x340(%rbp), %rdi
callq 0x5350
jmp 0x31dd
leaq 0xfe8a(%rip), %rsi      # 0x1306e
leaq -0x320(%rbp), %rdi
leaq -0x340(%rbp), %rdx
callq 0x5300
jmp 0x31f9
leaq -0x340(%rbp), %rdi
callq 0x20d0
movq -0x290(%rbp), %rax
movb 0x8(%rax), %al
movb %al, -0x341(%rbp)
movq -0x290(%rbp), %rax
movq (%rax), %rdi
callq 0x5460
movb %al, -0x3e9(%rbp)
jmp 0x322c
movb -0x3e9(%rbp), %al
testb $0x1, %al
jne 0x323b
jmp 0x331d
leaq 0xfe2e(%rip), %rsi      # 0x13070
leaq -0x218(%rbp), %rdi
callq 0x2140
movq %rax, -0x3f8(%rbp)
jmp 0x3257
movq -0x3f8(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
jmp 0x326a
jmp 0x334e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x34d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x34c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x20d0
jmp 0x34c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x344e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x340(%rbp), %rdi
callq 0x20d0
jmp 0x344e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x20d0
jmp 0x344e
leaq 0xfd69(%rip), %rsi      # 0x1308d
leaq -0x218(%rbp), %rdi
callq 0x2140
movq %rax, -0x400(%rbp)
jmp 0x3339
movq -0x400(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
jmp 0x334c
jmp 0x334e
leaq 0xfd4f(%rip), %rsi      # 0x130a4
leaq -0x218(%rbp), %rdi
callq 0x2140
movq %rax, -0x408(%rbp)
jmp 0x336a
movq -0x408(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
callq 0x2130
movq %rax, -0x410(%rbp)
jmp 0x3386
movq -0x410(%rbp), %rdi
leaq 0xfd13(%rip), %rsi      # 0x130a7
callq 0x2140
movq %rax, -0x418(%rbp)
jmp 0x33a2
movq -0x418(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x2130
movq %rax, -0x420(%rbp)
jmp 0x33be
movq -0x420(%rbp), %rdi
leaq 0xfce0(%rip), %rsi      # 0x130ac
callq 0x2140
movq %rax, -0x428(%rbp)
jmp 0x33da
movq -0x428(%rbp), %rdi
movsbl -0x341(%rbp), %esi
callq 0x21c0
movq %rax, -0x430(%rbp)
jmp 0x33f6
movq -0x430(%rbp), %rdi
leaq 0xfcb5(%rip), %rsi      # 0x130b9
callq 0x2140
movq %rax, -0x438(%rbp)
jmp 0x3412
movq -0x438(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
jmp 0x3425
leaq -0x320(%rbp), %rdi
callq 0x20d0
leaq -0x2e0(%rbp), %rdi
callq 0x20d0
leaq -0x280(%rbp), %rdi
callq 0x5480
jmp 0x3056
leaq -0x2e0(%rbp), %rdi
callq 0x20d0
jmp 0x34c5
jmp 0x345e
movq -0x268(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x268(%rbp)
jmp 0x2fbe
leaq 0xfc42(%rip), %rsi      # 0x130be
leaq -0x218(%rbp), %rdi
callq 0x2140
movq %rax, -0x440(%rbp)
jmp 0x3491
movq -0x440(%rbp), %rdi
movl $0xa, %esi
callq 0x21c0
jmp 0x34a4
leaq -0x260(%rbp), %rdi
callq 0x54a0
leaq -0x218(%rbp), %rdi
callq 0x21f0
addq $0x440, %rsp            # imm = 0x440
popq %rbp
retq
leaq -0x260(%rbp), %rdi
callq 0x54a0
leaq -0x218(%rbp), %rdi
callq 0x21f0
movq -0x220(%rbp), %rdi
callq 0x2240
nopl (%rax)