diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 2ce4ad1..984663f 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -374,6 +374,8 @@ struct LIBCUBESCRIPT_EXPORT any_value { float_type force_float(); integer_type force_int(); std::string_view force_str(); + bcode *force_code(state &cs); + ident *force_ident(state &cs); bool code_is_empty() const; @@ -589,7 +591,6 @@ struct LIBCUBESCRIPT_EXPORT state { void clear_overrides(); ident *new_ident(std::string_view name, int flags = IDENT_FLAG_UNKNOWN); - ident *force_ident(any_value &v); template integer_var *new_ivar( diff --git a/src/cs_state.cc b/src/cs_state.cc index 43bb31b..1e17f47 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -273,22 +273,6 @@ LIBCUBESCRIPT_EXPORT ident *state::new_ident( return id; } -LIBCUBESCRIPT_EXPORT ident *state::force_ident(any_value &v) { - switch (v.get_type()) { - case value_type::IDENT: - return v.get_ident(); - case value_type::STRING: { - ident *id = new_ident(v.get_str()); - v.set_ident(id); - return id; - } - default: - break; - } - v.set_ident(p_state->identmap[ID_IDX_DUMMY]); - return p_state->identmap[ID_IDX_DUMMY]; -} - LIBCUBESCRIPT_EXPORT ident *state::get_ident(std::string_view name) { auto id = p_state->idents.find(name); if (id != p_state->idents.end()) { diff --git a/src/cs_val.cc b/src/cs_val.cc index 6e85199..bf02bb6 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -2,6 +2,7 @@ #include "cs_gen.hh" #include "cs_std.hh" #include "cs_parser.hh" +#include "cs_state.hh" #include @@ -248,6 +249,36 @@ std::string_view any_value::force_str() { )); } +bcode *any_value::force_code(state &cs) { + switch (get_type()) { + case value_type::CODE: + return csv_get(&p_stor); + default: + break; + } + codegen_state gs{cs}; + gs.code.reserve(64); + gs.gen_main(get_str()); + gs.done(); + uint32_t *cbuf = bcode_alloc(cs, gs.code.size()); + std::memcpy(cbuf, gs.code.data(), gs.code.size() * sizeof(std::uint32_t)); + auto *bc = reinterpret_cast(cbuf + 1); + set_code(bc); + return bc; +} + +ident *any_value::force_ident(state &cs) { + switch (get_type()) { + case value_type::IDENT: + return csv_get(&p_stor); + default: + break; + } + auto *id = cs.new_ident(get_str()); + set_ident(id); + return id; +} + integer_type any_value::get_int() const { switch (get_type()) { case value_type::FLOAT: diff --git a/src/cs_vm.cc b/src/cs_vm.cc index dd11dc5..26a8265 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -62,35 +62,6 @@ bool stack_state::gap() const { return p_gap; } -static inline uint32_t *forcecode(state &cs, any_value &v) { - auto *code = v.get_code(); - if (!code) { - codegen_state gs(cs); - gs.code.reserve(64); - gs.gen_main(v.get_str()); - gs.done(); - uint32_t *cbuf = bcode_alloc(cs, gs.code.size()); - memcpy(cbuf, gs.code.data(), gs.code.size() * sizeof(uint32_t)); - v.set_code(reinterpret_cast(cbuf + 1)); - code = v.get_code(); - } - return code->get_raw(); -} - -static inline void forcecond(state &cs, any_value &v) { - switch (v.get_type()) { - case value_type::STRING: - if (!std::string_view{v.get_str()}.empty()) { - forcecode(cs, v); - } else { - v.set_int(0); - } - break; - default: - break; - } -} - static inline void force_arg(any_value &v, int type) { switch (type) { case BC_RET_STRING: @@ -192,8 +163,13 @@ static inline void callcommand( } args[i].set_none(); fakeargs++; - } else { - forcecond(cs, args[i]); + } else if (args[i].get_type() == value_type::STRING) { + auto str = std::string_view{args[i].get_str()}; + if (str.empty()) { + args[i].set_int(0); + } else { + args[i].force_code(cs); + } } break; case 'e': @@ -206,7 +182,7 @@ static inline void callcommand( ); fakeargs++; } else { - forcecode(cs, args[i]); + args[i].force_code(cs); } break; case 'r': @@ -217,7 +193,7 @@ static inline void callcommand( args[i].set_ident(cs.p_state->identmap[ID_IDX_DUMMY]); fakeargs++; } else { - cs.force_ident(args[i]); + args[i].force_ident(cs); } break; case '$': @@ -1295,9 +1271,9 @@ noid: case ID_LOCAL: { valarray locals{cs}; for (size_t j = 0; j < size_t(callargs); ++j) { - push_alias(cs, cs.force_ident( - args[offset + j] - ), locals[j]); + push_alias( + cs, args[offset + j].force_ident(cs), locals[j] + ); } call_with_cleanup([&]() { code = runcode(cs, code, result);