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

   T x = 1.1;
   T y = 2.2;
   T z = 3.3;
   T w = 4.4;

   symbol_table_t mutable_symbol_table;
   symbol_table_t immutable_symbol_table(symbol_table_t::symtab_mutability_type::e_immutable);

   mutable_symbol_table.add_variable("x", x);
   mutable_symbol_table.add_variable("y", y);

   immutable_symbol_table.add_variable("z", z);
   immutable_symbol_table.add_variable("w", w);

   expression_t expression;
   expression.register_symbol_table(immutable_symbol_table);
   expression.register_symbol_table(mutable_symbol_table  );

   parser_t parser;

   const std::vector<std::string> expressions =
   {
      "x := y + (z / w)",     // ok - will compile
      "y := y / x + (z / w)", // ok - will compile
      "z := y + x - w",       // Error - will not compile
      "z ==  (w := y / x)",   // Error - will not compile
   };

   for (const auto& expression_str : expressions)
   {

      if (!parser.compile(expression_str, expression))
      {
         for (std::size_t error_idx = 0; error_idx < parser.error_count(); ++error_idx)
         {
            const auto error = parser.get_error(error_idx);

            printf("Error: %02d Pos: %02d Type: [%14s] Message: %s\tExpression: %s\n",
                   static_cast<unsigned int>(error_idx),
                   static_cast<unsigned int>(error.token.position),
                   exprtk::parser_error::to_str(error.mode).c_str(),
                   error.diagnostic.c_str(),
                   expression_str.c_str());
         }

         continue;
      }

      // Modify all the variables from both the immutable
      // and mutable symbol tables

      x += 1.1;
      y += 2.2;
      z += 3.3;
      w += 4.4;

      expression.value();
   }

   return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb18, %rsp            # imm = 0xB18
