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

   symbol_table_t symbol_table;

   symbol_table.add_function("print",
                             [](T t) -> T
                             {
                                printf("%1d",static_cast<int>(t));
                                return T(1);
                             });

   const std::string e_10k_digits_spigot =
      " const var num_digits := 10000;                       "
      " var a[num_digits] := [2:1];                          "
      " var b[num_digits] := [1];                            "
      "                                                      "
      " print(2);                                            "
      "                                                      "
      " for (var digit := 0; digit < num_digits; digit += 1) "
      " {                                                    "
      "    b *= 10;                                          "
      "                                                      "
      "    for (var i := (b[] - 1); i > 0; i -= 1)           "
      "    {                                                 "
      "       var q := floor(b[i] / a[i]);                   "
      "       var r := floor(b[i] % a[i]);                   "
      "       b[i - 1] := b[i - 1] + q;                      "
      "       b[i] := r;                                     "
      "    };                                                "
      "                                                      "
      "    print(floor(b[0] / a[0]));                        "
      "                                                      "
      "    b[0] %= a[0];                                     "
      " }                                                    ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0xb18, %rsp            # imm = 0xB18
leaq 0xb10(%rsp), %rdi
movl $0x1, %esi
callq 0x118d30
leaq 0xaef(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x111640
movq 0x10(%rsp), %rdx
leaq 0x330d0e(%rip), %rsi    # 0x449545
leaq 0xaf0(%rsp), %rdi
callq 0x118740
jmp 0x118846
leaq 0xadb(%rsp), %rdi
callq 0x118ea0
movq %rax, %rdx
leaq 0xb10(%rsp), %rdi
leaq 0xaf0(%rsp), %rsi
callq 0x118d70
jmp 0x11886d
leaq 0xaf0(%rsp), %rdi
callq 0x111778
leaq 0xaef(%rsp), %rdi
callq 0x111760
leaq 0xab7(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x111640
movq 0x8(%rsp), %rdx
leaq 0x330ca6(%rip), %rsi    # 0x44954b
leaq 0xab8(%rsp), %rdi
callq 0x118740
jmp 0x1188b4
leaq 0xab7(%rsp), %rdi
callq 0x111760
leaq 0xa90(%rsp), %rdi
callq 0x118eb0
jmp 0x1188d0
leaq 0xa90(%rsp), %rdi
leaq 0xb10(%rsp), %rsi
callq 0x118f60
jmp 0x1188e7
leaq 0x18(%rsp), %rdi
movl $0x7f, %esi
callq 0x119010
jmp 0x1188f8
leaq 0x168(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x119140
jmp 0x11890c
leaq 0x18(%rsp), %rdi
callq 0x119970
leaq 0x168(%rsp), %rdi
leaq 0xab8(%rsp), %rsi
leaq 0xa90(%rsp), %rdx
callq 0x1199e0
jmp 0x118935
leaq 0xa90(%rsp), %rdi
callq 0x11a270
jmp 0x118944
leaq 0x168(%rsp), %rdi
callq 0x11a290
leaq 0xa90(%rsp), %rdi
callq 0x11a490
leaq 0xab8(%rsp), %rdi
callq 0x111778
leaq 0xb10(%rsp), %rdi
callq 0x11a4d0
addq $0xb18, %rsp            # imm = 0xB18
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
jmp 0x1189b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
leaq 0xaf0(%rsp), %rdi
callq 0x111778
leaq 0xaef(%rsp), %rdi
callq 0x111760
jmp 0x118a76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
leaq 0xab7(%rsp), %rdi
callq 0x111760
jmp 0x118a76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
jmp 0x118a69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
jmp 0x118a5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x119970
jmp 0x118a5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xae0(%rsp)
movl %eax, 0xadc(%rsp)
leaq 0x168(%rsp), %rdi
callq 0x11a290
leaq 0xa90(%rsp), %rdi
callq 0x11a490
leaq 0xab8(%rsp), %rdi
callq 0x111778
leaq 0xb10(%rsp), %rdi
callq 0x11a4d0
movq 0xae0(%rsp), %rdi
callq 0x111440