Browse Source

Added more array functions (turing complete == get)

crazy_things
Ludovic 'Archivist' Lagouardette 9 months ago
parent
commit
eaf13e092c
2 changed files with 94 additions and 3 deletions
  1. +7
    -3
      script_exe/main.cpp
  2. +87
    -0
      src/std/array.cpp

+ 7
- 3
script_exe/main.cpp View File

@ -9,18 +9,22 @@
#include <cstring>
#include "UserScript.h"
void print_value(std::ostream& stream, const scripting::script_value& res) {
void print_value(std::ostream& stream, const scripting::script_value& res, bool array_print = false) {
if(std::holds_alternative<scripting::array>(res)) {
stream << "[";
auto max = std::get<scripting::array>(res).value.size();
auto no_comma = max - 1;
for(size_t idx = 0; idx < max; ++idx) {
print_value(stream, std::get<scripting::array>(res).value[idx]);
print_value(stream, std::get<scripting::array>(res).value[idx], true);
stream << (idx != no_comma ? ", " : "");
}
stream << "]";
} else if(std::holds_alternative<std::string>(res)) {
stream << std::get<std::string>(res);
if(array_print) {
stream << std::quoted(std::get<std::string>(res));
} else {
stream << std::get<std::string>(res);
}
} else if(std::holds_alternative<scripting::null>(res)) {
stream << "null";
} else {

+ 87
- 0
src/std/array.cpp View File

@ -319,6 +319,92 @@ struct fn_array_index final : public scripting::function_impl {
~fn_array_index() final = default;
};
struct fn_array_set final : public scripting::function_impl {
fn_array_set() = default;
std::optional<script_value> apply(UserScript* self, std::vector<argument> n, std::optional<script_error>& error) final {
if(n.size() != 3) {
error = script_error{
.message = "/array_set takes exactly 3 argument of type (array, integer, value), provided a different amount"
};
return std::nullopt;
}
auto& arg = n.back();
if(std::holds_alternative<scripting::script_value>(arg)) {
error = script_error{
.message = "/array_set takes exactly 3 argument of type (array, integer, value), the array needs to be a variable"
};
return std::nullopt;
}
auto target = self->getValue(std::get<scripting::script_variable>(arg).name);
if(not target) {
error = script_error{
.message = "/array_set takes exactly 3 argument of type (array, integer, value), provided array variable is undefined"
};
return std::nullopt;
}
if(not std::holds_alternative<array>(target.value().get())) {
error = script_error{
.message = "/array_set takes exactly 1 argument of type array followed by an integer, argument 1 is not an array"
};
return std::nullopt;
}
auto& concrete_target = std::get<array>(target.value().get());
auto& idx_arg = n[1];
script_value idx;
if(std::holds_alternative<scripting::script_value>(idx_arg)) {
idx = std::get<scripting::script_value>(idx_arg);
} else {
idx = self->resolve(std::get<scripting::script_variable>(idx_arg).name);
}
if(not std::holds_alternative<int32_t>(idx)) {
error = script_error{
.message = "/array_set takes exactly 1 argument of type array followed by an integer, argument 2 is not an integer"
};
return std::nullopt;
}
if(static_cast<int32_t>(concrete_target.value.size()) <= std::get<int32_t>(idx)) {
error = script_error{
.message = "/array_set index must be smaller that the array size, the first element of the array has index 0"
};
return std::nullopt;
}
if(std::get<int32_t>(idx) < 0) {
error = script_error{
.message = "/array_set index must be 0 or more"
};
return std::nullopt;
}
auto& value_arg = n.front();
script_value value;
if(std::holds_alternative<scripting::script_value>(value_arg)) {
value = std::get<scripting::script_value>(value_arg);
} else {
value = self->resolve(std::get<scripting::script_variable>(value_arg).name);
}
concrete_target.value.at(std::get<int32_t>(idx)) = value;
return concrete_target.value[std::get<int32_t>(idx)];
}
~fn_array_set() final = default;
};
namespace scripting {
interpreter register_array_lib(interpreter target, bool recursive_arrays, int32_t size_limit) {
@ -329,6 +415,7 @@ namespace scripting {
target->registerFunction("array_pop", std::make_unique<fn_array_pop>());
target->registerFunction("array_size", std::make_unique<fn_array_size>());
target->registerFunction("array_index", std::make_unique<fn_array_index>());
target->registerFunction("array_set", std::make_unique<fn_array_set>());
return std::move(target);
}

Loading…
Cancel
Save