// File: /workspace/github_c_makefile_star2_O2/orangeduck[P]mpc/examples/tree_traversal.c
// Function: main
int main(int argc, char *argv[]) {

  mpc_parser_t *Input  = mpc_new("input");
  mpc_parser_t *Node  = mpc_new("node");
  mpc_parser_t *Leaf  = mpc_new("leaf");
  mpc_ast_t *ast, *tree, *child, *child_sub, *ast_next;
  mpc_ast_trav_t *trav;
  mpc_result_t r;
  int index, lb, i;

  mpca_lang(MPCA_LANG_PREDICTIVE,
        " node : '(' <node> ',' /foo/ ',' <node> ')' | <leaf>;"
        " leaf : /bar/;"
        " input : /^/ <node> /$/;",
        Node, Leaf, Input, NULL);

  if (argc > 1) {

    if (mpc_parse_contents(argv[1], Input, &r)) {
      ast = r.output;
    } else {
      mpc_err_print(r.error);
      mpc_err_delete(r.error);
      mpc_cleanup(3, Node, Leaf, Input);
      return EXIT_FAILURE;
    }

  } else {

    if (mpc_parse_pipe("<stdin>", stdin, Input, &r)) {
      ast = r.output;
    } else {
      mpc_err_print(r.error);
      mpc_err_delete(r.error);
      mpc_cleanup(3, Node, Leaf, Input);
      return EXIT_FAILURE;
    }

  }

  /* Get index or child of tree */
  tree = ast->children[1];

  index = mpc_ast_get_index(tree, "node|>");
  child = mpc_ast_get_child(tree, "node|>");

  if(child == NULL) {
    mpc_cleanup(3, Node, Leaf, Input);
    mpc_ast_delete(ast);
    return EXIT_FAILURE;
  }

  printf("Index: %d; Child: \"%s\"\n", index, child->tag);

  /* Get multiple indexes or children of trees */
  index     = mpc_ast_get_index_lb(child, "node|leaf|regex", 0);
  child_sub = mpc_ast_get_child_lb(child, "node|leaf|regex", 0);

  while(index != -1) {
    printf("-- Index: %d; Child: \"%s\"\n", index, child_sub->tag);

    lb = index + 1;
    index     = mpc_ast_get_index_lb(child, "node|leaf|regex", lb);
    child_sub = mpc_ast_get_child_lb(child, "node|leaf|regex", lb);
  }

  /* Traversal */
  printf("Pre order tree traversal.\n");
  trav = mpc_ast_traverse_start(ast, mpc_ast_trav_order_pre);

  ast_next = mpc_ast_traverse_next(&trav);

  while(ast_next != NULL) {
    printf("Tag: %s; Contents: %s\n",
      ast_next->tag,
      ast_next->contents);
    ast_next = mpc_ast_traverse_next(&trav);
  }

  mpc_ast_traverse_free(&trav);

  printf("Post order tree traversal.\n");

  trav = mpc_ast_traverse_start(ast, mpc_ast_trav_order_post);

  ast_next = mpc_ast_traverse_next(&trav);

  while(ast_next != NULL) {
    printf("Tag: %s; Contents: %s\n",
      ast_next->tag,
      ast_next->contents);
    ast_next = mpc_ast_traverse_next(&trav);
  }

  mpc_ast_traverse_free(&trav);

  printf("Partial traversal.\n");

  trav = mpc_ast_traverse_start(ast, mpc_ast_trav_order_post);

  ast_next = mpc_ast_traverse_next(&trav);

  for(i=0; i<2 && ast_next != NULL; i++) {
    printf("Tag: %s; Contents: %s\n",
      ast_next->tag,
      ast_next->contents);
    ast_next = mpc_ast_traverse_next(&trav);
  }

  mpc_ast_traverse_free(&trav);

  /* Clean up and return */
  mpc_cleanup(3, Node, Leaf, Input);
  mpc_ast_delete(ast);

  return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r12
movl %edi, %r13d
leaq 0x81cc(%rip), %rdi      # 0x9503
callq 0x2d7a
movq %rax, %rbx
leaq 0x7cbe(%rip), %rdi      # 0x9004
callq 0x2d7a
movq %rax, %r14
leaq 0x7cb4(%rip), %rdi      # 0x9009
callq 0x2d7a
movq %rax, %r15
leaq 0x7caa(%rip), %rsi      # 0x900e
pushq $0x1
popq %rbp
movl %ebp, %edi
movq %r14, %rdx
movq %rax, %rcx
movq %rbx, %r8
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x72fe
cmpl $0x2, %r13d
jl 0x1394
movq 0x8(%r12), %rdi
movq %rsp, %rdx
movq %rbx, %rsi
callq 0x2b73
jmp 0x13b0
movq 0xcc45(%rip), %rax      # 0xdfe0
movq (%rax), %rsi
leaq 0x7cc5(%rip), %rdi      # 0x906a
movq %rsp, %rcx
movq %rbx, %rdx
callq 0x2aad
testl %eax, %eax
je 0x1571
movq %r15, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %rbx, 0x20(%rsp)
movq (%rsp), %r12
movq 0x38(%r12), %rax
movq 0x8(%rax), %rbx
leaq 0x7c97(%rip), %r15      # 0x9072
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5f4b
movl %eax, %r14d
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5f9b
testq %rax, %rax
je 0x1598
movq %rax, %r13
movq (%rax), %rdx
leaq 0x7c82(%rip), %rdi      # 0x908c
movl %r14d, %esi
xorl %eax, %eax
callq 0x10b0
leaq 0x7c5e(%rip), %rbp      # 0x9079
leaq 0x7c67(%rip), %r14      # 0x9089
xorl %ebx, %ebx
movq %r13, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x5f52
movl %eax, %r15d
movq %r13, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x5fa2
cmpl $-0x1, %r15d
je 0x145f
movq (%rax), %rdx
movq %r14, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x10b0
incl %r15d
movl %r15d, %ebx
jmp 0x1424
leaq 0x7c55(%rip), %rdi      # 0x90bb
callq 0x1060
movq %r12, %rdi
xorl %esi, %esi
callq 0x5fe9
leaq 0x8(%rsp), %r14
movq %rax, (%r14)
leaq 0x7c20(%rip), %r15      # 0x90a4
movq %r14, %rdi
callq 0x6055
testq %rax, %rax
je 0x14a4
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r15, %rdi
xorl %eax, %eax
callq 0x10b0
jmp 0x1484
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0x6158
leaq 0x7c1d(%rip), %rdi      # 0x90d5
callq 0x1060
pushq $0x1
popq %rsi
movq %r12, %rdi
callq 0x5fe9
movq %rax, (%r13)
leaq 0x7bd1(%rip), %r14      # 0x90a4
movq 0x10(%rsp), %r15
movq %r13, %rdi
callq 0x6055
testq %rax, %rax
je 0x14f8
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r14, %rdi
xorl %eax, %eax
callq 0x10b0
jmp 0x14d8
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0x6158
leaq 0x7be4(%rip), %rdi      # 0x90f0
callq 0x1060
pushq $0x1
popq %rsi
movq %r12, %rdi
callq 0x5fe9
movq %rax, (%r13)
movq %r13, %rdi
callq 0x6055
leaq 0x7b75(%rip), %r14      # 0x90a4
xorl %ebx, %ebx
cmpl $0x1, %ebx
ja 0x1558
testq %rax, %rax
je 0x1558
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r14, %rdi
xorl %eax, %eax
callq 0x10b0
movq %r13, %rdi
callq 0x6055
incl %ebx
jmp 0x1531
leaq 0x8(%rsp), %rdi
callq 0x6158
xorl %ebp, %ebp
pushq $0x3
popq %rdi
movq 0x18(%rsp), %rsi
movq %r15, %rdx
jmp 0x15a5
movq (%rsp), %rdi
callq 0x1617
movq (%rsp), %rdi
callq 0x15cc
pushq $0x3
popq %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x316e
jmp 0x15b9
pushq $0x3
popq %rdi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x20(%rsp), %rcx
xorl %eax, %eax
callq 0x316e
movq %r12, %rdi
callq 0x5a4f
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop