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

   const std::string pythagorean_triples_program =
      " const var num_triples := 1000;                "
      " var triple_count      := 0;                   "
      " var n                 := 2;                   "
      "                                               "
      " while (true)                                  "
      " {                                             "
      "    for (var i := 1; i < n; i += 1)            "
      "    {                                          "
      "       var a := n^2 - i^2;                     "
      "       var b := 2 * n * i;                     "
      "       var c := n^2 + i^2;                     "
      "                                               "
      "       if (a > b) a <=> b;                     "
      "       if (b > c) b <=> c;                     "
      "       if (a > b) a <=> b;                     "
      "                                               "
      "       println('(', a ,',', b ,',', c ,')');   "
      "                                               "
      "       if ((triple_count += 1) >= num_triples) "
      "       {                                       "
      "          return [];                           "
      "       };                                      "
      "    };                                         "
      "                                               "
      "    n += 1;                                    "
      " }                                             ";

   exprtk::rtl::io::println<T> println;

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

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
subq $0xba8, %rsp            # imm = 0xBA8
leaq 0xb87(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x111650
movq 0x10(%rsp), %rdx
leaq 0x330d00(%rip), %rsi    # 0x449545
leaq 0xb88(%rsp), %rdi
callq 0x118760
jmp 0x118854
leaq 0xb87(%rsp), %rdi
callq 0x111780
leaq 0xae7(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x111650
movq 0x8(%rsp), %rdx
leaq 0x33118d(%rip), %rsi    # 0x449a0c
leaq 0xae8(%rsp), %rdi
callq 0x118760
jmp 0x11888e
leaq 0xb08(%rsp), %rdi
leaq 0xae8(%rsp), %rsi
callq 0x118e20
jmp 0x1188a5
leaq 0xae8(%rsp), %rdi
callq 0x111798
leaq 0xae7(%rsp), %rdi
callq 0x111780
leaq 0xad8(%rsp), %rdi
movl $0x1, %esi
callq 0x118f30
jmp 0x1188d3
leaq 0xab7(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x111650
movq (%rsp), %rdx
leaq 0x331124(%rip), %rsi    # 0x449a13
leaq 0xab8(%rsp), %rdi
callq 0x118760
jmp 0x1188fe
leaq 0xad8(%rsp), %rdi
leaq 0xab8(%rsp), %rsi
leaq 0xb08(%rsp), %rdx
callq 0x118f70
jmp 0x11891d
leaq 0xab8(%rsp), %rdi
callq 0x111798
leaq 0xab7(%rsp), %rdi
callq 0x111780
leaq 0xa90(%rsp), %rdi
callq 0x119170
jmp 0x118946
leaq 0xa90(%rsp), %rdi
leaq 0xad8(%rsp), %rsi
callq 0x119220
jmp 0x11895d
leaq 0x18(%rsp), %rdi
movl $0x7f, %esi
callq 0x1192d0
jmp 0x11896e
leaq 0x168(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x119400
jmp 0x118982
leaq 0x18(%rsp), %rdi
callq 0x119c30
leaq 0x168(%rsp), %rdi
leaq 0xb88(%rsp), %rsi
leaq 0xa90(%rsp), %rdx
callq 0x119ca0
jmp 0x1189ab
leaq 0xa90(%rsp), %rdi
callq 0x11a530
jmp 0x1189ba
leaq 0x168(%rsp), %rdi
callq 0x11a550
leaq 0xa90(%rsp), %rdi
callq 0x11a750
leaq 0xad8(%rsp), %rdi
callq 0x11a790
leaq 0xb08(%rsp), %rdi
callq 0x11a810
leaq 0xb88(%rsp), %rdi
callq 0x111798
addq $0xba8, %rsp            # imm = 0xBA8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
leaq 0xb87(%rsp), %rdi
callq 0x111780
jmp 0x118b72
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
jmp 0x118a60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
leaq 0xae8(%rsp), %rdi
callq 0x111798
leaq 0xae7(%rsp), %rdi
callq 0x111780
jmp 0x118b65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
jmp 0x118b58
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
jmp 0x118ac2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
leaq 0xab8(%rsp), %rdi
callq 0x111798
leaq 0xab7(%rsp), %rdi
callq 0x111780
jmp 0x118b4b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
jmp 0x118b4b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
jmp 0x118b3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x119c30
jmp 0x118b3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb78(%rsp)
movl %eax, 0xb74(%rsp)
leaq 0x168(%rsp), %rdi
callq 0x11a550
leaq 0xa90(%rsp), %rdi
callq 0x11a750
leaq 0xad8(%rsp), %rdi
callq 0x11a790
leaq 0xb08(%rsp), %rdi
callq 0x11a810
leaq 0xb88(%rsp), %rdi
callq 0x111798
movq 0xb78(%rsp), %rdi
callq 0x111450
nop