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

   const std::string nthroot_via_bisection_program =
      " for (var x := -30; x <= 30; x += 1)   "
      " {                                     "
      "    println('[', x, ']',               "
      "            ' sqrt = ', nthroot(x,2),  "
      "            ' cbrt = ', nthroot(x,3)); "
      " }                                     ";

   exprtk::rtl::io::println<T> println;

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

   compositor_t compositor(symbol_table);

   // define function: nthroot(x,n)
   compositor.add(
      function_t("nthroot")
      .var("x")
      .var("n")
      .expression
      (
        " if (abs(frac(n)) > 0)            "
        "    return [null];                "
        " else if (x < 0 and (n % 2 == 0)) "
        "    return [null];                "
        "                                  "
        " var lo := min(0,x);              "
        " var hi := max(0,x);              "
        "                                  "
        " while (true)                     "
        " {                                "
        "    var mid := avg(lo,hi);        "
        "    var y   := pow(mid,n);        "
        "                                  "
        "    if (equal(y, x))              "
        "       break [mid];               "
        "    else if (y < x)               "
        "       lo := mid;                 "
        "    else                          "
        "       hi := mid;                 "
        " };                               "
       ));

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
pushq %rbx
subq $0x1560, %rsp           # imm = 0x1560
leaq 0x130df6(%rip), %rsi    # 0x244118
leaq 0x78(%rsp), %rdi
leaq 0x250(%rsp), %rdx
callq 0x1132d8
leaq 0x130ec8(%rip), %rsi    # 0x244203
leaq 0x250(%rsp), %rdi
leaq 0xc38(%rsp), %rdx
callq 0x1132d8
leaq 0x98(%rsp), %rdi
leaq 0x250(%rsp), %rsi
callq 0x113740
leaq 0x250(%rsp), %rdi
callq 0x1115d8
leaq 0x10(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x1137d2
leaq 0x130e84(%rip), %rsi    # 0x24420a
leaq 0x250(%rsp), %rdi
leaq 0xc38(%rsp), %rdx
callq 0x1132d8
leaq 0x10(%rsp), %rdi
leaq 0x250(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x1137f6
leaq 0x250(%rsp), %rdi
callq 0x1115d8
leaq 0x250(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x1138be
leaq 0x130e37(%rip), %rsi    # 0x244212
leaq 0x100(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x1132d8
leaq 0xc38(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x1139dc
leaq 0x130c6c(%rip), %rsi    # 0x244075
leaq 0x18(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x1132d8
leaq 0xc78(%rsp), %rbx
leaq 0x18(%rsp), %rsi
movq %rbx, %rdi
callq 0x11e68c
leaq 0x130bb4(%rip), %rsi    # 0x243fe8
leaq 0x58(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1132d8
leaq 0x58(%rsp), %rsi
movq %rbx, %rdi
callq 0x11e68c
leaq 0x130dc3(%rip), %rsi    # 0x24421a
leaq 0x38(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x1132d8
leaq 0xc58(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x111550
leaq 0x250(%rsp), %rdi
leaq 0xc38(%rsp), %rsi
xorl %edx, %edx
callq 0x1139cc
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0x58(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x1115d8
leaq 0xc38(%rsp), %rdi
callq 0x113a28
leaq 0x100(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x113a48
leaq 0x18(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113aa8
leaq 0x100(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x113b04
leaq 0xc38(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x113c14
leaq 0x100(%rsp), %rdi
callq 0x11422c
leaq 0xc38(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x114274
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0xc38(%rsp), %rdi
callq 0x1146f6
leaq 0x18(%rsp), %rdi
callq 0x114830
leaq 0x250(%rsp), %rdi
callq 0x114846
leaq 0x10(%rsp), %rdi
callq 0x11489a
leaq 0x98(%rsp), %rdi
callq 0x1148dc
leaq 0x78(%rsp), %rdi
callq 0x1115d8
addq $0x1560, %rsp           # imm = 0x1560
popq %rbx
retq
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x11422c
jmp 0x113621
jmp 0x11359d
movq %rax, %rbx
jmp 0x113621
jmp 0x1135c8
jmp 0x1135a6
movq %rax, %rbx
jmp 0x11363a
jmp 0x1135b0
movq %rax, %rbx
jmp 0x113644
movq %rax, %rbx
jmp 0x11364e
movq %rax, %rbx
jmp 0x11365b
movq %rax, %rbx
jmp 0x113668
jmp 0x1135e7
movq %rax, %rbx
leaq 0x250(%rsp), %rdi
callq 0x1115d8
jmp 0x113675
movq %rax, %rbx
jmp 0x113675
movq %rax, %rbx
jmp 0x11367f
movq %rax, %rbx
leaq 0x250(%rsp), %rdi
callq 0x1115d8
jmp 0x11368c
movq %rax, %rbx
jmp 0x11368c
movq %rax, %rbx
leaq 0xc38(%rsp), %rdi
callq 0x1146f6
leaq 0x18(%rsp), %rdi
callq 0x114830
jmp 0x113668
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x1115d8
leaq 0x58(%rsp), %rdi
callq 0x1115d8
leaq 0x18(%rsp), %rdi
callq 0x1115d8
leaq 0xc38(%rsp), %rdi
callq 0x113a28
leaq 0x100(%rsp), %rdi
callq 0x1115d8
leaq 0x250(%rsp), %rdi
callq 0x114846
leaq 0x10(%rsp), %rdi
callq 0x11489a
leaq 0x98(%rsp), %rdi
callq 0x1148dc
leaq 0x78(%rsp), %rdi
callq 0x1115d8
movq %rbx, %rdi
callq 0x111310