// File: 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:
subq $0x19a8, %rsp           # imm = 0x19A8
movups 0x34dbb2(%rip), %xmm0   # 0x4693f0
movaps %xmm0, 0x1970(%rsp)
movups 0x34db93(%rip), %xmm0   # 0x4693e0
movaps %xmm0, 0x1960(%rsp)
movups 0x34db74(%rip), %xmm0   # 0x4693d0
movaps %xmm0, 0x1950(%rsp)
movups 0x34db55(%rip), %xmm0   # 0x4693c0
movaps %xmm0, 0x1940(%rsp)
movups 0x34db36(%rip), %xmm0   # 0x4693b0
movaps %xmm0, 0x1930(%rsp)
leaq 0x1930(%rsp), %rax
movq %rax, 0x1980(%rsp)
movq $0xa, 0x1988(%rsp)
leaq 0x192f(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x11c650
movq 0x90(%rsp), %rcx
movq 0x1980(%rsp), %rsi
movq 0x1988(%rsp), %rdx
leaq 0x1990(%rsp), %rdi
callq 0x11c660
jmp 0x11b8da
leaq 0x192f(%rsp), %rdi
callq 0x11c6f0
leaq 0x1848(%rsp), %rdi
callq 0x11c700
jmp 0x11b8f6
leaq 0x1840(%rsp), %rdi
movl $0x1, %esi
callq 0x11c850
jmp 0x11b90a
leaq 0x181f(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x114660
movq 0x88(%rsp), %rdx
leaq 0x348c37(%rip), %rsi    # 0x464565
leaq 0x1820(%rsp), %rdi
callq 0x11b770
jmp 0x11b93d
leaq 0x1840(%rsp), %rdi
leaq 0x1820(%rsp), %rsi
leaq 0x1990(%rsp), %rdx
callq 0x11c890
jmp 0x11b95c
leaq 0x1820(%rsp), %rdi
callq 0x1147a8
leaq 0x181f(%rsp), %rdi
callq 0x114790
leaq 0x1840(%rsp), %rdi
leaq 0x1848(%rsp), %rsi
callq 0x11c950
jmp 0x11b98d
leaq 0xe30(%rsp), %rdi
leaq 0x1840(%rsp), %rsi
callq 0x11c980
jmp 0x11b9a4
leaq 0xe30(%rsp), %rdi
movl $0x1, %esi
callq 0x11cb20
jmp 0x11b9b8
leaq 0xe30(%rsp), %rdi
movl $0x1, %esi
callq 0x11cb50
jmp 0x11b9cc
leaq 0xd7f(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x114660
movq 0x80(%rsp), %rdx
leaq 0x348b7b(%rip), %rsi    # 0x46456b
leaq 0xd80(%rsp), %rdi
callq 0x11b770
jmp 0x11b9ff
leaq 0xda0(%rsp), %rdi
leaq 0xd80(%rsp), %rsi
callq 0x11cbd0
jmp 0x11ba16
leaq 0xd57(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x114660
movq 0x78(%rsp), %rdx
leaq 0x348b3c(%rip), %rsi    # 0x464570
leaq 0xd58(%rsp), %rdi
callq 0x11b770
jmp 0x11ba43
leaq 0xd2f(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x114660
movq 0x70(%rsp), %rdx
leaq 0x348b14(%rip), %rsi    # 0x464575
leaq 0xd30(%rsp), %rdi
callq 0x11b770
jmp 0x11ba70
leaq 0xd07(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x114660
movq 0x68(%rsp), %rdx
leaq 0x348aef(%rip), %rsi    # 0x46457d
leaq 0xd08(%rsp), %rdi
callq 0x11b770
jmp 0x11ba9d
leaq 0xda0(%rsp), %rdi
leaq 0xd58(%rsp), %rsi
leaq 0xd30(%rsp), %rdx
leaq 0xd08(%rsp), %rcx
callq 0x11cc50
movq %rax, 0x60(%rsp)
jmp 0x11bac9
leaq 0xcdf(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x114660
movq 0x58(%rsp), %rdx
leaq 0x348a9f(%rip), %rsi    # 0x464586
leaq 0xce0(%rsp), %rdi
callq 0x11b770
jmp 0x11baf6
movq 0x60(%rsp), %rdi
leaq 0xce0(%rsp), %rsi
callq 0x11ccb0
movq %rax, 0x50(%rsp)
jmp 0x11bb0f
movq 0x50(%rsp), %rsi
leaq 0xe30(%rsp), %rdi
xorl %edx, %edx
callq 0x11cb80
jmp 0x11bb25
leaq 0xce0(%rsp), %rdi
callq 0x1147a8
leaq 0xcdf(%rsp), %rdi
callq 0x114790
leaq 0xd08(%rsp), %rdi
callq 0x1147a8
leaq 0xd07(%rsp), %rdi
callq 0x114790
leaq 0xd30(%rsp), %rdi
callq 0x1147a8
leaq 0xd2f(%rsp), %rdi
callq 0x114790
leaq 0xd58(%rsp), %rdi
callq 0x1147a8
leaq 0xd57(%rsp), %rdi
callq 0x114790
leaq 0xda0(%rsp), %rdi
callq 0x11cce0
leaq 0xd80(%rsp), %rdi
callq 0x1147a8
leaq 0xd7f(%rsp), %rdi
callq 0x114790
leaq 0xc27(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x114660
movq 0x48(%rsp), %rdx
leaq 0x348a03(%rip), %rsi    # 0x4645d5
leaq 0xc28(%rsp), %rdi
callq 0x11b770
jmp 0x11bbe1
leaq 0xc48(%rsp), %rdi
leaq 0xc28(%rsp), %rsi
callq 0x11cbd0
jmp 0x11bbf8
leaq 0xbff(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x114660
movq 0x40(%rsp), %rdx
leaq 0x34881a(%rip), %rsi    # 0x464430
leaq 0xc00(%rsp), %rdi
callq 0x11b770
jmp 0x11bc25
leaq 0xbd7(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114660
movq 0x38(%rsp), %rdx
leaq 0x3489a1(%rip), %rsi    # 0x4645e4
leaq 0xbd8(%rsp), %rdi
callq 0x11b770
jmp 0x11bc52
leaq 0xbaf(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114660
movq 0x30(%rsp), %rdx
leaq 0x348978(%rip), %rsi    # 0x4645e8
leaq 0xbb0(%rsp), %rdi
callq 0x11b770
jmp 0x11bc7f
leaq 0xb87(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114660
movq 0x28(%rsp), %rdx
leaq 0x34d6f1(%rip), %rsi    # 0x46938e
leaq 0xb88(%rsp), %rdi
callq 0x11b770
jmp 0x11bcac
leaq 0xc48(%rsp), %rdi
leaq 0xc00(%rsp), %rsi
leaq 0xbd8(%rsp), %rdx
leaq 0xbb0(%rsp), %rcx
leaq 0xb88(%rsp), %r8
callq 0x11cd20
movq %rax, 0x20(%rsp)
jmp 0x11bce0
leaq 0xb5f(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x114660
movq 0x18(%rsp), %rdx
leaq 0x3488ef(%rip), %rsi    # 0x4645ed
leaq 0xb60(%rsp), %rdi
callq 0x11b770
jmp 0x11bd0d
movq 0x20(%rsp), %rdi
leaq 0xb60(%rsp), %rsi
callq 0x11ccb0
movq %rax, 0x10(%rsp)
jmp 0x11bd26
movq 0x10(%rsp), %rsi
leaq 0xe30(%rsp), %rdi
xorl %edx, %edx
callq 0x11cb80
jmp 0x11bd3c
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
leaq 0xb88(%rsp), %rdi
callq 0x1147a8
leaq 0xb87(%rsp), %rdi
callq 0x114790
leaq 0xbb0(%rsp), %rdi
callq 0x1147a8
leaq 0xbaf(%rsp), %rdi
callq 0x114790
leaq 0xbd8(%rsp), %rdi
callq 0x1147a8
leaq 0xbd7(%rsp), %rdi
callq 0x114790
leaq 0xc00(%rsp), %rdi
callq 0x1147a8
leaq 0xbff(%rsp), %rdi
callq 0x114790
leaq 0xc48(%rsp), %rdi
callq 0x11cce0
leaq 0xc28(%rsp), %rdi
callq 0x1147a8
leaq 0xc27(%rsp), %rdi
callq 0x114790
leaq 0xb37(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x114660
movq 0x8(%rsp), %rdx
leaq 0x3489cb(%rip), %rsi    # 0x4647ce
leaq 0xb38(%rsp), %rdi
callq 0x11b770
jmp 0x11be12
leaq 0xb37(%rsp), %rdi
callq 0x114790
leaq 0xb10(%rsp), %rdi
callq 0x11cda0
jmp 0x11be2e
leaq 0xb10(%rsp), %rdi
leaq 0x1840(%rsp), %rsi
callq 0x11ce50
jmp 0x11be45
leaq 0x98(%rsp), %rdi
movl $0x7f, %esi
callq 0x11cf00
jmp 0x11be59
leaq 0x1e8(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x11d030
jmp 0x11be70
leaq 0x98(%rsp), %rdi
callq 0x11d860
leaq 0x1e8(%rsp), %rdi
leaq 0xb38(%rsp), %rsi
leaq 0xb10(%rsp), %rdx
callq 0x11d8d0
jmp 0x11be9c
leaq 0xb10(%rsp), %rdi
callq 0x11e160
jmp 0x11beab
leaq 0x1e8(%rsp), %rdi
callq 0x11e180
leaq 0xb10(%rsp), %rdi
callq 0x11e380
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xe30(%rsp), %rdi
callq 0x11e3c0
leaq 0x1840(%rsp), %rdi
callq 0x11e450
leaq 0x1848(%rsp), %rdi
callq 0x11e4d0
leaq 0x1990(%rsp), %rdi
callq 0x11e500
addq $0x19a8, %rsp           # imm = 0x19A8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0x192f(%rsp), %rdi
callq 0x11c6f0
jmp 0x11c394
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c387
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c37a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11bf9d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0x1820(%rsp), %rdi
callq 0x1147a8
leaq 0x181f(%rsp), %rdi
callq 0x114790
jmp 0x11c36d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c36d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c11d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c0f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c0dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c0c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c0b5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c0a8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0xce0(%rsp), %rdi
callq 0x1147a8
leaq 0xcdf(%rsp), %rdi
callq 0x114790
leaq 0xd08(%rsp), %rdi
callq 0x1147a8
leaq 0xd07(%rsp), %rdi
callq 0x114790
leaq 0xd30(%rsp), %rdi
callq 0x1147a8
leaq 0xd2f(%rsp), %rdi
callq 0x114790
leaq 0xd58(%rsp), %rdi
callq 0x1147a8
leaq 0xd57(%rsp), %rdi
callq 0x114790
leaq 0xda0(%rsp), %rdi
callq 0x11cce0
leaq 0xd80(%rsp), %rdi
callq 0x1147a8
leaq 0xd7f(%rsp), %rdi
callq 0x114790
jmp 0x11c360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c29e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c291
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c277
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c25d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c243
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c229
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c21c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c20f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
leaq 0xb88(%rsp), %rdi
callq 0x1147a8
leaq 0xb87(%rsp), %rdi
callq 0x114790
leaq 0xbb0(%rsp), %rdi
callq 0x1147a8
leaq 0xbaf(%rsp), %rdi
callq 0x114790
leaq 0xbd8(%rsp), %rdi
callq 0x1147a8
leaq 0xbd7(%rsp), %rdi
callq 0x114790
leaq 0xc00(%rsp), %rdi
callq 0x1147a8
leaq 0xbff(%rsp), %rdi
callq 0x114790
leaq 0xc48(%rsp), %rdi
callq 0x11cce0
leaq 0xc28(%rsp), %rdi
callq 0x1147a8
leaq 0xc27(%rsp), %rdi
callq 0x114790
jmp 0x11c360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0xb37(%rsp), %rdi
callq 0x114790
jmp 0x11c360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c353
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
jmp 0x11c346
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x11d860
jmp 0x11c346
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1920(%rsp)
movl %eax, 0x191c(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x11e180
leaq 0xb10(%rsp), %rdi
callq 0x11e380
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xe30(%rsp), %rdi
callq 0x11e3c0
leaq 0x1840(%rsp), %rdi
callq 0x11e450
leaq 0x1848(%rsp), %rdi
callq 0x11e4d0
leaq 0x1990(%rsp), %rdi
callq 0x11e500
movq 0x1920(%rsp), %rdi
callq 0x114450
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)