pass result to command callbacks instead of setting it via struct

master
Daniel Kolesa 2016-08-11 18:14:18 +01:00
parent a8b6843a88
commit 97c63951e5
5 changed files with 228 additions and 236 deletions

View File

@ -181,7 +181,7 @@ static TaggedValue no_ret = null_value;
void cs_init_lib_base(CsState &cs); void cs_init_lib_base(CsState &cs);
CsState::CsState(): result(&no_ret) { CsState::CsState(): p_result(&no_ret) {
noalias.id = nullptr; noalias.id = nullptr;
noalias.next = nullptr; noalias.next = nullptr;
noalias.usedargs = (1 << MaxArguments) - 1; noalias.usedargs = (1 << MaxArguments) - 1;
@ -2605,12 +2605,12 @@ static inline void callcommand(CsState &cs, Ident *id, TaggedValue *args, int nu
cscript::util::tvals_concat(buf, ostd::iter(args, i), " "); cscript::util::tvals_concat(buf, ostd::iter(args, i), " ");
TaggedValue tv; TaggedValue tv;
tv.set_mstr(buf.get().iter()); tv.set_mstr(buf.get().iter());
id->cb_cftv(TvalRange(&tv, 1)); id->cb_cftv(TvalRange(&tv, 1), *cs.p_result);
goto cleanup; goto cleanup;
} }
case 'V': case 'V':
i = ostd::max(i + 1, numargs); i = ostd::max(i + 1, numargs);
id->cb_cftv(ostd::iter(args, i)); id->cb_cftv(ostd::iter(args, i), *cs.p_result);
goto cleanup; goto cleanup;
case '1': case '1':
case '2': case '2':
@ -2623,7 +2623,7 @@ static inline void callcommand(CsState &cs, Ident *id, TaggedValue *args, int nu
break; break;
} }
++i; ++i;
id->cb_cftv(TvalRange(args, i)); id->cb_cftv(TvalRange(args, i), *cs.p_result);
cleanup: cleanup:
for (ostd::Size k = 0; k < ostd::Size(i); ++k) args[k].cleanup(); for (ostd::Size k = 0; k < ostd::Size(i); ++k) args[k].cleanup();
for (; i < numargs; i++) args[i].cleanup(); for (; i < numargs; i++) args[i].cleanup();
@ -2640,8 +2640,8 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
} }
++rundepth; ++rundepth;
int numargs = 0; int numargs = 0;
TaggedValue args[MaxArguments + MaxResults], *prevret = cs.result; TaggedValue args[MaxArguments + MaxResults], *prevret = cs.p_result;
cs.result = &result; cs.p_result = &result;
for (;;) { for (;;) {
ostd::Uint32 op = *code++; ostd::Uint32 op = *code++;
switch (op & 0xFF) { switch (op & 0xFF) {
@ -2972,11 +2972,11 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
{ \ { \
arg.cleanup(); \ arg.cleanup(); \
arg.set_null(); \ arg.set_null(); \
cs.result = &arg; \ cs.p_result = &arg; \
TaggedValue buf[MaxArguments]; \ TaggedValue buf[MaxArguments]; \
callcommand(cs, id, buf, 0, true); \ callcommand(cs, id, buf, 0, true); \
force_arg(arg, op&CODE_RET_MASK); \ force_arg(arg, op&CODE_RET_MASK); \
cs.result = &result; \ cs.p_result = &result; \
continue; \ continue; \
} \ } \
default: arg.cleanup(); nval; continue; \ default: arg.cleanup(); nval; continue; \
@ -3120,7 +3120,7 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
Ident *id = cs.identmap[op >> 8]; Ident *id = cs.identmap[op >> 8];
int offset = numargs - id->numargs; int offset = numargs - id->numargs;
result.force_null(); result.force_null();
id->cb_cftv(TvalRange(args + offset, id->numargs)); id->cb_cftv(TvalRange(args + offset, id->numargs), *cs.p_result);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
free_args(args, numargs, offset); free_args(args, numargs, offset);
continue; continue;
@ -3133,7 +3133,7 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
Ident *id = cs.identmap[op >> 13]; Ident *id = cs.identmap[op >> 13];
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
result.force_null(); result.force_null();
id->cb_cftv(ostd::iter(&args[offset], callargs)); id->cb_cftv(ostd::iter(&args[offset], callargs), *cs.p_result);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
free_args(args, numargs, offset); free_args(args, numargs, offset);
continue; continue;
@ -3150,7 +3150,7 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
cscript::util::tvals_concat(buf, ostd::iter(&args[offset], callargs), " "); cscript::util::tvals_concat(buf, ostd::iter(&args[offset], callargs), " ");
TaggedValue tv; TaggedValue tv;
tv.set_mstr(buf.get().iter()); tv.set_mstr(buf.get().iter());
id->cb_cftv(TvalRange(&tv, 1)); id->cb_cftv(TvalRange(&tv, 1), *cs.p_result);
} }
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
free_args(args, numargs, offset); free_args(args, numargs, offset);
@ -3327,7 +3327,7 @@ noid:
} }
} }
exit: exit:
cs.result = prevret; cs.p_result = prevret;
--rundepth; --rundepth;
return code; return code;
} }
@ -3351,8 +3351,8 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
int nargs = int(args.size()); int nargs = int(args.size());
ret.set_null(); ret.set_null();
++rundepth; ++rundepth;
TaggedValue *prevret = result; TaggedValue *prevret = p_result;
result = &ret; p_result = &ret;
if (rundepth > MaxRunDepth) cs_debug_code(*this, "exceeded recursion limit"); if (rundepth > MaxRunDepth) cs_debug_code(*this, "exceeded recursion limit");
else if (id) switch (id->type) { else if (id) switch (id->type) {
default: default:
@ -3393,7 +3393,7 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
break; break;
} }
free_args(args.data(), nargs, 0); free_args(args.data(), nargs, 0);
result = prevret; p_result = prevret;
--rundepth; --rundepth;
} }
@ -3520,18 +3520,18 @@ bool CsState::run_file(ostd::ConstCharRange fname) {
} }
void cs_init_lib_io(CsState &cs) { void cs_init_lib_io(CsState &cs) {
cs_add_command(cs, "exec", "sb", [&cs](TvalRange args) { cs_add_command(cs, "exec", "sb", [&cs](TvalRange args, TaggedValue &res) {
auto file = args[0].get_strr(); auto file = args[0].get_strr();
bool ret = cs.run_file(file); bool ret = cs.run_file(file);
if (!ret) { if (!ret) {
if (args[1].get_int()) if (args[1].get_int())
ostd::err.writefln("could not run file \"%s\"", file); ostd::err.writefln("could not run file \"%s\"", file);
cs.result->set_int(0); res.set_int(0);
} else } else
cs.result->set_int(1); res.set_int(1);
}); });
cs_add_command(cs, "echo", "C", [](TvalRange args) { cs_add_command(cs, "echo", "C", [](TvalRange args, TaggedValue &) {
ostd::writeln(args[0].get_strr()); ostd::writeln(args[0].get_strr());
}); });
} }
@ -3568,8 +3568,10 @@ static inline void cs_do_loop(CsState &cs, Ident &id, int offset, int n,
id.pop_arg(); id.pop_arg();
} }
static inline void cs_loop_conc(CsState &cs, Ident &id, int offset, int n, static inline void cs_loop_conc(
int step, Bytecode *body, bool space) { CsState &cs, TaggedValue &res, Ident &id, int offset, int n,
int step, Bytecode *body, bool space
) {
if (n <= 0 || id.type != ID_ALIAS) if (n <= 0 || id.type != ID_ALIAS)
return; return;
IdentStack stack; IdentStack stack;
@ -3586,86 +3588,86 @@ static inline void cs_loop_conc(CsState &cs, Ident &id, int offset, int n,
if (n > 0) id.pop_arg(); if (n > 0) id.pop_arg();
s.push('\0'); s.push('\0');
ostd::Size len = s.size() - 1; ostd::Size len = s.size() - 1;
cs.result->set_mstr(ostd::CharRange(s.disown(), len)); res.set_mstr(ostd::CharRange(s.disown(), len));
} }
void cs_init_lib_base(CsState &cs) { void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "do", "e", [&cs](TvalRange args) { cs_add_command(cs, "do", "e", [&cs](TvalRange args, TaggedValue &res) {
cs.run_ret(args[0].get_code()); cs.run_ret(args[0].get_code(), res);
}, ID_DO); }, ID_DO);
cs_add_command(cs, "doargs", "e", [&cs](TvalRange args) { 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()); }); cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code(), res); });
else else
cs.run_ret(args[0].get_code()); cs.run_ret(args[0].get_code(), res);
}, ID_DOARGS); }, ID_DOARGS);
cs_add_command(cs, "if", "tee", [&cs](TvalRange args) { cs_add_command(cs, "if", "tee", [&cs](TvalRange args, TaggedValue &res) {
cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code()); cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
}, ID_IF); }, ID_IF);
cs_add_command(cs, "result", "T", [&cs](TvalRange args) { cs_add_command(cs, "result", "T", [](TvalRange args, TaggedValue &res) {
TaggedValue &v = args[0]; TaggedValue &v = args[0];
*cs.result = v; res = v;
v.set_null(); v.set_null();
}, ID_RESULT); }, ID_RESULT);
cs_add_command(cs, "!", "t", [&cs](TvalRange args) { cs_add_command(cs, "!", "t", [](TvalRange args, TaggedValue &res) {
cs.result->set_int(!args[0].get_bool()); res.set_int(!args[0].get_bool());
}, ID_NOT); }, ID_NOT);
cs_add_command(cs, "&&", "E1V", [&cs](TvalRange args) { cs_add_command(cs, "&&", "E1V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty()) if (args.empty())
cs.result->set_int(1); res.set_int(1);
else for (ostd::Size i = 0; i < args.size(); ++i) { else for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) cs.result->cleanup(); if (i) res.cleanup();
if (args[i].get_type() == VAL_CODE) if (args[i].get_type() == VAL_CODE)
cs.run_ret(args[i].code); cs.run_ret(args[i].code, res);
else else
*cs.result = args[i]; res = args[i];
if (!cs.result->get_bool()) break; if (!res.get_bool()) break;
} }
}, ID_AND); }, ID_AND);
cs_add_command(cs, "||", "E1V", [&cs](TvalRange args) { cs_add_command(cs, "||", "E1V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty()) if (args.empty())
cs.result->set_int(0); res.set_int(0);
else for (ostd::Size i = 0; i < args.size(); ++i) { else for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) cs.result->cleanup(); if (i) res.cleanup();
if (args[i].get_type() == VAL_CODE) if (args[i].get_type() == VAL_CODE)
cs.run_ret(args[i].code); cs.run_ret(args[i].code, res);
else else
*cs.result = args[i]; res = args[i];
if (cs.result->get_bool()) break; if (res.get_bool()) break;
} }
}, ID_OR); }, ID_OR);
cs_add_command(cs, "?", "tTT", [&cs](TvalRange args) { cs_add_command(cs, "?", "tTT", [](TvalRange args, TaggedValue &res) {
cs.result->set(args[0].get_bool() ? args[1] : args[2]); res.set(args[0].get_bool() ? args[1] : args[2]);
}); });
cs_add_command(cs, "cond", "ee2V", [&cs](TvalRange args) { cs_add_command(cs, "cond", "ee2V", [&cs](TvalRange args, TaggedValue &res) {
for (ostd::Size i = 0; i < args.size(); i += 2) { for (ostd::Size i = 0; i < args.size(); i += 2) {
if ((i + 1) < args.size()) { if ((i + 1) < args.size()) {
if (cs.run_bool(args[i].code)) { if (cs.run_bool(args[i].code)) {
cs.run_ret(args[i + 1].code); cs.run_ret(args[i + 1].code, res);
break; break;
} }
} else { } else {
cs.run_ret(args[i].code); cs.run_ret(args[i].code, res);
break; break;
} }
} }
}); });
#define CS_CMD_CASE(name, fmt, type, acc, compare) \ #define CS_CMD_CASE(name, fmt, type, acc, compare) \
cs_add_command(cs, name, fmt "te2V", [&cs](TvalRange args) { \ cs_add_command(cs, name, fmt "te2V", [&cs](TvalRange args, TaggedValue &res) { \
type val = ostd::move(acc); \ type val = ostd::move(acc); \
ostd::Size i; \ ostd::Size i; \
for (i = 1; (i + 1) < args.size(); i += 2) { \ for (i = 1; (i + 1) < args.size(); i += 2) { \
if (compare) { \ if (compare) { \
cs.run_ret(args[i + 1].code); \ cs.run_ret(args[i + 1].code, res); \
return; \ return; \
} \ } \
} \ } \
@ -3685,7 +3687,7 @@ void cs_init_lib_base(CsState &cs) {
#undef CS_CMD_CASE #undef CS_CMD_CASE
cs_add_command(cs, "pushif", "rTe", [&cs](TvalRange args) { cs_add_command(cs, "pushif", "rTe", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
TaggedValue &v = args[1]; TaggedValue &v = args[1];
Bytecode *code = args[2].get_code(); Bytecode *code = args[2].get_code();
@ -3695,178 +3697,178 @@ void cs_init_lib_base(CsState &cs) {
IdentStack stack; IdentStack stack;
id->push_arg(v, stack); id->push_arg(v, stack);
v.set_null(); v.set_null();
cs.run_ret(code); cs.run_ret(code, res);
id->pop_arg(); id->pop_arg();
} }
}); });
cs_add_command(cs, "loop", "rie", [&cs](TvalRange args) { cs_add_command(cs, "loop", "rie", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr, cs, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr,
args[2].get_code() args[2].get_code()
); );
}); });
cs_add_command(cs, "loop+", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loop+", "riie", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1, cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
nullptr, args[3].get_code() nullptr, args[3].get_code()
); );
}); });
cs_add_command(cs, "loop*", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loop*", "riie", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(), cs, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(),
nullptr, args[3].get_code() nullptr, args[3].get_code()
); );
}); });
cs_add_command(cs, "loop+*", "riiie", [&cs](TvalRange args) { cs_add_command(cs, "loop+*", "riiie", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(), cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), nullptr, args[4].get_code() args[2].get_int(), nullptr, args[4].get_code()
); );
}); });
cs_add_command(cs, "loopwhile", "riee", [&cs](TvalRange args) { cs_add_command(cs, "loopwhile", "riee", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, cs, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), args[3].get_code() args[2].get_code(), args[3].get_code()
); );
}); });
cs_add_command(cs, "loopwhile+", "riiee", [&cs](TvalRange args) { cs_add_command(cs, "loopwhile+", "riiee", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1, cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), args[4].get_code() args[3].get_code(), args[4].get_code()
); );
}); });
cs_add_command(cs, "loopwhile*", "riiee", [&cs](TvalRange args) { cs_add_command(cs, "loopwhile*", "riiee", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(), cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), args[4].get_code() args[3].get_code(), args[4].get_code()
); );
}); });
cs_add_command(cs, "loopwhile+*", "riiiee", [&cs](TvalRange args) { cs_add_command(cs, "loopwhile+*", "riiiee", [&cs](TvalRange args, TaggedValue &) {
cs_do_loop( cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(), cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), args[5].get_code() args[2].get_int(), args[4].get_code(), args[5].get_code()
); );
}); });
cs_add_command(cs, "while", "ee", [&cs](TvalRange args) { cs_add_command(cs, "while", "ee", [&cs](TvalRange args, TaggedValue &) {
Bytecode *cond = args[0].get_code(), *body = args[1].get_code(); Bytecode *cond = args[0].get_code(), *body = args[1].get_code();
while (cs.run_bool(cond)) { while (cs.run_bool(cond)) {
cs.run_int(body); cs.run_int(body);
} }
}); });
cs_add_command(cs, "loopconcat", "rie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcat", "rie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), true args[2].get_code(), true
); );
}); });
cs_add_command(cs, "loopconcat+", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcat+", "riie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1, cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), true args[3].get_code(), true
); );
}); });
cs_add_command(cs, "loopconcat*", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcat*", "riie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(), cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), true args[3].get_code(), true
); );
}); });
cs_add_command(cs, "loopconcat+*", "riiie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcat+*", "riiie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(), cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), true args[2].get_int(), args[4].get_code(), true
); );
}); });
cs_add_command(cs, "loopconcatword", "rie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcatword", "rie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), false args[2].get_code(), false
); );
}); });
cs_add_command(cs, "loopconcatword+", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcatword+", "riie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1, cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), false args[3].get_code(), false
); );
}); });
cs_add_command(cs, "loopconcatword*", "riie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcatword*", "riie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(), cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), false args[3].get_code(), false
); );
}); });
cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](TvalRange args) { cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_conc( cs_loop_conc(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(), cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), false args[2].get_int(), args[4].get_code(), false
); );
}); });
cs_add_command(cs, "nodebug", "e", [&cs](TvalRange args) { cs_add_command(cs, "nodebug", "e", [&cs](TvalRange args, TaggedValue &res) {
++cs.nodebug; ++cs.nodebug;
cs.run_ret(args[0].get_code()); cs.run_ret(args[0].get_code(), res);
--cs.nodebug; --cs.nodebug;
}); });
cs_add_command(cs, "push", "rTe", [&cs](TvalRange args) { cs_add_command(cs, "push", "rTe", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
if (id->type != ID_ALIAS || id->index < MaxArguments) return; if (id->type != ID_ALIAS || id->index < MaxArguments) return;
IdentStack stack; IdentStack stack;
TaggedValue &v = args[1]; TaggedValue &v = args[1];
id->push_arg(v, stack); id->push_arg(v, stack);
v.set_null(); v.set_null();
cs.run_ret(args[2].get_code()); cs.run_ret(args[2].get_code(), res);
id->pop_arg(); id->pop_arg();
}); });
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL); cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);
cs_add_command(cs, "resetvar", "s", [&cs](TvalRange args) { cs_add_command(cs, "resetvar", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(cs.reset_var(args[0].get_strr())); res.set_int(cs.reset_var(args[0].get_strr()));
}); });
cs_add_command(cs, "alias", "sT", [&cs](TvalRange args) { cs_add_command(cs, "alias", "sT", [&cs](TvalRange args, TaggedValue &) {
TaggedValue &v = args[1]; TaggedValue &v = args[1];
cs.set_alias(args[0].get_strr(), v); cs.set_alias(args[0].get_strr(), v);
v.set_null(); v.set_null();
}); });
cs_add_command(cs, "getvarmin", "s", [&cs](TvalRange args) { cs_add_command(cs, "getvarmin", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0)); res.set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0));
}); });
cs_add_command(cs, "getvarmax", "s", [&cs](TvalRange args) { cs_add_command(cs, "getvarmax", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0)); res.set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0));
}); });
cs_add_command(cs, "getfvarmin", "s", [&cs](TvalRange args) { cs_add_command(cs, "getfvarmin", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f)); res.set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f));
}); });
cs_add_command(cs, "getfvarmax", "s", [&cs](TvalRange args) { cs_add_command(cs, "getfvarmax", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f)); res.set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f));
}); });
cs_add_command(cs, "identexists", "s", [&cs](TvalRange args) { cs_add_command(cs, "identexists", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(cs.have_ident(args[0].get_strr())); res.set_int(cs.have_ident(args[0].get_strr()));
}); });
cs_add_command(cs, "getalias", "s", [&cs](TvalRange args) { cs_add_command(cs, "getalias", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_str(ostd::move(cs.get_alias(args[0].get_strr()).value_or(""))); res.set_str(ostd::move(cs.get_alias(args[0].get_strr()).value_or("")));
}); });
} }

