HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
skeleton_for_node.hpp
1// Copyright Take Vos 2020-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "skeleton_node.hpp"
8
9namespace hi::inline v1 {
10
12 std::unique_ptr<formula_node> name_expression;
13 std::unique_ptr<formula_node> list_expression;
14 bool has_else = false;
15 statement_vector children;
16 statement_vector else_children;
17
19 parse_location location,
20 std::unique_ptr<formula_node> name_expression,
21 std::unique_ptr<formula_node> list_expression) noexcept :
22 skeleton_node(std::move(location)),
23 name_expression(std::move(name_expression)),
24 list_expression(std::move(list_expression))
25 {
26 }
27
30 bool append(std::unique_ptr<skeleton_node> x) noexcept override
31 {
32 if (has_else) {
33 append_child(else_children, std::move(x));
34 } else {
35 append_child(children, std::move(x));
36 }
37 return true;
38 }
39
40 bool found_else(parse_location _location) noexcept override
41 {
42 if (has_else) {
43 return false;
44 } else {
45 has_else = true;
46 return true;
47 }
48 }
49
50 void post_process(formula_post_process_context &context) override
51 {
52 if (ssize(children) > 0) {
53 children.back()->left_align();
54 }
55 if (ssize(else_children) > 0) {
56 else_children.back()->left_align();
57 }
58
59 post_process_expression(context, *name_expression, location);
60 post_process_expression(context, *list_expression, location);
61
62 for (hilet &child : children) {
63 child->post_process(context);
64 }
65 for (hilet &child : else_children) {
66 child->post_process(context);
67 }
68 }
69
71 {
72 auto list_data = evaluate_formula_without_output(context, *list_expression, location);
73
74 if (!holds_alternative<datum::vector_type>(list_data)) {
75 throw operation_error(std::format("{}: Expecting expression returns a vector, got {}", location, list_data));
76 }
77
78 hilet output_size = context.output_size();
79 if (hilet loop_size = list_data.size()) {
80 ssize_t loop_count = 0;
81 for (hilet &item : list_data) {
82 try {
83 name_expression->assign_without_output(context, item);
84
85 } catch (std::exception const &e) {
86 throw operation_error(std::format("{}: Could not evaluate for-loop expression.\n{}", location, e.what()));
87 }
88
89 context.loop_push(loop_count++, loop_size);
90 auto tmp = evaluate_children(context, children);
91 context.loop_pop();
92
93 if (tmp.is_break()) {
94 break;
95 } else if (tmp.is_continue()) {
96 continue;
97 } else if (!tmp.is_undefined()) {
98 context.set_output_size(output_size);
99 return tmp;
100 }
101 }
102
103 } else {
104 auto tmp = evaluate_children(context, else_children);
105 if (tmp.is_break() || tmp.is_continue()) {
106 return tmp;
107 } else if (!tmp.is_undefined()) {
108 context.set_output_size(output_size);
109 return tmp;
110 }
111 }
112 return {};
113 }
114
115 std::string string() const noexcept override
116 {
117 std::string s = "<for ";
118 s += to_string(*name_expression);
119 s += ": ";
120 s += to_string(*list_expression);
121 s += join(transform<std::vector<std::string>>(children, [](auto &x) {
122 return to_string(*x);
123 }));
124 if (has_else) {
125 s += "else ";
126 s += join(transform<std::vector<std::string>>(else_children, [](auto &x) {
127 return to_string(*x);
128 }));
129 }
130 s += ">";
131 return s;
132 }
133};
134
135} // namespace hi::inline v1
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
A dynamic data type.
Definition datum.hpp:219
Definition formula_evaluation_context.hpp:15
void set_output_size(ssize_t new_size) noexcept
Set the size of the output.
Definition formula_evaluation_context.hpp:67
ssize_t output_size() const noexcept
Get the size of the output.
Definition formula_evaluation_context.hpp:59
Definition parse_location.hpp:18
Definition skeleton_for_node.hpp:11
bool append(std::unique_ptr< skeleton_node > x) noexcept override
Append a template-piece to the current template.
Definition skeleton_for_node.hpp:30
datum evaluate(formula_evaluation_context &context) override
Evaluate the template.
Definition skeleton_for_node.hpp:70
Definition skeleton_node.hpp:16
T move(T... args)
T what(T... args)