// File: ArashPartow[P]exprtk-extras/exprtk_recursive_fibonacci.cpp
// Function: void recursive_fibonacci_example<double>()
void recursive_fibonacci_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;

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

   symbol_table_t symbol_table;

   symbol_table.add_package(io_package);

   compositor_t compositor(symbol_table);

   compositor.add(
      function_t("fibonacci")
      .var("n")
      .expression
      ( " (n < 2) ? n : fibonacci(n - 1) + fibonacci(n - 2); " ));


   const std::string fibonacci_program =
      " const var n := 35;                  "
      "                                     "
      " for (var i := 0; i <= n; i += 1)    "
      " {                                   "
      "    var fib_i := fibonacci(i);       "
      "    println('fib(',i,') = ', fib_i); "
      " }                                   ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   exprtk::timer timer;
   timer.start();

   expression.value();

   timer.stop();

   printf("Total time: %8.4fsec\n",timer.time());
}

// Assembly:
subq $0x16f8, %rsp           # imm = 0x16F8
leaq 0x1628(%rsp), %rdi
callq 0x11bfe0
leaq 0x1620(%rsp), %rdi
movl $0x1, %esi
callq 0x11c130
jmp 0x11b868
leaq 0x1620(%rsp), %rdi
leaq 0x1628(%rsp), %rsi
callq 0x11c170
jmp 0x11b87f
leaq 0xc28(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c1a0
jmp 0x11b896
leaq 0xb77(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114670
movq 0x30(%rsp), %rdx
leaq 0x347cb1(%rip), %rsi    # 0x463565
leaq 0xb78(%rsp), %rdi
callq 0x11b780
jmp 0x11b8c3
leaq 0xb98(%rsp), %rdi
leaq 0xb78(%rsp), %rsi
callq 0x11c390
jmp 0x11b8da
leaq 0xb4f(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114670
movq 0x28(%rsp), %rdx
leaq 0x347b38(%rip), %rsi    # 0x463430
leaq 0xb50(%rsp), %rdi
callq 0x11b780
jmp 0x11b907
leaq 0xb98(%rsp), %rdi
leaq 0xb50(%rsp), %rsi
callq 0x11c410
movq %rax, 0x20(%rsp)
jmp 0x11b923
leaq 0xb27(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x114670
movq 0x18(%rsp), %rdx
leaq 0x347c2e(%rip), %rsi    # 0x46356f
leaq 0xb28(%rsp), %rdi
callq 0x11b780
jmp 0x11b950
movq 0x20(%rsp), %rdi
leaq 0xb28(%rsp), %rsi
callq 0x11c440
movq %rax, 0x10(%rsp)
jmp 0x11b969
movq 0x10(%rsp), %rsi
leaq 0xc28(%rsp), %rdi
xorl %edx, %edx
callq 0x11c340
jmp 0x11b97f
leaq 0xb28(%rsp), %rdi
callq 0x1147b8
leaq 0xb27(%rsp), %rdi
callq 0x1147a0
leaq 0xb50(%rsp), %rdi
callq 0x1147b8
leaq 0xb4f(%rsp), %rdi
callq 0x1147a0
leaq 0xb98(%rsp), %rdi
callq 0x11c470
leaq 0xb78(%rsp), %rdi
callq 0x1147b8
leaq 0xb77(%rsp), %rdi
callq 0x1147a0
leaq 0xaff(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x114670
movq 0x8(%rsp), %rdx
leaq 0x347bac(%rip), %rsi    # 0x4635a4
leaq 0xb00(%rsp), %rdi
callq 0x11b780
jmp 0x11ba07
leaq 0xaff(%rsp), %rdi
callq 0x1147a0
leaq 0xad8(%rsp), %rdi
callq 0x11c4b0
jmp 0x11ba23
leaq 0xad8(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c560
jmp 0x11ba3a
leaq 0x60(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c610
jmp 0x11ba4b
leaq 0x1b0(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x11c740
jmp 0x11ba5f
leaq 0x60(%rsp), %rdi
callq 0x11cf70
leaq 0x1b0(%rsp), %rdi
leaq 0xb00(%rsp), %rsi
leaq 0xad8(%rsp), %rdx
callq 0x11cfe0
jmp 0x11ba88
leaq 0x38(%rsp), %rdi
callq 0x11d870
jmp 0x11ba94
leaq 0x38(%rsp), %rdi
callq 0x11d8a0
jmp 0x11baa0
leaq 0xad8(%rsp), %rdi
callq 0x11d8c0
jmp 0x11baaf
leaq 0x38(%rsp), %rdi
callq 0x11d8e0
jmp 0x11babb
leaq 0x38(%rsp), %rdi
callq 0x11d910
movsd %xmm0, (%rsp)
jmp 0x11bacc
movsd (%rsp), %xmm0
leaq 0x347bd0(%rip), %rdi    # 0x4636a8
movb $0x1, %al
callq 0x114080
jmp 0x11bae1
leaq 0x1b0(%rsp), %rdi
callq 0x11d960
leaq 0xad8(%rsp), %rdi
callq 0x11db60
leaq 0xb00(%rsp), %rdi
callq 0x1147b8
leaq 0xc28(%rsp), %rdi
callq 0x11dba0
leaq 0x1620(%rsp), %rdi
callq 0x11dc30
leaq 0x1628(%rsp), %rdi
callq 0x11dcb0
addq $0x16f8, %rsp           # imm = 0x16F8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bd18
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bd0b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bc3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bc32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bc18
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bc0b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bbfe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
leaq 0xb28(%rsp), %rdi
callq 0x1147b8
leaq 0xb27(%rsp), %rdi
callq 0x1147a0
leaq 0xb50(%rsp), %rdi
callq 0x1147b8
leaq 0xb4f(%rsp), %rdi
callq 0x1147a0
leaq 0xb98(%rsp), %rdi
callq 0x11c470
leaq 0xb78(%rsp), %rdi
callq 0x1147b8
leaq 0xb77(%rsp), %rdi
callq 0x1147a0
jmp 0x11bcfe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
leaq 0xaff(%rsp), %rdi
callq 0x1147a0
jmp 0x11bcfe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bcf1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
jmp 0x11bce4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x11cf70
jmp 0x11bce4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1618(%rsp)
movl %eax, 0x1614(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x11d960
leaq 0xad8(%rsp), %rdi
callq 0x11db60
leaq 0xb00(%rsp), %rdi
callq 0x1147b8
leaq 0xc28(%rsp), %rdi
callq 0x11dba0
leaq 0x1620(%rsp), %rdi
callq 0x11dc30
leaq 0x1628(%rsp), %rdi
callq 0x11dcb0
movq 0x1618(%rsp), %rdi
callq 0x114460
nopw %cs:(%rax,%rax)
nopl (%rax)