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

   compositor_t compositor;

   compositor.add(
      function_t("is_prime")
      .var("x")
      .expression
      (
         " switch                                                    "
         " {                                                         "
         "    case x <= 1       : return [false];                    "
         "    case frac(x) != 0 : return [false];                    "
         "    case x == 2       : return [true ];                    "
         "    default           :                                    "
         "    {                                                      "
         "       var prime_lut[81] :=                                "
         "       {                                                   "
         "            2,   3,   5,   7,  11,  13,  17,  19,  23,     "
         "           29,  31,  37,  41,  43,  47,  53,  59,  61,     "
         "           67,  71,  73,  79,  83,  89,  97, 101, 103,     "
         "          107, 109, 113, 127, 131, 137, 139, 149, 151,     "
         "          157, 163, 167, 173, 179, 181, 191, 193, 197,     "
         "          199, 211, 223, 227, 229, 233, 239, 241, 251,     "
         "          257, 263, 269, 271, 277, 281, 283, 293, 307,     "
         "          311, 313, 317, 331, 337, 347, 349, 353, 359,     "
         "          367, 373, 379, 383, 389, 397, 401, 409, 419      "
         "       };                                                  "
         "                                                           "
         "       var upper_bound := min(x - 1, trunc(sqrt(x)) + 1);  "
         "                                                           "
         "       for (var i := 0; i < prime_lut[]; i += 1)           "
         "       {                                                   "
         "          if (prime_lut[i] >= upper_bound)                 "
         "             return [true];                                "
         "          else if ((x % prime_lut[i]) == 0)                "
         "             return [false];                               "
         "       };                                                  "
         "                                                           "
         "       var lower_bound := prime_lut[prime_lut[] - 1] + 2;  "
         "                                                           "
         "       for (var i := lower_bound; i < upper_bound; i += 2) "
         "       {                                                   "
         "          if ((x % i) == 0)                                "
         "          {                                                "
         "             return [false];                               "
         "          }                                                "
         "       }                                                   "
         "    };                                                     "
         " };                                                        "
         "                                                           "
         " return [true];                                            "
      ));

   const std::string primes_via_naive_method_program =
      " for (var i := 1; i < 10000; i += 1) "
      " {                                   "
      "    if (is_prime(i))                 "
      "    {                                "
      "       println(i, ' is prime');      "
      "    }                                "
      " };                                  ";

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

   symbol_table_t& symbol_table = compositor.symbol_table();
   symbol_table.add_function("println",println);

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
pushq %rbx
subq $0x1510, %rsp           # imm = 0x1510
leaq 0xb28(%rsp), %rdi
callq 0x1136aa
leaq 0x130df2(%rip), %rsi    # 0x244121
leaq 0xb0(%rsp), %rdi
leaq 0x28(%rsp), %rdx
callq 0x1132d8
leaq 0x200(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x1137c6
leaq 0x130d1c(%rip), %rsi    # 0x244079
leaq 0x48(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x1132d8
leaq 0x240(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x11df02
leaq 0x130da5(%rip), %rsi    # 0x24412a
leaq 0x8(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x1132d8
leaq 0x220(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x111550
leaq 0xb28(%rsp), %rdi
leaq 0x200(%rsp), %rsi
xorl %edx, %edx
callq 0x1137b6
leaq 0x8(%rsp), %rdi
callq 0x1115d8
leaq 0x48(%rsp), %rdi
callq 0x1115d8
leaq 0x200(%rsp), %rdi
callq 0x113812
leaq 0xb0(%rsp), %rdi
callq 0x1115d8
leaq 0x131722(%rip), %rsi    # 0x244b14
leaq 0x8(%rsp), %rdi
leaq 0x200(%rsp), %rdx
callq 0x1132d8
leaq 0x13180d(%rip), %rsi    # 0x244c18
leaq 0x200(%rsp), %rdi
leaq 0xb0(%rsp), %rdx
callq 0x1132d8
leaq 0x48(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x113832
leaq 0x200(%rsp), %rdi
callq 0x1115d8
leaq 0x1317d9(%rip), %rsi    # 0x244c1f
leaq 0x200(%rsp), %rdi
leaq 0xb0(%rsp), %rdx
callq 0x1132d8
leaq 0xb28(%rsp), %rdi
leaq 0x200(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x1138c4
leaq 0x200(%rsp), %rdi
callq 0x1115d8
leaq 0x28(%rsp), %rdi
callq 0x11398c
leaq 0x28(%rsp), %rdi
leaq 0xb28(%rsp), %rsi
callq 0x1139ec
leaq 0xb0(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x113a48
leaq 0x200(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x113b58
leaq 0xb0(%rsp), %rdi
callq 0x114170
leaq 0x200(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x28(%rsp), %rdx
callq 0x1141b8
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0x200(%rsp), %rdi
callq 0x11463a
leaq 0x28(%rsp), %rdi
callq 0x114774
leaq 0x48(%rsp), %rdi
callq 0x11478a
leaq 0x8(%rsp), %rdi
callq 0x1115d8
leaq 0xb28(%rsp), %rdi
callq 0x1147a0
addq $0x1510, %rsp           # imm = 0x1510
popq %rbx
retq
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x114170
jmp 0x1135a8
jmp 0x11354b
movq %rax, %rbx
jmp 0x1135a8
jmp 0x113564
movq %rax, %rbx
leaq 0x200(%rsp), %rdi
callq 0x1115d8
jmp 0x1135b2
movq %rax, %rbx
jmp 0x1135b2
movq %rax, %rbx
leaq 0x200(%rsp), %rdi
callq 0x1115d8
jmp 0x1135bc
movq %rax, %rbx
jmp 0x1135bc
jmp 0x113593
jmp 0x113584
movq %rax, %rbx
jmp 0x1135d0
movq %rax, %rbx
jmp 0x1135da
movq %rax, %rbx
jmp 0x1135e7
movq %rax, %rbx
jmp 0x1135f4
movq %rax, %rbx
leaq 0x200(%rsp), %rdi
callq 0x11463a
leaq 0x28(%rsp), %rdi
callq 0x114774
leaq 0x48(%rsp), %rdi
callq 0x11478a
leaq 0x8(%rsp), %rdi
jmp 0x1135ef
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x1115d8
leaq 0x48(%rsp), %rdi
callq 0x1115d8
leaq 0x200(%rsp), %rdi
callq 0x113812
leaq 0xb0(%rsp), %rdi
callq 0x1115d8
leaq 0xb28(%rsp), %rdi
callq 0x1147a0
movq %rbx, %rdi
callq 0x111310