diff --git a/include/cubescript/cubescript/state.hh b/include/cubescript/cubescript/state.hh index 43dbefc..421a1d9 100644 --- a/include/cubescript/cubescript/state.hh +++ b/include/cubescript/cubescript/state.hh @@ -8,14 +8,17 @@ #include "callable.hh" #include "ident.hh" +#include "value.hh" namespace cubescript { +struct state; + using alloc_func = void *(*)(void *, void *, size_t, size_t); using hook_func = internal::callable; using command_func = internal::callable< - void, struct state &, std::span, struct any_value & + void, state &, std::span, any_value & >; enum { @@ -68,19 +71,19 @@ struct LIBCUBESCRIPT_EXPORT state { void clear_override(ident &id); void clear_overrides(); - integer_var *new_ivar( + integer_var &new_ivar( std::string_view n, integer_type v, bool read_only = false, var_type vtp = var_type::DEFAULT ); - float_var *new_fvar( + float_var &new_fvar( std::string_view n, float_type v, bool read_only = false, var_type vtp = var_type::DEFAULT ); - string_var *new_svar( + string_var &new_svar( std::string_view n, std::string_view v, bool read_only = false, var_type vtp = var_type::DEFAULT ); - ident *new_ident(std::string_view n); + ident &new_ident(std::string_view n); void reset_var(std::string_view name); void touch_var(std::string_view name); diff --git a/include/cubescript/cubescript/value.hh b/include/cubescript/cubescript/value.hh index 3aed162..a122481 100644 --- a/include/cubescript/cubescript/value.hh +++ b/include/cubescript/cubescript/value.hh @@ -114,7 +114,7 @@ struct LIBCUBESCRIPT_EXPORT any_value { integer_type force_int(); std::string_view force_str(); bcode_ref force_code(state &cs); - ident *force_ident(state &cs); + ident &force_ident(state &cs); private: template diff --git a/src/cs_gen.cc b/src/cs_gen.cc index 1ee9623..278f0cc 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -238,154 +238,152 @@ static void compilelookup(codegen_state &gs, int ltype) { if (lookup.empty()) goto invalid; lookup.push_back('\0'); lookupid: - ident *id = gs.ts.istate->new_ident( + ident &id = gs.ts.istate->new_ident( *gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN ); - if (id) { - switch (id->get_type()) { - case ident_type::IVAR: - gs.code.push_back( - BC_INST_IVAR | ret_code(ltype, BC_RET_INT) | - (id->get_index() << 8) - ); - switch (ltype) { - case VAL_POP: - gs.code.pop_back(); - break; - case VAL_CODE: - gs.code.push_back(BC_INST_COMPILE); - break; - case VAL_IDENT: - gs.code.push_back(BC_INST_IDENT_U); - break; - } - return; - case ident_type::FVAR: - gs.code.push_back( - BC_INST_FVAR | ret_code(ltype, BC_RET_FLOAT) | - (id->get_index() << 8) - ); - switch (ltype) { - case VAL_POP: - gs.code.pop_back(); - break; - case VAL_CODE: - gs.code.push_back(BC_INST_COMPILE); - break; - case VAL_IDENT: - gs.code.push_back(BC_INST_IDENT_U); - break; - } - return; - case ident_type::SVAR: - switch (ltype) { - case VAL_POP: - return; - default: - gs.code.push_back( - BC_INST_SVAR | ret_code(ltype, BC_RET_STRING) | - (id->get_index() << 8) - ); - break; - } - goto done; - case ident_type::ALIAS: - switch (ltype) { - case VAL_POP: - return; - case VAL_COND: - gs.code.push_back( - BC_INST_LOOKUP | (id->get_index() << 8) - ); - break; - default: - gs.code.push_back( - BC_INST_LOOKUP | - ret_code(ltype, BC_RET_STRING) | - (id->get_index() << 8) - ); - break; - } - goto done; - case ident_type::COMMAND: { - std::uint32_t comtype = BC_INST_COM, numargs = 0; - auto fmt = static_cast(id)->get_args(); - for (char c: fmt) { - switch (c) { - case 's': - gs.gen_str(std::string_view{}); - numargs++; - break; - case 'i': - gs.gen_int(); - numargs++; - break; - case 'b': - gs.gen_int(std::numeric_limits::min()); - numargs++; - break; - case 'f': - gs.gen_float(); - numargs++; - break; - case 'F': - gs.code.push_back(BC_INST_DUP | BC_RET_FLOAT); - numargs++; - break; - case 'E': - case 't': - gs.gen_null(); - numargs++; - break; - case 'e': - compileblock(gs); - numargs++; - break; - case 'r': - gs.gen_ident(); - numargs++; - break; - case '$': - gs.gen_ident(id); - numargs++; - break; - case 'N': - gs.gen_int(-1); - numargs++; - break; - case 'C': - comtype = BC_INST_COM_C; - goto compilecomv; - case 'V': - comtype = BC_INST_COM_V; - goto compilecomv; - case '1': - case '2': - case '3': - case '4': - break; - } - } - gs.code.push_back( - comtype | ret_code(ltype) | (id->get_index() << 8) - ); - gs.code.push_back( - BC_INST_RESULT_ARG | ret_code(ltype) - ); - goto done; - compilecomv: - gs.code.push_back( - comtype | ret_code(ltype) | (id->get_index() << 8) - ); - gs.code.push_back(numargs); - gs.code.push_back( - BC_INST_RESULT_ARG | ret_code(ltype) - ); - goto done; + switch (id.get_type()) { + case ident_type::IVAR: + gs.code.push_back( + BC_INST_IVAR | ret_code(ltype, BC_RET_INT) | + (id.get_index() << 8) + ); + switch (ltype) { + case VAL_POP: + gs.code.pop_back(); + break; + case VAL_CODE: + gs.code.push_back(BC_INST_COMPILE); + break; + case VAL_IDENT: + gs.code.push_back(BC_INST_IDENT_U); + break; } - default: - goto invalid; + return; + case ident_type::FVAR: + gs.code.push_back( + BC_INST_FVAR | ret_code(ltype, BC_RET_FLOAT) | + (id.get_index() << 8) + ); + switch (ltype) { + case VAL_POP: + gs.code.pop_back(); + break; + case VAL_CODE: + gs.code.push_back(BC_INST_COMPILE); + break; + case VAL_IDENT: + gs.code.push_back(BC_INST_IDENT_U); + break; + } + return; + case ident_type::SVAR: + switch (ltype) { + case VAL_POP: + return; + default: + gs.code.push_back( + BC_INST_SVAR | ret_code(ltype, BC_RET_STRING) | + (id.get_index() << 8) + ); + break; + } + goto done; + case ident_type::ALIAS: + switch (ltype) { + case VAL_POP: + return; + case VAL_COND: + gs.code.push_back( + BC_INST_LOOKUP | (id.get_index() << 8) + ); + break; + default: + gs.code.push_back( + BC_INST_LOOKUP | + ret_code(ltype, BC_RET_STRING) | + (id.get_index() << 8) + ); + break; + } + goto done; + case ident_type::COMMAND: { + std::uint32_t comtype = BC_INST_COM, numargs = 0; + auto fmt = static_cast(id).get_args(); + for (char c: fmt) { + switch (c) { + case 's': + gs.gen_str(std::string_view{}); + numargs++; + break; + case 'i': + gs.gen_int(); + numargs++; + break; + case 'b': + gs.gen_int(std::numeric_limits::min()); + numargs++; + break; + case 'f': + gs.gen_float(); + numargs++; + break; + case 'F': + gs.code.push_back(BC_INST_DUP | BC_RET_FLOAT); + numargs++; + break; + case 'E': + case 't': + gs.gen_null(); + numargs++; + break; + case 'e': + compileblock(gs); + numargs++; + break; + case 'r': + gs.gen_ident(); + numargs++; + break; + case '$': + gs.gen_ident(id); + numargs++; + break; + case 'N': + gs.gen_int(-1); + numargs++; + break; + case 'C': + comtype = BC_INST_COM_C; + goto compilecomv; + case 'V': + comtype = BC_INST_COM_V; + goto compilecomv; + case '1': + case '2': + case '3': + case '4': + break; + } + } + gs.code.push_back( + comtype | ret_code(ltype) | (id.get_index() << 8) + ); + gs.code.push_back( + BC_INST_RESULT_ARG | ret_code(ltype) + ); + goto done; + compilecomv: + gs.code.push_back( + comtype | ret_code(ltype) | (id.get_index() << 8) + ); + gs.code.push_back(numargs); + gs.code.push_back( + BC_INST_RESULT_ARG | ret_code(ltype) + ); + goto done; } + default: + goto invalid; } gs.gen_str(lookup.str_term()); break; @@ -512,28 +510,26 @@ static bool compileblocksub(codegen_state &gs) { } lookup.push_back('\0'); lookupid: - ident *id = gs.ts.istate->new_ident( + ident &id = gs.ts.istate->new_ident( *gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN ); - if (id) { - switch (id->get_type()) { - case ident_type::IVAR: - gs.code.push_back(BC_INST_IVAR | (id->get_index() << 8)); - goto done; - case ident_type::FVAR: - gs.code.push_back(BC_INST_FVAR | (id->get_index() << 8)); - goto done; - case ident_type::SVAR: - gs.code.push_back(BC_INST_SVAR | (id->get_index() << 8)); - goto done; - case ident_type::ALIAS: - gs.code.push_back( - BC_INST_LOOKUP | (id->get_index() << 8) - ); - goto done; - default: - break; - } + switch (id.get_type()) { + case ident_type::IVAR: + gs.code.push_back(BC_INST_IVAR | (id.get_index() << 8)); + goto done; + case ident_type::FVAR: + gs.code.push_back(BC_INST_FVAR | (id.get_index() << 8)); + goto done; + case ident_type::SVAR: + gs.code.push_back(BC_INST_SVAR | (id.get_index() << 8)); + goto done; + case ident_type::ALIAS: + gs.code.push_back( + BC_INST_LOOKUP | (id.get_index() << 8) + ); + goto done; + default: + break; } gs.gen_str(lookup.str_term()); gs.code.push_back(BC_INST_LOOKUP_U); @@ -800,7 +796,7 @@ static bool compilearg( } static void compile_cmd( - codegen_state &gs, command_impl *id, ident *self, bool &more, int rettype, + codegen_state &gs, command_impl *id, ident &self, bool &more, int rettype, std::uint32_t limit = 0 ) { std::uint32_t comtype = BC_INST_COM, numargs = 0, numcargs = 0, fakeargs = 0; @@ -1189,47 +1185,45 @@ static void compilestatements(codegen_state &gs, int rettype, int brak) { gs.next_char(); if (!idname.empty()) { idname.push_back('\0'); - ident *id = gs.ts.istate->new_ident( + ident &id = gs.ts.istate->new_ident( *gs.ts.pstate, idname.str_term(), IDENT_FLAG_UNKNOWN ); - if (id) { - switch (id->get_type()) { - case ident_type::ALIAS: - more = compilearg(gs, VAL_ANY); - if (!more) { - gs.gen_str(); - } - gs.code.push_back( - BC_INST_ALIAS | (id->get_index() << 8) - ); - goto endstatement; - case ident_type::IVAR: { - auto *hid = gs.ts.istate->cmd_ivar; - compile_cmd( - gs, static_cast(hid), - id, more, rettype, 1 - ); - goto endstatement; + switch (id.get_type()) { + case ident_type::ALIAS: + more = compilearg(gs, VAL_ANY); + if (!more) { + gs.gen_str(); } - case ident_type::FVAR: { - auto *hid = gs.ts.istate->cmd_fvar; - compile_cmd( - gs, static_cast(hid), - id, more, rettype, 1 - ); - goto endstatement; - } - case ident_type::SVAR: { - auto *hid = gs.ts.istate->cmd_svar; - compile_cmd( - gs, static_cast(hid), - id, more, rettype, 1 - ); - goto endstatement; - } - default: - break; + gs.code.push_back( + BC_INST_ALIAS | (id.get_index() << 8) + ); + goto endstatement; + case ident_type::IVAR: { + auto *hid = gs.ts.istate->cmd_ivar; + compile_cmd( + gs, static_cast(hid), + id, more, rettype, 1 + ); + goto endstatement; } + case ident_type::FVAR: { + auto *hid = gs.ts.istate->cmd_fvar; + compile_cmd( + gs, static_cast(hid), + id, more, rettype, 1 + ); + goto endstatement; + } + case ident_type::SVAR: { + auto *hid = gs.ts.istate->cmd_svar; + compile_cmd( + gs, static_cast(hid), + id, more, rettype, 1 + ); + goto endstatement; + } + default: + break; } gs.gen_str(idname.str_term()); } @@ -1285,7 +1279,7 @@ noid: break; case ID_COMMAND: compile_cmd( - gs, static_cast(id), id, more, + gs, static_cast(id), *id, more, rettype ); break; @@ -1332,7 +1326,7 @@ noid: auto *hid = gs.ts.istate->cmd_ivar; compile_cmd( gs, static_cast(hid), - id, more, rettype + *id, more, rettype ); break; } @@ -1340,7 +1334,7 @@ noid: auto *hid = gs.ts.istate->cmd_fvar; compile_cmd( gs, static_cast(hid), - id, more, rettype + *id, more, rettype ); break; } @@ -1348,7 +1342,7 @@ noid: auto *hid = gs.ts.istate->cmd_svar; compile_cmd( gs, static_cast(hid), - id, more, rettype + *id, more, rettype ); break; } diff --git a/src/cs_gen.hh b/src/cs_gen.hh index c4e4a49..7858fad 100644 --- a/src/cs_gen.hh +++ b/src/cs_gen.hh @@ -103,12 +103,12 @@ struct codegen_state { void gen_float(std::string_view word); - void gen_ident(ident *id) { - code.push_back(BC_INST_IDENT | (id->get_index() << 8)); + void gen_ident(ident &id) { + code.push_back(BC_INST_IDENT | (id.get_index() << 8)); } void gen_ident() { - gen_ident(ts.istate->id_dummy); + gen_ident(*ts.istate->id_dummy); } void gen_ident(std::string_view word) { diff --git a/src/cs_state.cc b/src/cs_state.cc index 5dcdc7f..e18d857 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -55,7 +55,7 @@ ident *internal_state::add_ident(ident *id, ident_impl *impl) { return identmap.back(); } -ident *internal_state::new_ident(state &cs, std::string_view name, int flags) { +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)) { @@ -68,7 +68,7 @@ ident *internal_state::new_ident(state &cs, std::string_view name, int flags) { ); id = add_ident(inst, inst); } - return id; + return *id; } ident *internal_state::get_ident(std::string_view name) const { @@ -120,10 +120,10 @@ state::state(alloc_func func, void *data) { ); } - statep->id_dummy = statep->new_ident(*this, "//dummy", IDENT_FLAG_UNKNOWN); + statep->id_dummy = &statep->new_ident(*this, "//dummy", IDENT_FLAG_UNKNOWN); - statep->ivar_numargs = new_ivar("numargs", 0, true); - statep->ivar_dbgalias = new_ivar("dbgalias", 4); + statep->ivar_numargs = &new_ivar("numargs", 0, true); + statep->ivar_dbgalias = &new_ivar("dbgalias", 4); /* default handlers for variables */ @@ -415,7 +415,7 @@ static void var_name_check( } } -LIBCUBESCRIPT_EXPORT integer_var *state::new_ivar( +LIBCUBESCRIPT_EXPORT integer_var &state::new_ivar( std::string_view n, integer_type v, bool read_only, var_type vtp ) { auto *iv = p_tstate->istate->create( @@ -429,10 +429,10 @@ LIBCUBESCRIPT_EXPORT integer_var *state::new_ivar( throw; } p_tstate->istate->add_ident(iv, iv); - return iv; + return *iv; } -LIBCUBESCRIPT_EXPORT float_var *state::new_fvar( +LIBCUBESCRIPT_EXPORT float_var &state::new_fvar( std::string_view n, float_type v, bool read_only, var_type vtp ) { auto *fv = p_tstate->istate->create( @@ -446,10 +446,10 @@ LIBCUBESCRIPT_EXPORT float_var *state::new_fvar( throw; } p_tstate->istate->add_ident(fv, fv); - return fv; + return *fv; } -LIBCUBESCRIPT_EXPORT string_var *state::new_svar( +LIBCUBESCRIPT_EXPORT string_var &state::new_svar( std::string_view n, std::string_view v, bool read_only, var_type vtp ) { auto *sv = p_tstate->istate->create( @@ -463,10 +463,10 @@ LIBCUBESCRIPT_EXPORT string_var *state::new_svar( throw; } p_tstate->istate->add_ident(sv, sv); - return sv; + return *sv; } -LIBCUBESCRIPT_EXPORT ident *state::new_ident(std::string_view n) { +LIBCUBESCRIPT_EXPORT ident &state::new_ident(std::string_view n) { return p_tstate->istate->new_ident(*this, n, IDENT_FLAG_UNKNOWN); } diff --git a/src/cs_state.hh b/src/cs_state.hh index 07a44b9..df45ded 100644 --- a/src/cs_state.hh +++ b/src/cs_state.hh @@ -69,7 +69,7 @@ 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 &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); diff --git a/src/cs_val.cc b/src/cs_val.cc index 077581d..b59eae5 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -269,17 +269,17 @@ bcode_ref any_value::force_code(state &cs) { return bcode_ref{bc}; } -ident *any_value::force_ident(state &cs) { +ident &any_value::force_ident(state &cs) { switch (get_type()) { case value_type::IDENT: - return csv_get(&p_stor); + return *csv_get(&p_stor); default: break; } - auto *id = state_p{cs}.ts().istate->new_ident( + auto &id = state_p{cs}.ts().istate->new_ident( cs, get_str(), IDENT_FLAG_UNKNOWN ); - set_ident(id); + set_ident(&id); return id; } diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 01c12c5..61a53e2 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -768,7 +768,7 @@ std::uint32_t *vm_exec( any_value &arg = args.back(); ident *id = ts.istate->id_dummy; if (arg.get_type() == value_type::STRING) { - id = ts.istate->new_ident( + id = &ts.istate->new_ident( cs, arg.get_str(), IDENT_FLAG_UNKNOWN ); } @@ -1121,7 +1121,7 @@ noid: std::size_t idstsz = ts.idstack.size(); for (size_t j = 0; j < size_t(callargs); ++j) { push_alias( - ts, args[offset + j].force_ident(cs), + ts, &args[offset + j].force_ident(cs), ts.idstack.emplace_back(*ts.pstate) ); } diff --git a/tools/edit_fallback.hh b/tools/edit_fallback.hh index 0dd4df8..938653c 100644 --- a/tools/edit_fallback.hh +++ b/tools/edit_fallback.hh @@ -7,10 +7,10 @@ inline void init_lineedit(cs::state &, std::string_view) { } -inline std::optional read_line(cs::state &, cs::string_var *pr) { +inline std::optional read_line(cs::state &, cs::string_var &pr) { std::string lbuf; char buf[512]; - printf("%s", pr->get_value().data()); + printf("%s", pr.get_value().data()); std::fflush(stdout); while (fgets(buf, sizeof(buf), stdin)) { lbuf += static_cast(buf); diff --git a/tools/edit_linenoise.hh b/tools/edit_linenoise.hh index 13e585a..0a25c2d 100644 --- a/tools/edit_linenoise.hh +++ b/tools/edit_linenoise.hh @@ -50,9 +50,9 @@ inline void init_lineedit(cs::state &cs, std::string_view) { linenoise::SetHintsCallback(ln_hint); } -inline std::optional read_line(cs::state &, cs::string_var *pr) { +inline std::optional read_line(cs::state &, cs::string_var &pr) { std::string line; - auto quit = linenoise::Readline(pr->get_value().data(), line); + auto quit = linenoise::Readline(pr.get_value().data(), line); if (quit) { /* linenoise traps ctrl-c, detect it and let the user exit */ if (errno == EAGAIN) { diff --git a/tools/edit_readline.hh b/tools/edit_readline.hh index b7c4a02..e4a965a 100644 --- a/tools/edit_readline.hh +++ b/tools/edit_readline.hh @@ -65,8 +65,8 @@ inline void init_lineedit(cs::state &cs, std::string_view) { rl_redisplay_function = ln_hint; } -inline std::optional read_line(cs::state &, cs::string_var *pr) { - auto line = readline(pr->get_value().data()); +inline std::optional read_line(cs::state &, cs::string_var &pr) { + auto line = readline(pr.get_value().data()); if (!line) { return std::string(); } diff --git a/tools/repl.cc b/tools/repl.cc index 2c41361..621b68c 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -277,8 +277,8 @@ static bool do_call(cs::state &cs, std::string_view line, bool file = false) { } static void do_tty(cs::state &cs) { - auto prompt = cs.new_svar("PROMPT", "> "); - auto prompt2 = cs.new_svar("PROMPT2", ">> "); + auto &prompt = cs.new_svar("PROMPT", "> "); + auto &prompt2 = cs.new_svar("PROMPT2", ">> "); bool do_exit = false; cs.new_command("quit", "", [&do_exit](auto &, auto, auto &) {