remove state::get_alias(), make get_ident() return an optional

master
Daniel Kolesa 2021-04-26 02:42:08 +02:00
parent fadee6ab6f
commit 92281e88c1
6 changed files with 55 additions and 48 deletions

View File

@ -13,6 +13,8 @@
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
#include <optional>
#include <functional>
#include <string_view> #include <string_view>
#include "callable.hh" #include "callable.hh"
@ -223,6 +225,11 @@ struct LIBCUBESCRIPT_EXPORT state {
*/ */
ident &new_ident(std::string_view n); ident &new_ident(std::string_view n);
/** @brief Get a specific cubescript::ident */
std::optional<std::reference_wrapper<ident>> get_ident(
std::string_view name
);
/** @brief Reset a variable or alias /** @brief Reset a variable or alias
* *
* This is like clear_override() except it works by name and performs * This is like clear_override() except it works by name and performs
@ -319,12 +326,6 @@ struct LIBCUBESCRIPT_EXPORT state {
); );
} }
/** @brief Get a specific cubescript::ident (or `nullptr`) */
ident *get_ident(std::string_view name);
/** @brief Get a specific cubescript::alias (or `nullptr`) */
alias *get_alias(std::string_view name);
/** @brief Check if a cubescript::ident of the given name exists */ /** @brief Check if a cubescript::ident of the given name exists */
bool have_ident(std::string_view name); bool have_ident(std::string_view name);

View File

@ -1494,7 +1494,7 @@ void parser_state::parse_block(int ltype, int term) {
} }
idname.push_back('\0'); idname.push_back('\0');
auto idstr = idname.str_term(); auto idstr = idname.str_term();
ident *id = ts.pstate->get_ident(idstr); auto id = ts.pstate->get_ident(idstr);
if (!id) { if (!id) {
/* no such ident exists but the name is valid, which means /* no such ident exists but the name is valid, which means
* it's a syntactically ok call, make it the VM's problem * it's a syntactically ok call, make it the VM's problem
@ -1527,7 +1527,7 @@ void parser_state::parse_block(int ltype, int term) {
continue; continue;
} }
/* the ident exists; treat like a call according to its type */ /* the ident exists; treat like a call according to its type */
more = parse_call_id(*id, ltype); more = parse_call_id(id->get(), ltype);
if (!finish_statement(*this, more, term)) { if (!finish_statement(*this, more, term)) {
return; return;
} }

View File

@ -315,20 +315,14 @@ LIBCUBESCRIPT_EXPORT void *state::alloc(void *ptr, size_t os, size_t ns) {
return p_tstate->istate->alloc(ptr, os, ns); return p_tstate->istate->alloc(ptr, os, ns);
} }
LIBCUBESCRIPT_EXPORT ident *state::get_ident(std::string_view name) { LIBCUBESCRIPT_EXPORT std::optional<
return p_tstate->istate->get_ident(name); std::reference_wrapper<ident>
} > state::get_ident(std::string_view name) {
auto *id = p_tstate->istate->get_ident(name);
LIBCUBESCRIPT_EXPORT alias *state::get_alias(std::string_view name) { if (!id) {
auto id = get_ident(name); return std::nullopt;
if (!id || !id->is_alias()) {
return nullptr;
} }
return static_cast<alias *>(id); return *id;
}
LIBCUBESCRIPT_EXPORT bool state::have_ident(std::string_view name) {
return p_tstate->istate->idents.find(name) != p_tstate->istate->idents.end();
} }
LIBCUBESCRIPT_EXPORT span_type<ident *> state::get_idents() { LIBCUBESCRIPT_EXPORT span_type<ident *> state::get_idents() {
@ -479,44 +473,44 @@ LIBCUBESCRIPT_EXPORT ident &state::new_ident(std::string_view n) {
} }
LIBCUBESCRIPT_EXPORT void state::reset_var(std::string_view name) { LIBCUBESCRIPT_EXPORT void state::reset_var(std::string_view name) {
ident *id = get_ident(name); auto id = get_ident(name);
if (!id) { if (!id) {
throw error{*this, "variable '%s' does not exist", name.data()}; throw error{*this, "variable '%s' does not exist", name.data()};
} }
if (id->is_var()) { if (id->get().is_var()) {
if (static_cast<global_var &>(*id).is_read_only()) { if (static_cast<global_var &>(id->get()).is_read_only()) {
throw error{*this, "variable '%s' is read only", name.data()}; throw error{*this, "variable '%s' is read only", name.data()};
} }
} }
clear_override(*id); clear_override(id->get());
} }
LIBCUBESCRIPT_EXPORT void state::touch_var(std::string_view name) { LIBCUBESCRIPT_EXPORT void state::touch_var(std::string_view name) {
ident *id = get_ident(name); auto id = get_ident(name);
if (id && id->is_var()) { if (id && id->get().is_var()) {
var_changed(*p_tstate, id); var_changed(*p_tstate, &id->get());
} }
} }
LIBCUBESCRIPT_EXPORT void state::set_alias( LIBCUBESCRIPT_EXPORT void state::set_alias(
std::string_view name, any_value v std::string_view name, any_value v
) { ) {
ident *id = get_ident(name); auto id = get_ident(name);
if (id) { if (id) {
switch (id->get_type()) { switch (id->get().get_type()) {
case ident_type::ALIAS: { case ident_type::ALIAS: {
static_cast<alias *>(id)->set_value(*this, std::move(v)); static_cast<alias &>(id->get()).set_value(*this, std::move(v));
return; return;
} }
case ident_type::IVAR: case ident_type::IVAR:
case ident_type::FVAR: case ident_type::FVAR:
case ident_type::SVAR: case ident_type::SVAR:
run(*id, span_type<any_value>{&v, 1}); run(id->get(), span_type<any_value>{&v, 1});
break; break;
default: default:
throw error{ throw error{
*this, "cannot redefine builtin %s with an alias", *this, "cannot redefine builtin %s with an alias",
id->get_name().data() id->get().get_name().data()
}; };
} }
} else if (!is_valid_name(name)) { } else if (!is_valid_name(name)) {

View File

@ -315,7 +315,12 @@ static inline int get_lookupu_type(
if (arg.get_type() != value_type::STRING) { if (arg.get_type() != value_type::STRING) {
return -2; /* default case */ return -2; /* default case */
} }
id = ts.pstate->get_ident(arg.get_string(*ts.pstate)); auto idopt = ts.pstate->get_ident(arg.get_string(*ts.pstate));
if (!idopt) {
id = nullptr;
} else {
id = &idopt->get();
}
if (id) { if (id) {
switch(id->get_type()) { switch(id->get_type()) {
case ident_type::ALIAS: { case ident_type::ALIAS: {
@ -1073,7 +1078,7 @@ litval:
continue; continue;
} }
auto idn = idarg.get_string(cs); auto idn = idarg.get_string(cs);
ident *id = cs.get_ident(idn); auto id = cs.get_ident(idn);
if (!id) { if (!id) {
noid: noid:
if (!is_valid_name(idn)) { if (!is_valid_name(idn)) {
@ -1087,16 +1092,16 @@ noid:
}; };
} }
result.force_none(); result.force_none();
switch (ident_p{*id}.impl().p_type) { switch (ident_p{id->get()}.impl().p_type) {
default: default:
if (!ident_is_callable(id)) { if (!ident_is_callable(&id->get())) {
args.resize(offset - 1); args.resize(offset - 1);
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
continue; continue;
} }
/* fallthrough */ /* fallthrough */
case ID_COMMAND: { case ID_COMMAND: {
auto *cimp = static_cast<command_impl *>(id); auto *cimp = static_cast<command_impl *>(&id->get());
args.resize(offset + std::max( args.resize(offset + std::max(
std::size_t(cimp->get_num_args()), callargs std::size_t(cimp->get_num_args()), callargs
)); ));
@ -1139,7 +1144,8 @@ noid:
std::size_t(cimp->get_num_args()), callargs std::size_t(cimp->get_num_args()), callargs
)); ));
exec_command( exec_command(
ts, cimp, id, &args[offset], result, callargs ts, cimp, &id->get(), &args[offset],
result, callargs
); );
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset - 1); args.resize(offset - 1);
@ -1154,7 +1160,8 @@ noid:
std::size_t(cimp->get_num_args()), callargs std::size_t(cimp->get_num_args()), callargs
)); ));
exec_command( exec_command(
ts, cimp, id, &args[offset], result, callargs ts, cimp, &id->get(), &args[offset],
result, callargs
); );
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset - 1); args.resize(offset - 1);
@ -1169,14 +1176,15 @@ noid:
std::size_t(cimp->get_num_args()), callargs std::size_t(cimp->get_num_args()), callargs
)); ));
exec_command( exec_command(
ts, cimp, id, &args[offset], result, callargs ts, cimp, &id->get(), &args[offset],
result, callargs
); );
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset - 1); args.resize(offset - 1);
continue; continue;
} }
case ID_ALIAS: { case ID_ALIAS: {
alias *a = static_cast<alias *>(id); alias *a = static_cast<alias *>(&id->get());
if (a->is_arg() && !ident_is_used_arg(a, ts)) { if (a->is_arg() && !ident_is_used_arg(a, ts)) {
args.resize(offset - 1); args.resize(offset - 1);
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);

View File

@ -337,14 +337,18 @@ end:
}); });
new_cmd_quiet(gcs, "identexists", "s", [](auto &cs, auto args, auto &res) { new_cmd_quiet(gcs, "identexists", "s", [](auto &cs, auto args, auto &res) {
res.set_integer(cs.have_ident(args[0].get_string(cs))); res.set_integer(cs.get_ident(args[0].get_string(cs)) != std::nullopt);
}); });
new_cmd_quiet(gcs, "getalias", "s", [](auto &cs, auto args, auto &res) { new_cmd_quiet(gcs, "getalias", "s", [](auto &cs, auto args, auto &res) {
auto *id = cs.get_alias(args[0].get_string(cs)); auto &id = cs.new_ident(args[0].get_string(cs));
if (id) { if (id.get_type() != ident_type::ALIAS) {
res = id->get_value(cs); throw error{cs, "'%s' is not an alias", id.get_name().data()};
} }
if (ident_p{id}.impl().p_flags & IDENT_FLAG_UNKNOWN) {
return;
}
res = static_cast<alias &>(id).get_value(cs);
}); });
} }

View File

@ -159,8 +159,8 @@ inline cs::command *get_hint_cmd(cs::state &cs, std::string_view buf) {
} }
if (!buf.empty()) { if (!buf.empty()) {
auto cmd = cs.get_ident(buf); auto cmd = cs.get_ident(buf);
if (cmd && cmd->is_command()) { if (cmd && cmd->get().is_command()) {
return static_cast<cs::command *>(cmd); return static_cast<cs::command *>(&cmd->get());
} }
} }
return nullptr; return nullptr;