// File: neguse[P]no/lang.cc
// Function: Lang::ValidateNode(std::shared_ptr<Node>, std::vector<SyntaxType, std::allocator<SyntaxType>>)
bool ValidateNode(Node::Ref n, AcceptableSyntax as) {
    // validate current node
    bool valid = false;
    auto syntax = syntax_[n->c];
    for (auto asi : as) {
      if (asi == syntax.st) {
        valid = true;
      }
    }
    if (!valid) {
      printf("failed to validate at %c (%d,%d)\n", n->c, n->pos.line,
             n->pos.col);
      printf("must be either ");
      for (auto asi : as) {
        printf("%d ", asi);
      }
      printf("\n");
      return false;
    }

    // validate child node
    if (n->a) {
      if (!ValidateNode(n->a, syntax.aa)) {
        return false;
      }
    }
    if (n->d) {
      if (!ValidateNode(n->d, syntax.ad)) {
        return false;
      }
    }
    return true;
  }

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rsi, 0x18(%rsp)
movq %rdi, %rax
movq 0x18(%rsp), %rdi
movq %rdi, 0x20(%rsp)
movq %rdx, 0x30(%rsp)
movq %rax, 0x128(%rsp)
movq %rdi, 0x120(%rsp)
movq %rdx, 0x118(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x28(%rsp)
movb $0x0, 0x117(%rsp)
callq 0x8410
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0x5440
movq %rax, %rsi
leaq 0xd8(%rsp), %rdi
callq 0x82d0
movq 0x30(%rsp), %rdx
movq %rdx, 0xd0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x97f0
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x9820
movq %rax, 0xc0(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x9850
testb $0x1, %al
jne 0x944f
jmp 0x948e
leaq 0xc8(%rsp), %rdi
callq 0x9890
movl (%rax), %eax
movl %eax, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
jne 0x947d
movb $0x1, 0x117(%rsp)
jmp 0x947f
leaq 0xc8(%rsp), %rdi
callq 0x98a0
jmp 0x9434
testb $0x1, 0x117(%rsp)
jne 0x95c4
movq 0x20(%rsp), %rdi
callq 0x8410
movq 0x20(%rsp), %rdi
movsbl (%rax), %eax
movl %eax, 0x10(%rsp)
callq 0x8410
movq 0x20(%rsp), %rdi
movl 0x28(%rax), %eax
movl %eax, 0x14(%rsp)
callq 0x8410
movl 0x10(%rsp), %esi
movl 0x14(%rsp), %edx
movl 0x2c(%rax), %ecx
leaq 0x7cb0(%rip), %rdi      # 0x1118a
xorl %eax, %eax
callq 0x2030
jmp 0x94e3
leaq 0x7cc2(%rip), %rdi      # 0x111ac
xorl %eax, %eax
callq 0x2030
jmp 0x94f3
movq 0x30(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x97f0
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x9820
movq %rax, 0x90(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x9850
testb $0x1, %al
jne 0x9545
jmp 0x959c
leaq 0x98(%rsp), %rdi
callq 0x9890
movl (%rax), %eax
movl %eax, 0x8c(%rsp)
movl 0x8c(%rsp), %esi
leaq 0x7c53(%rip), %rdi      # 0x111bc
xorl %eax, %eax
callq 0x2030
jmp 0x9572
jmp 0x9574
leaq 0x98(%rsp), %rdi
callq 0x98a0
jmp 0x952a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
jmp 0x97c9
leaq 0x7c07(%rip), %rdi      # 0x111aa
xorl %eax, %eax
callq 0x2030
jmp 0x95ac
movb $0x0, 0x137(%rsp)
movl $0x1, 0x88(%rsp)
jmp 0x97ab
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rdi
addq $0x8, %rdi
callq 0x9370
testb $0x1, %al
jne 0x95e3
jmp 0x96b1
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rsi
addq $0x8, %rsi
leaq 0x78(%rsp), %rdi
callq 0x4910
leaq 0xe0(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x52e0
jmp 0x9612
movq 0x28(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x9390
movb %al, 0xf(%rsp)
jmp 0x962c
movb 0xf(%rsp), %al
xorb $-0x1, %al
movb %al, 0xe(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x53e0
leaq 0x78(%rsp), %rdi
callq 0x4940
movb 0xe(%rsp), %al
testb $0x1, %al
jne 0x9654
jmp 0x96af
movb $0x0, 0x137(%rsp)
movl $0x1, 0x88(%rsp)
jmp 0x97ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
jmp 0x96a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x53e0
leaq 0x78(%rsp), %rdi
callq 0x4940
jmp 0x97c9
jmp 0x96b1
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rdi
addq $0x18, %rdi
callq 0x9370
testb $0x1, %al
jne 0x96d0
jmp 0x9798
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rsi
addq $0x18, %rsi
leaq 0x50(%rsp), %rdi
callq 0x4910
leaq 0xf8(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0x52e0
jmp 0x96ff
movq 0x28(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x9390
movb %al, 0xd(%rsp)
jmp 0x9719
movb 0xd(%rsp), %al
xorb $-0x1, %al
movb %al, 0xc(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x53e0
leaq 0x50(%rsp), %rdi
callq 0x4940
movb 0xc(%rsp), %al
testb $0x1, %al
jne 0x9741
jmp 0x9796
movb $0x0, 0x137(%rsp)
movl $0x1, 0x88(%rsp)
jmp 0x97ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
jmp 0x978a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x53e0
leaq 0x50(%rsp), %rdi
callq 0x4940
jmp 0x97c9
jmp 0x9798
movb $0x1, 0x137(%rsp)
movl $0x1, 0x88(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x5590
movb 0x137(%rsp), %al
andb $0x1, %al
addq $0x138, %rsp            # imm = 0x138
retq
leaq 0xd8(%rsp), %rdi
callq 0x5590
movq 0xb0(%rsp), %rdi
callq 0x21d0
nopw %cs:(%rax,%rax)
nopl (%rax)