mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
Add named arguments with the &named symbol.
Similar to &keys, but more ergonomic.
This commit is contained in:
parent
6d188f6e44
commit
87fc339c45
@ -2,6 +2,9 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased - ???
|
## Unreleased - ???
|
||||||
|
- Allow using `&named` in function prototypes for named arguments. This is a more ergonomic
|
||||||
|
variant of `&keys` that isn't as redundant, more self documenting, and allows extension to
|
||||||
|
things like default arguments.
|
||||||
- Add `debugger` - an easy to use debugger function that just takes a fiber.
|
- Add `debugger` - an easy to use debugger function that just takes a fiber.
|
||||||
- `dofile` will now start a debugger on errors if the environment it is passed has `:debug` set.
|
- `dofile` will now start a debugger on errors if the environment it is passed has `:debug` set.
|
||||||
- Add `debugger-on-status` function, which can be passed to `run-context` to start a debugger on
|
- Add `debugger-on-status` function, which can be passed to `run-context` to start a debugger on
|
||||||
|
@ -553,6 +553,10 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
|
|||||||
x = janet_get1(s, janet_ckeywordv("vararg"));
|
x = janet_get1(s, janet_ckeywordv("vararg"));
|
||||||
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_VARARG;
|
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_VARARG;
|
||||||
|
|
||||||
|
/* Check structarg */
|
||||||
|
x = janet_get1(s, janet_ckeywordv("structarg"));
|
||||||
|
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_STRUCTARG;
|
||||||
|
|
||||||
/* Check source */
|
/* Check source */
|
||||||
x = janet_get1(s, janet_ckeywordv("source"));
|
x = janet_get1(s, janet_ckeywordv("source"));
|
||||||
if (janet_checktype(x, JANET_STRING)) def->source = janet_unwrap_string(x);
|
if (janet_checktype(x, JANET_STRING)) def->source = janet_unwrap_string(x);
|
||||||
@ -884,6 +888,10 @@ static Janet janet_disasm_vararg(JanetFuncDef *def) {
|
|||||||
return janet_wrap_boolean(def->flags & JANET_FUNCDEF_FLAG_VARARG);
|
return janet_wrap_boolean(def->flags & JANET_FUNCDEF_FLAG_VARARG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_structarg(JanetFuncDef *def) {
|
||||||
|
return janet_wrap_boolean(def->flags & JANET_FUNCDEF_FLAG_STRUCTARG);
|
||||||
|
}
|
||||||
|
|
||||||
static Janet janet_disasm_constants(JanetFuncDef *def) {
|
static Janet janet_disasm_constants(JanetFuncDef *def) {
|
||||||
JanetArray *constants = janet_array(def->constants_length);
|
JanetArray *constants = janet_array(def->constants_length);
|
||||||
for (int32_t i = 0; i < def->constants_length; i++) {
|
for (int32_t i = 0; i < def->constants_length; i++) {
|
||||||
@ -933,6 +941,7 @@ Janet janet_disasm(JanetFuncDef *def) {
|
|||||||
janet_table_put(ret, janet_ckeywordv("bytecode"), janet_disasm_bytecode(def));
|
janet_table_put(ret, janet_ckeywordv("bytecode"), janet_disasm_bytecode(def));
|
||||||
janet_table_put(ret, janet_ckeywordv("source"), janet_disasm_source(def));
|
janet_table_put(ret, janet_ckeywordv("source"), janet_disasm_source(def));
|
||||||
janet_table_put(ret, janet_ckeywordv("vararg"), janet_disasm_vararg(def));
|
janet_table_put(ret, janet_ckeywordv("vararg"), janet_disasm_vararg(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("structarg"), janet_disasm_structarg(def));
|
||||||
janet_table_put(ret, janet_ckeywordv("name"), janet_disasm_name(def));
|
janet_table_put(ret, janet_ckeywordv("name"), janet_disasm_name(def));
|
||||||
janet_table_put(ret, janet_ckeywordv("slotcount"), janet_disasm_slotcount(def));
|
janet_table_put(ret, janet_ckeywordv("slotcount"), janet_disasm_slotcount(def));
|
||||||
janet_table_put(ret, janet_ckeywordv("constants"), janet_disasm_constants(def));
|
janet_table_put(ret, janet_ckeywordv("constants"), janet_disasm_constants(def));
|
||||||
@ -986,6 +995,7 @@ JANET_CORE_FN(cfun_disasm,
|
|||||||
if (!janet_cstrcmp(kw, "source")) return janet_disasm_source(f->def);
|
if (!janet_cstrcmp(kw, "source")) return janet_disasm_source(f->def);
|
||||||
if (!janet_cstrcmp(kw, "name")) return janet_disasm_name(f->def);
|
if (!janet_cstrcmp(kw, "name")) return janet_disasm_name(f->def);
|
||||||
if (!janet_cstrcmp(kw, "vararg")) return janet_disasm_vararg(f->def);
|
if (!janet_cstrcmp(kw, "vararg")) return janet_disasm_vararg(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "structarg")) return janet_disasm_structarg(f->def);
|
||||||
if (!janet_cstrcmp(kw, "slotcount")) return janet_disasm_slotcount(f->def);
|
if (!janet_cstrcmp(kw, "slotcount")) return janet_disasm_slotcount(f->def);
|
||||||
if (!janet_cstrcmp(kw, "constants")) return janet_disasm_constants(f->def);
|
if (!janet_cstrcmp(kw, "constants")) return janet_disasm_constants(f->def);
|
||||||
if (!janet_cstrcmp(kw, "sourcemap")) return janet_disasm_sourcemap(f->def);
|
if (!janet_cstrcmp(kw, "sourcemap")) return janet_disasm_sourcemap(f->def);
|
||||||
|
@ -822,6 +822,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
|||||||
int selfref = 0;
|
int selfref = 0;
|
||||||
int seenamp = 0;
|
int seenamp = 0;
|
||||||
int seenopt = 0;
|
int seenopt = 0;
|
||||||
|
int namedargs = 0;
|
||||||
|
|
||||||
/* Begin function */
|
/* Begin function */
|
||||||
c->scope->flags |= JANET_SCOPE_CLOSURE;
|
c->scope->flags |= JANET_SCOPE_CLOSURE;
|
||||||
@ -846,6 +847,9 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
|||||||
|
|
||||||
/* Keep track of destructured parameters */
|
/* Keep track of destructured parameters */
|
||||||
JanetSlot *destructed_params = NULL;
|
JanetSlot *destructed_params = NULL;
|
||||||
|
JanetSlot *named_params = NULL;
|
||||||
|
JanetTable *named_table = NULL;
|
||||||
|
JanetSlot named_slot;
|
||||||
|
|
||||||
/* Compile function parameters */
|
/* Compile function parameters */
|
||||||
params = janet_unwrap_tuple(argv[parami]);
|
params = janet_unwrap_tuple(argv[parami]);
|
||||||
@ -853,49 +857,74 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
|||||||
arity = paramcount;
|
arity = paramcount;
|
||||||
for (i = 0; i < paramcount; i++) {
|
for (i = 0; i < paramcount; i++) {
|
||||||
Janet param = params[i];
|
Janet param = params[i];
|
||||||
if (janet_checktype(param, JANET_SYMBOL)) {
|
if (namedargs) {
|
||||||
|
if (!janet_checktype(param, JANET_SYMBOL)) {
|
||||||
|
errmsg = "only named arguments can follow &named";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
Janet key = janet_wrap_keyword(janet_unwrap_symbol(param));
|
||||||
|
janet_table_put(named_table, key, param);
|
||||||
|
janet_v_push(named_params, janetc_farslot(c));
|
||||||
|
} else if (janet_checktype(param, JANET_SYMBOL)) {
|
||||||
/* Check for varargs and unfixed arity */
|
/* Check for varargs and unfixed arity */
|
||||||
if (!janet_cstrcmp(janet_unwrap_symbol(param), "&")) {
|
const uint8_t *sym = janet_unwrap_symbol(param);
|
||||||
if (seenamp) {
|
if (sym[0] == '&') {
|
||||||
errmsg = "& in unexpected location";
|
if (!janet_cstrcmp(sym, "&")) {
|
||||||
goto error;
|
if (seenamp) {
|
||||||
} else if (i == paramcount - 1) {
|
errmsg = "& in unexpected location";
|
||||||
allow_extra = 1;
|
goto error;
|
||||||
|
} else if (i == paramcount - 1) {
|
||||||
|
allow_extra = 1;
|
||||||
|
arity--;
|
||||||
|
} else if (i == paramcount - 2) {
|
||||||
|
vararg = 1;
|
||||||
|
arity -= 2;
|
||||||
|
} else {
|
||||||
|
errmsg = "& in unexpected location";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
seenamp = 1;
|
||||||
|
} else if (!janet_cstrcmp(sym, "&opt")) {
|
||||||
|
if (seenopt) {
|
||||||
|
errmsg = "only one &opt allowed";
|
||||||
|
goto error;
|
||||||
|
} else if (i == paramcount - 1) {
|
||||||
|
errmsg = "&opt cannot be last item in parameter list";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
min_arity = i;
|
||||||
arity--;
|
arity--;
|
||||||
} else if (i == paramcount - 2) {
|
seenopt = 1;
|
||||||
vararg = 1;
|
} else if (!janet_cstrcmp(sym, "&keys")) {
|
||||||
arity -= 2;
|
if (seenamp) {
|
||||||
} else {
|
errmsg = "&keys in unexpected location";
|
||||||
errmsg = "& in unexpected location";
|
goto error;
|
||||||
goto error;
|
} else if (i == paramcount - 2) {
|
||||||
}
|
vararg = 1;
|
||||||
seenamp = 1;
|
structarg = 1;
|
||||||
} else if (!janet_cstrcmp(janet_unwrap_symbol(param), "&opt")) {
|
arity -= 2;
|
||||||
if (seenopt) {
|
} else {
|
||||||
errmsg = "only one &opt allowed";
|
errmsg = "&keys in unexpected location";
|
||||||
goto error;
|
goto error;
|
||||||
} else if (i == paramcount - 1) {
|
}
|
||||||
errmsg = "&opt cannot be last item in parameter list";
|
seenamp = 1;
|
||||||
goto error;
|
} else if (!janet_cstrcmp(sym, "&named")) {
|
||||||
}
|
if (seenamp) {
|
||||||
min_arity = i;
|
errmsg = "&named in unexpected location";
|
||||||
arity--;
|
goto error;
|
||||||
seenopt = 1;
|
}
|
||||||
} else if (!janet_cstrcmp(janet_unwrap_symbol(param), "&keys")) {
|
|
||||||
if (seenamp) {
|
|
||||||
errmsg = "&keys in unexpected location";
|
|
||||||
goto error;
|
|
||||||
} else if (i == paramcount - 2) {
|
|
||||||
vararg = 1;
|
vararg = 1;
|
||||||
structarg = 1;
|
structarg = 1;
|
||||||
arity -= 2;
|
arity = i;
|
||||||
|
seenamp = 1;
|
||||||
|
namedargs = 1;
|
||||||
|
named_table = janet_table(10);
|
||||||
|
named_slot = janetc_farslot(c);
|
||||||
} else {
|
} else {
|
||||||
errmsg = "&keys in unexpected location";
|
janetc_nameslot(c, sym, janetc_farslot(c));
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
seenamp = 1;
|
|
||||||
} else {
|
} else {
|
||||||
janetc_nameslot(c, janet_unwrap_symbol(param), janetc_farslot(c));
|
janetc_nameslot(c, sym, janetc_farslot(c));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
janet_v_push(destructed_params, janetc_farslot(c));
|
janet_v_push(destructed_params, janetc_farslot(c));
|
||||||
@ -914,6 +943,14 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
|||||||
}
|
}
|
||||||
janet_v_free(destructed_params);
|
janet_v_free(destructed_params);
|
||||||
|
|
||||||
|
/* Compile named arguments */
|
||||||
|
if (namedargs) {
|
||||||
|
Janet param = janet_wrap_table(named_table);
|
||||||
|
destructure(c, param, named_slot, defleaf, NULL);
|
||||||
|
janetc_freeslot(c, named_slot);
|
||||||
|
janet_v_free(named_params);
|
||||||
|
}
|
||||||
|
|
||||||
max_arity = (vararg || allow_extra) ? INT32_MAX : arity;
|
max_arity = (vararg || allow_extra) ? INT32_MAX : arity;
|
||||||
if (!seenopt) min_arity = arity;
|
if (!seenopt) min_arity = arity;
|
||||||
|
|
||||||
|
@ -80,5 +80,12 @@
|
|||||||
"table rawget regression"
|
"table rawget regression"
|
||||||
(table/new -1))
|
(table/new -1))
|
||||||
|
|
||||||
|
# Named arguments
|
||||||
|
(defn named-arguments
|
||||||
|
[&named bob sally joe]
|
||||||
|
(+ bob sally joe))
|
||||||
|
|
||||||
|
(assert (= 15 (named-arguments :bob 3 :sally 5 :joe 7)) "named arguments 1")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user