HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
skeleton_function_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
9namespace hi::inline v1 {
10
12 std::string name;
13 std::vector<std::string> argument_names;
14 statement_vector children;
15
17
19 parse_location location,
21 std::unique_ptr<formula_node> function_declaration_expression) noexcept :
22 skeleton_node(std::move(location))
23 {
24 auto name_and_arguments = function_declaration_expression->get_name_and_argument_names();
25 hi_assert(name_and_arguments.size() >= 1);
26
27 name = name_and_arguments[0];
28 name_and_arguments.erase(name_and_arguments.begin());
29 argument_names = std::move(name_and_arguments);
30
31 super_function = context.set_function(
32 name, [this, &location](formula_evaluation_context &context, datum::vector_type const &arguments) {
33 try {
34 return this->evaluate_call(context, arguments);
35
36 } catch (std::exception const &e) {
37 throw operation_error(std::format("{}: Failed during handling of function call.\n{}", location, e.what()));
38 }
39 });
40 }
41
44 bool append(std::unique_ptr<skeleton_node> x) noexcept override
45 {
46 append_child(children, std::move(x));
47 return true;
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
56 context.push_super(super_function);
57 for (hilet &child : children) {
58 child->post_process(context);
59 }
60 context.pop_super();
61 }
62
64 {
65 return {};
66 }
67
68 datum evaluate_call(formula_evaluation_context &context, datum::vector_type const &arguments)
69 {
70 context.push();
71 if (ssize(argument_names) != ssize(arguments)) {
72 throw operation_error(std::format(
73 "{}: Invalid number of arguments to function {}() expecting {} got {}.",
74 location,
75 name,
76 argument_names.size(),
77 arguments.size()));
78 }
79
80 for (ssize_t i = 0; i != ssize(argument_names); ++i) {
81 context.set(argument_names[i], arguments[i]);
82 }
83
84 hilet output_size = context.output_size();
85 auto tmp = evaluate_children(context, children);
86 context.pop();
87
88 if (tmp.is_break()) {
89 throw operation_error(std::format("{}: Found #break not inside a loop statement.", location));
90
91 } else if (tmp.is_continue()) {
92 throw operation_error(std::format("{}: Found #continue not inside a loop statement.", location));
93
94 } else if (tmp.is_undefined()) {
95 return {};
96
97 } else {
98 // When a function returns, it should not have written data to the output.
99 context.set_output_size(output_size);
100 return tmp;
101 }
102 }
103
104 std::string string() const noexcept override
105 {
106 std::string s = "<function ";
107 s += name;
108 s += "(";
109 s += join(argument_names, ",");
110 s += ")";
111 s += join(transform<std::vector<std::string>>(children, [](auto &x) {
112 return to_string(*x);
113 }));
114 s += ">";
115 return s;
116 }
117};
118
119} // namespace hi::inline v1
#define hi_assert(expression)
Assert if expression is true.
Definition assert.hpp:86
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
A dynamic data type.
Definition datum.hpp:224
Definition formula_evaluation_context.hpp:16
void set_output_size(ssize_t new_size) noexcept
Set the size of the output.
Definition formula_evaluation_context.hpp:68
ssize_t output_size() const noexcept
Get the size of the output.
Definition formula_evaluation_context.hpp:60
Definition formula_post_process_context.hpp:19
Definition parse_location.hpp:18
Definition skeleton_function_node.hpp:11
datum evaluate(formula_evaluation_context &context) override
Evaluate the template.
Definition skeleton_function_node.hpp:63
bool append(std::unique_ptr< skeleton_node > x) noexcept override
Append a template-piece to the current template.
Definition skeleton_function_node.hpp:44
Definition skeleton_node.hpp:16
T move(T... args)
T size(T... args)
T to_string(T... args)
T what(T... args)