movabsq $0x3ff199999999999a, %rax # imm = 0x3FF199999999999A
movq %rax, 0x38(%rsp)
movabsq $0x400199999999999a, %rax # imm = 0x400199999999999A
movq %rax, 0x30(%rsp)
movabsq $0x400a666666666666, %rax # imm = 0x400A666666666666
movq %rax, 0x28(%rsp)
movabsq $0x401199999999999a, %rax # imm = 0x401199999999999A
movq %rax, 0x20(%rsp)
leaq 0x10(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x11086e
leaq 0x8(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x11086e
leaq 0x12ad40(%rip), %rsi    # 0x23b0a1
leaq 0x1f0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1102b8
leaq 0x10(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0x38(%rsp), %rdx
xorl %ecx, %ecx
callq 0x110892
leaq 0x1f0(%rsp), %rdi
callq 0x10e5b8
leaq 0x12af0c(%rip), %rsi    # 0x23b2af
leaq 0x1f0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1102b8
leaq 0x10(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0x30(%rsp), %rdx
xorl %ecx, %ecx
callq 0x110892
leaq 0x1f0(%rsp), %rdi
callq 0x10e5b8
leaq 0x12ad64(%rip), %rsi    # 0x23b149
leaq 0x1f0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1102b8
leaq 0x8(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0x28(%rsp), %rdx
xorl %ecx, %ecx
callq 0x110892
leaq 0x1f0(%rsp), %rdi
callq 0x10e5b8
leaq 0x12ad57(%rip), %rsi    # 0x23b17e
leaq 0x1f0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1102b8
leaq 0x8(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0x20(%rsp), %rdx
xorl %ecx, %ecx
callq 0x110892
leaq 0x1f0(%rsp), %rdi
callq 0x10e5b8
leaq 0x48(%rsp), %rdi
callq 0x1108fe
leaq 0x48(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x11095e
leaq 0x48(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x11095e
leaq 0xa0(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x1109ba
leaq 0x1f0(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x110aca
leaq 0xa0(%rsp), %rdi
callq 0x1110e2
leaq 0x12ac88(%rip), %rsi    # 0x23b14b
leaq 0xa0(%rsp), %r14
leaq 0x80(%rsp), %rdx
movq %r14, %rdi
callq 0x1102b8
leaq 0xc0(%rsp), %r15
leaq 0x12ac72(%rip), %rsi    # 0x23b15c
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x1102b8
leaq 0xe0(%rsp), %r15
leaq 0x12ac6b(%rip), %rsi    # 0x23b171
leaq 0x7(%rsp), %rdx
movq %r15, %rdi
callq 0x1102b8
leaq 0x100(%rsp), %r15
leaq 0x12ac5e(%rip), %rsi    # 0x23b180
leaq 0x6(%rsp), %rdx
movq %r15, %rdi
callq 0x1102b8
leaq 0x68(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
pushq $0x4
popq %rdx
leaq 0x5(%rsp), %rcx
callq 0x11112a
pushq $0x60
popq %rbx
leaq (%rsp,%rbx), %rdi
addq $0xa0, %rdi
callq 0x10e5b8
addq $-0x20, %rbx
cmpq $-0x20, %rbx
jne 0x11054c
movq 0x68(%rsp), %rbx
movq 0x70(%rsp), %r15
leaq 0xa0(%rsp), %r13
leaq 0x80(%rsp), %r12
leaq 0x12ac0c(%rip), %r14    # 0x23b193
movq %r15, 0x40(%rsp)
cmpq %r15, %rbx
je 0x1106aa
leaq 0x1f0(%rsp), %rdi
movq %rbx, %rsi
leaq 0x48(%rsp), %rdx
callq 0x111164
testb %al, %al
je 0x110612
movsd 0x38(%rsp), %xmm0
addsd 0x125a4c(%rip), %xmm0   # 0x236008
movsd %xmm0, 0x38(%rsp)
movsd 0x30(%rsp), %xmm0
addsd 0x125a40(%rip), %xmm0   # 0x236010
movsd %xmm0, 0x30(%rsp)
movsd 0x28(%rsp), %xmm0
addsd 0x125a34(%rip), %xmm0   # 0x236018
movsd %xmm0, 0x28(%rsp)
movsd 0x20(%rsp), %xmm0
addsd 0x125a28(%rip), %xmm0   # 0x236020
movsd %xmm0, 0x20(%rsp)
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
jmp 0x1106a1
xorl %r15d, %r15d
movq %r15, 0x18(%rsp)
leaq 0x4f8(%rsp), %rdi
callq 0x172688
cmpq %rax, %r15
jae 0x11069c
movq %r13, %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x1115e6
movq 0x18(%rsp), %rbp
movq 0xc8(%rsp), %r15
movl 0xd0(%rsp), %esi
movq %r12, %rdi
callq 0x11167a
movq 0x80(%rsp), %rcx
movq 0xd8(%rsp), %r8
movq (%rbx), %r9
movq %r14, %rdi
movl %ebp, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x10e060
movq %r12, %rdi
callq 0x10e5b8
movq %r13, %rdi
callq 0x111726
movq 0x18(%rsp), %r15
incq %r15
jmp 0x110615
movq 0x40(%rsp), %r15
addq $0x20, %rbx
jmp 0x11058c
leaq 0x68(%rsp), %rdi
callq 0x111752
leaq 0x1f0(%rsp), %rdi
callq 0x111774
leaq 0x48(%rsp), %rdi
callq 0x1118ae
leaq 0x8(%rsp), %rdi
callq 0x1118c4
leaq 0x10(%rsp), %rdi
callq 0x1118c4
addq $0xb18, %rsp            # imm = 0xB18
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
pushq $0x60
popq %r14
leaq (%rsp,%r14), %rdi
addq $0xa0, %rdi
callq 0x10e5b8
addq $-0x20, %r14
cmpq $-0x20, %r14
jne 0x1106f8
jmp 0x11079a
jmp 0x11071b
jmp 0x11071b
movq %rax, %rbx
addq $-0x20, %r15
movq %r15, %rdi
callq 0x10e5b8
cmpq %r14, %r15
jne 0x11071e
jmp 0x11079a
movq %rax, %rbx
jmp 0x11079a
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x1110e2
jmp 0x1107a7
jmp 0x110774
jmp 0x11076a
jmp 0x110758
jmp 0x11076a
jmp 0x110758
jmp 0x11076a
jmp 0x110758
jmp 0x11076a
movq %rax, %rbx
leaq 0x1f0(%rsp), %rdi
callq 0x10e5b8
jmp 0x1107b1
movq %rax, %rbx
jmp 0x1107b1
movq %rax, %rbx
jmp 0x1107bb
movq %rax, %rbx
jmp 0x1107a7
jmp 0x11078d
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x111726
jmp 0x110790
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x111752
leaq 0x1f0(%rsp), %rdi
callq 0x111774
leaq 0x48(%rsp), %rdi
callq 0x1118ae
leaq 0x8(%rsp), %rdi
callq 0x1118c4
leaq 0x10(%rsp), %rdi
callq 0x1118c4
movq %rbx, %rdi
callq 0x10e310