diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index ded3d98..cd9709e 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -233,7 +233,7 @@ struct LIBCUBESCRIPT_EXPORT ident { protected: ident() = default; - friend struct state; + friend struct internal_state; struct ident_impl *p_impl{}; }; @@ -343,8 +343,6 @@ struct LIBCUBESCRIPT_EXPORT state { std::string_view n, std::string_view v, bool read_only = false ); - ident *new_ident(std::string_view name, int flags); - template command *new_command( std::string_view name, std::string_view args, F &&f @@ -381,8 +379,6 @@ struct LIBCUBESCRIPT_EXPORT state { std::optional get_alias_val(std::string_view name); - void print_var(global_var const &v) const; - thread_state *thread_pointer() { return p_tstate; } @@ -406,8 +402,6 @@ private: LIBCUBESCRIPT_LOCAL state(internal_state *s); - ident *add_ident(ident *id, struct ident_impl *impl); - void *alloc(void *ptr, size_t olds, size_t news); thread_state *p_tstate = nullptr; diff --git a/src/cs_gen.cc b/src/cs_gen.cc index 5eee842..cc15d63 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -238,8 +238,8 @@ static void compilelookup(codegen_state &gs, int ltype) { if (lookup.empty()) goto invalid; lookup.push_back('\0'); lookupid: - ident *id = gs.ts.pstate->new_ident( - lookup.str_term(), IDENT_FLAG_UNKNOWN + ident *id = gs.ts.istate->new_ident( + *gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN ); if (id) { switch (id->get_type()) { @@ -512,8 +512,8 @@ static bool compileblocksub(codegen_state &gs) { } lookup.push_back('\0'); lookupid: - ident *id = gs.ts.pstate->new_ident( - lookup.str_term(), IDENT_FLAG_UNKNOWN + ident *id = gs.ts.istate->new_ident( + *gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN ); if (id) { switch (id->get_type()) { @@ -1189,8 +1189,8 @@ static void compilestatements(codegen_state &gs, int rettype, int brak) { gs.next_char(); if (!idname.empty()) { idname.push_back('\0'); - ident *id = gs.ts.pstate->new_ident( - idname.str_term(), IDENT_FLAG_UNKNOWN + ident *id = gs.ts.istate->new_ident( + *gs.ts.pstate, idname.str_term(), IDENT_FLAG_UNKNOWN ); if (id) { switch (id->get_type()) { diff --git a/src/cs_gen.hh b/src/cs_gen.hh index c25c80c..f963bc2 100644 --- a/src/cs_gen.hh +++ b/src/cs_gen.hh @@ -116,7 +116,7 @@ struct codegen_state { } void gen_ident(std::string_view word) { - gen_ident(ts.pstate->new_ident(word, IDENT_FLAG_UNKNOWN)); + gen_ident(ts.istate->new_ident(*ts.pstate, word, IDENT_FLAG_UNKNOWN)); } void gen_value( diff --git a/src/cs_state.cc b/src/cs_state.cc index 55682c1..6b50a4c 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -19,8 +19,11 @@ internal_state::internal_state(alloc_func af, void *data): {} internal_state::~internal_state() { - bcode_free_empty(this, empty); - destroy(strman); + for (auto &p: idents) { + destroy(p.second->p_impl); + } + bcode_free_empty(this, empty); + destroy(strman); } void *internal_state::alloc(void *ptr, size_t os, size_t ns) { @@ -39,6 +42,41 @@ static void *default_alloc(void *, void *p, size_t, size_t ns) { return std::realloc(p, ns); } +ident *internal_state::add_ident(ident *id, ident_impl *impl) { + if (!id) { + return nullptr; + } + id->p_impl = impl; + idents[id->get_name()] = id; + impl->p_index = int(identmap.size()); + identmap.push_back(id); + return identmap.back(); +} + +ident *internal_state::new_ident(state &cs, std::string_view name, int flags) { + ident *id = get_ident(name); + if (!id) { + if (!is_valid_name(name)) { + throw error{ + cs, "number %s is not a valid identifier name", name.data() + }; + } + auto *inst = create( + cs, string_ref{this, name}, flags + ); + id = add_ident(inst, inst); + } + return id; +} + +ident *internal_state::get_ident(std::string_view name) const { + auto id = idents.find(name); + if (id == idents.end()) { + return nullptr; + } + return id->second; +} + void init_lib_base(state &cs); void init_lib_math(state &cs); void init_lib_string(state &cs); @@ -75,10 +113,12 @@ state::state(alloc_func func, void *data) { for (std::size_t i = 0; i < MAX_ARGUMENTS; ++i) { char buf[16]; snprintf(buf, sizeof(buf), "arg%zu", i + 1); - new_ident(static_cast(buf), IDENT_FLAG_ARG); + statep->new_ident( + *this, static_cast(buf), IDENT_FLAG_ARG + ); } - ident *id = new_ident("//dummy", IDENT_FLAG_UNKNOWN); + ident *id = statep->new_ident(*this, "//dummy", IDENT_FLAG_UNKNOWN); if (id->get_index() != ID_IDX_DUMMY) { throw internal_error{"invalid dummy index"}; } @@ -191,9 +231,6 @@ LIBCUBESCRIPT_EXPORT void state::destroy() { return; } auto *sp = p_tstate->istate; - for (auto &p: sp->idents) { - sp->destroy(p.second->p_impl); - } sp->destroy(p_tstate); sp->destroy(sp); } @@ -223,45 +260,8 @@ LIBCUBESCRIPT_EXPORT void *state::alloc(void *ptr, size_t os, size_t ns) { return p_tstate->istate->alloc(ptr, os, ns); } -LIBCUBESCRIPT_EXPORT ident *state::add_ident( - ident *id, ident_impl *impl -) { - if (!id) { - return nullptr; - } - id->p_impl = impl; - p_tstate->istate->idents[id->get_name()] = id; - static_cast(impl)->p_index = int( - p_tstate->istate->identmap.size() - ); - p_tstate->istate->identmap.push_back(id); - return p_tstate->istate->identmap.back(); -} - -LIBCUBESCRIPT_EXPORT ident *state::new_ident( - std::string_view name, int flags -) { - ident *id = get_ident(name); - if (!id) { - if (!is_valid_name(name)) { - throw error{ - *this, "number %s is not a valid identifier name", name.data() - }; - } - auto *inst = p_tstate->istate->create( - *this, string_ref{p_tstate->istate, name}, flags - ); - id = add_ident(inst, inst); - } - return id; -} - LIBCUBESCRIPT_EXPORT ident *state::get_ident(std::string_view name) { - auto id = p_tstate->istate->idents.find(name); - if (id != p_tstate->istate->idents.end()) { - return id->second; - } - return nullptr; + return p_tstate->istate->get_ident(name); } LIBCUBESCRIPT_EXPORT alias *state::get_alias(std::string_view name) { @@ -295,7 +295,7 @@ LIBCUBESCRIPT_EXPORT integer_var *state::new_ivar( string_ref{p_tstate->istate, n}, v, read_only ? IDENT_FLAG_READONLY : 0 ); - add_ident(iv, iv); + p_tstate->istate->add_ident(iv, iv); return iv; } @@ -306,7 +306,7 @@ LIBCUBESCRIPT_EXPORT float_var *state::new_fvar( string_ref{p_tstate->istate, n}, v, read_only ? IDENT_FLAG_READONLY : 0 ); - add_ident(fv, fv); + p_tstate->istate->add_ident(fv, fv); return fv; } @@ -317,7 +317,7 @@ LIBCUBESCRIPT_EXPORT string_var *state::new_svar( string_ref{p_tstate->istate, n}, string_ref{p_tstate->istate, v}, read_only ? IDENT_FLAG_READONLY : 0 ); - add_ident(sv, sv); + p_tstate->istate->add_ident(sv, sv); return sv; } @@ -356,7 +356,7 @@ LIBCUBESCRIPT_EXPORT void state::set_alias( auto *a = p_tstate->istate->create( *this, string_ref{p_tstate->istate, name}, std::move(v), 0 ); - add_ident(a, a); + p_tstate->istate->add_ident(a, a); } } @@ -411,7 +411,7 @@ LIBCUBESCRIPT_EXPORT command *state::new_command( string_ref{p_tstate->istate, args}, nargs, std::move(func) ); - add_ident(cmd, cmd); + p_tstate->istate->add_ident(cmd, cmd); return cmd; } diff --git a/src/cs_state.hh b/src/cs_state.hh index 536dfd1..6357a7f 100644 --- a/src/cs_state.hh +++ b/src/cs_state.hh @@ -7,6 +7,7 @@ #include #include "cs_bcode.hh" +#include "cs_ident.hh" namespace cubescript { @@ -57,6 +58,10 @@ struct internal_state { ~internal_state(); + ident *add_ident(ident *id, ident_impl *impl); + ident *new_ident(state &cs, std::string_view name, int flags); + ident *get_ident(std::string_view name) const; + void *alloc(void *ptr, size_t os, size_t ns); template diff --git a/src/cs_val.cc b/src/cs_val.cc index 32823c2..ab28ccd 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -276,7 +276,9 @@ ident *any_value::force_ident(state &cs) { default: break; } - auto *id = cs.new_ident(get_str(), IDENT_FLAG_UNKNOWN); + auto *id = cs.thread_pointer()->istate->new_ident( + cs, get_str(), IDENT_FLAG_UNKNOWN + ); set_ident(id); return id; } diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 9c4e84a..0880f0a 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -755,7 +755,9 @@ std::uint32_t *vm_exec( any_value &arg = args.back(); ident *id = ts.istate->identmap[ID_IDX_DUMMY]; if (arg.get_type() == value_type::STRING) { - id = cs.new_ident(arg.get_str(), IDENT_FLAG_UNKNOWN); + id = ts.istate->new_ident( + cs, arg.get_str(), IDENT_FLAG_UNKNOWN + ); } alias *a = static_cast(id); if (a->is_arg() && !ident_is_used_arg(id, ts)) {