// File: ArashPartow[P]exprtk-extras/exprtk_collatz.cpp
// Function: void collatz<double>()
void collatz()
{
   typedef exprtk::symbol_table<T>         symbol_table_t;
   typedef exprtk::expression<T>           expression_t;
   typedef exprtk::parser<T>               parser_t;
   typedef exprtk::function_compositor<T>  compositor_t;
   typedef typename compositor_t::function function_t;

   exprtk::rtl::io::print<T> print("%3.0f ");

   symbol_table_t symbol_table;
   symbol_table.add_function("print",print);

   compositor_t compositor(symbol_table);

   // define function: collatz_trace(x)
   compositor.add(
      function_t("collatz_trace")
      .var("x")
      .expression
      (
         " while (x > 1)                           "
         " {                                       "
         "    x := (x % 2 == 0) ? x / 2 : 3x + 1;  "
         "    print(x);                            "
         " }                                       "
      ));

   const std::string collatz_program =
      " x := 0;              "
      " repeat               "
      "    print(x += 1);    "
      "    collatz_trace(x); "
      "    print('\n\n');    "
      " until (x > 100);     "
      " println;             ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0x16c8, %rsp           # imm = 0x16C8
leaq 0x163f(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x114660
movq 0x40(%rsp), %rdx
leaq 0x347d10(%rip), %rsi    # 0x463565
leaq 0x1640(%rsp), %rdi
callq 0x11b770
jmp 0x11b864
leaq 0x1660(%rsp), %rdi
leaq 0x1640(%rsp), %rsi
callq 0x11c0c0
jmp 0x11b87b
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
leaq 0x1620(%rsp), %rdi
movl $0x1, %esi
callq 0x11c1d0
jmp 0x11b8a9
leaq 0x15ff(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114660
movq 0x38(%rsp), %rdx
leaq 0x347ca5(%rip), %rsi    # 0x46356c
leaq 0x1600(%rsp), %rdi
callq 0x11b770
jmp 0x11b8d6
leaq 0x1620(%rsp), %rdi
leaq 0x1600(%rsp), %rsi
leaq 0x1660(%rsp), %rdx
callq 0x11c210
jmp 0x11b8f5
leaq 0x1600(%rsp), %rdi
callq 0x1147a8
leaq 0x15ff(%rsp), %rdi
callq 0x114790
leaq 0xc10(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c410
jmp 0x11b926
leaq 0xb5f(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114660
movq 0x30(%rsp), %rdx
leaq 0x347c2e(%rip), %rsi    # 0x463572
leaq 0xb60(%rsp), %rdi
callq 0x11b770
jmp 0x11b953
leaq 0xb80(%rsp), %rdi
leaq 0xb60(%rsp), %rsi
callq 0x11c600
jmp 0x11b96a
leaq 0xb37(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114660
movq 0x28(%rsp), %rdx
leaq 0x347b35(%rip), %rsi    # 0x4634bd
leaq 0xb38(%rsp), %rdi
callq 0x11b770
jmp 0x11b997
leaq 0xb80(%rsp), %rdi
leaq 0xb38(%rsp), %rsi
callq 0x11c680
movq %rax, 0x20(%rsp)
jmp 0x11b9b3
leaq 0xb0f(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x114660
movq 0x18(%rsp), %rdx
leaq 0x347baf(%rip), %rsi    # 0x463580
leaq 0xb10(%rsp), %rdi
callq 0x11b770
jmp 0x11b9e0
movq 0x20(%rsp), %rdi
leaq 0xb10(%rsp), %rsi
callq 0x11c6b0
movq %rax, 0x10(%rsp)
jmp 0x11b9f9
movq 0x10(%rsp), %rsi
leaq 0xc10(%rsp), %rdi
xorl %edx, %edx
callq 0x11c5b0
jmp 0x11ba0f
leaq 0xb10(%rsp), %rdi
callq 0x1147a8
leaq 0xb0f(%rsp), %rdi
callq 0x114790
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xb37(%rsp), %rdi
callq 0x114790
leaq 0xb80(%rsp), %rdi
callq 0x11c6e0
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
leaq 0xae7(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x114660
movq 0x8(%rsp), %rdx
leaq 0x347bc6(%rip), %rsi    # 0x46364e
leaq 0xae8(%rsp), %rdi
callq 0x11b770
jmp 0x11ba97
leaq 0xae7(%rsp), %rdi
callq 0x114790
leaq 0xac0(%rsp), %rdi
callq 0x11c720
jmp 0x11bab3
leaq 0xac0(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c7d0
jmp 0x11baca
leaq 0x48(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c880
jmp 0x11badb
leaq 0x198(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x11c9b0
jmp 0x11baef
leaq 0x48(%rsp), %rdi
callq 0x11d1e0
xorl %eax, %eax
movl %eax, %esi
leaq 0x198(%rsp), %rdi
callq 0x11d250
jmp 0x11bb0c
leaq 0x198(%rsp), %rdi
leaq 0xae8(%rsp), %rsi
leaq 0xac0(%rsp), %rdx
callq 0x11d2a0
jmp 0x11bb2b
leaq 0xac0(%rsp), %rdi
callq 0x11db30
jmp 0x11bb3a
leaq 0x198(%rsp), %rdi
callq 0x11db50
leaq 0xac0(%rsp), %rdi
callq 0x11dd50
leaq 0xae8(%rsp), %rdi
callq 0x1147a8
leaq 0xc10(%rsp), %rdi
callq 0x11dd90
leaq 0x1620(%rsp), %rdi
callq 0x11de20
leaq 0x1660(%rsp), %rdi
callq 0x11dea0
addq $0x16c8, %rsp           # imm = 0x16C8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bbc7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
jmp 0x11be10
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11be03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bc29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x1600(%rsp), %rdi
callq 0x1147a8
leaq 0x15ff(%rsp), %rdi
callq 0x114790
jmp 0x11bdf6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdf6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bd2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bd1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bd03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bcf6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bce9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0xb10(%rsp), %rdi
callq 0x1147a8
leaq 0xb0f(%rsp), %rdi
callq 0x114790
leaq 0xb38(%rsp), %rdi
callq 0x1147a8
leaq 0xb37(%rsp), %rdi
callq 0x114790
leaq 0xb80(%rsp), %rdi
callq 0x11c6e0
leaq 0xb60(%rsp), %rdi
callq 0x1147a8
leaq 0xb5f(%rsp), %rdi
callq 0x114790
jmp 0x11bde9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0xae7(%rsp), %rdi
callq 0x114790
jmp 0x11bde9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bddc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
jmp 0x11bdcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x11d1e0
jmp 0x11bdcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1630(%rsp)
movl %eax, 0x162c(%rsp)
leaq 0x198(%rsp), %rdi
callq 0x11db50
leaq 0xac0(%rsp), %rdi
callq 0x11dd50
leaq 0xae8(%rsp), %rdi
callq 0x1147a8
leaq 0xc10(%rsp), %rdi
callq 0x11dd90
leaq 0x1620(%rsp), %rdi
callq 0x11de20
leaq 0x1660(%rsp), %rdi
callq 0x11dea0
movq 0x1630(%rsp), %rdi
callq 0x114450
nopl (%rax)