HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
skeleton_block_node.hpp
1// Copyright Take Vos 2020-2022.
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#include "../macros.hpp"
9
10namespace hi::inline v1 {
11
13 std::string name;
14 statement_vector children;
15
16 formula_post_process_context::function_type function;
17 formula_post_process_context::function_type super_function;
18
20 parse_location location,
21 formula_post_process_context &context,
22 formula_node const &name_expression) noexcept :
23 skeleton_node(std::move(location)), name(name_expression.get_name())
24 {
25 name = name_expression.get_name();
26
27 super_function =
28 context.set_function(name, [&](formula_evaluation_context &context, datum::vector_type const &arguments) {
29 return this->evaluate_call(context, arguments);
30 });
31 }
32
35 bool append(std::unique_ptr<skeleton_node> x) noexcept override
36 {
37 append_child(children, std::move(x));
38 return true;
39 }
40
41 void post_process(formula_post_process_context &context) override
42 {
43 if (ssize(children) > 0) {
44 children.back()->left_align();
45 }
46
47 function = context.get_function(name);
48 hi_assert(function);
49
50 context.push_super(super_function);
51 for (hilet &child : children) {
52 child->post_process(context);
53 }
54 context.pop_super();
55 }
56
57 datum evaluate(formula_evaluation_context &context) override
58 {
59 datum tmp;
60 try {
61 tmp = function(context, datum::vector_type{});
62
63 } catch (std::exception const &e) {
64 throw operation_error(std::format("{}: Could not evaluate block.\n{}", location, e.what()));
65 }
66
67 if (tmp.is_break()) {
68 throw operation_error(std::format("{}: Found #break not inside a loop statement.", location));
69
70 } else if (tmp.is_continue()) {
71 throw operation_error(std::format("{}: Found #continue not inside a loop statement.", location));
72
73 } else if (tmp.is_undefined()) {
74 return {};
75
76 } else {
77 throw operation_error(std::format("{}: Can not use a #return statement inside a #block.", location));
78 }
79 }
80
81 datum evaluate_call(formula_evaluation_context &context, datum::vector_type const &arguments)
82 {
83 context.push();
84 auto tmp = evaluate_children(context, children);
85 context.pop();
86
87 if (tmp.is_break()) {
88 throw operation_error(std::format("{}: Found #break not inside a loop statement.", location));
89
90 } else if (tmp.is_continue()) {
91 throw operation_error(std::format("{}: Found #continue not inside a loop statement.", location));
92
93 } else if (tmp.is_undefined()) {
94 return {};
95
96 } else {
97 throw operation_error(std::format("{}: Can not use a #return statement inside a #block.", location));
98 }
99 }
100
101 std::string string() const noexcept override
102 {
103 std::string s = "<block ";
104 s += name;
105 s += join(transform<std::vector<std::string>>(children, [](auto &x) {
106 return to_string(*x);
107 }));
108 s += ">";
109 return s;
110 }
111};
112
113} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm.hpp:16
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition functional.hpp:17
Definition parse_location.hpp:18
Definition skeleton_block_node.hpp:12
bool append(std::unique_ptr< skeleton_node > x) noexcept override
Append a template-piece to the current template.
Definition skeleton_block_node.hpp:35
datum evaluate(formula_evaluation_context &context) override
Evaluate the template.
Definition skeleton_block_node.hpp:57
Definition skeleton_node.hpp:16
T move(T... args)
T to_string(T... args)
T what(T... args)