return refs for new_*var and new_ident (guarantee valid result)
parent
1a68dd1c25
commit
8c8aa26c20
|
@ -8,14 +8,17 @@
|
||||||
|
|
||||||
#include "callable.hh"
|
#include "callable.hh"
|
||||||
#include "ident.hh"
|
#include "ident.hh"
|
||||||
|
#include "value.hh"
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
|
struct state;
|
||||||
|
|
||||||
using alloc_func = void *(*)(void *, void *, size_t, size_t);
|
using alloc_func = void *(*)(void *, void *, size_t, size_t);
|
||||||
|
|
||||||
using hook_func = internal::callable<void, struct state &>;
|
using hook_func = internal::callable<void, struct state &>;
|
||||||
using command_func = internal::callable<
|
using command_func = internal::callable<
|
||||||
void, struct state &, std::span<struct any_value>, struct any_value &
|
void, state &, std::span<any_value>, any_value &
|
||||||
>;
|
>;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -68,19 +71,19 @@ struct LIBCUBESCRIPT_EXPORT state {
|
||||||
void clear_override(ident &id);
|
void clear_override(ident &id);
|
||||||
void clear_overrides();
|
void clear_overrides();
|
||||||
|
|
||||||
integer_var *new_ivar(
|
integer_var &new_ivar(
|
||||||
std::string_view n, integer_type v, bool read_only = false,
|
std::string_view n, integer_type v, bool read_only = false,
|
||||||
var_type vtp = var_type::DEFAULT
|
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,
|
std::string_view n, float_type v, bool read_only = false,
|
||||||
var_type vtp = var_type::DEFAULT
|
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,
|
std::string_view n, std::string_view v, bool read_only = false,
|
||||||
var_type vtp = var_type::DEFAULT
|
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 reset_var(std::string_view name);
|
||||||
void touch_var(std::string_view name);
|
void touch_var(std::string_view name);
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct LIBCUBESCRIPT_EXPORT any_value {
|
||||||
integer_type force_int();
|
integer_type force_int();
|
||||||
std::string_view force_str();
|
std::string_view force_str();
|
||||||
bcode_ref force_code(state &cs);
|
bcode_ref force_code(state &cs);
|
||||||
ident *force_ident(state &cs);
|
ident &force_ident(state &cs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
406
src/cs_gen.cc
406
src/cs_gen.cc
|
@ -238,154 +238,152 @@ static void compilelookup(codegen_state &gs, int ltype) {
|
||||||
if (lookup.empty()) goto invalid;
|
if (lookup.empty()) goto invalid;
|
||||||
lookup.push_back('\0');
|
lookup.push_back('\0');
|
||||||
lookupid:
|
lookupid:
|
||||||
ident *id = gs.ts.istate->new_ident(
|
ident &id = gs.ts.istate->new_ident(
|
||||||
*gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
*gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
if (id) {
|
switch (id.get_type()) {
|
||||||
switch (id->get_type()) {
|
case ident_type::IVAR:
|
||||||
case ident_type::IVAR:
|
gs.code.push_back(
|
||||||
gs.code.push_back(
|
BC_INST_IVAR | ret_code(ltype, BC_RET_INT) |
|
||||||
BC_INST_IVAR | ret_code(ltype, BC_RET_INT) |
|
(id.get_index() << 8)
|
||||||
(id->get_index() << 8)
|
);
|
||||||
);
|
switch (ltype) {
|
||||||
switch (ltype) {
|
case VAL_POP:
|
||||||
case VAL_POP:
|
gs.code.pop_back();
|
||||||
gs.code.pop_back();
|
break;
|
||||||
break;
|
case VAL_CODE:
|
||||||
case VAL_CODE:
|
gs.code.push_back(BC_INST_COMPILE);
|
||||||
gs.code.push_back(BC_INST_COMPILE);
|
break;
|
||||||
break;
|
case VAL_IDENT:
|
||||||
case VAL_IDENT:
|
gs.code.push_back(BC_INST_IDENT_U);
|
||||||
gs.code.push_back(BC_INST_IDENT_U);
|
break;
|
||||||
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<command_impl *>(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<integer_type>::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:
|
return;
|
||||||
goto invalid;
|
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<command_impl &>(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<integer_type>::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());
|
gs.gen_str(lookup.str_term());
|
||||||
break;
|
break;
|
||||||
|
@ -512,28 +510,26 @@ static bool compileblocksub(codegen_state &gs) {
|
||||||
}
|
}
|
||||||
lookup.push_back('\0');
|
lookup.push_back('\0');
|
||||||
lookupid:
|
lookupid:
|
||||||
ident *id = gs.ts.istate->new_ident(
|
ident &id = gs.ts.istate->new_ident(
|
||||||
*gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
*gs.ts.pstate, lookup.str_term(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
if (id) {
|
switch (id.get_type()) {
|
||||||
switch (id->get_type()) {
|
case ident_type::IVAR:
|
||||||
case ident_type::IVAR:
|
gs.code.push_back(BC_INST_IVAR | (id.get_index() << 8));
|
||||||
gs.code.push_back(BC_INST_IVAR | (id->get_index() << 8));
|
goto done;
|
||||||
goto done;
|
case ident_type::FVAR:
|
||||||
case ident_type::FVAR:
|
gs.code.push_back(BC_INST_FVAR | (id.get_index() << 8));
|
||||||
gs.code.push_back(BC_INST_FVAR | (id->get_index() << 8));
|
goto done;
|
||||||
goto done;
|
case ident_type::SVAR:
|
||||||
case ident_type::SVAR:
|
gs.code.push_back(BC_INST_SVAR | (id.get_index() << 8));
|
||||||
gs.code.push_back(BC_INST_SVAR | (id->get_index() << 8));
|
goto done;
|
||||||
goto done;
|
case ident_type::ALIAS:
|
||||||
case ident_type::ALIAS:
|
gs.code.push_back(
|
||||||
gs.code.push_back(
|
BC_INST_LOOKUP | (id.get_index() << 8)
|
||||||
BC_INST_LOOKUP | (id->get_index() << 8)
|
);
|
||||||
);
|
goto done;
|
||||||
goto done;
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gs.gen_str(lookup.str_term());
|
gs.gen_str(lookup.str_term());
|
||||||
gs.code.push_back(BC_INST_LOOKUP_U);
|
gs.code.push_back(BC_INST_LOOKUP_U);
|
||||||
|
@ -800,7 +796,7 @@ static bool compilearg(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_cmd(
|
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 limit = 0
|
||||||
) {
|
) {
|
||||||
std::uint32_t comtype = BC_INST_COM, numargs = 0, numcargs = 0, fakeargs = 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();
|
gs.next_char();
|
||||||
if (!idname.empty()) {
|
if (!idname.empty()) {
|
||||||
idname.push_back('\0');
|
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
|
*gs.ts.pstate, idname.str_term(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
if (id) {
|
switch (id.get_type()) {
|
||||||
switch (id->get_type()) {
|
case ident_type::ALIAS:
|
||||||
case ident_type::ALIAS:
|
more = compilearg(gs, VAL_ANY);
|
||||||
more = compilearg(gs, VAL_ANY);
|
if (!more) {
|
||||||
if (!more) {
|
gs.gen_str();
|
||||||
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<command_impl *>(hid),
|
|
||||||
id, more, rettype, 1
|
|
||||||
);
|
|
||||||
goto endstatement;
|
|
||||||
}
|
}
|
||||||
case ident_type::FVAR: {
|
gs.code.push_back(
|
||||||
auto *hid = gs.ts.istate->cmd_fvar;
|
BC_INST_ALIAS | (id.get_index() << 8)
|
||||||
compile_cmd(
|
);
|
||||||
gs, static_cast<command_impl *>(hid),
|
goto endstatement;
|
||||||
id, more, rettype, 1
|
case ident_type::IVAR: {
|
||||||
);
|
auto *hid = gs.ts.istate->cmd_ivar;
|
||||||
goto endstatement;
|
compile_cmd(
|
||||||
}
|
gs, static_cast<command_impl *>(hid),
|
||||||
case ident_type::SVAR: {
|
id, more, rettype, 1
|
||||||
auto *hid = gs.ts.istate->cmd_svar;
|
);
|
||||||
compile_cmd(
|
goto endstatement;
|
||||||
gs, static_cast<command_impl *>(hid),
|
|
||||||
id, more, rettype, 1
|
|
||||||
);
|
|
||||||
goto endstatement;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
case ident_type::FVAR: {
|
||||||
|
auto *hid = gs.ts.istate->cmd_fvar;
|
||||||
|
compile_cmd(
|
||||||
|
gs, static_cast<command_impl *>(hid),
|
||||||
|
id, more, rettype, 1
|
||||||
|
);
|
||||||
|
goto endstatement;
|
||||||
|
}
|
||||||
|
case ident_type::SVAR: {
|
||||||
|
auto *hid = gs.ts.istate->cmd_svar;
|
||||||
|
compile_cmd(
|
||||||
|
gs, static_cast<command_impl *>(hid),
|
||||||
|
id, more, rettype, 1
|
||||||
|
);
|
||||||
|
goto endstatement;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
gs.gen_str(idname.str_term());
|
gs.gen_str(idname.str_term());
|
||||||
}
|
}
|
||||||
|
@ -1285,7 +1279,7 @@ noid:
|
||||||
break;
|
break;
|
||||||
case ID_COMMAND:
|
case ID_COMMAND:
|
||||||
compile_cmd(
|
compile_cmd(
|
||||||
gs, static_cast<command_impl *>(id), id, more,
|
gs, static_cast<command_impl *>(id), *id, more,
|
||||||
rettype
|
rettype
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -1332,7 +1326,7 @@ noid:
|
||||||
auto *hid = gs.ts.istate->cmd_ivar;
|
auto *hid = gs.ts.istate->cmd_ivar;
|
||||||
compile_cmd(
|
compile_cmd(
|
||||||
gs, static_cast<command_impl *>(hid),
|
gs, static_cast<command_impl *>(hid),
|
||||||
id, more, rettype
|
*id, more, rettype
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1334,7 @@ noid:
|
||||||
auto *hid = gs.ts.istate->cmd_fvar;
|
auto *hid = gs.ts.istate->cmd_fvar;
|
||||||
compile_cmd(
|
compile_cmd(
|
||||||
gs, static_cast<command_impl *>(hid),
|
gs, static_cast<command_impl *>(hid),
|
||||||
id, more, rettype
|
*id, more, rettype
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1348,7 +1342,7 @@ noid:
|
||||||
auto *hid = gs.ts.istate->cmd_svar;
|
auto *hid = gs.ts.istate->cmd_svar;
|
||||||
compile_cmd(
|
compile_cmd(
|
||||||
gs, static_cast<command_impl *>(hid),
|
gs, static_cast<command_impl *>(hid),
|
||||||
id, more, rettype
|
*id, more, rettype
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,12 +103,12 @@ struct codegen_state {
|
||||||
|
|
||||||
void gen_float(std::string_view word);
|
void gen_float(std::string_view word);
|
||||||
|
|
||||||
void gen_ident(ident *id) {
|
void gen_ident(ident &id) {
|
||||||
code.push_back(BC_INST_IDENT | (id->get_index() << 8));
|
code.push_back(BC_INST_IDENT | (id.get_index() << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_ident() {
|
void gen_ident() {
|
||||||
gen_ident(ts.istate->id_dummy);
|
gen_ident(*ts.istate->id_dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_ident(std::string_view word) {
|
void gen_ident(std::string_view word) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ ident *internal_state::add_ident(ident *id, ident_impl *impl) {
|
||||||
return identmap.back();
|
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);
|
ident *id = get_ident(name);
|
||||||
if (!id) {
|
if (!id) {
|
||||||
if (!is_valid_name(name)) {
|
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);
|
id = add_ident(inst, inst);
|
||||||
}
|
}
|
||||||
return id;
|
return *id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ident *internal_state::get_ident(std::string_view name) const {
|
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_numargs = &new_ivar("numargs", 0, true);
|
||||||
statep->ivar_dbgalias = new_ivar("dbgalias", 4);
|
statep->ivar_dbgalias = &new_ivar("dbgalias", 4);
|
||||||
|
|
||||||
/* default handlers for variables */
|
/* 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
|
std::string_view n, integer_type v, bool read_only, var_type vtp
|
||||||
) {
|
) {
|
||||||
auto *iv = p_tstate->istate->create<ivar_impl>(
|
auto *iv = p_tstate->istate->create<ivar_impl>(
|
||||||
|
@ -429,10 +429,10 @@ LIBCUBESCRIPT_EXPORT integer_var *state::new_ivar(
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
p_tstate->istate->add_ident(iv, iv);
|
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
|
std::string_view n, float_type v, bool read_only, var_type vtp
|
||||||
) {
|
) {
|
||||||
auto *fv = p_tstate->istate->create<fvar_impl>(
|
auto *fv = p_tstate->istate->create<fvar_impl>(
|
||||||
|
@ -446,10 +446,10 @@ LIBCUBESCRIPT_EXPORT float_var *state::new_fvar(
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
p_tstate->istate->add_ident(fv, fv);
|
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
|
std::string_view n, std::string_view v, bool read_only, var_type vtp
|
||||||
) {
|
) {
|
||||||
auto *sv = p_tstate->istate->create<svar_impl>(
|
auto *sv = p_tstate->istate->create<svar_impl>(
|
||||||
|
@ -463,10 +463,10 @@ LIBCUBESCRIPT_EXPORT string_var *state::new_svar(
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
p_tstate->istate->add_ident(sv, sv);
|
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);
|
return p_tstate->istate->new_ident(*this, n, IDENT_FLAG_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct internal_state {
|
||||||
~internal_state();
|
~internal_state();
|
||||||
|
|
||||||
ident *add_ident(ident *id, ident_impl *impl);
|
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;
|
ident *get_ident(std::string_view name) const;
|
||||||
|
|
||||||
void *alloc(void *ptr, size_t os, size_t ns);
|
void *alloc(void *ptr, size_t os, size_t ns);
|
||||||
|
|
|
@ -269,17 +269,17 @@ bcode_ref any_value::force_code(state &cs) {
|
||||||
return bcode_ref{bc};
|
return bcode_ref{bc};
|
||||||
}
|
}
|
||||||
|
|
||||||
ident *any_value::force_ident(state &cs) {
|
ident &any_value::force_ident(state &cs) {
|
||||||
switch (get_type()) {
|
switch (get_type()) {
|
||||||
case value_type::IDENT:
|
case value_type::IDENT:
|
||||||
return csv_get<ident *>(&p_stor);
|
return *csv_get<ident *>(&p_stor);
|
||||||
default:
|
default:
|
||||||
break;
|
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
|
cs, get_str(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
set_ident(id);
|
set_ident(&id);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -768,7 +768,7 @@ std::uint32_t *vm_exec(
|
||||||
any_value &arg = args.back();
|
any_value &arg = args.back();
|
||||||
ident *id = ts.istate->id_dummy;
|
ident *id = ts.istate->id_dummy;
|
||||||
if (arg.get_type() == value_type::STRING) {
|
if (arg.get_type() == value_type::STRING) {
|
||||||
id = ts.istate->new_ident(
|
id = &ts.istate->new_ident(
|
||||||
cs, arg.get_str(), IDENT_FLAG_UNKNOWN
|
cs, arg.get_str(), IDENT_FLAG_UNKNOWN
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1121,7 @@ noid:
|
||||||
std::size_t idstsz = ts.idstack.size();
|
std::size_t idstsz = ts.idstack.size();
|
||||||
for (size_t j = 0; j < size_t(callargs); ++j) {
|
for (size_t j = 0; j < size_t(callargs); ++j) {
|
||||||
push_alias(
|
push_alias(
|
||||||
ts, args[offset + j].force_ident(cs),
|
ts, &args[offset + j].force_ident(cs),
|
||||||
ts.idstack.emplace_back(*ts.pstate)
|
ts.idstack.emplace_back(*ts.pstate)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
inline void init_lineedit(cs::state &, std::string_view) {
|
inline void init_lineedit(cs::state &, std::string_view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<std::string> read_line(cs::state &, cs::string_var *pr) {
|
inline std::optional<std::string> read_line(cs::state &, cs::string_var &pr) {
|
||||||
std::string lbuf;
|
std::string lbuf;
|
||||||
char buf[512];
|
char buf[512];
|
||||||
printf("%s", pr->get_value().data());
|
printf("%s", pr.get_value().data());
|
||||||
std::fflush(stdout);
|
std::fflush(stdout);
|
||||||
while (fgets(buf, sizeof(buf), stdin)) {
|
while (fgets(buf, sizeof(buf), stdin)) {
|
||||||
lbuf += static_cast<char const *>(buf);
|
lbuf += static_cast<char const *>(buf);
|
||||||
|
|
|
@ -50,9 +50,9 @@ inline void init_lineedit(cs::state &cs, std::string_view) {
|
||||||
linenoise::SetHintsCallback(ln_hint);
|
linenoise::SetHintsCallback(ln_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<std::string> read_line(cs::state &, cs::string_var *pr) {
|
inline std::optional<std::string> read_line(cs::state &, cs::string_var &pr) {
|
||||||
std::string line;
|
std::string line;
|
||||||
auto quit = linenoise::Readline(pr->get_value().data(), line);
|
auto quit = linenoise::Readline(pr.get_value().data(), line);
|
||||||
if (quit) {
|
if (quit) {
|
||||||
/* linenoise traps ctrl-c, detect it and let the user exit */
|
/* linenoise traps ctrl-c, detect it and let the user exit */
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
|
|
|
@ -65,8 +65,8 @@ inline void init_lineedit(cs::state &cs, std::string_view) {
|
||||||
rl_redisplay_function = ln_hint;
|
rl_redisplay_function = ln_hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<std::string> read_line(cs::state &, cs::string_var *pr) {
|
inline std::optional<std::string> read_line(cs::state &, cs::string_var &pr) {
|
||||||
auto line = readline(pr->get_value().data());
|
auto line = readline(pr.get_value().data());
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
static void do_tty(cs::state &cs) {
|
||||||
auto prompt = cs.new_svar("PROMPT", "> ");
|
auto &prompt = cs.new_svar("PROMPT", "> ");
|
||||||
auto prompt2 = cs.new_svar("PROMPT2", ">> ");
|
auto &prompt2 = cs.new_svar("PROMPT2", ">> ");
|
||||||
|
|
||||||
bool do_exit = false;
|
bool do_exit = false;
|
||||||
cs.new_command("quit", "", [&do_exit](auto &, auto, auto &) {
|
cs.new_command("quit", "", [&do_exit](auto &, auto, auto &) {
|
||||||
|
|
Loading…
Reference in New Issue