2021-03-23 00:11:21 +00:00
|
|
|
#ifndef LIBCUBESCRIPT_STATE_HH
|
|
|
|
#define LIBCUBESCRIPT_STATE_HH
|
|
|
|
|
|
|
|
#include <cubescript/cubescript.hh>
|
|
|
|
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <string>
|
2021-04-12 17:53:24 +00:00
|
|
|
#include <vector>
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
#include "cs_bcode.hh"
|
2021-04-03 04:16:43 +00:00
|
|
|
#include "cs_ident.hh"
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-03-23 22:32:25 +00:00
|
|
|
namespace cubescript {
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
struct internal_state;
|
|
|
|
struct string_pool;
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
template<typename T>
|
2021-03-23 22:29:32 +00:00
|
|
|
struct std_allocator {
|
2021-03-23 00:11:21 +00:00
|
|
|
using value_type = T;
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
inline std_allocator(internal_state *s);
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
template<typename U>
|
2021-03-30 23:35:02 +00:00
|
|
|
std_allocator(std_allocator<U> const &a): istate{a.istate} {}
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
inline T *allocate(std::size_t n);
|
|
|
|
inline void deallocate(T *p, std::size_t n);
|
|
|
|
|
|
|
|
template<typename U>
|
2021-03-23 22:29:32 +00:00
|
|
|
bool operator==(std_allocator<U> const &a) {
|
|
|
|
return istate == a.istate;
|
2021-03-23 00:11:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
internal_state *istate;
|
2021-03-23 00:11:21 +00:00
|
|
|
};
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
struct internal_state {
|
|
|
|
using allocator_type = std_allocator<
|
|
|
|
std::pair<std::string_view const, ident *>
|
2021-03-23 00:11:21 +00:00
|
|
|
>;
|
2021-03-23 22:29:32 +00:00
|
|
|
alloc_func allocf;
|
2021-03-23 00:11:21 +00:00
|
|
|
void *aptr;
|
|
|
|
|
|
|
|
std::unordered_map<
|
2021-03-23 22:29:32 +00:00
|
|
|
std::string_view, ident *,
|
2021-03-23 00:11:21 +00:00
|
|
|
std::hash<std::string_view>,
|
|
|
|
std::equal_to<std::string_view>,
|
|
|
|
allocator_type
|
|
|
|
> idents;
|
2021-03-23 22:29:32 +00:00
|
|
|
std::vector<ident *, std_allocator<ident *>> identmap;
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
string_pool *strman;
|
2021-03-23 00:11:21 +00:00
|
|
|
empty_block *empty;
|
|
|
|
|
2021-04-04 04:52:02 +00:00
|
|
|
ident *id_dummy;
|
|
|
|
|
|
|
|
integer_var *ivar_numargs;
|
|
|
|
integer_var *ivar_dbgalias;
|
|
|
|
|
2021-04-04 04:47:17 +00:00
|
|
|
command *cmd_ivar;
|
|
|
|
command *cmd_fvar;
|
|
|
|
command *cmd_svar;
|
|
|
|
command *cmd_var_changed;
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
internal_state() = delete;
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
internal_state(alloc_func af, void *data);
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
~internal_state();
|
2021-03-23 00:11:21 +00:00
|
|
|
|
2021-04-03 04:16:43 +00:00
|
|
|
ident *add_ident(ident *id, ident_impl *impl);
|
2021-04-05 17:52:13 +00:00
|
|
|
ident &new_ident(state &cs, std::string_view name, int flags);
|
2021-04-03 04:16:43 +00:00
|
|
|
ident *get_ident(std::string_view name) const;
|
|
|
|
|
2021-03-23 00:11:21 +00:00
|
|
|
void *alloc(void *ptr, size_t os, size_t ns);
|
|
|
|
|
|
|
|
template<typename T, typename ...A>
|
|
|
|
T *create(A &&...args) {
|
|
|
|
T *ret = static_cast<T *>(alloc(nullptr, 0, sizeof(T)));
|
|
|
|
new (ret) T(std::forward<A>(args)...);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T *create_array(size_t len) {
|
|
|
|
T *ret = static_cast<T *>(alloc(nullptr, 0, len * sizeof(T)));
|
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
|
|
new (&ret[i]) T();
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void destroy(T *v) noexcept {
|
|
|
|
v->~T();
|
|
|
|
alloc(v, sizeof(T), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void destroy_array(T *v, size_t len) noexcept {
|
|
|
|
v->~T();
|
|
|
|
alloc(v, len * sizeof(T), 0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-04-05 02:10:39 +00:00
|
|
|
struct state_p {
|
|
|
|
state_p(state &cs): csp{&cs} {}
|
|
|
|
|
|
|
|
thread_state &ts() { return *csp->p_tstate; }
|
|
|
|
|
|
|
|
state *csp;
|
|
|
|
};
|
|
|
|
|
2021-03-23 00:11:21 +00:00
|
|
|
template<typename T>
|
2021-03-23 22:29:32 +00:00
|
|
|
inline std_allocator<T>::std_allocator(internal_state *s): istate{s} {}
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
template<typename T>
|
2021-03-23 22:29:32 +00:00
|
|
|
inline T *std_allocator<T>::allocate(std::size_t n) {
|
|
|
|
return static_cast<T *>(istate->alloc(nullptr, 0, n * sizeof(T)));
|
2021-03-23 00:11:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2021-03-23 22:29:32 +00:00
|
|
|
inline void std_allocator<T>::deallocate(T *p, std::size_t n) {
|
|
|
|
istate->alloc(p, n, 0);
|
2021-03-23 00:11:21 +00:00
|
|
|
}
|
|
|
|
|
2021-04-11 17:36:20 +00:00
|
|
|
template<typename F>
|
|
|
|
inline void new_cmd_quiet(
|
|
|
|
state &cs, std::string_view name, std::string_view args, F &&f
|
|
|
|
) {
|
|
|
|
try {
|
|
|
|
cs.new_command(name, args, std::forward<F>(f));
|
|
|
|
} catch (error const &) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:32:25 +00:00
|
|
|
} /* namespace cubescript */
|
2021-03-23 00:11:21 +00:00
|
|
|
|
|
|
|
#endif
|