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

   const T n = T(15);
   std::vector<T> square(static_cast<std::size_t>(n * n), T(0));

   exprtk::rtl::io::package<T> io_package;

   symbol_table_t symbol_table;
   symbol_table.add_constant("n", n);
   symbol_table.add_vector  ("square", square);
   symbol_table.add_function("print_digit",
                             [](T v) ->T
                             { printf(" %03d ",static_cast<int>(v)); return 0; });
   symbol_table.add_package (io_package);

   compositor_t compositor(symbol_table);

   compositor.load_variables(true);
   compositor.load_vectors  (true);

   compositor.add(
      function_t("get_square")
      .vars("col", "row")
      .expression
      ( " square[row * n + col]; " ));

   compositor.add(
      function_t("set_square")
      .vars("col", "row", "value")
      .expression
      ( " square[row * n + col] := value; " ));

   compositor.add(
      function_t("display_magic_square")
      .expression
      (
         " for (var row := 0; row < n; row += 1)    "
         " {                                        "
         "    for (var col := 0; col < n; col += 1) "
         "    {                                     "
         "       print_digit(get_square(col,row));  "
         "    };                                    "
         "                                          "
         "    println('');                          "
         " }                                        "
      ));

   const std::string magic_square_program =
      " var num := 1;                           "
      " var i   := 0;                           "
      " var j   := floor(n / 2);                "
      "                                         "
      " while (num <= (n * n))                  "
      " {                                       "
      "    set_square(i, j, num);               "
      "    num += 1;                            "
      "                                         "
      "    var i_next := (i - 1 + n) % n;       "
      "    var j_next := (j + 1) % n;           "
      "                                         "
      "    if (get_square(i_next, j_next) != 0) "
      "    {                                    "
      "       i := (i + 1) % n;                 "
      "    }                                    "
      "    else                                 "
      "    {                                    "
      "       i := i_next;                      "
      "       j := j_next;                      "
      "    }                                    "
      " };                                      "
      "                                         "
      " println('sum: ', n * (n^2 + 1) / 2);    "
      "                                         "
      " display_magic_square();                 ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

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

   expression.value();
}

