// File: 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:
subq $0xdf8, %rsp            # imm = 0xDF8
movabsq $0x3ff199999999999a, %rax # imm = 0x3FF199999999999A
movq %rax, 0xdf0(%rsp)
movabsq $0x400199999999999a, %rax # imm = 0x400199999999999A
movq %rax, 0xde8(%rsp)
movabsq $0x400a666666666666, %rax # imm = 0x400A666666666666
movq %rax, 0xde0(%rsp)
movabsq $0x401199999999999a, %rax # imm = 0x401199999999999A
movq %rax, 0xdd8(%rsp)
leaq 0xdd0(%rsp), %rdi
movl $0x1, %esi
callq 0x119590
leaq 0xdc8(%rsp), %rdi
movl $0x2, %esi
callq 0x119590
jmp 0x118885
leaq 0xd97(%rsp), %rdi
movq %rdi, 0xd0(%rsp)
callq 0x111650
movq 0xd0(%rsp), %rdx
leaq 0x330c34(%rip), %rsi    # 0x4494dd
leaq 0xd98(%rsp), %rdi
callq 0x118750
jmp 0x1188b8
leaq 0xdd0(%rsp), %rdi
leaq 0xd98(%rsp), %rsi
leaq 0xdf0(%rsp), %rdx
xorl %ecx, %ecx
callq 0x1195d0
jmp 0x1188d9
leaq 0xd98(%rsp), %rdi
callq 0x111788
leaq 0xd97(%rsp), %rdi
callq 0x111770
leaq 0xd6f(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
callq 0x111650
movq 0xc8(%rsp), %rdx
leaq 0x330c6e(%rip), %rsi    # 0x449585
leaq 0xd70(%rsp), %rdi
callq 0x118750
jmp 0x118926
leaq 0xdd0(%rsp), %rdi
leaq 0xd70(%rsp), %rsi
leaq 0xde8(%rsp), %rdx
xorl %ecx, %ecx
callq 0x1195d0
jmp 0x118947
leaq 0xd70(%rsp), %rdi
callq 0x111788
leaq 0xd6f(%rsp), %rdi
callq 0x111770
leaq 0xd47(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
callq 0x111650
movq 0xc0(%rsp), %rdx
leaq 0x330c02(%rip), %rsi    # 0x449587
leaq 0xd48(%rsp), %rdi
callq 0x118750
jmp 0x118994
leaq 0xdc8(%rsp), %rdi
leaq 0xd48(%rsp), %rsi
leaq 0xde0(%rsp), %rdx
xorl %ecx, %ecx
callq 0x1195d0
jmp 0x1189b5
leaq 0xd48(%rsp), %rdi
callq 0x111788
leaq 0xd47(%rsp), %rdi
callq 0x111770
leaq 0xd1f(%rsp), %rdi
movq %rdi, 0xb8(%rsp)
callq 0x111650
movq 0xb8(%rsp), %rdx
leaq 0x330bc9(%rip), %rsi    # 0x4495bc
leaq 0xd20(%rsp), %rdi
callq 0x118750
jmp 0x118a02
leaq 0xdc8(%rsp), %rdi
leaq 0xd20(%rsp), %rsi
leaq 0xdd8(%rsp), %rdx
xorl %ecx, %ecx
callq 0x1195d0
jmp 0x118a23
leaq 0xd20(%rsp), %rdi
callq 0x111788
leaq 0xd1f(%rsp), %rdi
callq 0x111770
leaq 0xcf8(%rsp), %rdi
callq 0x119680
jmp 0x118a4c
leaq 0xcf8(%rsp), %rdi
leaq 0xdc8(%rsp), %rsi
callq 0x119730
jmp 0x118a63
leaq 0xcf8(%rsp), %rdi
leaq 0xdd0(%rsp), %rsi
callq 0x119730
jmp 0x118a7a
leaq 0x280(%rsp), %rdi
movl $0x7f, %esi
callq 0x1197e0
jmp 0x118a8e
leaq 0x3d0(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0x119910
jmp 0x118aa5
leaq 0x280(%rsp), %rdi
callq 0x11a140
movb $0x1, 0x1cb(%rsp)
leaq 0x1d8(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq %rax, 0x1d0(%rsp)
leaq 0x1cf(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
callq 0x111650
movq 0xa8(%rsp), %rdi
movq 0xb0(%rsp), %rdx
leaq 0x330a8b(%rip), %rsi    # 0x449589
callq 0x118750
jmp 0x118b05
leaq 0x1f8(%rsp), %rax
movq %rax, 0x98(%rsp)
movq %rax, 0x1d0(%rsp)
leaq 0x1ce(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x111650
movq 0x98(%rsp), %rdi
movq 0xa0(%rsp), %rdx
leaq 0x330a51(%rip), %rsi    # 0x44959a
callq 0x118750
jmp 0x118b50
leaq 0x218(%rsp), %rax
movq %rax, 0x88(%rsp)
movq %rax, 0x1d0(%rsp)
leaq 0x1cd(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x111650
movq 0x88(%rsp), %rdi
movq 0x90(%rsp), %rdx
leaq 0x330a1b(%rip), %rsi    # 0x4495af
callq 0x118750
jmp 0x118b9b
leaq 0x238(%rsp), %rax
movq %rax, 0x78(%rsp)
movq %rax, 0x1d0(%rsp)
leaq 0x1cc(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x111650
movq 0x78(%rsp), %rdi
movq 0x80(%rsp), %rdx
leaq 0x3309e5(%rip), %rsi    # 0x4495be
callq 0x118750
jmp 0x118be0
movb $0x0, 0x1cb(%rsp)
leaq 0x1d8(%rsp), %rax
movq %rax, 0x258(%rsp)
movq $0x4, 0x260(%rsp)
leaq 0x1ca(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x11a1b0
movq 0x70(%rsp), %rcx
movq 0x258(%rsp), %rsi
movq 0x260(%rsp), %rdx
leaq 0x268(%rsp), %rdi
callq 0x11a1c0
jmp 0x118c3a
leaq 0x1ca(%rsp), %rdi
callq 0x11a250
leaq 0x1d8(%rsp), %rax
movq %rax, 0x60(%rsp)
addq $0x80, %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, 0x58(%rsp)
callq 0x111788
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x68(%rsp)
jne 0x118c5f
leaq 0x1cc(%rsp), %rdi
callq 0x111770
leaq 0x1cd(%rsp), %rdi
callq 0x111770
leaq 0x1ce(%rsp), %rdi
callq 0x111770
leaq 0x1cf(%rsp), %rdi
callq 0x111770
leaq 0x268(%rsp), %rax
movq %rax, 0x1c0(%rsp)
movq 0x1c0(%rsp), %rdi
callq 0x11a260
movq %rax, 0x1b8(%rsp)
movq 0x1c0(%rsp), %rdi
callq 0x11a290
movq %rax, 0x1b0(%rsp)
leaq 0x1b8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x11a2c0
testb $0x1, %al
jne 0x118d12
jmp 0x11924f
leaq 0x1b8(%rsp), %rdi
callq 0x11a300
movq %rax, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rsi
leaq 0x3d0(%rsp), %rdi
leaq 0xcf8(%rsp), %rdx
callq 0x11a310
movb %al, 0x57(%rsp)
jmp 0x118d4a
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x1191b4
jmp 0x118d58
movq $0x0, 0x1a0(%rsp)
movq 0x1a0(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x3d0(%rsp), %rdi
callq 0x11aba0
movq %rax, 0x48(%rsp)
jmp 0x118d85
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
cmpq %rcx, %rax
jae 0x1191af
leaq 0xf8(%rsp), %rdi
leaq 0x3d0(%rsp), %rsi
leaq 0x1a0(%rsp), %rdx
callq 0x11abc0
jmp 0x118db7
movl 0x1a0(%rsp), %eax
movl %eax, 0x38(%rsp)
movl 0x120(%rsp), %eax
movl %eax, 0x3c(%rsp)
movl 0x128(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x11aca0
jmp 0x118de3
leaq 0xd8(%rsp), %rdi
callq 0x1110f0
movq %rax, 0x28(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x1110f0
movq %rax, 0x30(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0x1110f0
movl 0x38(%rsp), %esi
movl 0x3c(%rsp), %edx
movq 0x28(%rsp), %rcx
movq 0x30(%rsp), %r8
movq %rax, %r9
leaq 0x3307a1(%rip), %rdi    # 0x4495d1
xorl %eax, %eax
callq 0x111080
jmp 0x118e39
leaq 0xd8(%rsp), %rdi
callq 0x111788
leaq 0xf8(%rsp), %rdi
callq 0x11afe0
movq 0x1a0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x1a0(%rsp)
jmp 0x118d64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1192cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x118ebc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0xd98(%rsp), %rdi
callq 0x111788
leaq 0xd97(%rsp), %rdi
callq 0x111770
jmp 0x1192bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x118f05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0xd70(%rsp), %rdi
callq 0x111788
leaq 0xd6f(%rsp), %rdi
callq 0x111770
jmp 0x1192bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x118f4e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0xd48(%rsp), %rdi
callq 0x111788
leaq 0xd47(%rsp), %rdi
callq 0x111770
jmp 0x1192bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x118f97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0xd20(%rsp), %rdi
callq 0x111788
leaq 0xd1f(%rsp), %rdi
callq 0x111770
jmp 0x1192bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1192bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1192b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0x280(%rsp), %rdi
callq 0x11a140
jmp 0x1192b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1190eb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1190de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1190d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x1190c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0x1ca(%rsp), %rdi
callq 0x11a250
leaq 0x1d8(%rsp), %rax
movq %rax, 0x18(%rsp)
addq $0x80, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, 0x10(%rsp)
callq 0x111788
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x20(%rsp)
jne 0x11909b
jmp 0x1190c4
leaq 0x1cc(%rsp), %rdi
callq 0x111770
leaq 0x1cd(%rsp), %rdi
callq 0x111770
leaq 0x1ce(%rsp), %rdi
callq 0x111770
leaq 0x1cf(%rsp), %rdi
callq 0x111770
testb $0x1, 0x1cb(%rsp)
jne 0x119104
jmp 0x119148
movq 0x1d0(%rsp), %rax
leaq 0x1d8(%rsp), %rcx
cmpq %rax, %rcx
movq %rax, 0x8(%rsp)
je 0x119146
movq 0x8(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, (%rsp)
callq 0x111788
movq (%rsp), %rax
leaq 0x1d8(%rsp), %rcx
cmpq %rcx, %rax
movq %rax, 0x8(%rsp)
jne 0x11911e
jmp 0x119148
jmp 0x1192a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x119298
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
jmp 0x11919d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xdc0(%rsp)
movl %eax, 0xdbc(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x111788
leaq 0xf8(%rsp), %rdi
callq 0x11afe0
jmp 0x119298
jmp 0x11923d
movsd 0xdf0(%rsp), %xmm0
movsd 0x32ae43(%rip), %xmm1   # 0x444008
addsd %xmm1, %xmm0
movsd %xmm0, 0xdf0(%rsp)
movsd 0xde8(%rsp), %xmm0
movsd 0x32ae2d(%rip), %xmm1   # 0x444010
addsd %xmm1, %xmm0
movsd %xmm0, 0xde8(%rsp)
movsd 0xde0(%rsp), %xmm0
movsd 0x32ae17(%rip), %xmm1   # 0x444018
addsd %xmm1, %xmm0
movsd %xmm0, 0xde0(%rsp)
movsd 0xdd8(%rsp), %xmm0
movsd 0x32ae01(%rip), %xmm1   # 0x444020
addsd %xmm1, %xmm0
movsd %xmm0, 0xdd8(%rsp)
leaq 0xcf8(%rsp), %rdi
callq 0x11b030
jmp 0x11923b
jmp 0x11923d
leaq 0x1b8(%rsp), %rdi
callq 0x11b050
jmp 0x118cf4
leaq 0x268(%rsp), %rdi
callq 0x11b070
leaq 0x3d0(%rsp), %rdi
callq 0x11b0d0
leaq 0xcf8(%rsp), %rdi
callq 0x11b2d0
leaq 0xdc8(%rsp), %rdi
callq 0x11b310
leaq 0xdd0(%rsp), %rdi
callq 0x11b310
addq $0xdf8, %rsp            # imm = 0xDF8
retq
leaq 0x268(%rsp), %rdi
callq 0x11b070
leaq 0x3d0(%rsp), %rdi
callq 0x11b0d0
leaq 0xcf8(%rsp), %rdi
callq 0x11b2d0
leaq 0xdc8(%rsp), %rdi
callq 0x11b310
leaq 0xdd0(%rsp), %rdi
callq 0x11b310
movq 0xdc0(%rsp), %rdi
callq 0x111450
nopw %cs:(%rax,%rax)