|
#pragma once
|
|
#include <memory>
|
|
#include <string>
|
|
#include <variant>
|
|
#include <vector>
|
|
#include <optional>
|
|
|
|
namespace scripting {
|
|
struct null {};
|
|
struct array;
|
|
|
|
using script_value = std::variant<null, int32_t, std::string, array>;
|
|
struct script_variable {
|
|
std::string name;
|
|
};
|
|
|
|
struct code_location {
|
|
std::shared_ptr<const std::string> line_contents;
|
|
int32_t line_number;
|
|
int32_t column_number;
|
|
};
|
|
|
|
struct script_error {
|
|
std::shared_ptr<const code_location> location;
|
|
std::string message;
|
|
};
|
|
|
|
struct array {
|
|
std::vector<script_value> value;
|
|
operator std::vector<script_value>&() {
|
|
return value;
|
|
}
|
|
};
|
|
|
|
using argument = std::variant<script_value, script_variable>;
|
|
|
|
class UserScript;
|
|
|
|
struct function_impl {
|
|
virtual std::optional<script_value> apply(UserScript* self, std::vector<argument>, std::optional<script_error>&) = 0;
|
|
virtual ~function_impl() = default;
|
|
};
|
|
|
|
using function = std::unique_ptr<function_impl>;
|
|
|
|
class UserScript {
|
|
public:
|
|
virtual std::optional<std::reference_wrapper<script_value>> getValue(const std::string& name) = 0;
|
|
virtual bool setValue(const std::string& name, script_value value) = 0;
|
|
virtual void registerFunction(std::string name, function fn) = 0;
|
|
virtual script_value resolve(const std::string& name) = 0;
|
|
virtual std::variant<script_value, std::vector<script_error>> executeAtOnce(std::string code) = 0;
|
|
virtual std::vector<script_error> prepare(std::string code) = 0;
|
|
virtual std::optional<script_error> stepOnce() = 0;
|
|
virtual ~UserScript() = default;
|
|
};
|
|
|
|
std::unique_ptr<UserScript> prepare_interpreter(const std::string& code);
|
|
std::unique_ptr<UserScript> register_array_lib(std::unique_ptr<UserScript> target, bool recursive_arrays = false, int32_t size_limit = 1024);
|
|
}
|