remove automatic concatenating variadics

these were pretty much just pointless sugar for something that
can be better achieved with ordinary variadics and an extra call
(which is what it did, except in VM)
master
Daniel Kolesa 2021-04-29 19:29:51 +02:00
parent e52720ebb2
commit e14d5c4aa3
7 changed files with 14 additions and 59 deletions

View File

@ -316,17 +316,14 @@ struct LIBCUBESCRIPT_EXPORT state {
* check the type explicitly for whether it was actually provided. * check the type explicitly for whether it was actually provided.
* *
* Commands also support variadics. Variadic commands have their type * Commands also support variadics. Variadic commands have their type
* list suffixed with `V` or `C`. A `V` variadic is a traditional variadic * list suffixed with `V`.
* function, while `C` will concatenate all inputs into a single big
* string.
* *
* If either `C` or `V` is used alone, the inputs are any arbitrary * If `V` is used alone, the inputs are any arbitrary values. However,
* values. However, they can also be used with repetition. Repetition * they can also be used with repetition. Repetition works for example
* works for example like `if2V`. The `2` is the number of types to * like `if2V`. The `2` is the number of types to repeat; it must be at
* repeat; it must be at most the number of simple types preceeding * most the number of simple types preceeding it. It must be followed by
* it. It must be followed by `V` or `C`. This specific example means * `V`. This specific example means that the variadic arguments are a
* that the variadic arguments are a sequence of integer, float, integer, * sequence of integer, float, integer, float, integer, float and so on.
* float, integer, float and so on.
* *
* The resulting command stores the number of arguments it takes. The * The resulting command stores the number of arguments it takes. The
* variadic part is not a part of it (neither is the part subject to * variadic part is not a part of it (neither is the part subject to

View File

@ -173,10 +173,6 @@ enum {
* instruction, arguments are popped off the stack and passed as is * instruction, arguments are popped off the stack and passed as is
*/ */
BC_INST_COM_V, BC_INST_COM_V,
/* call builtin command with index D and arg count following the
* instruction, arguments are popped off the stack and concatenated
*/
BC_INST_COM_C,
/* opcode mask */ /* opcode mask */
BC_INST_OP_MASK = 0x3F, BC_INST_OP_MASK = 0x3F,

View File

@ -543,9 +543,6 @@ lookup_id:
gs.gen_val_integer(-1); gs.gen_val_integer(-1);
++numargs; ++numargs;
break; break;
case 'C':
comtype = BC_INST_COM_C;
break;
case 'V': case 'V':
comtype = BC_INST_COM_V; comtype = BC_INST_COM_V;
break; break;
@ -994,9 +991,8 @@ bool parser_state::parse_call_command(
gs.gen_val_integer(numargs - fakeargs); gs.gen_val_integer(numargs - fakeargs);
++numargs; ++numargs;
break; break;
case 'C': /* concatenated string */
case 'V': /* varargs */ case 'V': /* varargs */
comtype = (*it == 'C') ? BC_INST_COM_C : BC_INST_COM_V; comtype = BC_INST_COM_V;
if (more) { if (more) {
for (;;) { for (;;) {
more = parse_arg(VAL_ANY); more = parse_arg(VAL_ANY);
@ -1275,9 +1271,8 @@ static bool parse_assign_var(
ps.gs.gen_val_integer(nargs); ps.gs.gen_val_integer(nargs);
++nargs; ++nargs;
break; break;
case 'C':
case 'V': case 'V':
comtype = (*it == 'C') ? BC_INST_COM_C : BC_INST_COM_V; comtype = BC_INST_COM_V;
if (more && !got) { if (more && !got) {
more = ps.parse_arg(VAL_ANY); more = ps.parse_arg(VAL_ANY);
if (more) { if (more) {

View File

@ -621,7 +621,7 @@ LIBCUBESCRIPT_EXPORT command &state::new_command(
*this, "malformed argument list" *this, "malformed argument list"
}; };
} }
if ((fmt[1] != 'C') && (fmt[1] != 'V')) { if (fmt[1] != 'V') {
throw error{ throw error{
*this, "repetition without variadic arguments" *this, "repetition without variadic arguments"
}; };
@ -629,7 +629,6 @@ LIBCUBESCRIPT_EXPORT command &state::new_command(
nargs -= nrep; nargs -= nrep;
break; break;
} }
case 'C':
case 'V': case 'V':
if ((fmt + 1) != args.end()) { if ((fmt + 1) != args.end()) {
throw error{ throw error{

View File

@ -112,17 +112,6 @@ void exec_command(
i += 1; i += 1;
args[i].set_integer(integer_type(lookup ? -1 : i - fakeargs)); args[i].set_integer(integer_type(lookup ? -1 : i - fakeargs));
break; break;
case 'C': {
i = std::max(i + 1, numargs);
any_value tv{};
tv.set_string(concat_values(
*ts.pstate, span_type<any_value>{args, std::size_t(i)}, " "
));
static_cast<command_impl *>(id)->call(
ts, span_type<any_value>(&tv, &tv + 1), res
);
return;
}
case 'V': case 'V':
i = std::max(i + 1, numargs); i = std::max(i + 1, numargs);
static_cast<command_impl *>(id)->call( static_cast<command_impl *>(id)->call(
@ -1010,27 +999,6 @@ noid:
args.resize(offset); args.resize(offset);
continue; continue;
} }
case BC_INST_COM_C | BC_RET_NULL:
case BC_INST_COM_C | BC_RET_STRING:
case BC_INST_COM_C | BC_RET_FLOAT:
case BC_INST_COM_C | BC_RET_INT: {
command_impl *id = static_cast<command_impl *>(
ts.istate->identmap[op >> 8]
);
std::size_t callargs = *code++;
std::size_t offset = args.size() - callargs;
result.force_none();
{
any_value tv{};
tv.set_string(concat_values(cs, span_type<any_value>{
&args[offset], callargs
}, " "));
id->call(ts, span_type<any_value>{&tv, 1}, result);
}
force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset);
continue;
}
} }
} }
return code; return code;

View File

@ -50,8 +50,8 @@ int main(int argc, char **argv) {
cs::state gcs; cs::state gcs;
cs::std_init_all(gcs); cs::std_init_all(gcs);
gcs.new_command("echo", "C", [](auto &s, auto args, auto &) { gcs.new_command("echo", "V", [](auto &s, auto args, auto &) {
std::printf("%s\n", args[0].get_string(s).view().data()); std::printf("%s\n", cs::concat_values(s, args, " ").data());
}); });
gcs.new_command("skip_test", "", [](auto &, auto, auto &) { gcs.new_command("skip_test", "", [](auto &, auto, auto &) {

View File

@ -371,8 +371,8 @@ int main(int argc, char **argv) {
} }
}); });
gcs.new_command("echo", "C", [](auto &css, auto args, auto &) { gcs.new_command("echo", "V", [](auto &css, auto args, auto &) {
std::printf("%s\n", std::string_view{args[0].get_string(css)}.data()); std::printf("%s\n", cs::concat_values(css, args, " ").data());
}); });
int firstarg = 0; int firstarg = 0;