// File: hzeller[P]jcxxgen/schema-compiler.cc
// Function: ParseObjectTypesFromFile(char const*, std::vector<ObjectType*, std::allocator<ObjectType*>>*)
static bool ParseObjectTypesFromFile(const char *filename,
                                     ObjectTypeVector *parsed_out) {
  static const std::regex emptyline_re("^[ \t]*(#.*)?");
  static const std::regex toplevel_object_re("^([a-zA-Z0-9_]+):");

  // For now, let's just read up to the first type and leave out alternatives
  static const std::regex property_re(
    "^[ \t]+([a-zA-Z_<]+)([\\?\\+]*):[ ]*([a-zA-Z0-9_]+)[ ]*(=[ \t]*(.+))?");

  Location current_location = { filename, 0 };
  ObjectType *current_model = nullptr;
  std::ifstream in(filename);
  if (!in.good()) {
    std::cerr << "Can't open " << filename << "\n";
    return false;
  }
  std::string line;
  std::smatch matches;
  while (!in.eof()) {
    std::getline(in, line);
    current_location.line++;

    if (std::regex_match(line, emptyline_re))
      continue;

    if (std::regex_search(line, matches, toplevel_object_re)) {
      current_model = new ObjectType(current_location, matches[1]);
      parsed_out->push_back(current_model);
      continue;
    }

    if (!current_model) {
      std::cerr << current_location << "No ObjectType definition\n";
      return false;
    }
    if (!std::regex_search(line, matches, property_re)) {
      std::cerr << current_location << "This doesn't look like a property\n";
      return false;
    }

    if (matches[1] == "<") {
      current_model->extends.push_back(matches[3]);
      continue;
    }

    Property property(current_location, current_model, matches[1],
                      contains(matches[2], '?'), contains(matches[2], '+'));
    property.type = matches[3];  // TODO: allow multiple
    property.default_value = matches[5];
    current_model->properties.push_back(property);
  }
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpb $0x0, 0x4ee2e(%rip)     # 0x54808
jne 0x5a2d
leaq 0x4ee25(%rip), %rdi     # 0x54808
callq 0x56b0
cmpl $0x0, %eax
je 0x5a2d
leaq 0x4edf4(%rip), %rdi     # 0x547e8
leaq 0x32bd1(%rip), %rsi     # 0x385cc
movl $0x10, %edx
callq 0x84c0
jmp 0x5a07
leaq 0x2b52(%rip), %rdi      # 0x8560
leaq 0x4edd3(%rip), %rsi     # 0x547e8
leaq 0x4e9ac(%rip), %rdx     # 0x543c8
callq 0x5380
leaq 0x4ede0(%rip), %rdi     # 0x54808
callq 0x52c0
cmpb $0x0, 0x4edfc(%rip)     # 0x54830
jne 0x5a87
leaq 0x4edf3(%rip), %rdi     # 0x54830
callq 0x56b0
cmpl $0x0, %eax
je 0x5a87
leaq 0x4edc2(%rip), %rdi     # 0x54810
leaq 0x32b84(%rip), %rsi     # 0x385d9
movl $0x10, %edx
callq 0x84c0
jmp 0x5a61
leaq 0x2af8(%rip), %rdi      # 0x8560
leaq 0x4eda1(%rip), %rsi     # 0x54810
leaq 0x4e952(%rip), %rdx     # 0x543c8
callq 0x5380
leaq 0x4edae(%rip), %rdi     # 0x54830
callq 0x52c0
cmpb $0x0, 0x4edca(%rip)     # 0x54858
jne 0x5ae1
leaq 0x4edc1(%rip), %rdi     # 0x54858
callq 0x56b0
cmpl $0x0, %eax
je 0x5ae1
leaq 0x4ed90(%rip), %rdi     # 0x54838
leaq 0x32b3c(%rip), %rsi     # 0x385eb
movl $0x10, %edx
callq 0x84c0
jmp 0x5abb
leaq 0x2a9e(%rip), %rdi      # 0x8560
leaq 0x4ed6f(%rip), %rsi     # 0x54838
leaq 0x4e8f8(%rip), %rdx     # 0x543c8
callq 0x5380
leaq 0x4ed7c(%rip), %rdi     # 0x54858
callq 0x52c0
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x248(%rbp), %rdi
movl $0x8, %edx
callq 0x56d0
movq -0x248(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x248(%rbp,%rax), %rdi
callq 0x5620
movb %al, -0x401(%rbp)
jmp 0x5b2d
movb -0x401(%rbp), %al
testb $0x1, %al
jne 0x5c02
jmp 0x5b3d
movq 0x4e4ac(%rip), %rdi     # 0x53ff0
leaq 0x32ae2(%rip), %rsi     # 0x3862d
callq 0x53c0
movq %rax, -0x410(%rbp)
jmp 0x5b59
movq -0x410(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x53c0
movq %rax, -0x418(%rbp)
jmp 0x5b72
movq -0x418(%rbp), %rdi
leaq 0x3265a(%rip), %rsi     # 0x381da
callq 0x53c0
jmp 0x5b87
movb $0x0, -0x1(%rbp)
movl $0x1, -0x24c(%rbp)
jmp 0x61ea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq 0x4ec5b(%rip), %rdi     # 0x54808
callq 0x52b0
jmp 0x6210
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq 0x4ec66(%rip), %rdi     # 0x54830
callq 0x52b0
jmp 0x6210
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq 0x4ec71(%rip), %rdi     # 0x54858
callq 0x52b0
jmp 0x6210
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x6204
leaq -0x270(%rbp), %rdi
callq 0x5530
leaq -0x290(%rbp), %rdi
callq 0x8590
jmp 0x5c1c
jmp 0x5c1e
movq -0x248(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x248(%rbp,%rax), %rdi
callq 0x56e0
movb %al, -0x419(%rbp)
jmp 0x5c3e
movb -0x419(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x5c4f
jmp 0x61a8
leaq -0x248(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x50a0
jmp 0x5c64
movl -0x30(%rbp), %eax
incl %eax
movl %eax, -0x30(%rbp)
leaq 0x4eb75(%rip), %rsi     # 0x547e8
leaq -0x270(%rbp), %rdi
xorl %edx, %edx
callq 0x85d0
movb %al, -0x41a(%rbp)
jmp 0x5c89
movb -0x41a(%rbp), %al
testb $0x1, %al
jne 0x5c95
jmp 0x5cb9
jmp 0x5c1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x61dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x61d0
leaq 0x4eb50(%rip), %rdx     # 0x54810
leaq -0x270(%rbp), %rdi
leaq -0x290(%rbp), %rsi
xorl %ecx, %ecx
callq 0x8620
movb %al, -0x41b(%rbp)
jmp 0x5cdd
movb -0x41b(%rbp), %al
testb $0x1, %al
jne 0x5cec
jmp 0x5dc7
movl $0x78, %edi
callq 0x53d0
movq %rax, -0x428(%rbp)
jmp 0x5cff
movb $0x1, -0x2b1(%rbp)
leaq -0x290(%rbp), %rdi
movl $0x1, %esi
callq 0x8680
movq %rax, -0x430(%rbp)
jmp 0x5d20
movq -0x430(%rbp), %rsi
leaq -0x2b0(%rbp), %rdi
callq 0x86f0
jmp 0x5d35
movq -0x428(%rbp), %rdi
leaq -0x38(%rbp), %rsi
leaq -0x2b0(%rbp), %rdx
callq 0x8720
jmp 0x5d4e
movq -0x428(%rbp), %rax
movb $0x0, -0x2b1(%rbp)
movq %rax, -0x40(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x5280
movq -0x18(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x8790
jmp 0x5d7b
jmp 0x5c1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x5da6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x5280
testb $0x1, -0x2b1(%rbp)
jne 0x5db1
jmp 0x5dc2
movq -0x428(%rbp), %rdi
movl $0x78, %esi
callq 0x53e0
jmp 0x61d0
cmpq $0x0, -0x40(%rbp)
jne 0x5e0f
movq 0x4e21b(%rip), %rdi     # 0x53ff0
leaq -0x38(%rbp), %rsi
callq 0x8130
movq %rax, -0x438(%rbp)
jmp 0x5de7
movq -0x438(%rbp), %rdi
leaq 0x32844(%rip), %rsi     # 0x38639
callq 0x53c0
jmp 0x5dfc
movb $0x0, -0x1(%rbp)
movl $0x1, -0x24c(%rbp)
jmp 0x61b6
leaq 0x4ea22(%rip), %rdx     # 0x54838
leaq -0x270(%rbp), %rdi
leaq -0x290(%rbp), %rsi
xorl %ecx, %ecx
callq 0x8620
movb %al, -0x439(%rbp)
jmp 0x5e33
movb -0x439(%rbp), %al
testb $0x1, %al
jne 0x5e80
jmp 0x5e3f
movq 0x4e1aa(%rip), %rdi     # 0x53ff0
leaq -0x38(%rbp), %rsi
callq 0x8130
movq %rax, -0x448(%rbp)
jmp 0x5e58
movq -0x448(%rbp), %rdi
leaq 0x327ed(%rip), %rsi     # 0x38653
callq 0x53c0
jmp 0x5e6d
movb $0x0, -0x1(%rbp)
movl $0x1, -0x24c(%rbp)
jmp 0x61b6
leaq -0x290(%rbp), %rdi
movl $0x1, %esi
callq 0x8680
movq %rax, -0x450(%rbp)
jmp 0x5e9a
movq -0x450(%rbp), %rdi
leaq 0x327ce(%rip), %rsi     # 0x38676
callq 0x8800
movb %al, -0x451(%rbp)
jmp 0x5eb5
movb -0x451(%rbp), %al
testb $0x1, %al
jne 0x5ec4
jmp 0x5f45
movq -0x40(%rbp), %rax
addq $0x30, %rax
movq %rax, -0x468(%rbp)
leaq -0x290(%rbp), %rdi
movl $0x3, %esi
callq 0x8680
movq %rax, -0x460(%rbp)
jmp 0x5eed
movq -0x460(%rbp), %rsi
leaq -0x2d8(%rbp), %rdi
callq 0x86f0
jmp 0x5f02
movq -0x468(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x8830
jmp 0x5f17
leaq -0x2d8(%rbp), %rdi
callq 0x5280
jmp 0x5c1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x2d8(%rbp), %rdi
callq 0x5280
jmp 0x61d0
movq -0x40(%rbp), %rax
movq %rax, -0x478(%rbp)
leaq -0x290(%rbp), %rdi
movl $0x1, %esi
callq 0x8680
movq %rax, -0x470(%rbp)
jmp 0x5f6a
movq -0x470(%rbp), %rsi
leaq -0x380(%rbp), %rdi
callq 0x86f0
jmp 0x5f7f
leaq -0x290(%rbp), %rdi
movl $0x2, %esi
callq 0x8680
movq %rax, -0x480(%rbp)
jmp 0x5f99
movq -0x480(%rbp), %rsi
leaq -0x3a0(%rbp), %rdi
callq 0x86f0
jmp 0x5fae
leaq -0x3a0(%rbp), %rdi
movl $0x3f, %esi
callq 0x7d10
movb %al, -0x481(%rbp)
jmp 0x5fc7
leaq -0x290(%rbp), %rdi
movl $0x2, %esi
callq 0x8680
movq %rax, -0x490(%rbp)
jmp 0x5fe1
movq -0x490(%rbp), %rsi
leaq -0x3c0(%rbp), %rdi
callq 0x86f0
jmp 0x5ff6
leaq -0x3c0(%rbp), %rdi
movl $0x2b, %esi
callq 0x7d10
movb %al, -0x491(%rbp)
jmp 0x600f
movq -0x478(%rbp), %rdx
movb -0x491(%rbp), %al
movb -0x481(%rbp), %cl
movzbl %cl, %r8d
andl $0x1, %r8d
movzbl %al, %r9d
andl $0x1, %r9d
leaq -0x360(%rbp), %rdi
leaq -0x38(%rbp), %rsi
leaq -0x380(%rbp), %rcx
callq 0x8860
jmp 0x604b
leaq -0x3c0(%rbp), %rdi
callq 0x5280
leaq -0x3a0(%rbp), %rdi
callq 0x5280
leaq -0x380(%rbp), %rdi
callq 0x5280
leaq -0x290(%rbp), %rdi
movl $0x3, %esi
callq 0x8680
movq %rax, -0x4a0(%rbp)
jmp 0x6089
movq -0x4a0(%rbp), %rsi
leaq -0x3e0(%rbp), %rdi
callq 0x86f0
jmp 0x609e
leaq -0x300(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
movq %rsi, -0x4b0(%rbp)
callq 0x54a0
movq -0x4b0(%rbp), %rdi
callq 0x5280
leaq -0x290(%rbp), %rdi
movl $0x5, %esi
callq 0x8680
movq %rax, -0x4a8(%rbp)
jmp 0x60de
movq -0x4a8(%rbp), %rsi
leaq -0x400(%rbp), %rdi
callq 0x86f0
jmp 0x60f3
leaq -0x320(%rbp), %rdi
leaq -0x400(%rbp), %rsi
movq %rsi, -0x4b8(%rbp)
callq 0x54a0
movq -0x4b8(%rbp), %rdi
callq 0x5280
movq -0x40(%rbp), %rdi
addq $0x48, %rdi
leaq -0x360(%rbp), %rsi
callq 0x8920
jmp 0x612f
leaq -0x360(%rbp), %rdi
callq 0x8990
jmp 0x5c1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x6180
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x6174
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x3c0(%rbp), %rdi
callq 0x5280
leaq -0x3a0(%rbp), %rdi
callq 0x5280
leaq -0x380(%rbp), %rdi
callq 0x5280
jmp 0x61d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x8990
jmp 0x61d0
movb $0x1, -0x1(%rbp)
movl $0x1, -0x24c(%rbp)
leaq -0x290(%rbp), %rdi
callq 0x89d0
leaq -0x270(%rbp), %rdi
callq 0x5280
jmp 0x61ea
leaq -0x290(%rbp), %rdi
callq 0x89d0
leaq -0x270(%rbp), %rdi
callq 0x5280
jmp 0x6204
leaq -0x248(%rbp), %rdi
callq 0x50f0
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
leaq -0x248(%rbp), %rdi
callq 0x50f0
movq -0x20(%rbp), %rdi
callq 0x5680
nopl (%rax)