// File: /workspace/github_c_makefile_star2_O1/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, %ebp
leaq 0xa1ad(%rip), %rdi      # 0xb4e3
callq 0x3151
movq %rax, %rbx
leaq 0x9cbf(%rip), %rdi      # 0xb004
callq 0x3151
movq %rax, %r14
leaq 0x9cb5(%rip), %rdi      # 0xb009
callq 0x3151
movq %rax, %r15
leaq 0x9cab(%rip), %rsi      # 0xb00e
movl $0x1, %edi
movq %r14, %rdx
movq %rax, %rcx
movq %rbx, %r8
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x8d58
cmpl $0x2, %ebp
jl 0x1392
movq 0x8(%r12), %rdi
movq %rsp, %rdx
movq %rbx, %rsi
callq 0x2f19
jmp 0x13ae
movq 0xec47(%rip), %rax      # 0xffe0
movq (%rax), %rsi
leaq 0x9cc7(%rip), %rdi      # 0xb06a
movq %rsp, %rcx
movq %rbx, %rdx
callq 0x2e51
testl %eax, %eax
je 0x15ca
movq %r15, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq (%rsp), %r12
movq 0x38(%r12), %rax
movq 0x8(%rax), %r14
leaq 0x9c9e(%rip), %r15      # 0xb072
movq %r14, %rdi
movq %r15, %rsi
callq 0x7026
movl %eax, %ebp
movq %r14, %rdi
movq %r15, %rsi
callq 0x7080
testq %rax, %rax
je 0x15f3
movq %rax, %r13
movq %r12, 0x20(%rsp)
movq (%rax), %rdx
leaq 0x9c85(%rip), %rdi      # 0xb08c
movl %ebp, %esi
xorl %eax, %eax
callq 0x10b0
leaq 0x9c62(%rip), %r14      # 0xb079
movq %r13, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x702d
movl %eax, %ebp
movq %r13, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x7087
cmpl $-0x1, %ebp
je 0x147d
leaq 0x9c4a(%rip), %r14      # 0xb089
leaq 0x9c33(%rip), %r15      # 0xb079
movq (%rax), %rdx
movq %r14, %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x10b0
incl %ebp
movq %r13, %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0x702d
movl %eax, %r12d
movq %r13, %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0x7087
movl %r12d, %ebp
cmpl $-0x1, %r12d
jne 0x1446
leaq 0x9c37(%rip), %rdi      # 0xb0bb
callq 0x1060
movq 0x20(%rsp), %r12
movq %r12, %rdi
xorl %esi, %esi
callq 0x70d5
leaq 0x8(%rsp), %rdi
movq %rax, (%rdi)
callq 0x7144
testq %rax, %rax
je 0x14d4
leaq 0x9bf3(%rip), %r14      # 0xb0a4
leaq 0x8(%rsp), %r15
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r14, %rdi
xorl %eax, %eax
callq 0x10b0
movq %r15, %rdi
callq 0x7144
testq %rax, %rax
jne 0x14b6
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x725c
leaq 0x9bed(%rip), %rdi      # 0xb0d5
callq 0x1060
movq %r12, %rdi
movl $0x1, %esi
callq 0x70d5
movq %rax, (%r14)
movq %r14, %rdi
callq 0x7144
testq %rax, %rax
je 0x1534
leaq 0x9b93(%rip), %r14      # 0xb0a4
leaq 0x8(%rsp), %r15
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r14, %rdi
xorl %eax, %eax
callq 0x10b0
movq %r15, %rdi
callq 0x7144
testq %rax, %rax
jne 0x1516
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x725c
leaq 0x9ba8(%rip), %rdi      # 0xb0f0
callq 0x1060
movq %r12, %rdi
movl $0x1, %esi
callq 0x70d5
movq %rax, (%r14)
movq %r14, %rdi
callq 0x7144
testq %rax, %rax
je 0x159b
leaq 0x9b33(%rip), %r14      # 0xb0a4
leaq 0x8(%rsp), %r15
xorl %ebp, %ebp
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r14, %rdi
xorl %eax, %eax
callq 0x10b0
movq %r15, %rdi
callq 0x7144
subl $0x1, %ebp
jae 0x159b
testq %rax, %rax
jne 0x1578
leaq 0x8(%rsp), %rdi
callq 0x725c
xorl %ebp, %ebp
movl $0x3, %edi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x35a0
movq %r12, %rdi
callq 0x6ad7
jmp 0x1619
movq (%rsp), %rdi
callq 0x167f
movq (%rsp), %rdi
callq 0x162c
movl $0x3, %edi
movq %r14, %rsi
movq %r15, %rdx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x35a0
jmp 0x1614
movl $0x3, %edi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x35a0
movq %r12, %rdi
callq 0x6ad7
movl $0x1, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop