// File: ArashPartow[P]exprtk-extras/exprtk_prime_sieve.cpp
// Function: void sieve_of_eratosthenes<double>()
void sieve_of_eratosthenes()
{
   typedef exprtk::expression<T> expression_t;
   typedef exprtk::parser<T>     parser_t;

   const std::string sieve_of_eratosthenes_program =
      " var sieve[10^8] := [false];                   "
      " var m := trunc(sqrt(sieve[]));                "
      "                                               "
      " sieve[0] := true;                             "
      " sieve[1] := true;                             "
      "                                               "
      " for (var i := 0; i <= m; i += 1)              "
      " {                                             "
      "    if (false == sieve[i])                     "
      "    {                                          "
      "       for (var j := i^2; j < sieve[]; j += i) "
      "       {                                       "
      "          sieve[j] := true;                    "
      "       }                                       "
      "    }                                          "
      " };                                            "
      "                                               "
      " var prime_count := sieve[] - sum(sieve);      "
      "                                               "
      " prime_count == 5761455;                       ";

   expression_t expression;

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

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

   const T result = expression.value();

   timer.stop();

   printf("Result: %8.3f\n",result);

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

// Assembly:
subq $0xb18, %rsp            # imm = 0xB18
leaq 0xaf7(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x111650
movq 0x10(%rsp), %rdx
leaq 0x32dd14(%rip), %rsi    # 0x446549
leaq 0xaf8(%rsp), %rdi
callq 0x118750
jmp 0x118844
leaq 0xaf7(%rsp), %rdi
callq 0x111770
leaq 0xac0(%rsp), %rdi
callq 0x118cc0
jmp 0x118860
leaq 0x48(%rsp), %rdi
movl $0x7f, %esi
callq 0x118d70
jmp 0x118871
leaq 0x198(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x118ea0
jmp 0x118885
leaq 0x48(%rsp), %rdi
callq 0x1196d0
leaq 0x198(%rsp), %rdi
leaq 0xaf8(%rsp), %rsi
leaq 0xac0(%rsp), %rdx
callq 0x119740
jmp 0x1188ae
leaq 0x20(%rsp), %rdi
callq 0x119fd0
jmp 0x1188ba
leaq 0x20(%rsp), %rdi
callq 0x11a000
jmp 0x1188c6
leaq 0xac0(%rsp), %rdi
callq 0x11a020
movsd %xmm0, 0x8(%rsp)
jmp 0x1188db
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x11a040
jmp 0x1188f3
movsd 0x18(%rsp), %xmm0
leaq 0x32dff6(%rip), %rdi    # 0x4468f6
movb $0x1, %al
callq 0x111080
jmp 0x118909
leaq 0x20(%rsp), %rdi
callq 0x11a070
movsd %xmm0, (%rsp)
jmp 0x11891a
movsd (%rsp), %xmm0
leaq 0x32dfdf(%rip), %rdi    # 0x446905
movb $0x1, %al
callq 0x111080
jmp 0x11892f
leaq 0x198(%rsp), %rdi
callq 0x11a0c0
leaq 0xac0(%rsp), %rdi
callq 0x11a2c0
leaq 0xaf8(%rsp), %rdi
callq 0x111788
addq $0xb18, %rsp            # imm = 0xB18
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae8(%rsp)
movl %eax, 0xae4(%rsp)
leaq 0xaf7(%rsp), %rdi
callq 0x111770
jmp 0x118a0b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae8(%rsp)
movl %eax, 0xae4(%rsp)
jmp 0x1189fe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae8(%rsp)
movl %eax, 0xae4(%rsp)
jmp 0x1189f1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae8(%rsp)
movl %eax, 0xae4(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x1196d0
jmp 0x1189f1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae8(%rsp)
movl %eax, 0xae4(%rsp)
leaq 0x198(%rsp), %rdi
callq 0x11a0c0
leaq 0xac0(%rsp), %rdi
callq 0x11a2c0
leaq 0xaf8(%rsp), %rdi
callq 0x111788
movq 0xae8(%rsp), %rdi
callq 0x111450
nopl (%rax,%rax)