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