View File

@ -164,7 +164,7 @@ union IdentValuePtr {
struct CsState; struct CsState;
using VarCb = ostd::Function<void(Ident &)>; using VarCb = ostd::Function<void(Ident &)>;
using CmdFunc = ostd::Function<void(TvalRange)>; using CmdFunc = ostd::Function<void(TvalRange, TaggedValue &)>;
enum class IdentType { enum class IdentType {
unknown = -1, unknown = -1,
@ -333,7 +333,7 @@ struct OSTD_EXPORT CsState {
ostd::Vector<Ident *> identmap; ostd::Vector<Ident *> identmap;
Ident *dummy = nullptr; Ident *dummy = nullptr;
TaggedValue *result = nullptr; TaggedValue *p_result = nullptr;
IdentLink noalias; IdentLink noalias;
IdentLink *stack = &noalias; IdentLink *stack = &noalias;
@ -397,18 +397,6 @@ struct OSTD_EXPORT CsState {
void run_ret(ostd::ConstCharRange code, TaggedValue &ret); void run_ret(ostd::ConstCharRange code, TaggedValue &ret);
void run_ret(Ident *id, TvalRange args, TaggedValue &ret); void run_ret(Ident *id, TvalRange args, TaggedValue &ret);
void run_ret(Bytecode const *code) {
run_ret(code, *result);
}
void run_ret(ostd::ConstCharRange code) {
run_ret(code, *result);
}
void run_ret(Ident *id, TvalRange args) {
run_ret(id, args, *result);
}
bool run_file(ostd::ConstCharRange fname); bool run_file(ostd::ConstCharRange fname);
void set_alias(ostd::ConstCharRange name, TaggedValue &v); void set_alias(ostd::ConstCharRange name, TaggedValue &v);

View File

@ -174,8 +174,10 @@ static inline void cs_set_iter(Ident &id, char *val, IdentStack &stack) {
id.push_arg(v, stack); id.push_arg(v, stack);
} }
static void cs_loop_list_conc(CsState &cs, Ident *id, ostd::ConstCharRange list, static void cs_loop_list_conc(
Bytecode const *body, bool space) { CsState &cs, TaggedValue &res, Ident *id, ostd::ConstCharRange list,
Bytecode const *body, bool space
) {
if (!id->is_alias()) if (!id->is_alias())
return; return;
IdentStack stack; IdentStack stack;
@ -196,7 +198,7 @@ static void cs_loop_list_conc(CsState &cs, Ident *id, ostd::ConstCharRange list,
id->pop_arg(); id->pop_arg();
r.push('\0'); r.push('\0');
ostd::Size len = r.size(); ostd::Size len = r.size();
cs.result->set_mstr(ostd::CharRange(r.disown(), len - 1)); res.set_mstr(ostd::CharRange(r.disown(), len - 1));
} }
int cs_list_includes(ostd::ConstCharRange list, ostd::ConstCharRange needle) { int cs_list_includes(ostd::ConstCharRange list, ostd::ConstCharRange needle) {
@ -212,11 +214,11 @@ int cs_list_includes(ostd::ConstCharRange list, ostd::ConstCharRange needle) {
static void cs_init_lib_list_sort(CsState &cs); static void cs_init_lib_list_sort(CsState &cs);
void cs_init_lib_list(CsState &cs) { void cs_init_lib_list(CsState &cs) {
cs.add_command("listlen", "s", [&cs](TvalRange args) { cs.add_command("listlen", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(int(util::list_length(args[0].get_strr()))); res.set_int(int(util::list_length(args[0].get_strr())));
}); });
cs.add_command("at", "si1V", [&cs](TvalRange args) { cs.add_command("at", "si1V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty()) if (args.empty())
return; return;
ostd::String str = ostd::move(args[0].get_str()); ostd::String str = ostd::move(args[0].get_str());
@ -233,10 +235,10 @@ void cs_init_lib_list(CsState &cs) {
auto elem = p.element(); auto elem = p.element();
auto er = p.element().iter(); auto er = p.element().iter();
elem.disown(); elem.disown();
cs.result->set_mstr(er); res.set_mstr(er);
}); });
cs.add_command("sublist", "siiN", [&cs](TvalRange args) { cs.add_command("sublist", "siiN", [&cs](TvalRange args, TaggedValue &res) {
int skip = args[1].get_int(), int skip = args[1].get_int(),
count = args[2].get_int(), count = args[2].get_int(),
numargs = args[2].get_int(); numargs = args[2].get_int();
@ -250,7 +252,7 @@ void cs_init_lib_list(CsState &cs) {
if (len < 0) { if (len < 0) {
if (offset > 0) if (offset > 0)
p.skip(); p.skip();
cs.result->set_str(p.input); res.set_str(p.input);
return; return;
} }
@ -259,14 +261,14 @@ void cs_init_lib_list(CsState &cs) {
if (len > 0 && p.parse()) if (len > 0 && p.parse())
while (--len > 0 && p.parse()); while (--len > 0 && p.parse());
char const *qend = !p.quote.empty() ? &p.quote[p.quote.size()] : list; char const *qend = !p.quote.empty() ? &p.quote[p.quote.size()] : list;
cs.result->set_str(ostd::ConstCharRange(list, qend - list)); res.set_str(ostd::ConstCharRange(list, qend - list));
}); });
cs.add_command("listfind", "rse", [&cs](TvalRange args) { cs.add_command("listfind", "rse", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
auto body = args[2].get_code(); auto body = args[2].get_code();
if (!id->is_alias()) { if (!id->is_alias()) {
cs.result->set_int(-1); res.set_int(-1);
return; return;
} }
IdentStack stack; IdentStack stack;
@ -275,17 +277,17 @@ void cs_init_lib_list(CsState &cs) {
++n; ++n;
cs_set_iter(*id, cs_dup_ostr(p.item), stack); cs_set_iter(*id, cs_dup_ostr(p.item), stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
cs.result->set_int(n); res.set_int(n);
goto found; goto found;
} }
} }
cs.result->set_int(-1); res.set_int(-1);
found: found:
if (n >= 0) if (n >= 0)
id->pop_arg(); id->pop_arg();
}); });
cs.add_command("listassoc", "rse", [&cs](TvalRange args) { cs.add_command("listassoc", "rse", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
auto body = args[2].get_code(); auto body = args[2].get_code();
if (!id->is_alias()) if (!id->is_alias())
@ -300,7 +302,7 @@ found:
auto elem = p.element(); auto elem = p.element();
auto er = elem.iter(); auto er = elem.iter();
elem.disown(); elem.disown();
cs.result->set_mstr(er); res.set_mstr(er);
} }
break; break;
} }
@ -312,12 +314,12 @@ found:
}); });
#define CS_CMD_LIST_FIND(name, fmt, gmeth, cmp) \ #define CS_CMD_LIST_FIND(name, fmt, gmeth, cmp) \
cs.add_command(name, "s" fmt "i", [&cs](TvalRange args) { \ cs.add_command(name, "s" fmt "i", [&cs](TvalRange args, TaggedValue &res) { \
int n = 0, skip = args[2].get_int(); \ int n = 0, skip = args[2].get_int(); \
auto val = args[1].gmeth(); \ auto val = args[1].gmeth(); \
for (ListParser p(args[0].get_strr()); p.parse(); ++n) { \ for (ListParser p(args[0].get_strr()); p.parse(); ++n) { \
if (cmp) { \ if (cmp) { \
cs.result->set_int(n); \ res.set_int(n); \
return; \ return; \
} \ } \
for (int i = 0; i < skip; ++i) { \ for (int i = 0; i < skip; ++i) { \
@ -327,7 +329,7 @@ found:
} \ } \
} \ } \
notfound: \ notfound: \
cs.result->set_int(-1); \ res.set_int(-1); \
}); });
CS_CMD_LIST_FIND("listfind=", "i", get_int, cs_parse_int(p.item) == val); CS_CMD_LIST_FIND("listfind=", "i", get_int, cs_parse_int(p.item) == val);
@ -337,7 +339,7 @@ found:
#undef CS_CMD_LIST_FIND #undef CS_CMD_LIST_FIND
#define CS_CMD_LIST_ASSOC(name, fmt, gmeth, cmp) \ #define CS_CMD_LIST_ASSOC(name, fmt, gmeth, cmp) \
cs.add_command(name, "s" fmt, [&cs](TvalRange args) { \ cs.add_command(name, "s" fmt, [&cs](TvalRange args, TaggedValue &res) { \
auto val = args[1].gmeth(); \ auto val = args[1].gmeth(); \
for (ListParser p(args[0].get_strr()); p.parse();) { \ for (ListParser p(args[0].get_strr()); p.parse();) { \
if (cmp) { \ if (cmp) { \
@ -345,7 +347,7 @@ found:
auto elem = p.element(); \ auto elem = p.element(); \
auto er = elem.iter(); \ auto er = elem.iter(); \
elem.disown(); \ elem.disown(); \
cs.result->set_mstr(er); \ res.set_mstr(er); \
} \ } \
return; \ return; \
} \ } \
@ -360,7 +362,7 @@ found:
#undef CS_CMD_LIST_ASSOC #undef CS_CMD_LIST_ASSOC
cs.add_command("looplist", "rse", [&cs](TvalRange args) { cs.add_command("looplist", "rse", [&cs](TvalRange args, TaggedValue &) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
auto body = args[2].get_code(); auto body = args[2].get_code();
if (!id->is_alias()) if (!id->is_alias())
@ -375,7 +377,7 @@ found:
id->pop_arg(); id->pop_arg();
}); });
cs.add_command("looplist2", "rrse", [&cs](TvalRange args) { cs.add_command("looplist2", "rrse", [&cs](TvalRange args, TaggedValue &) {
Ident *id = args[0].get_ident(), *id2 = args[1].get_ident(); Ident *id = args[0].get_ident(), *id2 = args[1].get_ident();
auto body = args[3].get_code(); auto body = args[3].get_code();
if (!id->is_alias() || !id2->is_alias()) if (!id->is_alias() || !id2->is_alias())
@ -394,7 +396,7 @@ found:
} }
}); });
cs.add_command("looplist3", "rrrse", [&cs](TvalRange args) { cs.add_command("looplist3", "rrrse", [&cs](TvalRange args, TaggedValue &) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
Ident *id2 = args[1].get_ident(); Ident *id2 = args[1].get_ident();
Ident *id3 = args[2].get_ident(); Ident *id3 = args[2].get_ident();
@ -418,21 +420,21 @@ found:
} }
}); });
cs.add_command("looplistconcat", "rse", [&cs](TvalRange args) { cs.add_command("looplistconcat", "rse", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_list_conc( cs_loop_list_conc(
cs, args[0].get_ident(), args[1].get_strr(), cs, res, args[0].get_ident(), args[1].get_strr(),
args[2].get_code(), true args[2].get_code(), true
); );
}); });
cs.add_command("looplistconcatword", "rse", [&cs](TvalRange args) { cs.add_command("looplistconcatword", "rse", [&cs](TvalRange args, TaggedValue &res) {
cs_loop_list_conc( cs_loop_list_conc(
cs, args[0].get_ident(), args[1].get_strr(), cs, res, args[0].get_ident(), args[1].get_strr(),
args[2].get_code(), false args[2].get_code(), false
); );
}); });
cs.add_command("listfilter", "rse", [&cs](TvalRange args) { cs.add_command("listfilter", "rse", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
auto body = args[2].get_code(); auto body = args[2].get_code();
if (!id->is_alias()) if (!id->is_alias())
@ -452,10 +454,10 @@ found:
id->pop_arg(); id->pop_arg();
r.push('\0'); r.push('\0');
ostd::Size len = r.size() - 1; ostd::Size len = r.size() - 1;
cs.result->set_mstr(ostd::CharRange(r.disown(), len)); res.set_mstr(ostd::CharRange(r.disown(), len));
}); });
cs.add_command("listcount", "rse", [&cs](TvalRange args) { cs.add_command("listcount", "rse", [&cs](TvalRange args, TaggedValue &res) {
Ident *id = args[0].get_ident(); Ident *id = args[0].get_ident();
auto body = args[2].get_code(); auto body = args[2].get_code();
if (!id->is_alias()) if (!id->is_alias())
@ -470,10 +472,10 @@ found:
} }
if (n >= 0) if (n >= 0)
id->pop_arg(); id->pop_arg();
cs.result->set_int(r); res.set_int(r);
}); });
cs.add_command("prettylist", "ss", [&cs](TvalRange args) { cs.add_command("prettylist", "ss", [&cs](TvalRange args, TaggedValue &res) {
ostd::Vector<char> buf; ostd::Vector<char> buf;
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange conj = args[1].get_strr(); ostd::ConstCharRange conj = args[1].get_strr();
@ -502,17 +504,17 @@ found:
} }
buf.push('\0'); buf.push('\0');
ostd::Size slen = buf.size() - 1; ostd::Size slen = buf.size() - 1;
cs.result->set_mstr(ostd::CharRange(buf.disown(), slen)); res.set_mstr(ostd::CharRange(buf.disown(), slen));
}); });
cs.add_command("indexof", "ss", [&cs](TvalRange args) { cs.add_command("indexof", "ss", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int( res.set_int(
cs_list_includes(args[0].get_strr(), args[1].get_strr()) cs_list_includes(args[0].get_strr(), args[1].get_strr())
); );
}); });
#define CS_CMD_LIST_MERGE(name, init, iter, filter, dir) \ #define CS_CMD_LIST_MERGE(name, init, iter, filter, dir) \
cs.add_command(name, "ss", [&cs](TvalRange args) { \ cs.add_command(name, "ss", [&cs](TvalRange args, TaggedValue &res) { \
ostd::ConstCharRange list = args[0].get_strr(); \ ostd::ConstCharRange list = args[0].get_strr(); \
ostd::ConstCharRange elems = args[1].get_strr(); \ ostd::ConstCharRange elems = args[1].get_strr(); \
ostd::Vector<char> buf; \ ostd::Vector<char> buf; \
@ -526,7 +528,7 @@ found:
} \ } \
buf.push('\0'); \ buf.push('\0'); \
ostd::Size len = buf.size() - 1; \ ostd::Size len = buf.size() - 1; \
cs.result->set_mstr(ostd::CharRange(buf.disown(), len)); \ res.set_mstr(ostd::CharRange(buf.disown(), len)); \
}); });
CS_CMD_LIST_MERGE("listdel", {}, list, elems, <); CS_CMD_LIST_MERGE("listdel", {}, list, elems, <);
@ -536,7 +538,7 @@ found:
#undef CS_CMD_LIST_MERGE #undef CS_CMD_LIST_MERGE
cs.add_command("listsplice", "ssii", [&cs](TvalRange args) { cs.add_command("listsplice", "ssii", [&cs](TvalRange args, TaggedValue &res) {
int offset = ostd::max(args[2].get_int(), 0); int offset = ostd::max(args[2].get_int(), 0);
int len = ostd::max(args[3].get_int(), 0); int len = ostd::max(args[3].get_int(), 0);
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
@ -571,7 +573,7 @@ found:
} }
buf.push('\0'); buf.push('\0');
ostd::Size slen = buf.size() - 1; ostd::Size slen = buf.size() - 1;
cs.result->set_mstr(ostd::CharRange(buf.disown(), slen)); res.set_mstr(ostd::CharRange(buf.disown(), slen));
}); });
cs_init_lib_list_sort(cs); cs_init_lib_list_sort(cs);
@ -605,7 +607,7 @@ struct ListSortFun {
}; };
static void cs_list_sort( static void cs_list_sort(
CsState &cs, ostd::ConstCharRange list, Ident *x, Ident *y, CsState &cs, TaggedValue &res, ostd::ConstCharRange list, Ident *x, Ident *y,
Bytecode *body, Bytecode *unique Bytecode *body, Bytecode *unique
) { ) {
if (x == y || !x->is_alias() || !y->is_alias()) if (x == y || !x->is_alias() || !y->is_alias())
@ -624,7 +626,7 @@ static void cs_list_sort(
} }
if (items.empty()) { if (items.empty()) {
cs.result->set_mstr(cstr); res.set_mstr(cstr);
return; return;
} }
@ -693,20 +695,20 @@ static void cs_list_sort(
} }
sorted[offset] = '\0'; sorted[offset] = '\0';
cs.result->set_mstr(sorted); res.set_mstr(sorted);
} }
static void cs_init_lib_list_sort(CsState &cs) { static void cs_init_lib_list_sort(CsState &cs) {
cs.add_command("sortlist", "srree", [&cs](TvalRange args) { cs.add_command("sortlist", "srree", [&cs](TvalRange args, TaggedValue &res) {
cs_list_sort( cs_list_sort(
cs, args[0].get_strr(), args[1].get_ident(), args[2].get_ident(), cs, res, args[0].get_strr(), args[1].get_ident(),
args[3].get_code(), args[4].get_code() args[2].get_ident(), args[3].get_code(), args[4].get_code()
); );
}); });
cs.add_command("uniquelist", "srre", [&cs](TvalRange args) { cs.add_command("uniquelist", "srre", [&cs](TvalRange args, TaggedValue &res) {
cs_list_sort( cs_list_sort(
cs, args[0].get_strr(), args[1].get_ident(), args[2].get_ident(), cs, res, args[0].get_strr(), args[1].get_ident(),
nullptr, args[3].get_code() args[2].get_ident(), nullptr, args[3].get_code()
); );
}); });
} }

