19 ssize_t output_disable_count = 0;
30 loop_info(ssize_t count, ssize_t size) : count(), size(), first(), last()
34 this->first = count == 0;
37 this->last = count == (size - 1);
49 void write(
std::string_view
text) noexcept
51 if (output_disable_count == 0) {
71 output.resize(new_size);
74 void enable_output() noexcept
77 output_disable_count--;
80 void disable_output() noexcept
82 output_disable_count++;
85 void loop_push(ssize_t count = -1, ssize_t size = -1) noexcept
90 void loop_pop() noexcept
109 [[nodiscard]]
bool has_locals() const noexcept
111 return local_stack.
size() > 0;
114 scope
const &locals()
const
117 return local_stack.
back();
123 return local_stack.
back();
126 [[nodiscard]] datum
const &loop_get(std::string_view name)
const
129 if (name.back() ==
'$') {
130 throw operation_error(std::format(
"Invalid loop variable '{}'", name));
133 std::string_view short_name = name.substr(1);
136 while (short_name[0] ==
'$') {
137 if (i == loop_stack.
crend() || holds_alternative<std::monostate>(i->count)) {
138 throw operation_error(std::format(
"Accessing loop variable {} while not in loop", name));
141 short_name = short_name.substr(1);
145 if (short_name ==
"i" || short_name ==
"count") {
147 }
else if (short_name ==
"first") {
149 }
else if (short_name ==
"size" || short_name ==
"length") {
150 if (holds_alternative<std::monostate>(i->size)) {
151 throw operation_error(std::format(
"Accessing loop variable {} only available in #for loops", name));
154 }
else if (short_name ==
"last") {
155 if (holds_alternative<std::monostate>(i->last)) {
156 throw operation_error(std::format(
"Accessing loop variable {} only available in #for loops", name));
160 throw operation_error(std::format(
"Unknown loop variable {}", name));
164 [[nodiscard]] datum
const &get(
std::string const &name)
const
168 if (name[0] ==
'$') {
169 return loop_get(name);
173 hilet i = locals().find(name);
174 if (i != locals().
end()) {
180 if (j != globals.
end()) {
184 throw operation_error(std::format(
"Could not find {} in local or global scope.", name));
192 hilet i = locals().find(name);
193 if (i != locals().
end()) {
199 if (j != globals.
end()) {
203 throw operation_error(std::format(
"Could not find {} in local or global scope.", name));
209 locals()[name] = std::forward<T>(value);
213 void set_global(
std::string const &name, T &&value)
215 globals[name] = std::forward<T>(value);
218 datum &set(
std::string const &name, datum
const &value)
221 return locals()[name] = value;
223 return globals[name] = value;
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:184