// File: /workspace/github_cpp_makefile_star2_O2/ArashPartow[P]exprtk-extras/exprtk_tower_of_hanoi.cpp
// Function: void tower_of_hanoi_example<double>()
void tower_of_hanoi_example()
{
   typedef exprtk::symbol_table<T>         symbol_table_t;
   typedef exprtk::expression<T>           expression_t;
   typedef exprtk::parser<T>               parser_t;
   typedef exprtk::function_compositor<T>  compositor_t;
   typedef typename compositor_t::function function_t;

   std::vector<T> disks = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

   exprtk::rtl::io::package<T> io_package;

   symbol_table_t symbol_table;
   symbol_table.add_vector ("disks", disks);
   symbol_table.add_package(io_package);

   compositor_t compositor(symbol_table);

   compositor.load_variables(true);
   compositor.load_vectors  (true);

   compositor.add(
      function_t("move_disk")
      .vars("disk", "src_rod", "dest_rod")
      .expression
      (
         "println('Move disk', disk ,' from rod[', src_rod ,'] to rod[', dest_rod ,']');"
      ));

   compositor.add(
      function_t("tower_of_hanoi")
      .vars("n", "src", "dest", "aux")
      .expression
      (
         " if (n == 1)                            "
         " {                                      "
         "    move_disk(disks[0], src, dest);     "
         "    return [true];                      "
         " };                                     "
         "                                        "
         " tower_of_hanoi(n - 1, src, aux, dest); "
         "                                        "
         " move_disk(disks[n - 1], src, dest);    "
         "                                        "
         " tower_of_hanoi(n - 1, aux, dest, src); "
         "                                        "
      ));

   const std::string tower_of_hanoi_program =
      " tower_of_hanoi(disks[], 1, 2, 3); ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;
   parser.compile(tower_of_hanoi_program,expression);

   expression.value();
}

