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

   const std::string mandelbrot_program =
      " width    := 118;                                  "
      " height   := 41;                                   "
      " imag_max := +1;                                   "
      " imag_min := -1;                                   "
      " real_max := +1;                                   "
      " real_min := -2.5;                                 "
      " x_step   := (real_max - real_min) / width;        "
      " y_step   := (imag_max - imag_min) / height;       "
      "                                                   "
      " for (var y := 0; y < height; y += 1)              "
      " {                                                 "
      "    imag := imag_min + (y_step * y);               "
      "                                                   "
      "    for (var x := 0; x < width; x += 1)            "
      "    {                                              "
      "       real   := real_min + x_step * x;            "
      "       z_real := real;                             "
      "       z_imag := imag;                             "
      "                                                   "
      "       for (var n := 0; n < 30; n += 1)            "
      "       {                                           "
      "          a := z_real^2;                           "
      "          b := z_imag^2;                           "
      "          plot_value := n;                         "
      "                                                   "
      "          if ((a + b) < 4)                         "
      "          {                                        "
      "             z_imag := 2 * z_real * z_imag + imag; "
      "             z_real := a - b + real;               "
      "          }                                        "
      "          else                                     "
      "             break;                                "
      "       };                                          "
      "                                                   "
      "       putch(61 - plot_value);                     "
      "    };                                             "
      "                                                   "
      "    println()                                      "
      " }                                                 ";

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

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

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;
   parser.enable_unknown_symbol_resolver();
   parser.compile(mandelbrot_program,expression);

   expression.value();
}

// Assembly:
subq $0xbd8, %rsp            # imm = 0xBD8
leaq 0xbb7(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x111650
movq 0x18(%rsp), %rdx
leaq 0x332d00(%rip), %rsi    # 0x44b545
leaq 0xbb8(%rsp), %rdi
callq 0x118760
jmp 0x118854
leaq 0xbb7(%rsp), %rdi
callq 0x111780
leaq 0xb17(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x111650
movq 0x10(%rsp), %rdx
leaq 0x33348c(%rip), %rsi    # 0x44bd0b
leaq 0xb18(%rsp), %rdi
callq 0x118760
jmp 0x11888e
leaq 0xb38(%rsp), %rdi
leaq 0xb18(%rsp), %rsi
callq 0x118ee0
jmp 0x1188a5
leaq 0xb18(%rsp), %rdi
callq 0x111798
leaq 0xb17(%rsp), %rdi
callq 0x111780
leaq 0xb08(%rsp), %rdi
movl $0x1, %esi
callq 0x118ff0
jmp 0x1188d3
leaq 0xae7(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x111650
movq 0x8(%rsp), %rdx
leaq 0x333421(%rip), %rsi    # 0x44bd12
leaq 0xae8(%rsp), %rdi
callq 0x118760
jmp 0x118900
leaq 0x859(%rip), %rdx       # 0x119160
leaq 0xb08(%rsp), %rdi
leaq 0xae8(%rsp), %rsi
callq 0x119030
jmp 0x11891e
leaq 0xae8(%rsp), %rdi
callq 0x111798
leaq 0xae7(%rsp), %rdi
callq 0x111780
leaq 0xabf(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x111650
movq (%rsp), %rdx
leaq 0x3333c4(%rip), %rsi    # 0x44bd18
leaq 0xac0(%rsp), %rdi
callq 0x118760
jmp 0x118963
leaq 0xb08(%rsp), %rdi
leaq 0xac0(%rsp), %rsi
leaq 0xb38(%rsp), %rdx
callq 0x119180
jmp 0x118982
leaq 0xac0(%rsp), %rdi
callq 0x111798
leaq 0xabf(%rsp), %rdi
callq 0x111780
leaq 0xa98(%rsp), %rdi
callq 0x119380
jmp 0x1189ab
leaq 0xa98(%rsp), %rdi
leaq 0xb08(%rsp), %rsi
callq 0x119430
jmp 0x1189c2
leaq 0x20(%rsp), %rdi
movl $0x7f, %esi
callq 0x1194e0
jmp 0x1189d3
leaq 0x170(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x119610
jmp 0x1189e7
leaq 0x20(%rsp), %rdi
callq 0x119e40
xorl %eax, %eax
movl %eax, %esi
leaq 0x170(%rsp), %rdi
callq 0x119eb0
jmp 0x118a04
leaq 0x170(%rsp), %rdi
leaq 0xbb8(%rsp), %rsi
leaq 0xa98(%rsp), %rdx
callq 0x119f00
jmp 0x118a23
leaq 0xa98(%rsp), %rdi
callq 0x11a790
jmp 0x118a32
leaq 0x170(%rsp), %rdi
callq 0x11a7b0
leaq 0xa98(%rsp), %rdi
callq 0x11a9b0
leaq 0xb08(%rsp), %rdi
callq 0x11a9f0
leaq 0xb38(%rsp), %rdi
callq 0x11aa70
leaq 0xbb8(%rsp), %rdi
callq 0x111798
addq $0xbd8, %rsp            # imm = 0xBD8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0xbb7(%rsp), %rdi
callq 0x111780
jmp 0x118c33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118ad8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0xb18(%rsp), %rdi
callq 0x111798
leaq 0xb17(%rsp), %rdi
callq 0x111780
jmp 0x118c26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118c19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118b3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0xae8(%rsp), %rdi
callq 0x111798
leaq 0xae7(%rsp), %rdi
callq 0x111780
jmp 0x118c0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118b83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0xac0(%rsp), %rdi
callq 0x111798
leaq 0xabf(%rsp), %rdi
callq 0x111780
jmp 0x118c0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118c0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
jmp 0x118bff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x119e40
jmp 0x118bff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xba8(%rsp)
movl %eax, 0xba4(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x11a7b0
leaq 0xa98(%rsp), %rdi
callq 0x11a9b0
leaq 0xb08(%rsp), %rdi
callq 0x11a9f0
leaq 0xb38(%rsp), %rdi
callq 0x11aa70
leaq 0xbb8(%rsp), %rdi
callq 0x111798
movq 0xba8(%rsp), %rdi
callq 0x111450