View File

@ -6,51 +6,51 @@ static constexpr float PI = 3.14159265358979f;
static constexpr float RAD = PI / 180.0f; static constexpr float RAD = PI / 180.0f;
void cs_init_lib_math(CsState &cs) { void cs_init_lib_math(CsState &cs) {
cs.add_command("sin", "f", [&cs](TvalRange args) { cs.add_command("sin", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(sin(args[0].get_float() * RAD)); res.set_float(sin(args[0].get_float() * RAD));
}); });
cs.add_command("cos", "f", [&cs](TvalRange args) { cs.add_command("cos", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(cos(args[0].get_float() * RAD)); res.set_float(cos(args[0].get_float() * RAD));
}); });
cs.add_command("tan", "f", [&cs](TvalRange args) { cs.add_command("tan", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(tan(args[0].get_float() * RAD)); res.set_float(tan(args[0].get_float() * RAD));
}); });
cs.add_command("asin", "f", [&cs](TvalRange args) { cs.add_command("asin", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(asin(args[0].get_float()) / RAD); res.set_float(asin(args[0].get_float()) / RAD);
}); });
cs.add_command("acos", "f", [&cs](TvalRange args) { cs.add_command("acos", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(acos(args[0].get_float()) / RAD); res.set_float(acos(args[0].get_float()) / RAD);
}); });
cs.add_command("atan", "f", [&cs](TvalRange args) { cs.add_command("atan", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(atan(args[0].get_float()) / RAD); res.set_float(atan(args[0].get_float()) / RAD);
}); });
cs.add_command("atan2", "ff", [&cs](TvalRange args) { cs.add_command("atan2", "ff", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(atan2(args[0].get_float(), args[1].get_float()) / RAD); res.set_float(atan2(args[0].get_float(), args[1].get_float()) / RAD);
}); });
cs.add_command("sqrt", "f", [&cs](TvalRange args) { cs.add_command("sqrt", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(sqrt(args[0].get_float())); res.set_float(sqrt(args[0].get_float()));
}); });
cs.add_command("loge", "f", [&cs](TvalRange args) { cs.add_command("loge", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(log(args[0].get_float())); res.set_float(log(args[0].get_float()));
}); });
cs.add_command("log2", "f", [&cs](TvalRange args) { cs.add_command("log2", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(log(args[0].get_float()) / M_LN2); res.set_float(log(args[0].get_float()) / M_LN2);
}); });
cs.add_command("log10", "f", [&cs](TvalRange args) { cs.add_command("log10", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(log10(args[0].get_float())); res.set_float(log10(args[0].get_float()));
}); });
cs.add_command("exp", "f", [&cs](TvalRange args) { cs.add_command("exp", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(exp(args[0].get_float())); res.set_float(exp(args[0].get_float()));
}); });
#define CS_CMD_MIN_MAX(name, fmt, type, op) \ #define CS_CMD_MIN_MAX(name, fmt, type, op) \
cs.add_command(#name, #fmt "1V", [&cs](TvalRange args) { \ cs.add_command(#name, #fmt "1V", [&cs](TvalRange args, TaggedValue &res) { \
type v = !args.empty() ? args[0].fmt : 0; \ type v = !args.empty() ? args[0].fmt : 0; \
for (ostd::Size i = 1; i < args.size(); ++i) v = op(v, args[i].fmt); \ for (ostd::Size i = 1; i < args.size(); ++i) v = op(v, args[i].fmt); \
cs.result->set_##type(v); \ res.set_##type(v); \
}) })
CS_CMD_MIN_MAX(min, i, int, ostd::min); CS_CMD_MIN_MAX(min, i, int, ostd::min);
@ -60,21 +60,21 @@ void cs_init_lib_math(CsState &cs) {
#undef CS_CMD_MIN_MAX #undef CS_CMD_MIN_MAX
cs.add_command("abs", "i", [&cs](TvalRange args) { cs.add_command("abs", "i", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(abs(args[0].get_int())); res.set_int(abs(args[0].get_int()));
}); });
cs.add_command("absf", "f", [&cs](TvalRange args) { cs.add_command("absf", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(fabs(args[0].get_float())); res.set_float(fabs(args[0].get_float()));
}); });
cs.add_command("floor", "f", [&cs](TvalRange args) { cs.add_command("floor", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(floor(args[0].get_float())); res.set_float(floor(args[0].get_float()));
}); });
cs.add_command("ceil", "f", [&cs](TvalRange args) { cs.add_command("ceil", "f", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_float(ceil(args[0].get_float())); res.set_float(ceil(args[0].get_float()));
}); });
cs.add_command("round", "ff", [&cs](TvalRange args) { cs.add_command("round", "ff", [&cs](TvalRange args, TaggedValue &res) {
double step = args[1].get_float(); double step = args[1].get_float();
double r = args[0].get_float(); double r = args[0].get_float();
if (step > 0) { if (step > 0) {
@ -83,11 +83,11 @@ void cs_init_lib_math(CsState &cs) {
} else { } else {
r = (r < 0) ? ceil(r - 0.5) : floor(r + 0.5); r = (r < 0) ? ceil(r - 0.5) : floor(r + 0.5);
} }
cs.result->set_float(float(r)); res.set_float(float(r));
}); });
#define CS_CMD_MATH(name, fmt, type, op, initval, unaryop) \ #define CS_CMD_MATH(name, fmt, type, op, initval, unaryop) \
cs.add_command(name, #fmt "1V", [&cs](TvalRange args) { \ cs.add_command(name, #fmt "1V", [&cs](TvalRange args, TaggedValue &res) { \
type val; \ type val; \
if (args.size() >= 2) { \ if (args.size() >= 2) { \
val = args[0].fmt; \ val = args[0].fmt; \
@ -101,7 +101,7 @@ void cs_init_lib_math(CsState &cs) {
val = (args.size() > 0) ? args[0].fmt : initval; \ val = (args.size() > 0) ? args[0].fmt : initval; \
unaryop; \ unaryop; \
} \ } \
cs.result->set_##type(val); \ res.set_##type(val); \
}); });
#define CS_CMD_MATHIN(name, op, initval, unaryop) \ #define CS_CMD_MATHIN(name, op, initval, unaryop) \
@ -156,7 +156,7 @@ void cs_init_lib_math(CsState &cs) {
#undef CS_CMD_MATH #undef CS_CMD_MATH
#define CS_CMD_CMP(name, fmt, type, op) \ #define CS_CMD_CMP(name, fmt, type, op) \
cs.add_command(name, #fmt "1V", [&cs](TvalRange args) { \ cs.add_command(name, #fmt "1V", [&cs](TvalRange args, TaggedValue &res) { \
bool val; \ bool val; \
if (args.size() >= 2) { \ if (args.size() >= 2) { \
val = args[0].fmt op args[1].fmt; \ val = args[0].fmt op args[1].fmt; \
@ -164,7 +164,7 @@ void cs_init_lib_math(CsState &cs) {
val = args[i-1].fmt op args[i].fmt; \ val = args[i-1].fmt op args[i].fmt; \
} else \ } else \
val = ((args.size() > 0) ? args[0].fmt : 0) op 0; \ val = ((args.size() > 0) ? args[0].fmt : 0) op 0; \
cs.result->set_int(int(val)); \ res.set_int(int(val)); \
}) })
#define CS_CMD_CMPIN(name, op) CS_CMD_CMP(#name, i, int, op) #define CS_CMD_CMPIN(name, op) CS_CMD_CMP(#name, i, int, op)

