// File: ArashPartow[P]exprtk-extras/exprtk_gcd.cpp
// Function: void gcd<double>()
void gcd()
{
   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;

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

   compositor_t compositor(symbol_table);

   // define function: gcd(x,y)
   compositor.add(
      function_t("gcd")
      .vars("x","y")
      .expression
      (
         " switch                         "
         " {                              "
         "    case 0 = x : 0;             "
         "    case 0 = y : x;             "
         "    case x = y : x;             "
         "    case x > y : gcd(x - y, y); "
         "    default    : gcd(x, y - x); "
         " }                              "
      ));

   const std::string gcd_program =
      " i := 0;                        "
      " while ((i += 1) < 100)         "
      " {                              "
      "    j := 0;                     "
      "    repeat                      "
      "       println(i, j, gcd(i,j)); "
      "    until ((j += 1) >= 100);    "
      " };                             ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0x1658, %rsp           # imm = 0x1658
leaq 0x1650(%rsp), %rdi
movl $0x1, %esi
callq 0x11c040
leaq 0x162f(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114650
movq 0x38(%rsp), %rdx
leaq 0x347d1e(%rip), %rsi    # 0x463565
leaq 0x1630(%rsp), %rdi
callq 0x11b750
jmp 0x11b856
leaq 0x953(%rip), %rdx       # 0x11c1b0
leaq 0x1650(%rsp), %rdi
leaq 0x1630(%rsp), %rsi
callq 0x11c080
jmp 0x11b874
leaq 0x1630(%rsp), %rdi
callq 0x114788
leaq 0x162f(%rsp), %rdi
callq 0x114770
leaq 0xc30(%rsp), %rdi
leaq 0x1650(%rsp), %rsi
callq 0x11c1f0
jmp 0x11b8a5
leaq 0xb7f(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114650
movq 0x30(%rsp), %rdx
leaq 0x347caa(%rip), %rsi    # 0x46356d
leaq 0xb80(%rsp), %rdi
callq 0x11b750
jmp 0x11b8d2
leaq 0xba0(%rsp), %rdi
leaq 0xb80(%rsp), %rsi
callq 0x11c3e0
jmp 0x11b8e9
leaq 0xb57(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114650
movq 0x28(%rsp), %rdx
leaq 0x347bb6(%rip), %rsi    # 0x4634bd
leaq 0xb58(%rsp), %rdi
callq 0x11b750
jmp 0x11b916
leaq 0xb2f(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x114650
movq 0x20(%rsp), %rdx
leaq 0x347c3d(%rip), %rsi    # 0x463571
leaq 0xb30(%rsp), %rdi
callq 0x11b750
jmp 0x11b943
leaq 0xba0(%rsp), %rdi
leaq 0xb58(%rsp), %rsi
leaq 0xb30(%rsp), %rdx
callq 0x11c460
movq %rax, 0x18(%rsp)
jmp 0x11b967
leaq 0xb07(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x114650
movq 0x10(%rsp), %rdx
leaq 0x347bee(%rip), %rsi    # 0x463573
leaq 0xb08(%rsp), %rdi
callq 0x11b750
jmp 0x11b994
movq 0x18(%rsp), %rdi
leaq 0xb08(%rsp), %rsi
callq 0x11c4b0
movq %rax, 0x8(%rsp)
jmp 0x11b9ad
movq 0x8(%rsp), %rsi
leaq 0xc30(%rsp), %rdi
xorl %edx, %edx
callq 0x11c390
jmp 0x11b9c3
leaq 0xb08(%rsp), %rdi
callq 0x114788
leaq 0xb07(%rsp), %rdi
callq 0x114770
leaq 0xb30(%rsp), %rdi
callq 0x114788
leaq 0xb2f(%rsp), %rdi
callq 0x114770
leaq 0xb58(%rsp), %rdi
callq 0x114788
leaq 0xb57(%rsp), %rdi
callq 0x114770
leaq 0xba0(%rsp), %rdi
callq 0x11c4e0
leaq 0xb80(%rsp), %rdi
callq 0x114788
leaq 0xb7f(%rsp), %rdi
callq 0x114770
leaq 0xadf(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x114650
movq (%rsp), %rdx
leaq 0x347c20(%rip), %rsi    # 0x463674
leaq 0xae0(%rsp), %rdi
callq 0x11b750
jmp 0x11ba63
leaq 0xadf(%rsp), %rdi
callq 0x114770
leaq 0xab8(%rsp), %rdi
callq 0x11c520
jmp 0x11ba7f
leaq 0xab8(%rsp), %rdi
leaq 0x1650(%rsp), %rsi
callq 0x11c5d0
jmp 0x11ba96
leaq 0x40(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c680
jmp 0x11baa7
leaq 0x190(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x11c7b0
jmp 0x11babb
leaq 0x40(%rsp), %rdi
callq 0x11cfe0
xorl %eax, %eax
movl %eax, %esi
leaq 0x190(%rsp), %rdi
callq 0x11d050
jmp 0x11bad8
leaq 0x190(%rsp), %rdi
leaq 0xae0(%rsp), %rsi
leaq 0xab8(%rsp), %rdx
callq 0x11d0a0
jmp 0x11baf7
leaq 0xab8(%rsp), %rdi
callq 0x11d930
jmp 0x11bb06
leaq 0x190(%rsp), %rdi
callq 0x11d950
leaq 0xab8(%rsp), %rdi
callq 0x11db50
leaq 0xae0(%rsp), %rdi
callq 0x114788
leaq 0xc30(%rsp), %rdi
callq 0x11db90
leaq 0x1650(%rsp), %rdi
callq 0x11dc20
addq $0x1658, %rsp           # imm = 0x1658
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bb86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
leaq 0x1630(%rsp), %rdi
callq 0x114788
leaq 0x162f(%rsp), %rdi
callq 0x114770
jmp 0x11bd86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bd86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bcba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bcad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bc93
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bc79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bc6c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bc5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
leaq 0xb08(%rsp), %rdi
callq 0x114788
leaq 0xb07(%rsp), %rdi
callq 0x114770
leaq 0xb30(%rsp), %rdi
callq 0x114788
leaq 0xb2f(%rsp), %rdi
callq 0x114770
leaq 0xb58(%rsp), %rdi
callq 0x114788
leaq 0xb57(%rsp), %rdi
callq 0x114770
leaq 0xba0(%rsp), %rdi
callq 0x11c4e0
leaq 0xb80(%rsp), %rdi
callq 0x114788
leaq 0xb7f(%rsp), %rdi
callq 0x114770
jmp 0x11bd79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
leaq 0xadf(%rsp), %rdi
callq 0x114770
jmp 0x11bd79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bd6c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
jmp 0x11bd5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x11cfe0
jmp 0x11bd5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1620(%rsp)
movl %eax, 0x161c(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x11d950
leaq 0xab8(%rsp), %rdi
callq 0x11db50
leaq 0xae0(%rsp), %rdi
callq 0x114788
leaq 0xc30(%rsp), %rdi
callq 0x11db90
leaq 0x1650(%rsp), %rdi
callq 0x11dc20
movq 0x1620(%rsp), %rdi
callq 0x114440