mirror of
https://github.com/janet-lang/janet
synced 2025-11-01 08:03:02 +00:00
Replace unquote-splicing with a more general splce special form.
This allows splicing behavior in normal function calls.
This commit is contained in:
@@ -34,20 +34,26 @@ static JanetSlot janetc_quote(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
return janetc_cslot(argv[0]);
|
||||
}
|
||||
|
||||
static JanetSlot janetc_splice(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
JanetSlot ret;
|
||||
if (argn != 1) {
|
||||
janetc_cerror(opts.compiler, "expected 1 argument");
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
ret = janetc_value(opts, argv[0]);
|
||||
ret.flags |= JANET_SLOT_SPLICED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static JanetSlot qq_slots(JanetFopts opts, JanetSlot *slots, int makeop) {
|
||||
JanetSlot target = janetc_gettarget(opts);
|
||||
int32_t i;
|
||||
for (i = 0; i < janet_v_count(slots); i++) {
|
||||
JanetSlot s = slots[i];
|
||||
int op = (s.flags & JANET_SLOT_SPLICED) ? JOP_PUSH_ARRAY : JOP_PUSH;
|
||||
janetc_emit_s(opts.compiler, op, s, 0);
|
||||
}
|
||||
janetc_pushslots(opts.compiler, slots);
|
||||
janetc_freeslots(opts.compiler, slots);
|
||||
janetc_emit_s(opts.compiler, makeop, target, 1);
|
||||
return target;
|
||||
}
|
||||
|
||||
static JanetSlot quasiquote(JanetFopts opts, Janet x, int can_splice) {
|
||||
static JanetSlot quasiquote(JanetFopts opts, Janet x) {
|
||||
JanetSlot *slots = NULL;
|
||||
switch (janet_type(x)) {
|
||||
default:
|
||||
@@ -59,20 +65,11 @@ static JanetSlot quasiquote(JanetFopts opts, Janet x, int can_splice) {
|
||||
len = janet_tuple_length(tup);
|
||||
if (len > 1 && janet_checktype(tup[0], JANET_SYMBOL)) {
|
||||
const uint8_t *head = janet_unwrap_symbol(tup[0]);
|
||||
if (!janet_cstrcmp(head, "unquote")) {
|
||||
if (!janet_cstrcmp(head, "unquote"))
|
||||
return janetc_value(janetc_fopts_default(opts.compiler), tup[1]);
|
||||
} else if (!janet_cstrcmp(head, "unquote-splicing")) {
|
||||
JanetSlot s;
|
||||
if (!can_splice) {
|
||||
janetc_cerror(opts.compiler, "cannot use unquote-splicing here");
|
||||
}
|
||||
s = janetc_value(janetc_fopts_default(opts.compiler), tup[1]);
|
||||
s.flags |= JANET_SLOT_SPLICED;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
janet_v_push(slots, quasiquote(opts, tup[i], 1));
|
||||
janet_v_push(slots, quasiquote(opts, tup[i]));
|
||||
return qq_slots(opts, slots, JOP_MAKE_TUPLE);
|
||||
}
|
||||
case JANET_ARRAY:
|
||||
@@ -80,7 +77,7 @@ static JanetSlot quasiquote(JanetFopts opts, Janet x, int can_splice) {
|
||||
int32_t i;
|
||||
JanetArray *array = janet_unwrap_array(x);
|
||||
for (i = 0; i < array->count; i++)
|
||||
janet_v_push(slots, quasiquote(opts, array->data[i], 1));
|
||||
janet_v_push(slots, quasiquote(opts, array->data[i]));
|
||||
return qq_slots(opts, slots, JOP_MAKE_ARRAY);
|
||||
}
|
||||
case JANET_TABLE:
|
||||
@@ -90,8 +87,12 @@ static JanetSlot quasiquote(JanetFopts opts, Janet x, int can_splice) {
|
||||
int32_t len, cap;
|
||||
janet_dictionary_view(x, &kvs, &len, &cap);
|
||||
while ((kv = janet_dictionary_next(kvs, cap, kv))) {
|
||||
janet_v_push(slots, quasiquote(opts, kv->key, 0));
|
||||
janet_v_push(slots, quasiquote(opts, kv->value, 0));
|
||||
JanetSlot key = quasiquote(opts, kv->key);
|
||||
JanetSlot value = quasiquote(opts, kv->value);
|
||||
key.flags &= ~JANET_SLOT_SPLICED;
|
||||
value.flags &= ~JANET_SLOT_SPLICED;
|
||||
janet_v_push(slots, key);
|
||||
janet_v_push(slots, value);
|
||||
}
|
||||
return qq_slots(opts, slots,
|
||||
janet_checktype(x, JANET_TABLE) ? JOP_MAKE_TABLE : JOP_MAKE_STRUCT);
|
||||
@@ -104,7 +105,7 @@ static JanetSlot janetc_quasiquote(JanetFopts opts, int32_t argn, const Janet *a
|
||||
janetc_cerror(opts.compiler, "expected 1 argument");
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
return quasiquote(opts, argv[0], 0);
|
||||
return quasiquote(opts, argv[0]);
|
||||
}
|
||||
|
||||
static JanetSlot janetc_unquote(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
@@ -114,13 +115,6 @@ static JanetSlot janetc_unquote(JanetFopts opts, int32_t argn, const Janet *argv
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
|
||||
static JanetSlot janetc_unquote_splicing(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
(void) argn;
|
||||
(void) argv;
|
||||
janetc_cerror(opts.compiler, "cannot use unquote-splicing here");
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
|
||||
/* Preform destructuring. Be careful to
|
||||
* keep the order registers are freed.
|
||||
* Returns if the slot 'right' can be freed. */
|
||||
@@ -661,8 +655,9 @@ static const JanetSpecial janetc_specials[] = {
|
||||
{"if", janetc_if},
|
||||
{"quasiquote", janetc_quasiquote},
|
||||
{"quote", janetc_quote},
|
||||
{"splice", janetc_splice},
|
||||
{"unquote", janetc_unquote},
|
||||
{"unquote", janetc_unquote},
|
||||
{"unquote-splicing", janetc_unquote_splicing},
|
||||
{"var", janetc_var},
|
||||
{"while", janetc_while}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user