// File: ArashPartow[P]exprtk-extras/exprtk_archimedes_pi.cpp
// Function: void archimedes_pi<double>()
void archimedes_pi()
{
   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::println<T> println("%25.23f");

   symbol_table_t symbol_table;

   symbol_table.add_function("println", println);
   symbol_table.add_constants();

   compositor_t compositor(symbol_table);

   compositor.add(
      function_t("archimedes_pi")
      .var("iterations")
      .expression
      (
         " var s         := 1.0;                    "
         " var approx_pi := 0.0;                    "
         "                                          "
         " for (var i := 0; i < iterations; i += 1) "
         " {                                        "
         "     var n  := 6 * 2^i;                   "
         "     var s2 := (s / 2)^2;                 "
         "     var t  := sqrt(1 - s2);              "
         "     var q  := 1 - t;                     "
         "     var p  := n * s;                     "
         "                                          "
         "     approx_pi := p / 2;                  "
         "     s         := sqrt(q^2 + s2);         "
         " };                                       "
         "                                          "
         " approx_pi;                               "
      ));

   const std::string archimedes_pi_program =
      " const var n := 30;                                              "
      "                                                                 "
      " for (var i := 1; i <= n; i += 1)                                "
      " {                                                               "
      "    var approx_pi := archimedes_pi(i);                           "
      "    var abs_error := abs(approx_pi - pi);                        "
      "                                                                 "
      "    println('approx pi: ', approx_pi, ' abs error:', abs_error); "
      " }                                                               ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0x16c8, %rsp           # imm = 0x16C8
leaq 0x163f(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x114660
movq 0x40(%rsp), %rdx
leaq 0x347d10(%rip), %rsi    # 0x463565
leaq 0x1640(%rsp), %rdi
callq 0x11b770
jmp 0x11b864
leaq 0x1660(%rsp), %rdi
leaq 0x1640(%rsp), %rsi
callq 0x11c0c0
jmp 0x11b87b
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
leaq 0x1620(%rsp), %rdi
movl $0x1, %esi
callq 0x11c1d0
jmp 0x11b8a9
leaq 0x15ff(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114660
movq 0x38(%rsp), %rdx
leaq 0x347ca6(%rip), %rsi    # 0x46356d
leaq 0x1600(%rsp), %rdi
callq 0x11b770
jmp 0x11b8d6
leaq 0x1620(%rsp), %rdi
leaq 0x1600(%rsp), %rsi
leaq 0x1660(%rsp), %rdx
callq 0x11c210
jmp 0x11b8f5
leaq 0x1600(%rsp), %rdi
callq 0x1147a8
leaq 0x15ff(%rsp), %rdi
callq 0x114790
leaq 0x1620(%rsp), %rdi
callq 0x11c410
jmp 0x11b91e
leaq 0xc10(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c470
jmp 0x11b935
leaq 0xb5f(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114660
movq 0x30(%rsp), %rdx
leaq 0x347c22(%rip), %rsi    # 0x463575
leaq 0xb60(%rsp), %rdi
callq 0x11b770
jmp 0x11b962
leaq 0xb80(%rsp), %rdi
leaq 0xb60(%rsp), %rsi
callq 0x11c660
jmp 0x11b979
leaq 0xb37(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114660
movq 0x28(%rsp), %rdx
leaq 0x347bec(%rip), %rsi    # 0x463583
leaq 0xb38(%rsp), %rdi
callq 0x11b770
jmp 0x11b9a6
leaq 0xb80(%rsp), %rdi
leaq 0xb38(%rsp), %rsi
callq 0x11c6e0
movq %rax, 0x20(%rsp)
jmp 0x11b9c2
leaq 0xb0f(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x114660
movq 0x18(%rsp), %rdx
leaq 0x347bae(%rip), %rsi    # 0x46358e
leaq 0xb10(%rsp), %rdi
callq 0x11b770
jmp 0x11b9ef
movq 0x20(%rsp), %rdi
leaq 0xb10(%rsp), %rsi
callq 0x11c710
movq %rax, 0x10(%rsp)
jmp 0x11ba08
movq 0x10(%rsp), %rsi
leaq 0xc10(%rsp), %rdi
xorl %edx, %edx
callq 0x11c610
jmp 0x11ba1e
leaq 0xb10(%rsp), %rdi
callq 0x1147a8
leaq 0xb0f(%rsp), %rdi
callq 0x114790
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xb37(%rsp), %rdi
callq 0x114790
leaq 0xb80(%rsp), %rdi
callq 0x11c740
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
leaq 0xae7(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x114660
movq 0x8(%rsp), %rdx
leaq 0x347d98(%rip), %rsi    # 0x46382f
leaq 0xae8(%rsp), %rdi
callq 0x11b770
jmp 0x11baa6
leaq 0xae7(%rsp), %rdi
callq 0x114790
leaq 0xac0(%rsp), %rdi
callq 0x11c780
jmp 0x11bac2
leaq 0xac0(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c830
jmp 0x11bad9
leaq 0x48(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c8e0
jmp 0x11baea
leaq 0x198(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x11ca10
jmp 0x11bafe
leaq 0x48(%rsp), %rdi
callq 0x11d240
leaq 0x198(%rsp), %rdi
leaq 0xae8(%rsp), %rsi
leaq 0xac0(%rsp), %rdx
callq 0x11d2b0
jmp 0x11bb27
leaq 0xac0(%rsp), %rdi
callq 0x11db40
jmp 0x11bb36
leaq 0x198(%rsp), %rdi
callq 0x11db60
leaq 0xac0(%rsp), %rdi
callq 0x11dd60
leaq 0xae8(%rsp), %rdi
callq 0x1147a8
leaq 0xc10(%rsp), %rdi
callq 0x11dda0
leaq 0x1620(%rsp), %rdi
callq 0x11de30
leaq 0x1660(%rsp), %rdi
callq 0x11deb0
addq $0x16c8, %rsp           # imm = 0x16C8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bbc3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
jmp 0x11be0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bc25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x1600(%rsp), %rdi
callq 0x1147a8
leaq 0x15ff(%rsp), %rdi
callq 0x114790
jmp 0x11bdf2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdf2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bd26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bd19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bcff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bcf2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bce5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0xb10(%rsp), %rdi
callq 0x1147a8
leaq 0xb0f(%rsp), %rdi
callq 0x114790
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xb37(%rsp), %rdi
callq 0x114790
leaq 0xb80(%rsp), %rdi
callq 0x11c740
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
jmp 0x11bde5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0xae7(%rsp), %rdi
callq 0x114790
jmp 0x11bde5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdd8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdcb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x11d240
jmp 0x11bdcb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x198(%rsp), %rdi
callq 0x11db60
leaq 0xac0(%rsp), %rdi
callq 0x11dd60
leaq 0xae8(%rsp), %rdi
callq 0x1147a8
leaq 0xc10(%rsp), %rdi
callq 0x11dda0
leaq 0x1620(%rsp), %rdi
callq 0x11de30
leaq 0x1660(%rsp), %rdi
callq 0x11deb0
movq 0x1630(%rsp), %rdi
callq 0x114450
nopl (%rax)