pass result to command callbacks instead of setting it via struct
parent
a8b6843a88
commit
97c63951e5
198
cubescript.cc
198
cubescript.cc
|
@ -181,7 +181,7 @@ static TaggedValue no_ret = null_value;
|
|||
|
||||
void cs_init_lib_base(CsState &cs);
|
||||
|
||||
CsState::CsState(): result(&no_ret) {
|
||||
CsState::CsState(): p_result(&no_ret) {
|
||||
noalias.id = nullptr;
|
||||
noalias.next = nullptr;
|
||||
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), " ");
|
||||
TaggedValue tv;
|
||||
tv.set_mstr(buf.get().iter());
|
||||
id->cb_cftv(TvalRange(&tv, 1));
|
||||
id->cb_cftv(TvalRange(&tv, 1), *cs.p_result);
|
||||
goto cleanup;
|
||||
}
|
||||
case 'V':
|
||||
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;
|
||||
case '1':
|
||||
case '2':
|
||||
|
@ -2623,7 +2623,7 @@ static inline void callcommand(CsState &cs, Ident *id, TaggedValue *args, int nu
|
|||
break;
|
||||
}
|
||||
++i;
|
||||
id->cb_cftv(TvalRange(args, i));
|
||||
id->cb_cftv(TvalRange(args, i), *cs.p_result);
|
||||
cleanup:
|
||||
for (ostd::Size k = 0; k < ostd::Size(i); ++k) args[k].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;
|
||||
int numargs = 0;
|
||||
TaggedValue args[MaxArguments + MaxResults], *prevret = cs.result;
|
||||
cs.result = &result;
|
||||
TaggedValue args[MaxArguments + MaxResults], *prevret = cs.p_result;
|
||||
cs.p_result = &result;
|
||||
for (;;) {
|
||||
ostd::Uint32 op = *code++;
|
||||
switch (op & 0xFF) {
|
||||
|
@ -2972,11 +2972,11 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
|
|||
{ \
|
||||
arg.cleanup(); \
|
||||
arg.set_null(); \
|
||||
cs.result = &arg; \
|
||||
cs.p_result = &arg; \
|
||||
TaggedValue buf[MaxArguments]; \
|
||||
callcommand(cs, id, buf, 0, true); \
|
||||
force_arg(arg, op&CODE_RET_MASK); \
|
||||
cs.result = &result; \
|
||||
cs.p_result = &result; \
|
||||
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];
|
||||
int offset = numargs - id->numargs;
|
||||
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);
|
||||
free_args(args, numargs, offset);
|
||||
continue;
|
||||
|
@ -3133,7 +3133,7 @@ static ostd::Uint32 const *runcode(CsState &cs, ostd::Uint32 const *code, Tagged
|
|||
Ident *id = cs.identmap[op >> 13];
|
||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
||||
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);
|
||||
free_args(args, numargs, offset);
|
||||
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), " ");
|
||||
TaggedValue tv;
|
||||
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);
|
||||
free_args(args, numargs, offset);
|
||||
|
@ -3327,7 +3327,7 @@ noid:
|
|||
}
|
||||
}
|
||||
exit:
|
||||
cs.result = prevret;
|
||||
cs.p_result = prevret;
|
||||
--rundepth;
|
||||
return code;
|
||||
}
|
||||
|
@ -3351,8 +3351,8 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
|||
int nargs = int(args.size());
|
||||
ret.set_null();
|
||||
++rundepth;
|
||||
TaggedValue *prevret = result;
|
||||
result = &ret;
|
||||
TaggedValue *prevret = p_result;
|
||||
p_result = &ret;
|
||||
if (rundepth > MaxRunDepth) cs_debug_code(*this, "exceeded recursion limit");
|
||||
else if (id) switch (id->type) {
|
||||
default:
|
||||
|
@ -3393,7 +3393,7 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
|||
break;
|
||||
}
|
||||
free_args(args.data(), nargs, 0);
|
||||
result = prevret;
|
||||
p_result = prevret;
|
||||
--rundepth;
|
||||
}
|
||||
|
||||
|
@ -3520,18 +3520,18 @@ bool CsState::run_file(ostd::ConstCharRange fname) {
|
|||
}
|
||||
|
||||
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();
|
||||
bool ret = cs.run_file(file);
|
||||
if (!ret) {
|
||||
if (args[1].get_int())
|
||||
ostd::err.writefln("could not run file \"%s\"", file);
|
||||
cs.result->set_int(0);
|
||||
res.set_int(0);
|
||||
} 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());
|
||||
});
|
||||
}
|
||||
|
@ -3568,8 +3568,10 @@ static inline void cs_do_loop(CsState &cs, Ident &id, int offset, int n,
|
|||
id.pop_arg();
|
||||
}
|
||||
|
||||
static inline void cs_loop_conc(CsState &cs, Ident &id, int offset, int n,
|
||||
int step, Bytecode *body, bool space) {
|
||||
static inline void cs_loop_conc(
|
||||
CsState &cs, TaggedValue &res, Ident &id, int offset, int n,
|
||||
int step, Bytecode *body, bool space
|
||||
) {
|
||||
if (n <= 0 || id.type != ID_ALIAS)
|
||||
return;
|
||||
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();
|
||||
s.push('\0');
|
||||
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) {
|
||||
cs_add_command(cs, "do", "e", [&cs](TvalRange args) {
|
||||
cs.run_ret(args[0].get_code());
|
||||
cs_add_command(cs, "do", "e", [&cs](TvalRange args, TaggedValue &res) {
|
||||
cs.run_ret(args[0].get_code(), res);
|
||||
}, 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)
|
||||
cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code()); });
|
||||
cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code(), res); });
|
||||
else
|
||||
cs.run_ret(args[0].get_code());
|
||||
cs.run_ret(args[0].get_code(), res);
|
||||
}, ID_DOARGS);
|
||||
|
||||
cs_add_command(cs, "if", "tee", [&cs](TvalRange args) {
|
||||
cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code());
|
||||
cs_add_command(cs, "if", "tee", [&cs](TvalRange args, TaggedValue &res) {
|
||||
cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
|
||||
}, 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];
|
||||
*cs.result = v;
|
||||
res = v;
|
||||
v.set_null();
|
||||
}, ID_RESULT);
|
||||
|
||||
cs_add_command(cs, "!", "t", [&cs](TvalRange args) {
|
||||
cs.result->set_int(!args[0].get_bool());
|
||||
cs_add_command(cs, "!", "t", [](TvalRange args, TaggedValue &res) {
|
||||
res.set_int(!args[0].get_bool());
|
||||
}, ID_NOT);
|
||||
|
||||
cs_add_command(cs, "&&", "E1V", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "&&", "E1V", [&cs](TvalRange args, TaggedValue &res) {
|
||||
if (args.empty())
|
||||
cs.result->set_int(1);
|
||||
res.set_int(1);
|
||||
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)
|
||||
cs.run_ret(args[i].code);
|
||||
cs.run_ret(args[i].code, res);
|
||||
else
|
||||
*cs.result = args[i];
|
||||
if (!cs.result->get_bool()) break;
|
||||
res = args[i];
|
||||
if (!res.get_bool()) break;
|
||||
}
|
||||
}, ID_AND);
|
||||
|
||||
cs_add_command(cs, "||", "E1V", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "||", "E1V", [&cs](TvalRange args, TaggedValue &res) {
|
||||
if (args.empty())
|
||||
cs.result->set_int(0);
|
||||
res.set_int(0);
|
||||
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)
|
||||
cs.run_ret(args[i].code);
|
||||
cs.run_ret(args[i].code, res);
|
||||
else
|
||||
*cs.result = args[i];
|
||||
if (cs.result->get_bool()) break;
|
||||
res = args[i];
|
||||
if (res.get_bool()) break;
|
||||
}
|
||||
}, ID_OR);
|
||||
|
||||
cs_add_command(cs, "?", "tTT", [&cs](TvalRange args) {
|
||||
cs.result->set(args[0].get_bool() ? args[1] : args[2]);
|
||||
cs_add_command(cs, "?", "tTT", [](TvalRange args, TaggedValue &res) {
|
||||
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) {
|
||||
if ((i + 1) < args.size()) {
|
||||
if (cs.run_bool(args[i].code)) {
|
||||
cs.run_ret(args[i + 1].code);
|
||||
cs.run_ret(args[i + 1].code, res);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cs.run_ret(args[i].code);
|
||||
cs.run_ret(args[i].code, res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#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); \
|
||||
ostd::Size i; \
|
||||
for (i = 1; (i + 1) < args.size(); i += 2) { \
|
||||
if (compare) { \
|
||||
cs.run_ret(args[i + 1].code); \
|
||||
cs.run_ret(args[i + 1].code, res); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
@ -3685,7 +3687,7 @@ void cs_init_lib_base(CsState &cs) {
|
|||
|
||||
#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();
|
||||
TaggedValue &v = args[1];
|
||||
Bytecode *code = args[2].get_code();
|
||||
|
@ -3695,178 +3697,178 @@ void cs_init_lib_base(CsState &cs) {
|
|||
IdentStack stack;
|
||||
id->push_arg(v, stack);
|
||||
v.set_null();
|
||||
cs.run_ret(code);
|
||||
cs.run_ret(code, res);
|
||||
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, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr,
|
||||
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, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
||||
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, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(),
|
||||
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, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
||||
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, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
||||
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, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
||||
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, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
|
||||
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, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
||||
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();
|
||||
while (cs.run_bool(cond)) {
|
||||
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, *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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcat+", "riie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcat+", "riie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcat*", "riie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcat*", "riie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcat+*", "riiie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcat+*", "riiie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcatword", "rie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcatword", "rie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcatword+", "riie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcatword+", "riie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcatword*", "riie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcatword*", "riie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
cs_add_command(cs, "nodebug", "e", [&cs](TvalRange args) {
|
||||
cs_add_command(cs, "nodebug", "e", [&cs](TvalRange args, TaggedValue &res) {
|
||||
++cs.nodebug;
|
||||
cs.run_ret(args[0].get_code());
|
||||
cs.run_ret(args[0].get_code(), res);
|
||||
--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();
|
||||
if (id->type != ID_ALIAS || id->index < MaxArguments) return;
|
||||
IdentStack stack;
|
||||
TaggedValue &v = args[1];
|
||||
id->push_arg(v, stack);
|
||||
v.set_null();
|
||||
cs.run_ret(args[2].get_code());
|
||||
cs.run_ret(args[2].get_code(), res);
|
||||
id->pop_arg();
|
||||
});
|
||||
|
||||
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);
|
||||
|
||||
cs_add_command(cs, "resetvar", "s", [&cs](TvalRange args) {
|
||||
cs.result->set_int(cs.reset_var(args[0].get_strr()));
|
||||
cs_add_command(cs, "resetvar", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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];
|
||||
cs.set_alias(args[0].get_strr(), v);
|
||||
v.set_null();
|
||||
});
|
||||
|
||||
cs_add_command(cs, "getvarmin", "s", [&cs](TvalRange args) {
|
||||
cs.result->set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0));
|
||||
cs_add_command(cs, "getvarmin", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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.result->set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0));
|
||||
cs_add_command(cs, "getvarmax", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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.result->set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f));
|
||||
cs_add_command(cs, "getfvarmin", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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.result->set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f));
|
||||
cs_add_command(cs, "getfvarmax", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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.result->set_int(cs.have_ident(args[0].get_strr()));
|
||||
cs_add_command(cs, "identexists", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_int(cs.have_ident(args[0].get_strr()));
|
||||
});
|
||||
|
||||
cs_add_command(cs, "getalias", "s", [&cs](TvalRange args) {
|
||||
cs.result->set_str(ostd::move(cs.get_alias(args[0].get_strr()).value_or("")));
|
||||
cs_add_command(cs, "getalias", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_str(ostd::move(cs.get_alias(args[0].get_strr()).value_or("")));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ union IdentValuePtr {
|
|||
struct CsState;
|
||||
|
||||
using VarCb = ostd::Function<void(Ident &)>;
|
||||
using CmdFunc = ostd::Function<void(TvalRange)>;
|
||||
using CmdFunc = ostd::Function<void(TvalRange, TaggedValue &)>;
|
||||
|
||||
enum class IdentType {
|
||||
unknown = -1,
|
||||
|
@ -333,7 +333,7 @@ struct OSTD_EXPORT CsState {
|
|||
ostd::Vector<Ident *> identmap;
|
||||
|
||||
Ident *dummy = nullptr;
|
||||
TaggedValue *result = nullptr;
|
||||
TaggedValue *p_result = nullptr;
|
||||
|
||||
IdentLink noalias;
|
||||
IdentLink *stack = &noalias;
|
||||
|
@ -397,18 +397,6 @@ struct OSTD_EXPORT CsState {
|
|||
void run_ret(ostd::ConstCharRange code, 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);
|
||||
|
||||
void set_alias(ostd::ConstCharRange name, TaggedValue &v);
|
||||
|
|
100
lib_list.cc
100
lib_list.cc
|
@ -174,8 +174,10 @@ static inline void cs_set_iter(Ident &id, char *val, IdentStack &stack) {
|
|||
id.push_arg(v, stack);
|
||||
}
|
||||
|
||||
static void cs_loop_list_conc(CsState &cs, Ident *id, ostd::ConstCharRange list,
|
||||
Bytecode const *body, bool space) {
|
||||
static void cs_loop_list_conc(
|
||||
CsState &cs, TaggedValue &res, Ident *id, ostd::ConstCharRange list,
|
||||
Bytecode const *body, bool space
|
||||
) {
|
||||
if (!id->is_alias())
|
||||
return;
|
||||
IdentStack stack;
|
||||
|
@ -196,7 +198,7 @@ static void cs_loop_list_conc(CsState &cs, Ident *id, ostd::ConstCharRange list,
|
|||
id->pop_arg();
|
||||
r.push('\0');
|
||||
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) {
|
||||
|
@ -212,11 +214,11 @@ int cs_list_includes(ostd::ConstCharRange list, ostd::ConstCharRange needle) {
|
|||
static void cs_init_lib_list_sort(CsState &cs);
|
||||
|
||||
void cs_init_lib_list(CsState &cs) {
|
||||
cs.add_command("listlen", "s", [&cs](TvalRange args) {
|
||||
cs.result->set_int(int(util::list_length(args[0].get_strr())));
|
||||
cs.add_command("listlen", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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())
|
||||
return;
|
||||
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 er = p.element().iter();
|
||||
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(),
|
||||
count = args[2].get_int(),
|
||||
numargs = args[2].get_int();
|
||||
|
@ -250,7 +252,7 @@ void cs_init_lib_list(CsState &cs) {
|
|||
if (len < 0) {
|
||||
if (offset > 0)
|
||||
p.skip();
|
||||
cs.result->set_str(p.input);
|
||||
res.set_str(p.input);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -259,14 +261,14 @@ void cs_init_lib_list(CsState &cs) {
|
|||
if (len > 0 && p.parse())
|
||||
while (--len > 0 && p.parse());
|
||||
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();
|
||||
auto body = args[2].get_code();
|
||||
if (!id->is_alias()) {
|
||||
cs.result->set_int(-1);
|
||||
res.set_int(-1);
|
||||
return;
|
||||
}
|
||||
IdentStack stack;
|
||||
|
@ -275,17 +277,17 @@ void cs_init_lib_list(CsState &cs) {
|
|||
++n;
|
||||
cs_set_iter(*id, cs_dup_ostr(p.item), stack);
|
||||
if (cs.run_bool(body)) {
|
||||
cs.result->set_int(n);
|
||||
res.set_int(n);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
cs.result->set_int(-1);
|
||||
res.set_int(-1);
|
||||
found:
|
||||
if (n >= 0)
|
||||
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();
|
||||
auto body = args[2].get_code();
|
||||
if (!id->is_alias())
|
||||
|
@ -300,7 +302,7 @@ found:
|
|||
auto elem = p.element();
|
||||
auto er = elem.iter();
|
||||
elem.disown();
|
||||
cs.result->set_mstr(er);
|
||||
res.set_mstr(er);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -312,12 +314,12 @@ found:
|
|||
});
|
||||
|
||||
#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(); \
|
||||
auto val = args[1].gmeth(); \
|
||||
for (ListParser p(args[0].get_strr()); p.parse(); ++n) { \
|
||||
if (cmp) { \
|
||||
cs.result->set_int(n); \
|
||||
res.set_int(n); \
|
||||
return; \
|
||||
} \
|
||||
for (int i = 0; i < skip; ++i) { \
|
||||
|
@ -327,7 +329,7 @@ found:
|
|||
} \
|
||||
} \
|
||||
notfound: \
|
||||
cs.result->set_int(-1); \
|
||||
res.set_int(-1); \
|
||||
});
|
||||
|
||||
CS_CMD_LIST_FIND("listfind=", "i", get_int, cs_parse_int(p.item) == val);
|
||||
|
@ -337,7 +339,7 @@ found:
|
|||
#undef CS_CMD_LIST_FIND
|
||||
|
||||
#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(); \
|
||||
for (ListParser p(args[0].get_strr()); p.parse();) { \
|
||||
if (cmp) { \
|
||||
|
@ -345,7 +347,7 @@ found:
|
|||
auto elem = p.element(); \
|
||||
auto er = elem.iter(); \
|
||||
elem.disown(); \
|
||||
cs.result->set_mstr(er); \
|
||||
res.set_mstr(er); \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
|
@ -360,7 +362,7 @@ found:
|
|||
|
||||
#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();
|
||||
auto body = args[2].get_code();
|
||||
if (!id->is_alias())
|
||||
|
@ -375,7 +377,7 @@ found:
|
|||
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();
|
||||
auto body = args[3].get_code();
|
||||
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 *id2 = args[1].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, args[0].get_ident(), args[1].get_strr(),
|
||||
cs, res, args[0].get_ident(), args[1].get_strr(),
|
||||
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, args[0].get_ident(), args[1].get_strr(),
|
||||
cs, res, args[0].get_ident(), args[1].get_strr(),
|
||||
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();
|
||||
auto body = args[2].get_code();
|
||||
if (!id->is_alias())
|
||||
|
@ -452,10 +454,10 @@ found:
|
|||
id->pop_arg();
|
||||
r.push('\0');
|
||||
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();
|
||||
auto body = args[2].get_code();
|
||||
if (!id->is_alias())
|
||||
|
@ -470,10 +472,10 @@ found:
|
|||
}
|
||||
if (n >= 0)
|
||||
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::ConstCharRange s = args[0].get_strr();
|
||||
ostd::ConstCharRange conj = args[1].get_strr();
|
||||
|
@ -502,17 +504,17 @@ found:
|
|||
}
|
||||
buf.push('\0');
|
||||
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.result->set_int(
|
||||
cs.add_command("indexof", "ss", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_int(
|
||||
cs_list_includes(args[0].get_strr(), args[1].get_strr())
|
||||
);
|
||||
});
|
||||
|
||||
#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 elems = args[1].get_strr(); \
|
||||
ostd::Vector<char> buf; \
|
||||
|
@ -526,7 +528,7 @@ found:
|
|||
} \
|
||||
buf.push('\0'); \
|
||||
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, <);
|
||||
|
@ -536,7 +538,7 @@ found:
|
|||
|
||||
#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 len = ostd::max(args[3].get_int(), 0);
|
||||
ostd::ConstCharRange s = args[0].get_strr();
|
||||
|
@ -571,7 +573,7 @@ found:
|
|||
}
|
||||
buf.push('\0');
|
||||
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);
|
||||
|
@ -605,7 +607,7 @@ struct ListSortFun {
|
|||
};
|
||||
|
||||
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
|
||||
) {
|
||||
if (x == y || !x->is_alias() || !y->is_alias())
|
||||
|
@ -624,7 +626,7 @@ static void cs_list_sort(
|
|||
}
|
||||
|
||||
if (items.empty()) {
|
||||
cs.result->set_mstr(cstr);
|
||||
res.set_mstr(cstr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -693,20 +695,20 @@ static void cs_list_sort(
|
|||
}
|
||||
sorted[offset] = '\0';
|
||||
|
||||
cs.result->set_mstr(sorted);
|
||||
res.set_mstr(sorted);
|
||||
}
|
||||
|
||||
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, args[0].get_strr(), args[1].get_ident(), args[2].get_ident(),
|
||||
args[3].get_code(), args[4].get_code()
|
||||
cs, res, args[0].get_strr(), args[1].get_ident(),
|
||||
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, args[0].get_strr(), args[1].get_ident(), args[2].get_ident(),
|
||||
nullptr, args[3].get_code()
|
||||
cs, res, args[0].get_strr(), args[1].get_ident(),
|
||||
args[2].get_ident(), nullptr, args[3].get_code()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
80
lib_math.cc
80
lib_math.cc
|
@ -6,51 +6,51 @@ static constexpr float PI = 3.14159265358979f;
|
|||
static constexpr float RAD = PI / 180.0f;
|
||||
|
||||
void cs_init_lib_math(CsState &cs) {
|
||||
cs.add_command("sin", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(sin(args[0].get_float() * RAD));
|
||||
cs.add_command("sin", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(sin(args[0].get_float() * RAD));
|
||||
});
|
||||
cs.add_command("cos", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(cos(args[0].get_float() * RAD));
|
||||
cs.add_command("cos", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(cos(args[0].get_float() * RAD));
|
||||
});
|
||||
cs.add_command("tan", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(tan(args[0].get_float() * RAD));
|
||||
cs.add_command("tan", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(tan(args[0].get_float() * RAD));
|
||||
});
|
||||
|
||||
cs.add_command("asin", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(asin(args[0].get_float()) / RAD);
|
||||
cs.add_command("asin", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(asin(args[0].get_float()) / RAD);
|
||||
});
|
||||
cs.add_command("acos", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(acos(args[0].get_float()) / RAD);
|
||||
cs.add_command("acos", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(acos(args[0].get_float()) / RAD);
|
||||
});
|
||||
cs.add_command("atan", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(atan(args[0].get_float()) / RAD);
|
||||
cs.add_command("atan", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(atan(args[0].get_float()) / RAD);
|
||||
});
|
||||
cs.add_command("atan2", "ff", [&cs](TvalRange args) {
|
||||
cs.result->set_float(atan2(args[0].get_float(), args[1].get_float()) / RAD);
|
||||
cs.add_command("atan2", "ff", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(atan2(args[0].get_float(), args[1].get_float()) / RAD);
|
||||
});
|
||||
|
||||
cs.add_command("sqrt", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(sqrt(args[0].get_float()));
|
||||
cs.add_command("sqrt", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(sqrt(args[0].get_float()));
|
||||
});
|
||||
cs.add_command("loge", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(log(args[0].get_float()));
|
||||
cs.add_command("loge", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(log(args[0].get_float()));
|
||||
});
|
||||
cs.add_command("log2", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(log(args[0].get_float()) / M_LN2);
|
||||
cs.add_command("log2", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(log(args[0].get_float()) / M_LN2);
|
||||
});
|
||||
cs.add_command("log10", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(log10(args[0].get_float()));
|
||||
cs.add_command("log10", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(log10(args[0].get_float()));
|
||||
});
|
||||
|
||||
cs.add_command("exp", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(exp(args[0].get_float()));
|
||||
cs.add_command("exp", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(exp(args[0].get_float()));
|
||||
});
|
||||
|
||||
#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; \
|
||||
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);
|
||||
|
@ -60,21 +60,21 @@ void cs_init_lib_math(CsState &cs) {
|
|||
|
||||
#undef CS_CMD_MIN_MAX
|
||||
|
||||
cs.add_command("abs", "i", [&cs](TvalRange args) {
|
||||
cs.result->set_int(abs(args[0].get_int()));
|
||||
cs.add_command("abs", "i", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_int(abs(args[0].get_int()));
|
||||
});
|
||||
cs.add_command("absf", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(fabs(args[0].get_float()));
|
||||
cs.add_command("absf", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(fabs(args[0].get_float()));
|
||||
});
|
||||
|
||||
cs.add_command("floor", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(floor(args[0].get_float()));
|
||||
cs.add_command("floor", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_float(floor(args[0].get_float()));
|
||||
});
|
||||
cs.add_command("ceil", "f", [&cs](TvalRange args) {
|
||||
cs.result->set_float(ceil(args[0].get_float()));
|
||||
cs.add_command("ceil", "f", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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 r = args[0].get_float();
|
||||
if (step > 0) {
|
||||
|
@ -83,11 +83,11 @@ void cs_init_lib_math(CsState &cs) {
|
|||
} else {
|
||||
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) \
|
||||
cs.add_command(name, #fmt "1V", [&cs](TvalRange args) { \
|
||||
cs.add_command(name, #fmt "1V", [&cs](TvalRange args, TaggedValue &res) { \
|
||||
type val; \
|
||||
if (args.size() >= 2) { \
|
||||
val = args[0].fmt; \
|
||||
|
@ -101,7 +101,7 @@ void cs_init_lib_math(CsState &cs) {
|
|||
val = (args.size() > 0) ? args[0].fmt : initval; \
|
||||
unaryop; \
|
||||
} \
|
||||
cs.result->set_##type(val); \
|
||||
res.set_##type(val); \
|
||||
});
|
||||
|
||||
#define CS_CMD_MATHIN(name, op, initval, unaryop) \
|
||||
|
@ -156,7 +156,7 @@ void cs_init_lib_math(CsState &cs) {
|
|||
#undef CS_CMD_MATH
|
||||
|
||||
#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; \
|
||||
if (args.size() >= 2) { \
|
||||
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; \
|
||||
} else \
|
||||
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)
|
||||
|
|
70
lib_str.cc
70
lib_str.cc
|
@ -3,89 +3,89 @@
|
|||
namespace cscript {
|
||||
|
||||
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 s = a;
|
||||
for (int i = 0; b.size() <= s.size(); ++i) {
|
||||
if (b == s.slice(0, b.size())) {
|
||||
cs.result->set_int(i);
|
||||
res.set_int(i);
|
||||
return;
|
||||
}
|
||||
s.pop_front();
|
||||
}
|
||||
cs.result->set_int(-1);
|
||||
res.set_int(-1);
|
||||
});
|
||||
|
||||
cs.add_command("strlen", "s", [&cs](TvalRange args) {
|
||||
cs.result->set_int(int(args[0].get_strr().size()));
|
||||
cs.add_command("strlen", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
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();
|
||||
int i = args[1].get_int();
|
||||
if (i >= int(str.size())) {
|
||||
cs.result->set_int(0);
|
||||
res.set_int(0);
|
||||
} 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];
|
||||
s[0] = char(args[0].get_int());
|
||||
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();
|
||||
char *buf = new char[s.size() + 1];
|
||||
for (auto i: ostd::range(s.size()))
|
||||
buf[i] = tolower(s[i]);
|
||||
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();
|
||||
char *buf = new char[s.size() + 1];
|
||||
for (auto i: ostd::range(s.size()))
|
||||
buf[i] = toupper(s[i]);
|
||||
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>();
|
||||
util::escape_string(x, args[0].get_strr());
|
||||
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();
|
||||
char *buf = new char[s.size() + 1];
|
||||
auto writer = ostd::CharRange(buf, s.size() + 1);
|
||||
util::unescape_string(writer, s);
|
||||
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>();
|
||||
cscript::util::tvals_concat(s, args, " ");
|
||||
cs.result->set_mstr(s.get().iter());
|
||||
res.set_mstr(s.get().iter());
|
||||
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>();
|
||||
cscript::util::tvals_concat(s, args);
|
||||
cs.result->set_mstr(s.get().iter());
|
||||
res.set_mstr(s.get().iter());
|
||||
s.get().disown();
|
||||
});
|
||||
|
||||
cs.add_command("format", "V", [&cs](TvalRange args) {
|
||||
cs.add_command("format", "V", [&cs](TvalRange args, TaggedValue &res) {
|
||||
if (args.empty())
|
||||
return;
|
||||
ostd::Vector<char> s;
|
||||
|
@ -107,23 +107,23 @@ void cs_init_lib_string(CsState &cs) {
|
|||
}
|
||||
s.push('\0');
|
||||
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>>();
|
||||
ostd::format(r, "0x%.*X", ostd::max(args[1].get_int(), 1), args[0].get_int());
|
||||
r.put('\0');
|
||||
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();
|
||||
int start = args[1].get_int(), count = args[2].get_int();
|
||||
int numargs = args[3].get_int();
|
||||
int len = int(s.size()), offset = ostd::clamp(start, 0, len);
|
||||
cs.result->set_str(ostd::ConstCharRange(
|
||||
res.set_str(ostd::ConstCharRange(
|
||||
&s[offset],
|
||||
(numargs >= 3) ? ostd::clamp(count, 0, len - offset)
|
||||
: (len - offset)
|
||||
|
@ -131,7 +131,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
#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; \
|
||||
if (args.size() >= 2) { \
|
||||
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; \
|
||||
} else \
|
||||
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, ==);
|
||||
|
@ -152,7 +152,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
|
||||
#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 oldval = args[1].get_strr(),
|
||||
newval = args[2].get_strr(),
|
||||
|
@ -162,7 +162,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
}
|
||||
ostd::Vector<char> buf;
|
||||
if (!oldval.size()) {
|
||||
cs.result->set_str(s);
|
||||
res.set_str(s);
|
||||
return;
|
||||
}
|
||||
for (ostd::Size i = 0;; ++i) {
|
||||
|
@ -190,13 +190,13 @@ void cs_init_lib_string(CsState &cs) {
|
|||
}
|
||||
buf.push('\0');
|
||||
ostd::Size len = buf.size() - 1;
|
||||
cs.result->set_mstr(ostd::CharRange(buf.disown(), len));
|
||||
res.set_mstr(ostd::CharRange(buf.disown(), len));
|
||||
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 vals = args[1].get_strr();
|
||||
int skip = args[2].get_int(),
|
||||
|
@ -213,7 +213,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
if (offset + len < slen)
|
||||
memcpy(&p[offset + vlen], &s[offset + len], slen - (offset + len));
|
||||
p[slen - len + vlen] = '\0';
|
||||
cs.result->set_mstr(ostd::CharRange(p, slen - len + vlen));
|
||||
res.set_mstr(ostd::CharRange(p, slen - len + vlen));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue