// File: /workspace/github_cpp_makefile_star2_O2/ArashPartow[P]exprtk/exprtk_simple_example_24.cpp
// Function: void rpn_example<double>()
void rpn_example()
{
   typedef exprtk::symbol_table<T> symbol_table_t;
   typedef exprtk::expression<T>   expression_t;
   typedef exprtk::parser<T>       parser_t;

   const std::string rpn_program =
      " var stack[1000] := [0];                                                  "
      " var top_index   := 0;                                                    "
      "                                                                          "
      " for (var i := 0; i < rpn_expression[]; i += 1)                           "
      " {                                                                        "
      "    var c := rpn_expression[i : i + 1];                                   "
      "                                                                          "
      "    if (c == ' ')                                                         "
      "    {                                                                     "
      "       continue;                                                          "
      "    }                                                                     "
      "    else if (is_digit(c))                                                 "
      "    {                                                                     "
      "       stack[top_index] := to_num(c);                                     "
      "       top_index        += 1;                                             "
      "    }                                                                     "
      "    else                                                                  "
      "    {                                                                     "
      "       var operator := c;                                                 "
      "       var operand1 := stack[top_index - 2];                              "
      "       var operand2 := stack[top_index - 1];                              "
      "       top_index    -= 2;                                                 "
      "                                                                          "
      "       switch                                                             "
      "       {                                                                  "
      "          case operator == '+' : stack[top_index] := operand1 + operand2; "
      "          case operator == '-' : stack[top_index] := operand1 - operand2; "
      "          case operator == '*' : stack[top_index] := operand1 * operand2; "
      "          case operator == '/' : stack[top_index] := operand1 / operand2; "
      "          case operator == '^' : stack[top_index] := operand1 ^ operand2; "
      "       };                                                                 "
      "                                                                          "
      "       top_index += 1;                                                    "
      "    }                                                                     "
      " };                                                                       "
      "                                                                          "
      " println(stack[0], ' = ', rpn_expression);                                "
      "                                                                          ";

   std::string rpn_expression;

   char_process<T,is_digit_func<T> > isdigit;
   char_process<T,to_num_func<T> >   tonum;
   exprtk::rtl::io::println<T>       println;

   symbol_table_t symbol_table;
   symbol_table.add_stringvar("rpn_expression", rpn_expression);
   symbol_table.add_function ("println"       , println       );
   symbol_table.add_function ("is_digit"      , isdigit       );
   symbol_table.add_function ("to_num"        , tonum         );

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   const std::string rpn_expressions[] =
   {
      "2 3 8 / ^ 4 6 * + 3 9 / -", // 2 ^ (3 / 8) + 4 * 6 - 3 / 9
      "1 2 / 6 5 2 - / * 7 +"    , // (1 / 2) * (6 / (5 - 2)) + 7
      "1 2 * 3 / 4 * 5 / 6 *"    , // ((((1 * 2) / 3) * 4) / 5) * 6
      "8 6 4 + * 2 /"              // (8 * (6 + 4)) / 2
   };

   for (std::size_t i = 0; i < sizeof(rpn_expressions) / sizeof(std::string); ++i)
   {
      rpn_expression = rpn_expressions[i];
      expression.value();
   }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0xbe0, %rsp            # imm = 0xBE0
leaq 0x12ade5(%rip), %rsi    # 0x23b0fb
leaq 0x50(%rsp), %rdi
leaq 0x2b8(%rsp), %rdx
callq 0x1102c8
leaq 0x40(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0xb8(%rsp), %rdi
callq 0x1107d2
leaq 0x70(%rsp), %rdi
callq 0x110834
leaq 0x12b8a1(%rip), %rsi    # 0x23bbf8
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1102c8
leaq 0x250(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x110896
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
movq %rsp, %rdi
pushq $0x1
popq %rsi
callq 0x110928
leaq 0x12b85f(%rip), %rsi    # 0x23bbff
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1102c8
movq %rsp, %rdi
leaq 0x2b8(%rsp), %rsi
leaq 0x30(%rsp), %rdx
xorl %ecx, %ecx
callq 0x11094c
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
leaq 0x12b82e(%rip), %rsi    # 0x23bc0e
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1102c8
movq %rsp, %rdi
leaq 0x2b8(%rsp), %rsi
leaq 0x250(%rsp), %rdx
callq 0x1109be
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
leaq 0x12b7f5(%rip), %rsi    # 0x23bc16
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1102c8
movq %rsp, %rdi
leaq 0x2b8(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0x1109be
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
leaq 0x12b7bd(%rip), %rsi    # 0x23bc1f
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1102c8
movq %rsp, %rdi
leaq 0x2b8(%rsp), %rsi
leaq 0x70(%rsp), %rdx
callq 0x1109be
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
leaq 0x10(%rsp), %rdi
callq 0x110a86
leaq 0x10(%rsp), %rdi
movq %rsp, %rsi
callq 0x110ae6
leaq 0x100(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x110b42
leaq 0x2b8(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x110c52
leaq 0x100(%rsp), %rdi
callq 0x11126a
leaq 0x2b8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x1112b2
leaq 0x12b726(%rip), %rsi    # 0x23bc26
leaq 0x100(%rsp), %r14
leaq 0xf(%rsp), %rdx
movq %r14, %rdi
callq 0x1102c8
leaq 0x120(%rsp), %r15
leaq 0x12b71c(%rip), %rsi    # 0x23bc40
leaq 0xe(%rsp), %rdx
movq %r15, %rdi
callq 0x1102c8
leaq 0x140(%rsp), %r15
leaq 0x12b716(%rip), %rsi    # 0x23bc56
leaq 0xd(%rsp), %rdx
movq %r15, %rdi
callq 0x1102c8
leaq 0x160(%rsp), %r15
leaq 0x12b710(%rip), %rsi    # 0x23bc6c
leaq 0xc(%rsp), %rdx
movq %r15, %rdi
callq 0x1102c8
xorl %r14d, %r14d
leaq 0x30(%rsp), %rbx
cmpq $0x80, %r14
je 0x1105a2
leaq (%rsp,%r14), %rsi
addq $0x100, %rsi            # imm = 0x100
movq %rbx, %rdi
callq 0x10e540
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
addq $0x20, %r14
jmp 0x110571
pushq $0x60
popq %rbx
leaq (%rsp,%rbx), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x10e5c8
addq $-0x20, %rbx
cmpq $-0x20, %rbx
jne 0x1105a5
leaq 0x2b8(%rsp), %rdi
callq 0x111734
leaq 0x10(%rsp), %rdi
callq 0x11186e
movq %rsp, %rdi
callq 0x111884
leaq 0x250(%rsp), %rdi
callq 0x1118c6
leaq 0x70(%rsp), %rdi
callq 0x1118dc
leaq 0xb8(%rsp), %rdi
callq 0x1118dc
leaq 0x30(%rsp), %rdi
callq 0x10e5c8
leaq 0x50(%rsp), %rdi
callq 0x10e5c8
addq $0xbe0, %rsp            # imm = 0xBE0
popq %rbx
popq %r14
popq %r15
retq
jmp 0x110627
jmp 0x110627
movq %rax, %rbx
addq $-0x20, %r15
movq %r15, %rdi
callq 0x10e5c8
cmpq %r14, %r15
jne 0x11062a
jmp 0x1106d2
jmp 0x110642
movq %rax, %rbx
jmp 0x1106d2
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x11126a
jmp 0x1106df
jmp 0x110661
movq %rax, %rbx
jmp 0x1106df
jmp 0x110686
jmp 0x110674
jmp 0x110686
jmp 0x110674
jmp 0x110686
jmp 0x110674
jmp 0x110686
movq %rax, %rbx
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
jmp 0x1106e9
movq %rax, %rbx
jmp 0x1106e9
movq %rax, %rbx
jmp 0x1106f1
movq %rax, %rbx
leaq 0x2b8(%rsp), %rdi
callq 0x10e5c8
jmp 0x1106fe
movq %rax, %rbx
jmp 0x1106fe
movq %rax, %rbx
jmp 0x110708
movq %rax, %rbx
jmp 0x110715
movq %rax, %rbx
pushq $0x60
popq %r14
leaq (%rsp,%r14), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x10e5c8
addq $-0x20, %r14
cmpq $-0x20, %r14
jne 0x1106b8
leaq 0x2b8(%rsp), %rdi
callq 0x111734
leaq 0x10(%rsp), %rdi
callq 0x11186e
movq %rsp, %rdi
callq 0x111884
leaq 0x250(%rsp), %rdi
callq 0x1118c6
leaq 0x70(%rsp), %rdi
callq 0x1118dc
leaq 0xb8(%rsp), %rdi
callq 0x1118dc
leaq 0x30(%rsp), %rdi
callq 0x10e5c8
leaq 0x50(%rsp), %rdi
callq 0x10e5c8
movq %rbx, %rdi
callq 0x10e310