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
parent
e52720ebb2
commit
e14d5c4aa3
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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{
|
||||||
|
|
32
src/cs_vm.cc
32
src/cs_vm.cc
|
@ -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;
|
||||||
|
|
|
@ -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 &) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue