6#include "TTauri/Foundation/datum.hpp"
7#include "TTauri/Foundation/parse_location.hpp"
8#include "TTauri/Foundation/exceptions.hpp"
9#include "TTauri/Foundation/tokenizer.hpp"
14#include <unordered_map>
24 ssize_t output_disable_count = 0;
36 count(), size(), first(), last()
40 this->first = count == 0;
43 this->last = count == (size - 1);
55 void write(std::string_view text)
noexcept {
56 if (output_disable_count == 0) {
72 tt_assert(new_size > 0);
77 void enable_output() noexcept {
78 tt_assert(output_disable_count > 0);
79 output_disable_count--;
82 void disable_output() noexcept {
83 output_disable_count++;
86 void loop_push(ssize_t count = -1, ssize_t size = -1) noexcept {
90 void loop_pop() noexcept {
91 tt_assert(ssize(loop_stack) > 0);
101 tt_assert(local_stack.
size() > 0);
106 [[nodiscard]]
bool has_locals() const noexcept {
107 return local_stack.
size() > 0;
110 tt_force_inline scope
const& locals()
const {
111 tt_assume(has_locals());
112 return local_stack.
back();
115 tt_force_inline scope& locals() {
116 tt_assume(has_locals());
117 return local_stack.
back();
120 [[nodiscard]] datum
const &loop_get(std::string_view name)
const {
121 tt_assume(name.size() > 0);
122 if (name.back() ==
'$') {
123 TTAURI_THROW(invalid_operation_error(
"Invalid loop variable '{}'", name));
126 std::string_view short_name = name.substr(1);
129 while (short_name[0] ==
'$') {
130 if (i == loop_stack.
crend() || i->count.is_undefined()) {
131 TTAURI_THROW(invalid_operation_error(
"Accessing loop variable {} while not in loop", name));
134 short_name = short_name.substr(1);
138 if (short_name ==
"i" || short_name ==
"count") {
140 }
else if (short_name ==
"first") {
142 }
else if (short_name ==
"size" || short_name ==
"length") {
143 if (i->size.is_undefined()) {
144 TTAURI_THROW(invalid_operation_error(
"Accessing loop variable {} only available in #for loops", name));
147 }
else if (short_name ==
"last") {
148 if (i->last.is_undefined()) {
149 TTAURI_THROW(invalid_operation_error(
"Accessing loop variable {} only available in #for loops", name));
153 TTAURI_THROW(invalid_operation_error(
"Unknown loop variable {}", name));
157 [[nodiscard]] datum
const& get(
std::string const &name)
const {
158 tt_assert(name.
size() > 0);
160 if (name[0] ==
'$') {
161 return loop_get(name);
165 ttlet i = locals().
find(name);
166 if (i != locals().
end()) {
171 ttlet j = globals.
find(name);
172 if (j != globals.
end()) {
176 TTAURI_THROW(invalid_operation_error(
"Could not find {} in local or global scope.", name));
179 [[nodiscard]] datum &get(
std::string const &name) {
180 tt_assert(name.
size() > 0);
183 ttlet i = locals().
find(name);
184 if (i != locals().
end()) {
189 ttlet j = globals.
find(name);
190 if (j != globals.
end()) {
194 TTAURI_THROW(invalid_operation_error(
"Could not find {} in local or global scope.", name));
198 void set_local(
std::string const &name, T &&value) {
199 locals()[name] = std::forward<T>(value);
203 void set_global(
std::string const& name, T &&value) {
204 globals[name] = std::forward<T>(value);
207 datum &set(
std::string const &name, datum
const &value) {
209 return locals()[name] = value;
211 return globals[name] = value;
232 if (name ==
"super") {
233 if (super_stack.
size() > 0) {
234 return super_stack.
back();
240 ttlet i = functions.
find(name);
241 if (i != functions.
end()) {
245 ttlet j = global_functions.
find(name);
246 if (j != global_functions.
end()) {
256 swap(functions[name], func);
264 void pop_super(
void)
noexcept {
269 ttlet i = global_filters.
find(name);
270 if (i != global_filters.
end()) {
278 ttlet i = global_methods.
find(name);
279 if (i != global_methods.
end()) {
288 using const_iterator =
typename std::vector<token_t>::const_iterator;
290 std::string_view::const_iterator first;
291 std::string_view::const_iterator last;
294 const_iterator token_it;
297 first(first), last(last), tokens(parseTokens(first, last)), token_it(tokens.
begin()) {}
299 [[nodiscard]]
token_t const& operator*()
const noexcept {
303 [[nodiscard]]
token_t const *operator->()
const noexcept {
308 tt_assume(token_it != tokens.
end());
309 tt_assume(*token_it != tokenizer_name_t::End);
345 context.disable_output();
347 context.enable_output();
357 virtual bool has_evaluate_xvalue()
const {
374 context.disable_output();
375 auto &r =
assign(context, rhs);
376 context.enable_output();
389 TTAURI_THROW(
parse_error(
"Expect a name got {})", *
this).set_location(location));
396 TTAURI_THROW(
parse_error(
"Expect a function definition got {})", *
this).set_location(location));
406 return lhs << to_string(rhs);
419 auto parse_context = expression_parse_context(first, last);
420 auto e = parse_expression(parse_context);
422 auto post_process_context = expression_post_process_context();
423 e->post_process(post_process_context);
431 return parse_expression(text.cbegin(), text.cend());
442std::string_view::const_iterator find_end_of_expression(
443 std::string_view::const_iterator first,
444 std::string_view::const_iterator last,
445 std::string_view terminating_string);
Definition exceptions.hpp:154
Definition expression.hpp:20
void write(std::string_view text) noexcept
Write data to the output.
Definition expression.hpp:55
ssize_t output_size() const noexcept
Get the size of the output.
Definition expression.hpp:64
void set_output_size(ssize_t new_size) noexcept
Set the size of the output.
Definition expression.hpp:71
Definition expression.hpp:29
Definition expression.hpp:216
Definition expression.hpp:287
Definition expression.hpp:321
virtual std::string get_name() const
Get the name of a expression_name_node.
Definition expression.hpp:388
virtual std::vector< std::string > get_name_and_argument_names() const
Get name and argument names from a function declaration.
Definition expression.hpp:395
virtual void post_process(expression_post_process_context &context)
Resolve function and method pointers.
Definition expression.hpp:333
virtual datum evaluate(expression_evaluation_context &context) const =0
Evaluate an rvalue.
virtual datum & assign(expression_evaluation_context &context, datum const &rhs) const
Assign to a non-existing or existing lvalue.
Definition expression.hpp:369
virtual datum & evaluate_lvalue(expression_evaluation_context &context) const
Evaluate an existing lvalue.
Definition expression.hpp:353
virtual void resolve_function_pointer(expression_post_process_context &context)
Resolve function and method pointers.
Definition expression.hpp:338
virtual datum const & evaluate_xvalue(expression_evaluation_context const &context) const
Evaluate an existing xvalue.
Definition expression.hpp:363
virtual datum call(expression_evaluation_context &context, datum::vector const &arguments) const
Call a function with a datum::vector as arguments.
Definition expression.hpp:382
Definition parse_location.hpp:15
Definition tokenizer.hpp:62
T emplace_back(T... args)