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