// File: eatonphil[P]cpp-json/json.cpp
// Function: json::parse[abi:cxx11](std::vector<json::JSONToken, std::allocator<json::JSONToken>>, int)
std::tuple<JSONValue, int, std::string> parse(std::vector<JSONToken> tokens,
                                              int index) {
  auto token = tokens[index];
  switch (token.type) {
  case JSONTokenType::Number: {
    auto n = std::stod(token.value);
    return {JSONValue{.number = n, .type = JSONValueType::Number}, index + 1,
            ""};
  }
  case JSONTokenType::Boolean:
    return {JSONValue{.boolean = token.value == "true",
                      .type = JSONValueType::Boolean},
            index + 1, ""};
  case JSONTokenType::Null:
    return {JSONValue{.type = JSONValueType::Null}, index + 1, ""};
  case JSONTokenType::String:
    return {JSONValue{.string = token.value, .type = JSONValueType::String},
            index + 1, ""};
  case JSONTokenType::Syntax:
    if (token.value == "[") {
      auto [array, new_index, error] = parse_array(tokens, index + 1);
      return {JSONValue{.array = array, .type = JSONValueType::Array},
              new_index, error};
    }

    if (token.value == "{") {
      auto [object, new_index, error] = parse_object(tokens, index + 1);
      return {JSONValue{.object = std::optional(object),
                        .type = JSONValueType::Object},
              new_index, error};
    }
  }

  return {{}, index, format_parse_error("Failed to parse", token)};
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6f0, %rsp            # imm = 0x6F0
movq %rsi, -0x680(%rbp)
movq %rdi, %rax
movq -0x680(%rbp), %rdi
movq %rax, -0x678(%rbp)
movq %rax, %rcx
movq %rcx, -0x670(%rbp)
movq %rax, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x8da0
movq %rax, %rsi
leaq -0x50(%rbp), %rdi
callq 0x8dc0
movl -0x30(%rbp), %eax
movq %rax, -0x668(%rbp)
subq $0x4, %rax
ja 0x6baa
movq -0x668(%rbp), %rax
leaq 0xeb29(%rip), %rcx      # 0x15018
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %eax, %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x9410
movsd %xmm0, -0x688(%rbp)
jmp 0x650f
movsd -0x688(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
leaq -0x108(%rbp), %rdi
movq %rdi, -0x690(%rbp)
callq 0x9450
leaq -0xe0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x9470
leaq -0xd0(%rbp), %rdi
callq 0x94a0
leaq -0xc8(%rbp), %rdi
callq 0x94c0
leaq -0xa8(%rbp), %rdi
callq 0x94e0
movq -0x678(%rbp), %rdi
movq -0x690(%rbp), %rsi
movl $0x1, -0x70(%rbp)
movl -0x14(%rbp), %eax
incl %eax
movl %eax, -0x10c(%rbp)
leaq 0xec61(%rip), %rcx      # 0x151eb
leaq -0x10c(%rbp), %rdx
callq 0x9500
jmp 0x6598
leaq -0x108(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x6d42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x9540
jmp 0x6d42
leaq -0x1b0(%rbp), %rdi
movq %rdi, -0x6a8(%rbp)
callq 0x9450
leaq -0x188(%rbp), %rdi
callq 0x9580
leaq -0x178(%rbp), %rax
movq %rax, -0x6a0(%rbp)
leaq 0xea92(%rip), %rsi      # 0x150a7
leaq -0x50(%rbp), %rdi
callq 0x8e10
movb %al, -0x691(%rbp)
jmp 0x6626
movq -0x6a0(%rbp), %rdi
movb -0x691(%rbp), %al
andb $0x1, %al
movb %al, -0x1b1(%rbp)
leaq -0x1b1(%rbp), %rsi
callq 0x95a0
leaq -0x170(%rbp), %rdi
callq 0x94c0
leaq -0x150(%rbp), %rdi
callq 0x94e0
movq -0x678(%rbp), %rdi
movl $0x4, -0x118(%rbp)
movl -0x14(%rbp), %eax
incl %eax
movl %eax, -0x1b8(%rbp)
leaq 0xeb69(%rip), %rcx      # 0x151eb
leaq -0x1b0(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
callq 0x9500
jmp 0x6697
leaq -0x1b0(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
jmp 0x6d29
movq -0x6a8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x95d0
jmp 0x6d42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x9540
jmp 0x6d42
leaq -0x258(%rbp), %rdi
movq %rdi, -0x6b0(%rbp)
callq 0x9450
leaq -0x230(%rbp), %rdi
callq 0x9580
leaq -0x220(%rbp), %rdi
callq 0x94a0
leaq -0x218(%rbp), %rdi
callq 0x94c0
leaq -0x1f8(%rbp), %rdi
callq 0x94e0
movq -0x678(%rbp), %rdi
movq -0x6b0(%rbp), %rsi
movl $0x5, -0x1c0(%rbp)
movl -0x14(%rbp), %eax
incl %eax
movl %eax, -0x25c(%rbp)
leaq 0xea92(%rip), %rcx      # 0x151eb
leaq -0x25c(%rbp), %rdx
callq 0x9500
jmp 0x6767
leaq -0x258(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x9540
jmp 0x6d42
leaq -0x300(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x95f0
jmp 0x67b1
leaq -0x2d8(%rbp), %rdi
callq 0x9580
leaq -0x2c8(%rbp), %rdi
callq 0x94a0
leaq -0x2c0(%rbp), %rdi
callq 0x94c0
leaq -0x2a0(%rbp), %rdi
callq 0x94e0
movq -0x678(%rbp), %rdi
movl $0x0, -0x268(%rbp)
movl -0x14(%rbp), %eax
incl %eax
movl %eax, -0x304(%rbp)
leaq 0xe9e7(%rip), %rcx      # 0x151eb
leaq -0x300(%rbp), %rsi
leaq -0x304(%rbp), %rdx
callq 0x9500
jmp 0x6819
leaq -0x300(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x9540
jmp 0x6d42
leaq 0xe97b(%rip), %rsi      # 0x151d3
leaq -0x50(%rbp), %rdi
callq 0x8e10
movb %al, -0x6b1(%rbp)
jmp 0x6869
movb -0x6b1(%rbp), %al
testb $0x1, %al
jne 0x6878
jmp 0x69f3
movq -0x680(%rbp), %rsi
leaq -0x360(%rbp), %rdi
callq 0x8fa0
jmp 0x688d
movl -0x14(%rbp), %edx
incl %edx
leaq -0x348(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x5e90
jmp 0x68a7
leaq -0x360(%rbp), %rdi
callq 0x8bb0
leaq -0x348(%rbp), %rdi
movq %rdi, -0x6c8(%rbp)
callq 0x9620
movq -0x6c8(%rbp), %rdi
movq %rax, -0x368(%rbp)
callq 0x9640
movq -0x6c8(%rbp), %rdi
movq %rax, -0x370(%rbp)
callq 0x9660
movq %rax, -0x378(%rbp)
leaq -0x418(%rbp), %rdi
movq %rdi, -0x6c0(%rbp)
callq 0x9450
leaq -0x3f0(%rbp), %rdi
callq 0x9580
leaq -0x3e0(%rbp), %rdi
callq 0x94a0
leaq -0x3d8(%rbp), %rdi
movq -0x368(%rbp), %rsi
callq 0x9680
jmp 0x6933
leaq -0x3b8(%rbp), %rdi
callq 0x94e0
movq -0x678(%rbp), %rdi
movl $0x3, -0x380(%rbp)
movq -0x370(%rbp), %rdx
movq -0x378(%rbp), %rcx
leaq -0x418(%rbp), %rsi
callq 0x96b0
jmp 0x696c
leaq -0x418(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x96f0
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x8bb0
jmp 0x6d42
movq -0x6c0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x95d0
jmp 0x69e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x418(%rbp), %rdi
callq 0x9540
leaq -0x348(%rbp), %rdi
callq 0x96f0
jmp 0x6d42
leaq 0xe7db(%rip), %rsi      # 0x151d5
leaq -0x50(%rbp), %rdi
callq 0x8e10
movb %al, -0x6c9(%rbp)
jmp 0x6a0b
movb -0x6c9(%rbp), %al
testb $0x1, %al
jne 0x6a1a
jmp 0x6ba8
movq -0x680(%rbp), %rsi
leaq -0x488(%rbp), %rdi
callq 0x8fa0
jmp 0x6a2f
movl -0x14(%rbp), %edx
incl %edx
leaq -0x470(%rbp), %rdi
leaq -0x488(%rbp), %rsi
callq 0x6d60
jmp 0x6a49
leaq -0x488(%rbp), %rdi
callq 0x8bb0
leaq -0x470(%rbp), %rdi
movq %rdi, -0x6e8(%rbp)
callq 0x9710
movq -0x6e8(%rbp), %rdi
movq %rax, -0x490(%rbp)
callq 0x9730
movq -0x6e8(%rbp), %rdi
movq %rax, -0x498(%rbp)
callq 0x9750
movq %rax, -0x4a0(%rbp)
leaq -0x540(%rbp), %rdi
movq %rdi, -0x6e0(%rbp)
callq 0x9450
leaq -0x518(%rbp), %rdi
callq 0x9580
leaq -0x508(%rbp), %rdi
callq 0x94a0
leaq -0x500(%rbp), %rdi
movq %rdi, -0x6d8(%rbp)
callq 0x94c0
leaq -0x4e0(%rbp), %rdi
movq -0x490(%rbp), %rsi
callq 0x9770
jmp 0x6ae8
movq -0x678(%rbp), %rdi
movl $0x2, -0x4a8(%rbp)
movq -0x498(%rbp), %rdx
movq -0x4a0(%rbp), %rcx
leaq -0x540(%rbp), %rsi
callq 0x96b0
jmp 0x6b15
leaq -0x540(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
leaq -0x470(%rbp), %rdi
callq 0x97c0
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x488(%rbp), %rdi
callq 0x8bb0
jmp 0x6d42
movq -0x6d8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x97a0
movq -0x6e0(%rbp), %rdi
callq 0x95d0
jmp 0x6b97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x540(%rbp), %rdi
callq 0x9540
leaq -0x470(%rbp), %rdi
callq 0x97c0
jmp 0x6d42
jmp 0x6baa
leaq -0x5e0(%rbp), %rdi
callq 0x9450
leaq -0x5b8(%rbp), %rdi
callq 0x9580
leaq -0x5a8(%rbp), %rdi
callq 0x94a0
leaq -0x5a0(%rbp), %rdi
callq 0x94c0
leaq -0x580(%rbp), %rdi
callq 0x94e0
movl $0x0, -0x548(%rbp)
leaq -0x621(%rbp), %rdi
movq %rdi, -0x6f0(%rbp)
callq 0x42b0
movq -0x6f0(%rbp), %rdx
leaq 0xe5c6(%rip), %rsi      # 0x151d7
leaq -0x620(%rbp), %rdi
callq 0x8560
jmp 0x6c1f
leaq -0x660(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x8dc0
jmp 0x6c31
leaq -0x600(%rbp), %rdi
leaq -0x620(%rbp), %rsi
leaq -0x660(%rbp), %rdx
callq 0x5c50
jmp 0x6c4d
movq -0x678(%rbp), %rdi
leaq -0x5e0(%rbp), %rsi
leaq -0x14(%rbp), %rdx
leaq -0x600(%rbp), %rcx
callq 0x97e0
jmp 0x6c6d
leaq -0x600(%rbp), %rdi
callq 0x87f0
leaq -0x660(%rbp), %rdi
callq 0x88b0
leaq -0x620(%rbp), %rdi
callq 0x87f0
leaq -0x621(%rbp), %rdi
callq 0x41d0
leaq -0x5e0(%rbp), %rdi
callq 0x9540
movl $0x1, -0x110(%rbp)
jmp 0x6d29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x6d0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x6d03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x6cf7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x600(%rbp), %rdi
callq 0x87f0
leaq -0x660(%rbp), %rdi
callq 0x88b0
leaq -0x620(%rbp), %rdi
callq 0x87f0
leaq -0x621(%rbp), %rdi
callq 0x41d0
leaq -0x5e0(%rbp), %rdi
callq 0x9540
jmp 0x6d42
leaq -0x50(%rbp), %rdi
callq 0x88b0
movq -0x670(%rbp), %rax
addq $0x6f0, %rsp            # imm = 0x6F0
popq %rbp
retq
leaq -0x50(%rbp), %rdi
callq 0x88b0
movq -0x60(%rbp), %rdi
callq 0x42a0
nopw %cs:(%rax,%rax)