clean up cubescript.cc

master
Daniel Kolesa 2016-08-17 17:53:38 +01:00
parent 6a9be3885f
commit caf30eaa03
1 changed files with 547 additions and 412 deletions

View File

@ -24,12 +24,13 @@ char *cs_dup_ostr(ostd::ConstCharRange s) {
}
bool cs_check_num(ostd::ConstCharRange s) {
if (isdigit(s[0]))
if (isdigit(s[0])) {
return true;
}
switch (s[0]) {
case '+':
case '-':
return isdigit(s[1]) || (s[1] == '.' && isdigit(s[2]));
return isdigit(s[1]) || ((s[1] == '.') && isdigit(s[2]));
case '.':
return isdigit(s[1]) != 0;
default:
@ -40,61 +41,73 @@ bool cs_check_num(ostd::ConstCharRange s) {
Ident::Ident(): type(ID_UNKNOWN) {}
/* ID_IVAR */
Ident::Ident(ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s,
VarCb f, int flagsv)
: type(ID_IVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
minval(m), maxval(x), cb_var(ostd::move(f)) {
Ident::Ident(
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s, VarCb f, int flagsv
):
type(ID_IVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
minval(m), maxval(x), cb_var(ostd::move(f))
{
storage.ip = s;
}
/* ID_FVAR */
Ident::Ident(ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
VarCb f, int flagsv)
: type(ID_FVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
minvalf(m), maxvalf(x), cb_var(ostd::move(f)) {
Ident::Ident(
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
VarCb f, int flagsv
):
type(ID_FVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
minvalf(m), maxvalf(x), cb_var(ostd::move(f))
{
storage.fp = s;
}
/* ID_SVAR */
Ident::Ident(ostd::ConstCharRange n, char **s, VarCb f, int flagsv)
: type(ID_SVAR), flags(flagsv), name(n), cb_var(ostd::move(f)) {
Ident::Ident(ostd::ConstCharRange n, char **s, VarCb f, int flagsv):
type(ID_SVAR), flags(flagsv), name(n), cb_var(ostd::move(f))
{
storage.sp = s;
}
/* ID_ALIAS */
Ident::Ident(ostd::ConstCharRange n, char *a, int flagsv)
: type(ID_ALIAS), valtype(VAL_STR), flags(flagsv), name(n), code(nullptr),
stack(nullptr) {
Ident::Ident(ostd::ConstCharRange n, char *a, int flagsv):
type(ID_ALIAS), valtype(VAL_STR), flags(flagsv), name(n), code(nullptr),
stack(nullptr)
{
val.s = a;
val.len = strlen(a);
}
Ident::Ident(ostd::ConstCharRange n, CsInt a, int flagsv)
: type(ID_ALIAS), valtype(VAL_INT), flags(flagsv), name(n), code(nullptr),
stack(nullptr) {
Ident::Ident(ostd::ConstCharRange n, CsInt a, int flagsv):
type(ID_ALIAS), valtype(VAL_INT), flags(flagsv), name(n), code(nullptr),
stack(nullptr)
{
val.i = a;
}
Ident::Ident(ostd::ConstCharRange n, CsFloat a, int flagsv)
: type(ID_ALIAS), valtype(VAL_FLOAT), flags(flagsv), name(n), code(nullptr),
stack(nullptr) {
Ident::Ident(ostd::ConstCharRange n, CsFloat a, int flagsv):
type(ID_ALIAS), valtype(VAL_FLOAT), flags(flagsv), name(n), code(nullptr),
stack(nullptr)
{
val.f = a;
}
Ident::Ident(ostd::ConstCharRange n, int flagsv)
: type(ID_ALIAS), valtype(VAL_NULL), flags(flagsv), name(n), code(nullptr),
stack(nullptr) {
}
Ident::Ident(ostd::ConstCharRange n, TaggedValue const &v, int flagsv)
: type(ID_ALIAS), valtype(v.p_type), flags(flagsv), name(n), code(nullptr),
stack(nullptr) {
Ident::Ident(ostd::ConstCharRange n, int flagsv):
type(ID_ALIAS), valtype(VAL_NULL), flags(flagsv), name(n), code(nullptr),
stack(nullptr)
{}
Ident::Ident(ostd::ConstCharRange n, TaggedValue const &v, int flagsv):
type(ID_ALIAS), valtype(v.p_type), flags(flagsv), name(n), code(nullptr),
stack(nullptr)
{
val = v;
}
/* ID_COMMAND */
Ident::Ident(int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
ostd::Uint32 argmask, int numargs, CmdFunc f)
: type(t), numargs(numargs), flags(0), name(n),
Ident::Ident(
int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
ostd::Uint32 argmask, int numargs, CmdFunc f
):
type(t), numargs(numargs), flags(0), name(n),
cargs(!args.empty() ? cs_dup_ostr(args) : nullptr),
argmask(argmask), cb_cftv(ostd::move(f)) {
}
argmask(argmask), cb_cftv(ostd::move(f))
{}
void cs_init_lib_base(CsState &cs);
@ -127,11 +140,12 @@ CsState::~CsState() {
}
void CsState::clear_override(Ident &id) {
if (!(id.flags & IDF_OVERRIDDEN)) return;
if (!(id.flags & IDF_OVERRIDDEN)) {
return;
}
switch (id.type) {
case ID_ALIAS:
if (id.get_valtype() == VAL_STR) {
if (!id.val.s[0]) break;
delete[] id.val.s;
}
id.clean_code();
@ -157,16 +171,18 @@ void CsState::clear_override(Ident &id) {
}
void CsState::clear_overrides() {
for (Ident &id: idents.iter())
for (Ident &id: idents.iter()) {
clear_override(id);
}
}
Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) {
Ident *id = idents.at(name);
if (!id) {
if (cs_check_num(name)) {
cs_debug_code(*this, "number %s is not a valid identifier name",
name);
cs_debug_code(
*this, "number %s is not a valid identifier name", name
);
return dummy;
}
id = add_ident(name, flags);
@ -198,7 +214,9 @@ Ident *CsState::force_ident(TaggedValue &v) {
bool CsState::reset_var(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id) return false;
if (!id) {
return false;
}
if (id->flags & IDF_READONLY) {
cs_debug_code(*this, "variable %s is read only", id->name);
return false;
@ -209,12 +227,8 @@ bool CsState::reset_var(ostd::ConstCharRange name) {
void CsState::touch_var(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (id) switch (id->type) {
case ID_IVAR:
case ID_FVAR:
case ID_SVAR:
if (id && id->is_var()) {
id->changed();
break;
}
}
@ -223,10 +237,11 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
if (id) {
switch (id->type) {
case ID_ALIAS:
if (id->index < MaxArguments)
if (id->index < MaxArguments) {
id->set_arg(*this, v);
else
} else {
id->set_alias(*this, v);
}
return;
case ID_IVAR:
set_var_int_checked(id, v.get_int());
@ -238,8 +253,9 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
set_var_str_checked(id, v.get_str());
break;
default:
cs_debug_code(*this, "cannot redefine builtin %s with an alias",
id->name);
cs_debug_code(
*this, "cannot redefine builtin %s with an alias", id->name
);
break;
}
v.cleanup();
@ -257,26 +273,30 @@ void CsState::print_var_int(Ident *id, CsInt i) {
return;
}
if (id->flags & IDF_HEX) {
if (id->maxval == 0xFFFFFF)
writefln("%s = 0x%.6X (%d, %d, %d)", id->name,
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
else
if (id->maxval == 0xFFFFFF) {
writefln(
"%s = 0x%.6X (%d, %d, %d)", id->name,
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
);
} else {
writefln("%s = 0x%X", id->name, i);
return;
}
} else {
writefln("%s = %d", id->name, i);
}
}
void CsState::print_var_float(Ident *id, CsFloat f) {
writefln("%s = %s", id->name, floatstr(f));
}
void CsState::print_var_str(Ident *id, ostd::ConstCharRange s) {
if (ostd::find(s, '"').empty())
if (ostd::find(s, '"').empty()) {
writefln("%s = \"%s\"", id->name, s);
else
} else {
writefln("%s = [%s]", id->name, s);
}
}
void CsState::print_var(Ident *id) {
switch (id->type) {
@ -309,7 +329,9 @@ void TaggedValue::cleanup() {
}
void TaggedValue::force_null() {
if (get_type() == VAL_NULL) return;
if (get_type() == VAL_NULL) {
return;
}
cleanup();
set_null();
}
@ -418,14 +440,16 @@ CsFloat Ident::get_float() const {
}
Bytecode *TaggedValue::get_code() const {
if (get_type() != VAL_CODE)
if (get_type() != VAL_CODE) {
return nullptr;
}
return const_cast<Bytecode *>(code);
}
Ident *TaggedValue::get_ident() const {
if (get_type() != VAL_IDENT)
if (get_type() != VAL_IDENT) {
return nullptr;
}
return id;
}
@ -503,9 +527,9 @@ OSTD_EXPORT bool code_is_empty(Bytecode const *code) {
if (!code) {
return true;
}
return (*reinterpret_cast<
ostd::Uint32 const *
>(code) & CODE_OP_MASK) == CODE_EXIT;
return (
*reinterpret_cast<ostd::Uint32 const *>(code) & CODE_OP_MASK
) == CODE_EXIT;
}
bool TaggedValue::code_is_empty() const {
@ -604,14 +628,19 @@ void Ident::push_arg(TaggedValue const &v, IdentStack &st, bool um) {
stack = &st;
set_value(v);
clean_code();
if (um)
if (um) {
flags &= ~IDF_UNKNOWN;
}
}
void Ident::pop_arg() {
if (!stack) return;
if (!stack) {
return;
}
IdentStack *st = stack;
if (get_valtype() == VAL_STR) delete[] val.s;
if (get_valtype() == VAL_STR) {
delete[] val.s;
}
set_value(*stack);
clean_code();
stack = st->next;
@ -637,17 +666,22 @@ void Ident::redo_arg(IdentStack const &st) {
}
void Ident::push_alias(IdentStack &stack) {
if (type == ID_ALIAS && index >= MaxArguments)
if (type == ID_ALIAS && index >= MaxArguments) {
push_arg(null_value, stack);
}
}
void Ident::pop_alias() {
if (type == ID_ALIAS && index >= MaxArguments) pop_arg();
if (type == ID_ALIAS && index >= MaxArguments) {
pop_arg();
}
}
void Ident::set_arg(CsState &cs, TaggedValue &v) {
if (cs.stack->usedargs & (1 << index)) {
if (get_valtype() == VAL_STR) delete[] val.s;
if (get_valtype() == VAL_STR) {
delete[] val.s;
}
set_value(v);
clean_code();
} else {
@ -657,7 +691,9 @@ void Ident::set_arg(CsState &cs, TaggedValue &v) {
}
void Ident::set_alias(CsState &cs, TaggedValue &v) {
if (get_valtype() == VAL_STR) delete[] val.s;
if (get_valtype() == VAL_STR) {
delete[] val.s;
}
set_value(v);
clean_code();
flags = (flags & cs.identflags) | cs.identflags;
@ -681,7 +717,9 @@ bool cs_override_var(CsState &cs, Ident *id, SF sf, RF rf, CF cf) {
if (!(id->flags & IDF_OVERRIDDEN)) {
sf();
id->flags |= IDF_OVERRIDDEN;
} else cf();
} else {
cf();
}
} else {
if (id->flags & IDF_OVERRIDDEN) {
rf();
@ -692,130 +730,165 @@ bool cs_override_var(CsState &cs, Ident *id, SF sf, RF rf, CF cf) {
return true;
}
void CsState::set_var_int(ostd::ConstCharRange name, CsInt v,
bool dofunc, bool doclamp) {
void CsState::set_var_int(
ostd::ConstCharRange name, CsInt v, bool dofunc, bool doclamp
) {
Ident *id = idents.at(name);
if (!id || id->type != ID_IVAR)
if (!id || id->is_ivar()) {
return;
bool success = cs_override_var(*this, id,
}
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.i = *id->storage.ip; },
[]() {}, []() {});
if (!success)
[]() {}, []() {}
);
if (!success) {
return;
if (doclamp)
}
if (doclamp) {
*id->storage.ip = ostd::clamp(v, id->minval, id->maxval);
else
} else {
*id->storage.ip = v;
if (dofunc)
}
if (dofunc) {
id->changed();
}
}
void CsState::set_var_float(ostd::ConstCharRange name, CsFloat v,
bool dofunc, bool doclamp) {
void CsState::set_var_float(
ostd::ConstCharRange name, CsFloat v, bool dofunc, bool doclamp
) {
Ident *id = idents.at(name);
if (!id || id->type != ID_FVAR)
if (!id || id->is_fvar()) {
return;
bool success = cs_override_var(*this, id,
}
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.f = *id->storage.fp; },
[]() {}, []() {});
if (!success)
[]() {}, []() {}
);
if (!success) {
return;
if (doclamp)
}
if (doclamp) {
*id->storage.fp = ostd::clamp(v, id->minvalf, id->maxvalf);
else
} else {
*id->storage.fp = v;
if (dofunc)
}
if (dofunc) {
id->changed();
}
}
void CsState::set_var_str(ostd::ConstCharRange name, ostd::ConstCharRange v,
bool dofunc) {
void CsState::set_var_str(
ostd::ConstCharRange name, ostd::ConstCharRange v, bool dofunc
) {
Ident *id = idents.at(name);
if (!id || id->type != ID_SVAR)
if (!id || id->is_svar()) {
return;
bool success = cs_override_var(*this, id,
}
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.s = *id->storage.sp; },
[&id]() { delete[] id->overrideval.s; },
[&id]() { delete[] *id->storage.sp; });
if (!success)
[&id]() { delete[] *id->storage.sp; }
);
if (!success) {
return;
}
*id->storage.sp = cs_dup_ostr(v);
if (dofunc)
if (dofunc) {
id->changed();
}
}
ostd::Maybe<CsInt> CsState::get_var_int(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_IVAR)
if (!id || id->is_ivar()) {
return ostd::nothing;
}
return *id->storage.ip;
}
ostd::Maybe<CsFloat> CsState::get_var_float(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_FVAR)
if (!id || id->is_fvar()) {
return ostd::nothing;
}
return *id->storage.fp;
}
ostd::Maybe<ostd::String> CsState::get_var_str(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_SVAR)
if (!id || id->is_svar()) {
return ostd::nothing;
}
return ostd::String(*id->storage.sp);
}
ostd::Maybe<CsInt> CsState::get_var_min_int(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_IVAR)
if (!id || id->is_ivar()) {
return ostd::nothing;
}
return id->minval;
}
ostd::Maybe<CsInt> CsState::get_var_max_int(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_IVAR)
if (!id || id->is_ivar()) {
return ostd::nothing;
}
return id->maxval;
}
ostd::Maybe<CsFloat> CsState::get_var_min_float(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_FVAR)
if (!id || id->is_fvar()) {
return ostd::nothing;
}
return id->minvalf;
}
ostd::Maybe<CsFloat> CsState::get_var_max_float(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_FVAR)
if (!id || id->is_fvar()) {
return ostd::nothing;
}
return id->maxvalf;
}
ostd::Maybe<ostd::String>
CsState::get_alias(ostd::ConstCharRange name) {
Ident *id = idents.at(name);
if (!id || id->type != ID_ALIAS)
if (!id || id->is_alias()) {
return ostd::nothing;
if ((id->index < MaxArguments) && !(stack->usedargs & (1 << id->index)))
}
if ((id->index < MaxArguments) && !(stack->usedargs & (1 << id->index))) {
return ostd::nothing;
}
return ostd::move(id->get_str());
}
CsInt cs_clamp_var(CsState &cs, Ident *id, CsInt v) {
if (v < id->minval)
if (v < id->minval) {
v = id->minval;
else if (v > id->maxval)
} else if (v > id->maxval) {
v = id->maxval;
else
} else {
return v;
cs_debug_code(cs, (id->flags & IDF_HEX)
? ((id->minval <= 255)
}
cs_debug_code(
cs,
(id->flags & IDF_HEX)
? (
(id->minval <= 255)
? "valid range for '%s' is %d..0x%X"
: "valid range for '%s' is 0x%X..0x%X")
: "valid range for '%s' is 0x%X..0x%X"
)
: "valid range for '%s' is %d..%d",
id->name, id->minval, id->maxval);
id->name, id->minval, id->maxval
);
return v;
}
@ -824,13 +897,17 @@ void CsState::set_var_int_checked(Ident *id, CsInt v) {
cs_debug_code(*this, "variable '%s' is read only", id->name);
return;
}
bool success = cs_override_var(*this, id,
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.i = *id->storage.ip; },
[]() {}, []() {});
if (!success)
[]() {}, []() {}
);
if (!success) {
return;
if (v < id->minval || v > id->maxval)
}
if ((v < id->minval) || (v > id->maxval)) {
v = cs_clamp_var(*this, id, v);
}
*id->storage.ip = v;
id->changed();
}
@ -839,21 +916,25 @@ void CsState::set_var_int_checked(Ident *id, TvalRange args) {
CsInt v = args[0].force_int();
if ((id->flags & IDF_HEX) && (args.size() > 1)) {
v = (v << 16) | (args[1].force_int() << 8);
if (args.size() > 2)
if (args.size() > 2) {
v |= args[2].force_int();
}
}
set_var_int_checked(id, v);
}
CsFloat cs_clamp_fvar(CsState &cs, Ident *id, CsFloat v) {
if (v < id->minvalf)
if (v < id->minvalf) {
v = id->minvalf;
else if (v > id->maxvalf)
} else if (v > id->maxvalf) {
v = id->maxvalf;
else
} else {
return v;
cs_debug_code(cs, "valid range for '%s' is %s..%s", floatstr(id->minvalf),
floatstr(id->maxvalf));
}
cs_debug_code(
cs, "valid range for '%s' is %s..%s", floatstr(id->minvalf),
floatstr(id->maxvalf)
);
return v;
}
@ -862,13 +943,17 @@ void CsState::set_var_float_checked(Ident *id, CsFloat v) {
cs_debug_code(*this, "variable '%s' is read only", id->name);
return;
}
bool success = cs_override_var(*this, id,
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.f = *id->storage.fp; },
[]() {}, []() {});
if (!success)
[]() {}, []() {}
);
if (!success) {
return;
if (v < id->minvalf || v > id->maxvalf)
}
if ((v < id->minvalf) || (v > id->maxvalf)) {
v = cs_clamp_fvar(*this, id, v);
}
*id->storage.fp = v;
id->changed();
}
@ -878,11 +963,15 @@ void CsState::set_var_str_checked(Ident *id, ostd::ConstCharRange v) {
cs_debug_code(*this, "variable '%s' is read only", id->name);
return;
}
bool success = cs_override_var(*this, id,
bool success = cs_override_var(
*this, id,
[&id]() { id->overrideval.s = *id->storage.sp; },
[&id]() { delete[] id->overrideval.s; },
[&id]() { delete[] *id->storage.sp; });
if (!success) return;
[&id]() { delete[] *id->storage.sp; }
);
if (!success) {
return;
}
*id->storage.sp = cs_dup_ostr(v);
id->changed();
}
@ -893,9 +982,8 @@ static bool cs_add_command(
) {
ostd::Uint32 argmask = 0;
int nargs = 0;
ostd::ConstCharRange fmt(args);
for (; !fmt.empty(); fmt.pop_front()) {
switch (fmt.front()) {
for (ostd::ConstCharRange fmt(args); !fmt.empty(); ++fmt) {
switch (*fmt) {
case 'i':
case 'b':
case 'f':
@ -905,7 +993,9 @@ static bool cs_add_command(
case 'E':
case 'N':
case 'D':
if (nargs < MaxArguments) nargs++;
if (nargs < MaxArguments) {
nargs++;
}
break;
case 'S':
case 's':
@ -921,15 +1011,18 @@ static bool cs_add_command(
case '2':
case '3':
case '4':
if (nargs < MaxArguments)
if (nargs < MaxArguments) {
fmt.push_front_n(fmt.front() - '0' + 1);
}
break;
case 'C':
case 'V':
break;
default:
ostd::err.writefln("builtin %s declared with illegal type: %c",
name, fmt.front());
ostd::err.writefln(
"builtin %s declared with illegal type: %c",
name, fmt.front()
);
return false;
}
}
@ -948,11 +1041,13 @@ void cs_init_lib_io(CsState &cs) {
auto file = args[0].get_strr();
bool ret = cs.run_file(file);
if (!ret) {
if (args[1].get_int())
if (args[1].get_int()) {
ostd::err.writefln("could not run file \"%s\"", file);
}
res.set_int(0);
} else
} else {
res.set_int(1);
}
});
cs_add_command(cs, "echo", "C", [](TvalRange args, TaggedValue &) {
@ -979,14 +1074,19 @@ static inline void cs_set_iter(Ident &id, CsInt i, IdentStack &stack) {
id.push_arg(v, stack);
}
static inline void cs_do_loop(CsState &cs, Ident &id, CsInt offset, CsInt n,
CsInt step, Bytecode *cond, Bytecode *body) {
if (n <= 0 || (id.type != ID_ALIAS))
static inline void cs_do_loop(
CsState &cs, Ident &id, CsInt offset, CsInt n, CsInt step,
Bytecode *cond, Bytecode *body
) {
if (n <= 0 || !id.is_alias()) {
return;
}
IdentStack stack;
for (CsInt i = 0; i < n; ++i) {
cs_set_iter(id, offset + i * step, stack);
if (cond && !cs.run_bool(cond)) break;
if (cond && !cs.run_bool(cond)) {
break;
}
cs.run_int(body);
}
id.pop_arg();
@ -996,8 +1096,9 @@ static inline void cs_loop_conc(
CsState &cs, TaggedValue &res, Ident &id, CsInt offset, CsInt n,
CsInt step, Bytecode *body, bool space
) {
if (n <= 0 || id.type != ID_ALIAS)
if (n <= 0 || !id.is_alias()) {
return;
}
IdentStack stack;
ostd::Vector<char> s;
for (CsInt i = 0; i < n; ++i) {
@ -1005,11 +1106,15 @@ static inline void cs_loop_conc(
TaggedValue v;
cs.run_ret(body, v);
ostd::String vstr = ostd::move(v.get_str());
if (space && i) s.push(' ');
if (space && i) {
s.push(' ');
}
s.push_n(vstr.data(), vstr.size());
v.cleanup();
}
if (n > 0) id.pop_arg();
if (n > 0) {
id.pop_arg();
}
s.push('\0');
ostd::Size len = s.size() - 1;
res.set_mstr(ostd::CharRange(s.disown(), len));
@ -1021,10 +1126,11 @@ void cs_init_lib_base(CsState &cs) {
}, ID_DO);
cs_add_command(cs, "doargs", "e", [&cs](TvalRange args, TaggedValue &res) {
if (cs.stack != &cs.noalias)
if (cs.stack != &cs.noalias) {
cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code(), res); });
else
} else {
cs.run_ret(args[0].get_code(), res);
}
}, ID_DOARGS);
cs_add_command(cs, "if", "tee", [&cs](TvalRange args, TaggedValue &res) {
@ -1042,28 +1148,42 @@ void cs_init_lib_base(CsState &cs) {
}, ID_NOT);
cs_add_command(cs, "&&", "E1V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty())
if (args.empty()) {
res.set_int(1);
else for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) res.cleanup();
if (args[i].get_type() == VAL_CODE)
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
if (args[i].get_type() == VAL_CODE) {
cs.run_ret(args[i].code, res);
else
} else {
res = args[i];
if (!res.get_bool()) break;
}
if (!res.get_bool()) {
break;
}
}
}
}, ID_AND);
cs_add_command(cs, "||", "E1V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty())
if (args.empty()) {
res.set_int(0);
else for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) res.cleanup();
if (args[i].get_type() == VAL_CODE)
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
if (args[i].get_type() == VAL_CODE) {
cs.run_ret(args[i].code, res);
else
} else {
res = args[i];
if (res.get_bool()) break;
}
if (res.get_bool()) {
break;
}
}
}
}, ID_OR);
@ -1085,38 +1205,43 @@ void cs_init_lib_base(CsState &cs) {
}
});
#define CS_CMD_CASE(name, fmt, type, acc, compare) \
cs_add_command(cs, name, fmt "te2V", [&cs](TvalRange args, TaggedValue &res) { \
type val = ostd::move(acc); \
ostd::Size i; \
for (i = 1; (i + 1) < args.size(); i += 2) { \
if (compare) { \
cs.run_ret(args[i + 1].code, res); \
return; \
} \
} \
cs_add_command(cs, "case", "ite2V", [&cs](TvalRange args, TaggedValue &res) {
CsInt val = args[0].get_int();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_int() == val)) {
cs.run_ret(args[i + 1].code, res);
return;
}
}
});
CS_CMD_CASE("case", "i", CsInt, args[0].get_int(),
((args[i].get_type() == VAL_NULL) ||
(args[i].get_int() == val)));
cs_add_command(cs, "casef", "fte2V", [&cs](TvalRange args, TaggedValue &res) {
CsFloat val = args[0].get_float();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_float() == val)) {
cs.run_ret(args[i + 1].code, res);
return;
}
}
});
CS_CMD_CASE("casef", "f", CsFloat, args[0].get_float(),
((args[i].get_type() == VAL_NULL) ||
(args[i].get_float() == val)));
CS_CMD_CASE("cases", "s", ostd::String, args[0].get_str(),
((args[i].get_type() == VAL_NULL) ||
(args[i].get_str() == val)));
#undef CS_CMD_CASE
cs_add_command(cs, "cases", "ste2V", [&cs](TvalRange args, TaggedValue &res) {
ostd::String val = args[0].get_str();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_str() == val)) {
cs.run_ret(args[i + 1].code, res);
return;
}
}
});
cs_add_command(cs, "pushif", "rTe", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident();
TaggedValue &v = args[1];
Bytecode *code = args[2].get_code();
if ((id->type != ID_ALIAS) || (id->index < MaxArguments))
if (!id->is_alias() || (id->index < MaxArguments)) {
return;
}
if (v.get_bool()) {
IdentStack stack;
id->push_arg(v, stack);
@ -1253,7 +1378,9 @@ void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "push", "rTe", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident();
if (id->type != ID_ALIAS || id->index < MaxArguments) return;
if (!id->is_alias() || (id->index < MaxArguments)) {
return;
}
IdentStack stack;
TaggedValue &v = args[1];
id->push_arg(v, stack);
@ -1301,10 +1428,18 @@ void cs_init_lib_string(CsState &cs);
void cs_init_lib_list(CsState &cs);
OSTD_EXPORT void init_libs(CsState &cs, int libs) {
if (libs & CS_LIB_IO ) cs_init_lib_io(cs);
if (libs & CS_LIB_MATH ) cs_init_lib_math(cs);
if (libs & CS_LIB_STRING) cs_init_lib_string(cs);
if (libs & CS_LIB_LIST ) cs_init_lib_list(cs);
if (libs & CS_LIB_IO) {
cs_init_lib_io(cs);
}
if (libs & CS_LIB_MATH) {
cs_init_lib_math(cs);
}
if (libs & CS_LIB_STRING) {
cs_init_lib_string(cs);
}
if (libs & CS_LIB_LIST) {
cs_init_lib_list(cs);
}
}
} /* namespace cscript */