// File: /workspace/github_cpp_makefile_star2_O2/ArashPartow[P]exprtk/exprtk_simple_example_04.cpp
// Function: void fibonacci<double>()
void fibonacci()
{
   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;

   T x = T(0);

   compositor_t compositor;

   compositor.add(
      function_t("fibonacci")
      .var("x")
      .expression
      (
         " switch                      "
         " {                           "
         "    case x == 0 : 0;         "
         "    case x == 1 : 1;         "
         "    default     :            "
         "    {                        "
         "       var prev := 0;        "
         "       var curr := 1;        "
         "       while ((x -= 1) > 0)  "
         "       {                     "
         "          var temp := prev;  "
         "          prev := curr;      "
         "          curr += temp;      "
         "       };                    "
         "    };                       "
         " }                           "
      ));

   symbol_table_t& symbol_table = compositor.symbol_table();
   symbol_table.add_constants();
   symbol_table.add_variable("x",x);

   std::string expression_str = "fibonacci(x)";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   for (std::size_t i = 0; i < 40; ++i)
   {
      x = static_cast<T>(i);

      const T result = expression.value();

      printf("fibonacci(%3d) = %10.0f\n",
             static_cast<int>(i),
             result);
   }
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x14b8, %rsp           # imm = 0x14B8
andq $0x0, 0x10(%rsp)
leaq 0xad0(%rsp), %rdi
callq 0x11265c
leaq 0x130dfa(%rip), %rsi    # 0x243121
leaq 0x58(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x1122c8
leaq 0x1a8(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x112778
leaq 0x130d2a(%rip), %rsi    # 0x243079
leaq 0x38(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x1122c8
leaq 0x1e8(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x11ca8e
leaq 0x130db4(%rip), %rsi    # 0x24312b
leaq 0x18(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1122c8
leaq 0x1c8(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x110550
leaq 0xad0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
xorl %edx, %edx
callq 0x112768
leaq 0x18(%rsp), %rdi
callq 0x1105c8
leaq 0x38(%rsp), %rdi
callq 0x1105c8
leaq 0x1a8(%rsp), %rdi
callq 0x1127c4
leaq 0x58(%rsp), %rdi
callq 0x1105c8
leaq 0xad0(%rsp), %rdi
callq 0x1127e4
leaq 0x130c8b(%rip), %rsi    # 0x243079
leaq 0x1a8(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x1122c8
leaq 0xad0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
leaq 0x10(%rsp), %rdx
xorl %ecx, %ecx
callq 0x11280a
leaq 0x1a8(%rsp), %rdi
callq 0x1105c8
leaq 0x130ecc(%rip), %rsi    # 0x2432fc
leaq 0x38(%rsp), %rdi
leaq 0x1a8(%rsp), %rdx
callq 0x1122c8
leaq 0x18(%rsp), %rdi
callq 0x112876
leaq 0x18(%rsp), %rdi
leaq 0xad0(%rsp), %rsi
callq 0x1128d6
leaq 0x58(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x112932
leaq 0x1a8(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x112a42
leaq 0x58(%rsp), %rdi
callq 0x11305a
leaq 0x1a8(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x1130a2
xorl %ebx, %ebx
leaq 0x130e62(%rip), %r14    # 0x243309
cmpq $0x28, %rbx
je 0x1124d8
cvtsi2sd %rbx, %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movq %r14, %rdi
movl %ebx, %esi
movb $0x1, %al
callq 0x110060
incq %rbx
jmp 0x1124a7
leaq 0x1a8(%rsp), %rdi
callq 0x113524
leaq 0x18(%rsp), %rdi
callq 0x11365e
leaq 0x38(%rsp), %rdi
callq 0x1105c8
leaq 0xad0(%rsp), %rdi
callq 0x113674
addq $0x14b8, %rsp           # imm = 0x14B8
popq %rbx
popq %r14
retq
jmp 0x112582
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x11305a
jmp 0x112592
jmp 0x112524
movq %rax, %rbx
jmp 0x112592
movq %rax, %rbx
jmp 0x11259c
jmp 0x112552
movq %rax, %rbx
leaq 0x1a8(%rsp), %rdi
jmp 0x1125a1
jmp 0x112552
jmp 0x112552
jmp 0x112543
movq %rax, %rbx
jmp 0x112564
movq %rax, %rbx
jmp 0x11256e
movq %rax, %rbx
jmp 0x11257b
movq %rax, %rbx
jmp 0x1125a6
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x1105c8
leaq 0x38(%rsp), %rdi
callq 0x1105c8
leaq 0x1a8(%rsp), %rdi
callq 0x1127c4
leaq 0x58(%rsp), %rdi
jmp 0x1125a1
movq %rax, %rbx
leaq 0x1a8(%rsp), %rdi
callq 0x113524
leaq 0x18(%rsp), %rdi
callq 0x11365e
leaq 0x38(%rsp), %rdi
callq 0x1105c8
leaq 0xad0(%rsp), %rdi
callq 0x113674
movq %rbx, %rdi
callq 0x110310