// Assembly:
pushq %rbx
subq $0x1600, %rsp           # imm = 0x1600
leaq 0x136c2e(%rip), %rsi    # 0x249f50
pushq $0xa
popq %rdx
leaq 0xc18(%rsp), %rax
movq %rdx, %rcx
movq %rax, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x98(%rsp), %rdi
leaq 0x2f0(%rsp), %rcx
movq %rax, %rsi
callq 0x1138f2
leaq 0x220(%rsp), %rdi
callq 0x113928
leaq 0x10(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x1139cc
leaq 0x131dae(%rip), %rsi    # 0x24511d
leaq 0xc18(%rsp), %rdi
leaq 0x2f0(%rsp), %rdx
callq 0x1132d8
leaq 0x10(%rsp), %rdi
leaq 0xc18(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x1139f0
leaq 0xc18(%rsp), %rdi
callq 0x1115d8
leaq 0x220(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x1165de
leaq 0xc18(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113a5a
movw $0x101, 0x15f8(%rsp)    # imm = 0x101
leaq 0x131d43(%rip), %rsi    # 0x245123
leaq 0xd0(%rsp), %rdi
leaq 0xb0(%rsp), %rdx
callq 0x1132d8
leaq 0x2f0(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x113b78
leaq 0x131d17(%rip), %rsi    # 0x245128
leaq 0x38(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1132d8
leaq 0x131d06(%rip), %rsi    # 0x24512d
leaq 0x18(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x1132d8
leaq 0x131cf8(%rip), %rsi    # 0x245135
leaq 0x78(%rsp), %rdi
leaq 0xb(%rsp), %rdx
callq 0x1132d8
leaq 0x2f0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0x18(%rsp), %rdx
leaq 0x78(%rsp), %rcx
callq 0x113bc4
movq %rax, %rbx
leaq 0x131ccc(%rip), %rsi    # 0x24513e
leaq 0x58(%rsp), %rdi
leaq 0xa(%rsp), %rdx
callq 0x1132d8
leaq 0x20(%rbx), %rdi
leaq 0x58(%rsp), %rsi
callq 0x111550
leaq 0xc18(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x113b68
leaq 0x58(%rsp), %rdi
callq 0x1115d8
leaq 0x78(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x1115d8
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0x2f0(%rsp), %rdi
callq 0x113c06
leaq 0xd0(%rsp), %rdi
callq 0x1115d8
leaq 0x131ca3(%rip), %rsi    # 0x24518d
leaq 0xd0(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1132d8
leaq 0x2f0(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x113b78
leaq 0x131ad0(%rip), %rsi    # 0x244fe8
leaq 0x38(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x1132d8
leaq 0x131c6e(%rip), %rsi    # 0x24519c
leaq 0x18(%rsp), %rdi
leaq 0xb(%rsp), %rdx
callq 0x1132d8
leaq 0x131c5c(%rip), %rsi    # 0x2451a0
leaq 0x78(%rsp), %rdi
leaq 0xa(%rsp), %rdx
callq 0x1132d8
leaq 0x1369d7(%rip), %rsi    # 0x249f31
leaq 0x58(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x1132d8
leaq 0x2f0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0x18(%rsp), %rdx
leaq 0x78(%rsp), %rcx
leaq 0x58(%rsp), %r8
callq 0x113c26
movq %rax, %rbx
leaq 0x131c11(%rip), %rsi    # 0x2451a5
leaq 0xb0(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x1132d8
leaq 0x20(%rbx), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x111550
leaq 0xc18(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x113b68
leaq 0xb0(%rsp), %rdi
callq 0x1115d8
leaq 0x58(%rsp), %rdi
callq 0x1115d8
leaq 0x78(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x1115d8
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0x2f0(%rsp), %rdi
callq 0x113c06
leaq 0xd0(%rsp), %rdi
callq 0x1115d8
leaq 0x131d67(%rip), %rsi    # 0x245386
leaq 0x38(%rsp), %rdi
leaq 0x2f0(%rsp), %rdx
callq 0x1132d8
leaq 0x18(%rsp), %rdi
callq 0x113c76
leaq 0x18(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113cd6
leaq 0xd0(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x113d32
leaq 0x2f0(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x113e42
leaq 0xd0(%rsp), %rdi
callq 0x11445a
leaq 0x2f0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x1144a2
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0x2f0(%rsp), %rdi
callq 0x114924
leaq 0x18(%rsp), %rdi
callq 0x114a5e
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0xc18(%rsp), %rdi
callq 0x114a74
leaq 0x10(%rsp), %rdi
callq 0x114ac8
leaq 0x220(%rsp), %rdi
callq 0x114b0a
leaq 0x98(%rsp), %rdi
callq 0x114b7c
addq $0x1600, %rsp           # imm = 0x1600
popq %rbx
retq
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x11445a
jmp 0x1137af
jmp 0x113714
movq %rax, %rbx
jmp 0x1137af
movq %rax, %rbx
jmp 0x1137b9
jmp 0x113766
jmp 0x1137d2
jmp 0x1137d2
jmp 0x11373e
jmp 0x113746
jmp 0x11374e
jmp 0x113756
jmp 0x11375e
jmp 0x113766
jmp 0x11373e
movq %rax, %rbx
jmp 0x1137df
movq %rax, %rbx
jmp 0x1137e9
movq %rax, %rbx
jmp 0x1137f3
movq %rax, %rbx
jmp 0x1137fd
movq %rax, %rbx
jmp 0x11380a
movq %rax, %rbx
jmp 0x113817
jmp 0x113787
jmp 0x113787
movq %rax, %rbx
leaq 0xc18(%rsp), %rdi
callq 0x1115d8
jmp 0x113824
movq %rax, %rbx
jmp 0x113824
movq %rax, %rbx
jmp 0x11382e
movq %rax, %rbx
jmp 0x11383b
movq %rax, %rbx
leaq 0x2f0(%rsp), %rdi
callq 0x114924
leaq 0x18(%rsp), %rdi
callq 0x114a5e
leaq 0x38(%rsp), %rdi
jmp 0x113812
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x1115d8
jmp 0x1137d5
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x1115d8
leaq 0x78(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x1115d8
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0x2f0(%rsp), %rdi
callq 0x113c06
leaq 0xd0(%rsp), %rdi
callq 0x1115d8
leaq 0xc18(%rsp), %rdi
callq 0x114a74
leaq 0x10(%rsp), %rdi
callq 0x114ac8
leaq 0x220(%rsp), %rdi
callq 0x114b0a
leaq 0x98(%rsp), %rdi
callq 0x114b7c
movq %rbx, %rdi
callq 0x111310