27{
32 typedef typename compositor_t::function function_t;
33
34 const T n = T(15);
35 std::vector<T> square(static_cast<std::size_t>(n * n), T(0));
36
38
39 symbol_table_t symbol_table;
40 symbol_table.add_constant("n", n);
41 symbol_table.add_vector ("square", square);
42 symbol_table.add_function("print_digit",
43 [](T v) ->T
44 { printf(" %03d ",static_cast<int>(v)); return 0; });
45 symbol_table.add_package (io_package);
46
47 compositor_t compositor(symbol_table);
48
49 compositor.load_variables(true);
50 compositor.load_vectors (true);
51
52 compositor.add(
53 function_t("get_square")
54 .vars("col", "row")
55 .expression
56 ( " square[row * n + col]; " ));
57
58 compositor.add(
59 function_t("set_square")
60 .vars("col", "row", "value")
61 .expression
62 ( " square[row * n + col] := value; " ));
63
64 compositor.add(
65 function_t("display_magic_square")
66 .expression
67 (
68 " for (var row := 0; row < n; row += 1) "
69 " { "
70 " for (var col := 0; col < n; col += 1) "
71 " { "
72 " print_digit(get_square(col,row)); "
73 " }; "
74 " "
75 " println(''); "
76 " } "
77 ));
78
79 const std::string magic_square_program =
80 " var num := 1; "
81 " var i := 0; "
82 " var j := floor(n / 2); "
83 " "
84 " while (num <= (n * n)) "
85 " { "
86 " set_square(i, j, num); "
87 " num += 1; "
88 " "
89 " var i_next := (i - 1 + n) % n; "
90 " var j_next := (j + 1) % n; "
91 " "
92 " if (get_square(i_next, j_next) != 0) "
93 " { "
94 " i := (i + 1) % n; "
95 " } "
96 " else "
97 " { "
98 " i := i_next; "
99 " j := j_next; "
100 " } "
101 " }; "
102 " "
103 " println('sum: ', n * (n^2 + 1) / 2); "
104 " "
105 " display_magic_square(); ";
106
107 expression_t expression;
108 expression.register_symbol_table(symbol_table);
109
110 parser_t parser;
111 parser.compile(magic_square_program,expression);
112
113 expression.value();
114}