// Assembly:
pushq %rbx
subq $0x15f0, %rsp           # imm = 0x15F0
movabsq $0x402e000000000000, %rax # imm = 0x402E000000000000
movq %rax, 0x80(%rsp)
leaq 0xc08(%rsp), %rdx
andq $0x0, (%rdx)
leaq 0x88(%rsp), %rdi
leaq 0x2e0(%rsp), %rcx
movl $0xe1, %esi
callq 0x1139be
leaq 0x210(%rsp), %rdi
callq 0x113a14
leaq 0x10(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x113ab8
leaq 0x131c74(%rip), %rsi    # 0x244fe8
leaq 0xc08(%rsp), %rdi
leaq 0x2e0(%rsp), %rdx
callq 0x1132d8
leaq 0x10(%rsp), %rdi
leaq 0xc08(%rsp), %rsi
leaq 0x80(%rsp), %rdx
callq 0x113adc
leaq 0xc08(%rsp), %rdi
callq 0x1115d8
leaq 0x131dd9(%rip), %rsi    # 0x245190
leaq 0xc08(%rsp), %rdi
leaq 0x2e0(%rsp), %rdx
callq 0x1132d8
leaq 0x10(%rsp), %rdi
leaq 0xc08(%rsp), %rsi
leaq 0x88(%rsp), %rdx
callq 0x113b58
leaq 0xc08(%rsp), %rdi
callq 0x1115d8
leaq 0x131d23(%rip), %rsi    # 0x24511d
leaq 0xc08(%rsp), %rdi
leaq 0x2e0(%rsp), %rdx
callq 0x1132d8
leaq 0x4202(%rip), %rdx      # 0x117618
leaq 0x10(%rsp), %rdi
leaq 0xc08(%rsp), %rsi
callq 0x113bc2
leaq 0xc08(%rsp), %rdi
callq 0x1115d8
leaq 0x210(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x117640
leaq 0xc08(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113c76
movw $0x101, 0x15e8(%rsp)    # imm = 0x101
leaq 0x131cbf(%rip), %rsi    # 0x245129
leaq 0xc0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1132d8
leaq 0x2e0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x113d94
leaq 0x131c99(%rip), %rsi    # 0x245134
leaq 0x20(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x1132d8
leaq 0x131c87(%rip), %rsi    # 0x245138
leaq 0x40(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x1132d8
leaq 0x2e0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x113de0
movq %rax, %rbx
leaq 0x131c5b(%rip), %rsi    # 0x24513c
leaq 0x60(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1132d8
leaq 0x20(%rbx), %rdi
leaq 0x60(%rsp), %rsi
callq 0x111550
leaq 0xc08(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x113d84
leaq 0x60(%rsp), %rdi
callq 0x1115d8
leaq 0x40(%rsp), %rdi
callq 0x1115d8
leaq 0x20(%rsp), %rdi
callq 0x1115d8
leaq 0x2e0(%rsp), %rdi
callq 0x113e0c
leaq 0xc0(%rsp), %rdi
callq 0x1115d8
leaq 0x131c06(%rip), %rsi    # 0x245155
leaq 0xc0(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x1132d8
leaq 0x2e0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x113d94
leaq 0x131bb7(%rip), %rsi    # 0x245134
leaq 0x20(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x1132d8
leaq 0x131ba5(%rip), %rsi    # 0x245138
leaq 0x40(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0x1132d8
leaq 0x132365(%rip), %rsi    # 0x24590e
leaq 0x60(%rsp), %rdi
leaq 0x1f(%rsp), %rdx
callq 0x1132d8
leaq 0x2e0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x40(%rsp), %rdx
leaq 0x60(%rsp), %rcx
callq 0x113e2c
movq %rax, %rbx
leaq 0x131b82(%rip), %rsi    # 0x245160
leaq 0xa0(%rsp), %rdi
leaq 0x1e(%rsp), %rdx
callq 0x1132d8
leaq 0x20(%rbx), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x111550
leaq 0xc08(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x113d84
leaq 0xa0(%rsp), %rdi
callq 0x1115d8
leaq 0x60(%rsp), %rdi
callq 0x1115d8
leaq 0x40(%rsp), %rdi
callq 0x1115d8
leaq 0x20(%rsp), %rdi
callq 0x1115d8
leaq 0x2e0(%rsp), %rdi
callq 0x113e0c
leaq 0xc0(%rsp), %rdi
callq 0x1115d8
leaq 0x131b23(%rip), %rsi    # 0x245182
leaq 0xc0(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x1132d8
leaq 0x2e0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x113d94
leaq 0x131b0a(%rip), %rsi    # 0x245197
leaq 0x20(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x1132d8
leaq 0x300(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x111550
leaq 0xc08(%rsp), %rdi
leaq 0x2e0(%rsp), %rsi
xorl %edx, %edx
callq 0x113d84
leaq 0x20(%rsp), %rdi
callq 0x1115d8
leaq 0x2e0(%rsp), %rdi
callq 0x113e0c
leaq 0xc0(%rsp), %rdi
callq 0x1115d8
leaq 0x131c22(%rip), %rsi    # 0x245312
leaq 0x20(%rsp), %rdi
leaq 0x2e0(%rsp), %rdx
callq 0x1132d8
leaq 0x40(%rsp), %rdi
callq 0x113e6e
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x113ece
leaq 0xc0(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x113f2a
leaq 0x2e0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x11403a
leaq 0xc0(%rsp), %rdi
callq 0x114652
leaq 0x2e0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x11469a
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0x2e0(%rsp), %rdi
callq 0x114b1c
leaq 0x40(%rsp), %rdi
callq 0x114c56
leaq 0x20(%rsp), %rdi
callq 0x1115d8
leaq 0xc08(%rsp), %rdi
callq 0x114c6c
leaq 0x10(%rsp), %rdi
callq 0x114cc0
leaq 0x210(%rsp), %rdi
callq 0x114d02
leaq 0x88(%rsp), %rdi
callq 0x114d44
addq $0x15f0, %rsp           # imm = 0x15F0
popq %rbx
retq
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x114652
jmp 0x113881
jmp 0x1137e5
movq %rax, %rbx
jmp 0x113881
movq %rax, %rbx
jmp 0x11388b
jmp 0x113830
jmp 0x113820
jmp 0x113828
jmp 0x113830
jmp 0x1138a9
jmp 0x1138a9
jmp 0x113816
jmp 0x113892
jmp 0x113820
jmp 0x113828
jmp 0x113830
jmp 0x113816
movq %rax, %rbx
jmp 0x1138b6
jmp 0x113892
movq %rax, %rbx
jmp 0x1138ca
movq %rax, %rbx
jmp 0x1138d7
movq %rax, %rbx
jmp 0x1138e4
jmp 0x113859
jmp 0x113859
jmp 0x113844
jmp 0x113859
jmp 0x113844
jmp 0x113859
movq %rax, %rbx
leaq 0xc08(%rsp), %rdi
callq 0x1115d8
jmp 0x1138f1
movq %rax, %rbx
jmp 0x1138f1
movq %rax, %rbx
jmp 0x1138fb
movq %rax, %rbx
jmp 0x113908
movq %rax, %rbx
leaq 0x2e0(%rsp), %rdi
callq 0x114b1c
leaq 0x40(%rsp), %rdi
callq 0x114c56
leaq 0x20(%rsp), %rdi
jmp 0x1138df
movq %rax, %rbx
jmp 0x1138c0
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x1115d8
jmp 0x1138ac
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x1115d8
leaq 0x40(%rsp), %rdi
callq 0x1115d8
leaq 0x20(%rsp), %rdi
callq 0x1115d8
leaq 0x2e0(%rsp), %rdi
callq 0x113e0c
leaq 0xc0(%rsp), %rdi
callq 0x1115d8
leaq 0xc08(%rsp), %rdi
callq 0x114c6c
leaq 0x10(%rsp), %rdi
callq 0x114cc0
leaq 0x210(%rsp), %rdi
callq 0x114d02
leaq 0x88(%rsp), %rdi
callq 0x114d44
movq %rbx, %rdi
callq 0x111310