// File: ArashPartow[P]exprtk-extras/exprtk_pascals_triangle.cpp
// Function: void pascals_triangle<double>()
void pascals_triangle()
{
   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::package<T> io_package;

   symbol_table_t symbol_table;
   symbol_table.add_package(io_package);
   symbol_table.add_function("print_coeff",
                             [](T t)
                             {
                                printf("%6d", static_cast<unsigned int>(t));
                                return T(0);
                             });

   compositor_t compositor(symbol_table);

   compositor.add(
      function_t("n_choose_k")
      .vars("n","k")
      .expression
      (
        " switch                                      "
        " {                                           "
        "    case n <= k : 1;                         "
        "    case k <= 0 : 1;                         "
        "    default     : n_choose_k(n - 1, k - 1) + "
        "                  n_choose_k(n - 1, k    ) ; "
        " }                                           "
      ));

   const std::string pascals_triangle_program =
      " const var rows := 20;                            "
      "                                                  "
      " for (var n := 0; n < rows; n += 1)               "
      " {                                                "
      "    for (var s := 0; s <= (rows - n) - 2; s += 1) "
      "    {                                             "
      "       print('   ');                              "
      "    };                                            "
      "                                                  "
      "    for (var k := 0; k <= n; k += 1)              "
      "    {                                             "
      "       print_coeff(n_choose_k(n,k));              "
      "    };                                            "
      "                                                  "
      "    println();                                    "
      " }                                                ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0x1728, %rsp           # imm = 0x1728
leaq 0x1658(%rsp), %rdi
callq 0x11c0b0
leaq 0x1650(%rsp), %rdi
movl $0x1, %esi
callq 0x11c200
jmp 0x11b858
leaq 0x1650(%rsp), %rdi
leaq 0x1658(%rsp), %rsi
callq 0x11c240
jmp 0x11b86f
leaq 0x161f(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114660
movq 0x38(%rsp), %rdx
leaq 0x348cd8(%rip), %rsi    # 0x464565
leaq 0x1620(%rsp), %rdi
callq 0x11b770
jmp 0x11b89c
leaq 0x161e(%rsp), %rdi
callq 0x11c3a0
movq %rax, %rdx
leaq 0x1650(%rsp), %rdi
leaq 0x1620(%rsp), %rsi
callq 0x11c270
jmp 0x11b8c3
leaq 0x1620(%rsp), %rdi
callq 0x1147a8
leaq 0x161f(%rsp), %rdi
callq 0x114790
leaq 0xc30(%rsp), %rdi
leaq 0x1650(%rsp), %rsi
callq 0x11c3b0
jmp 0x11b8f4
leaq 0xb7f(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x114660
movq 0x30(%rsp), %rdx
leaq 0x348c5f(%rip), %rsi    # 0x464571
leaq 0xb80(%rsp), %rdi
callq 0x11b770
jmp 0x11b921
leaq 0xba0(%rsp), %rdi
leaq 0xb80(%rsp), %rsi
callq 0x11c5a0
jmp 0x11b938
leaq 0xb57(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114660
movq 0x28(%rsp), %rdx
leaq 0x348ada(%rip), %rsi    # 0x464430
leaq 0xb58(%rsp), %rdi
callq 0x11b770
jmp 0x11b965
leaq 0xb2f(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x114660
movq 0x20(%rsp), %rdx
leaq 0x348bf7(%rip), %rsi    # 0x46457a
leaq 0xb30(%rsp), %rdi
callq 0x11b770
jmp 0x11b992
leaq 0xba0(%rsp), %rdi
leaq 0xb58(%rsp), %rsi
leaq 0xb30(%rsp), %rdx
callq 0x11c620
movq %rax, 0x18(%rsp)
jmp 0x11b9b6
leaq 0xb07(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x114660
movq 0x10(%rsp), %rdx
leaq 0x348ba8(%rip), %rsi    # 0x46457c
leaq 0xb08(%rsp), %rdi
callq 0x11b770
jmp 0x11b9e3
movq 0x18(%rsp), %rdi
leaq 0xb08(%rsp), %rsi
callq 0x11c670
movq %rax, 0x8(%rsp)
jmp 0x11b9fc
movq 0x8(%rsp), %rsi
leaq 0xc30(%rsp), %rdi
xorl %edx, %edx
callq 0x11c550
jmp 0x11ba12
leaq 0xb08(%rsp), %rdi
callq 0x1147a8
leaq 0xb07(%rsp), %rdi
callq 0x114790
leaq 0xb30(%rsp), %rdi
callq 0x1147a8
leaq 0xb2f(%rsp), %rdi
callq 0x114790
leaq 0xb58(%rsp), %rdi
callq 0x1147a8
leaq 0xb57(%rsp), %rdi
callq 0x114790
leaq 0xba0(%rsp), %rdi
callq 0x11c6a0
leaq 0xb80(%rsp), %rdi
callq 0x1147a8
leaq 0xb7f(%rsp), %rdi
callq 0x114790
leaq 0xadf(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x114660
movq (%rsp), %rdx
leaq 0x348c15(%rip), %rsi    # 0x4646b8
leaq 0xae0(%rsp), %rdi
callq 0x11b770
jmp 0x11bab2
leaq 0xadf(%rsp), %rdi
callq 0x114790
leaq 0xab8(%rsp), %rdi
callq 0x11c6e0
jmp 0x11bace
leaq 0xab8(%rsp), %rdi
leaq 0x1650(%rsp), %rsi
callq 0x11c790
jmp 0x11bae5
leaq 0x40(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c840
jmp 0x11baf6
leaq 0x190(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x11c970
jmp 0x11bb0a
leaq 0x40(%rsp), %rdi
callq 0x11d1a0
leaq 0x190(%rsp), %rdi
leaq 0xae0(%rsp), %rsi
leaq 0xab8(%rsp), %rdx
callq 0x11d210
jmp 0x11bb33
leaq 0xab8(%rsp), %rdi
callq 0x11daa0
jmp 0x11bb42
leaq 0x190(%rsp), %rdi
callq 0x11dac0
leaq 0xab8(%rsp), %rdi
callq 0x11dcc0
leaq 0xae0(%rsp), %rdi
callq 0x1147a8
leaq 0xc30(%rsp), %rdi
callq 0x11dd00
leaq 0x1650(%rsp), %rdi
callq 0x11dd90
leaq 0x1658(%rsp), %rdi
callq 0x11de10
addq $0x1728, %rsp           # imm = 0x1728
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bdf5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bde8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bc01
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
leaq 0x1620(%rsp), %rdi
callq 0x1147a8
leaq 0x161f(%rsp), %rdi
callq 0x114790
jmp 0x11bde8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bd1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bd0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bcf5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bcdb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bcce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bcc1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
leaq 0xb08(%rsp), %rdi
callq 0x1147a8
leaq 0xb07(%rsp), %rdi
callq 0x114790
leaq 0xb30(%rsp), %rdi
callq 0x1147a8
leaq 0xb2f(%rsp), %rdi
callq 0x114790
leaq 0xb58(%rsp), %rdi
callq 0x1147a8
leaq 0xb57(%rsp), %rdi
callq 0x114790
leaq 0xba0(%rsp), %rdi
callq 0x11c6a0
leaq 0xb80(%rsp), %rdi
callq 0x1147a8
leaq 0xb7f(%rsp), %rdi
callq 0x114790
jmp 0x11bddb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
leaq 0xadf(%rsp), %rdi
callq 0x114790
jmp 0x11bddb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bdce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
jmp 0x11bdc1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x11d1a0
jmp 0x11bdc1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1648(%rsp)
movl %eax, 0x1644(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x11dac0
leaq 0xab8(%rsp), %rdi
callq 0x11dcc0
leaq 0xae0(%rsp), %rdi
callq 0x1147a8
leaq 0xc30(%rsp), %rdi
callq 0x11dd00
leaq 0x1650(%rsp), %rdi
callq 0x11dd90
leaq 0x1658(%rsp), %rdi
callq 0x11de10
movq 0x1648(%rsp), %rdi
callq 0x114450
nop