View File

@ -3,89 +3,89 @@
namespace cscript { namespace cscript {
void cs_init_lib_string(CsState &cs) { void cs_init_lib_string(CsState &cs) {
cs.add_command("strstr", "ss", [&cs](TvalRange args) { cs.add_command("strstr", "ss", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange a = args[0].get_strr(), b = args[1].get_strr(); ostd::ConstCharRange a = args[0].get_strr(), b = args[1].get_strr();
ostd::ConstCharRange s = a; ostd::ConstCharRange s = a;
for (int i = 0; b.size() <= s.size(); ++i) { for (int i = 0; b.size() <= s.size(); ++i) {
if (b == s.slice(0, b.size())) { if (b == s.slice(0, b.size())) {
cs.result->set_int(i); res.set_int(i);
return; return;
} }
s.pop_front(); s.pop_front();
} }
cs.result->set_int(-1); res.set_int(-1);
}); });
cs.add_command("strlen", "s", [&cs](TvalRange args) { cs.add_command("strlen", "s", [&cs](TvalRange args, TaggedValue &res) {
cs.result->set_int(int(args[0].get_strr().size())); res.set_int(int(args[0].get_strr().size()));
}); });
cs.add_command("strcode", "si", [&cs](TvalRange args) { cs.add_command("strcode", "si", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange str = args[0].get_strr(); ostd::ConstCharRange str = args[0].get_strr();
int i = args[1].get_int(); int i = args[1].get_int();
if (i >= int(str.size())) { if (i >= int(str.size())) {
cs.result->set_int(0); res.set_int(0);
} else { } else {
cs.result->set_int(ostd::byte(str[i])); res.set_int(ostd::byte(str[i]));
} }
}); });
cs.add_command("codestr", "i", [&cs](TvalRange args) { cs.add_command("codestr", "i", [&cs](TvalRange args, TaggedValue &res) {
char *s = new char[2]; char *s = new char[2];
s[0] = char(args[0].get_int()); s[0] = char(args[0].get_int());
s[1] = '\0'; s[1] = '\0';
cs.result->set_mstr(s); res.set_mstr(s);
}); });
cs.add_command("strlower", "s", [&cs](TvalRange args) { cs.add_command("strlower", "s", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
char *buf = new char[s.size() + 1]; char *buf = new char[s.size() + 1];
for (auto i: ostd::range(s.size())) for (auto i: ostd::range(s.size()))
buf[i] = tolower(s[i]); buf[i] = tolower(s[i]);
buf[s.size()] = '\0'; buf[s.size()] = '\0';
cs.result->set_mstr(ostd::CharRange(buf, s.size())); res.set_mstr(ostd::CharRange(buf, s.size()));
}); });
cs.add_command("strupper", "s", [&cs](TvalRange args) { cs.add_command("strupper", "s", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
char *buf = new char[s.size() + 1]; char *buf = new char[s.size() + 1];
for (auto i: ostd::range(s.size())) for (auto i: ostd::range(s.size()))
buf[i] = toupper(s[i]); buf[i] = toupper(s[i]);
buf[s.size()] = '\0'; buf[s.size()] = '\0';
cs.result->set_mstr(ostd::CharRange(buf, s.size())); res.set_mstr(ostd::CharRange(buf, s.size()));
}); });
cs.add_command("escape", "s", [&cs](TvalRange args) { cs.add_command("escape", "s", [&cs](TvalRange args, TaggedValue &res) {
auto x = ostd::appender<ostd::String>(); auto x = ostd::appender<ostd::String>();
util::escape_string(x, args[0].get_strr()); util::escape_string(x, args[0].get_strr());
ostd::Size len = x.size(); ostd::Size len = x.size();
cs.result->set_mstr(ostd::CharRange(x.get().disown(), len)); res.set_mstr(ostd::CharRange(x.get().disown(), len));
}); });
cs.add_command("unescape", "s", [&cs](TvalRange args) { cs.add_command("unescape", "s", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
char *buf = new char[s.size() + 1]; char *buf = new char[s.size() + 1];
auto writer = ostd::CharRange(buf, s.size() + 1); auto writer = ostd::CharRange(buf, s.size() + 1);
util::unescape_string(writer, s); util::unescape_string(writer, s);
writer.put('\0'); writer.put('\0');
cs.result->set_mstr(ostd::CharRange(buf, s.size())); res.set_mstr(ostd::CharRange(buf, s.size()));
}); });
cs.add_command("concat", "V", [&cs](TvalRange args) { cs.add_command("concat", "V", [&cs](TvalRange args, TaggedValue &res) {
auto s = ostd::appender<ostd::String>(); auto s = ostd::appender<ostd::String>();
cscript::util::tvals_concat(s, args, " "); cscript::util::tvals_concat(s, args, " ");
cs.result->set_mstr(s.get().iter()); res.set_mstr(s.get().iter());
s.get().disown(); s.get().disown();
}); });
cs.add_command("concatword", "V", [&cs](TvalRange args) { cs.add_command("concatword", "V", [&cs](TvalRange args, TaggedValue &res) {
auto s = ostd::appender<ostd::String>(); auto s = ostd::appender<ostd::String>();
cscript::util::tvals_concat(s, args); cscript::util::tvals_concat(s, args);
cs.result->set_mstr(s.get().iter()); res.set_mstr(s.get().iter());
s.get().disown(); s.get().disown();
}); });
cs.add_command("format", "V", [&cs](TvalRange args) { cs.add_command("format", "V", [&cs](TvalRange args, TaggedValue &res) {
if (args.empty()) if (args.empty())
return; return;
ostd::Vector<char> s; ostd::Vector<char> s;
@ -107,23 +107,23 @@ void cs_init_lib_string(CsState &cs) {
} }
s.push('\0'); s.push('\0');
ostd::Size len = s.size() - 1; ostd::Size len = s.size() - 1;
cs.result->set_mstr(ostd::CharRange(s.disown(), len)); res.set_mstr(ostd::CharRange(s.disown(), len));
}); });
cs.add_command("tohex", "ii", [&cs](TvalRange args) { cs.add_command("tohex", "ii", [&cs](TvalRange args, TaggedValue &res) {
auto r = ostd::appender<ostd::Vector<char>>(); auto r = ostd::appender<ostd::Vector<char>>();
ostd::format(r, "0x%.*X", ostd::max(args[1].get_int(), 1), args[0].get_int()); ostd::format(r, "0x%.*X", ostd::max(args[1].get_int(), 1), args[0].get_int());
r.put('\0'); r.put('\0');
ostd::Size len = r.size() - 1; ostd::Size len = r.size() - 1;
cs.result->set_mstr(ostd::CharRange(r.get().disown(), len)); res.set_mstr(ostd::CharRange(r.get().disown(), len));
}); });
cs.add_command("substr", "siiN", [&cs](TvalRange args) { cs.add_command("substr", "siiN", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
int start = args[1].get_int(), count = args[2].get_int(); int start = args[1].get_int(), count = args[2].get_int();
int numargs = args[3].get_int(); int numargs = args[3].get_int();
int len = int(s.size()), offset = ostd::clamp(start, 0, len); int len = int(s.size()), offset = ostd::clamp(start, 0, len);
cs.result->set_str(ostd::ConstCharRange( res.set_str(ostd::ConstCharRange(
&s[offset], &s[offset],
(numargs >= 3) ? ostd::clamp(count, 0, len - offset) (numargs >= 3) ? ostd::clamp(count, 0, len - offset)
: (len - offset) : (len - offset)
@ -131,7 +131,7 @@ void cs_init_lib_string(CsState &cs) {
}); });
#define CS_CMD_CMPS(name, op) \ #define CS_CMD_CMPS(name, op) \
cs.add_command(#name, "s1V", [&cs](TvalRange args) { \ cs.add_command(#name, "s1V", [&cs](TvalRange args, TaggedValue &res) { \
bool val; \ bool val; \
if (args.size() >= 2) { \ if (args.size() >= 2) { \
val = strcmp(args[0].s, args[1].s) op 0; \ val = strcmp(args[0].s, args[1].s) op 0; \
@ -139,7 +139,7 @@ void cs_init_lib_string(CsState &cs) {
val = strcmp(args[i-1].s, args[i].s) op 0; \ val = strcmp(args[i-1].s, args[i].s) op 0; \
} else \ } else \
val = (!args.empty() ? args[0].s[0] : 0) op 0; \ val = (!args.empty() ? args[0].s[0] : 0) op 0; \
cs.result->set_int(int(val)); \ res.set_int(int(val)); \
}) })
CS_CMD_CMPS(strcmp, ==); CS_CMD_CMPS(strcmp, ==);
@ -152,7 +152,7 @@ void cs_init_lib_string(CsState &cs) {
#undef CS_CMD_CMPS #undef CS_CMD_CMPS
cs.add_command("strreplace", "ssss", [&cs](TvalRange args) { cs.add_command("strreplace", "ssss", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange oldval = args[1].get_strr(), ostd::ConstCharRange oldval = args[1].get_strr(),
newval = args[2].get_strr(), newval = args[2].get_strr(),
@ -162,7 +162,7 @@ void cs_init_lib_string(CsState &cs) {
} }
ostd::Vector<char> buf; ostd::Vector<char> buf;
if (!oldval.size()) { if (!oldval.size()) {
cs.result->set_str(s); res.set_str(s);
return; return;
} }
for (ostd::Size i = 0;; ++i) { for (ostd::Size i = 0;; ++i) {
@ -190,13 +190,13 @@ void cs_init_lib_string(CsState &cs) {
} }
buf.push('\0'); buf.push('\0');
ostd::Size len = buf.size() - 1; ostd::Size len = buf.size() - 1;
cs.result->set_mstr(ostd::CharRange(buf.disown(), len)); res.set_mstr(ostd::CharRange(buf.disown(), len));
return; return;
} }
} }
}); });
cs.add_command("strsplice", "ssii", [&cs](TvalRange args) { cs.add_command("strsplice", "ssii", [&cs](TvalRange args, TaggedValue &res) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange vals = args[1].get_strr(); ostd::ConstCharRange vals = args[1].get_strr();
int skip = args[2].get_int(), int skip = args[2].get_int(),
@ -213,7 +213,7 @@ void cs_init_lib_string(CsState &cs) {
if (offset + len < slen) if (offset + len < slen)
memcpy(&p[offset + vlen], &s[offset + len], slen - (offset + len)); memcpy(&p[offset + vlen], &s[offset + len], slen - (offset + len));
p[slen - len + vlen] = '\0'; p[slen - len + vlen] = '\0';
cs.result->set_mstr(ostd::CharRange(p, slen - len + vlen)); res.set_mstr(ostd::CharRange(p, slen - len + vlen));
}); });
} }