// File: ghallak[P]regex-to-dfa/src/RegexTree.cpp
// Function: RegexTree::Alphabet(RegexTree::Node*)
std::unordered_set<char> RegexTree::Alphabet(RegexTree::Node* n) {
  if (auto node = dynamic_cast<RegexTree::ConcatNode*>(n)) {
    auto alphabet1 = Alphabet(node->left.get());
    auto alphabet2 = Alphabet(node->right.get());
    alphabet1.insert(alphabet2.begin(), alphabet2.end());
    return alphabet1;
  } else if (auto node = dynamic_cast<RegexTree::UnionNode*>(n)) {
    auto alphabet1 = Alphabet(node->left.get());
    auto alphabet2 = Alphabet(node->right.get());
    alphabet1.insert(alphabet2.begin(), alphabet2.end());
    return alphabet1;
  } else if (auto node = dynamic_cast<RegexTree::StarNode*>(n)) {
    return Alphabet(node->child.get());
  } else if (auto node = dynamic_cast<RegexTree::LeafNode*>(n)) {
    return std::unordered_set<char>({node->label});
  } else if (auto node = dynamic_cast<RegexTree::EndNode*>(n)) {
    return std::unordered_set<char>();
  } else {
    // there is no 6th type of RegexTree nodes
    throw std::exception();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x128(%rbp)
movq %rdi, %rax
movq %rax, -0x120(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x110(%rbp)
cmpq $0x0, %rax
je 0xccfb
movq -0x110(%rbp), %rdi
leaq 0x11fa6(%rip), %rsi     # 0x1ec88
leaq 0x11faf(%rip), %rdx     # 0x1ec98
xorl %eax, %eax
movl %eax, %ecx
callq 0x21a0
movq %rax, -0x130(%rbp)
jmp 0xcd06
xorl %eax, %eax
movq %rax, -0x130(%rbp)
jmp 0xcd06
movq -0x130(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0xcdfe
movb $0x0, -0x21(%rbp)
movq -0x20(%rbp), %rdi
subq $-0x80, %rdi
callq 0x5cb0
movq -0x128(%rbp), %rdi
movq -0x118(%rbp), %rsi
movq %rax, %rdx
callq 0xcc90
movq -0x20(%rbp), %rdi
addq $0x88, %rdi
callq 0x5cb0
movq -0x118(%rbp), %rsi
movq %rax, %rdx
leaq -0x60(%rbp), %rdi
callq 0xcc90
jmp 0xcd68
leaq -0x60(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0xddb0
movq -0x138(%rbp), %rdi
movq %rax, -0x78(%rbp)
callq 0xdde0
movq -0x128(%rbp), %rdi
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rsi
movq -0x80(%rbp), %rdx
callq 0xdd70
jmp 0xcda2
movb $0x1, -0x21(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xb8f0
testb $0x1, -0x21(%rbp)
jne 0xcde8
jmp 0xcddc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xcded
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xb8f0
jmp 0xcded
movq -0x128(%rbp), %rdi
callq 0xb8f0
jmp 0xd1a5
movq -0x128(%rbp), %rdi
callq 0xb8f0
jmp 0xd1b5
movq -0x18(%rbp), %rax
movq %rax, -0x140(%rbp)
cmpq $0x0, %rax
je 0xce36
movq -0x140(%rbp), %rdi
leaq 0x11e6b(%rip), %rsi     # 0x1ec88
leaq 0x11e8c(%rip), %rdx     # 0x1ecb0
xorl %eax, %eax
movl %eax, %ecx
callq 0x21a0
movq %rax, -0x148(%rbp)
jmp 0xce41
xorl %eax, %eax
movq %rax, -0x148(%rbp)
jmp 0xce41
movq -0x148(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0xcf66
movb $0x0, -0x89(%rbp)
movq -0x88(%rbp), %rdi
subq $-0x80, %rdi
callq 0x5cb0
movq -0x128(%rbp), %rdi
movq -0x118(%rbp), %rsi
movq %rax, %rdx
callq 0xcc90
movq -0x88(%rbp), %rdi
addq $0x88, %rdi
callq 0x5cb0
movq -0x118(%rbp), %rsi
movq %rax, %rdx
leaq -0xc8(%rbp), %rdi
callq 0xcc90
jmp 0xceb5
leaq -0xc8(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0xddb0
movq -0x150(%rbp), %rdi
movq %rax, -0xd0(%rbp)
callq 0xdde0
movq -0x128(%rbp), %rdi
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rsi
movq -0xd8(%rbp), %rdx
callq 0xdd70
jmp 0xcefe
movb $0x1, -0x89(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0xb8f0
testb $0x1, -0x89(%rbp)
jne 0xcf50
jmp 0xcf44
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xcf55
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0xb8f0
jmp 0xcf55
movq -0x128(%rbp), %rdi
callq 0xb8f0
jmp 0xd1a5
movq -0x128(%rbp), %rdi
callq 0xb8f0
jmp 0xd1b5
movq -0x18(%rbp), %rax
movq %rax, -0x158(%rbp)
cmpq $0x0, %rax
je 0xcf9e
movq -0x158(%rbp), %rdi
leaq 0x11d03(%rip), %rsi     # 0x1ec88
leaq 0x11d3c(%rip), %rdx     # 0x1ecc8
xorl %eax, %eax
movl %eax, %ecx
callq 0x21a0
movq %rax, -0x160(%rbp)
jmp 0xcfa9
xorl %eax, %eax
movq %rax, -0x160(%rbp)
jmp 0xcfa9
movq -0x160(%rbp), %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0xe0(%rbp)
je 0xcfef
movq -0xe0(%rbp), %rdi
addq $0x80, %rdi
callq 0x5cb0
movq -0x128(%rbp), %rdi
movq -0x118(%rbp), %rsi
movq %rax, %rdx
callq 0xcc90
jmp 0xd1a5
movq -0x18(%rbp), %rax
movq %rax, -0x168(%rbp)
cmpq $0x0, %rax
je 0xd027
movq -0x168(%rbp), %rdi
leaq 0x11c7a(%rip), %rsi     # 0x1ec88
leaq 0x11ccb(%rip), %rdx     # 0x1ece0
xorl %eax, %eax
movl %eax, %ecx
callq 0x21a0
movq %rax, -0x170(%rbp)
jmp 0xd032
xorl %eax, %eax
movq %rax, -0x170(%rbp)
jmp 0xd032
movq -0x170(%rbp), %rax
movq %rax, -0xe8(%rbp)
cmpq $0x0, -0xe8(%rbp)
je 0xd0f6
movq -0xe8(%rbp), %rax
movb 0xb8(%rax), %al
movb %al, -0xf9(%rbp)
leaq -0xf9(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq $0x1, -0xf0(%rbp)
leaq -0xfc(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x2250
movq -0x178(%rbp), %rcx
movq -0x128(%rbp), %rdi
movq -0xf8(%rbp), %rsi
movq -0xf0(%rbp), %rdx
movq %rsp, %rax
movq %rcx, (%rax)
xorl %eax, %eax
movl %eax, %ecx
leaq -0xfa(%rbp), %r8
leaq -0xfb(%rbp), %r9
callq 0xde10
jmp 0xd0c8
leaq -0xfc(%rbp), %rdi
callq 0x2180
jmp 0xd1a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xfc(%rbp), %rdi
callq 0x2180
jmp 0xd1b5
movq -0x18(%rbp), %rax
movq %rax, -0x180(%rbp)
cmpq $0x0, %rax
je 0xd12e
movq -0x180(%rbp), %rdi
leaq 0x11b73(%rip), %rsi     # 0x1ec88
leaq 0x11bdc(%rip), %rdx     # 0x1ecf8
xorl %eax, %eax
movl %eax, %ecx
callq 0x21a0
movq %rax, -0x188(%rbp)
jmp 0xd139
xorl %eax, %eax
movq %rax, -0x188(%rbp)
jmp 0xd139
movq -0x188(%rbp), %rax
movq %rax, -0x108(%rbp)
cmpq $0x0, -0x108(%rbp)
je 0xd172
movq -0x128(%rbp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x20b0
movq -0x128(%rbp), %rdi
callq 0xde70
jmp 0xd1a5
movl $0x8, %edi
callq 0x2090
movq %rax, %rdi
movq %rdi, -0x190(%rbp)
callq 0xde90
movq -0x190(%rbp), %rdi
movq 0x11e47(%rip), %rsi     # 0x1efe0
movq 0x11e58(%rip), %rdx     # 0x1eff8
callq 0x2230
movq -0x120(%rbp), %rax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x2240
nop