1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-18 11:19:56 +00:00

Allow calling keywords and symbols as functions to look

themselves up in a data structure. Allow calling  a data
structure to look up the argument.
This commit is contained in:
Calvin Rose 2019-01-03 22:46:25 -05:00
parent d8b0a5ed01
commit b9c0fc8201
4 changed files with 63 additions and 7 deletions

View File

@ -139,6 +139,7 @@ DEF_PARSER_STACK(_pushstate, JanetParseState, states, statecount, statecap)
#define PFLAG_STRING 0x2000
#define PFLAG_LONGSTRING 0x4000
#define PFLAG_READERMAC 0x8000
#define PFLAG_PAIR 0x10000
static void pushstate(JanetParser *p, Consumer consumer, int flags) {
JanetParseState s;

View File

@ -633,10 +633,33 @@ static void *op_lookup[255] = {
goto vm_exit;
}
goto vm_return_cfunc;
} else {
int status;
int32_t argn = fiber->stacktop - fiber->stackstart;
Janet ds, key;
if (janet_checktypes(callee, JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)) {
if (argn != 1) vm_throw("bad arity");
ds = callee;
key = fiber->data[fiber->stackstart];
} else if (janet_checktypes(callee, JANET_TFLAG_SYMBOL | JANET_TFLAG_KEYWORD)) {
if (argn != 1) vm_throw("bad arity");
ds = fiber->data[fiber->stackstart];
key = callee;
} else {
expected_types = JANET_TFLAG_CALLABLE;
retreg = callee;
goto vm_type_error;
}
fiber->stacktop = fiber->stackstart;
status = janet_get(ds, key, stack + oparg(1, 0xFF));
if (status == -2) {
vm_throw("expected integer key");
} else if (status == -1) {
vm_throw("cannot look up in data structure");
}
pc++;
vm_next();
}
expected_types = JANET_TFLAG_CALLABLE;
retreg = callee;
goto vm_type_error;
}
VM_OP(JOP_TAILCALL)
@ -661,10 +684,34 @@ static void *op_lookup[255] = {
goto vm_exit;
}
goto vm_return_cfunc_tail;
} else {
int status;
int32_t argn = fiber->stacktop - fiber->stackstart;
Janet ds, key;
if (janet_checktypes(callee, JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)) {
if (argn != 1) vm_throw("bad arity");
ds = callee;
key = fiber->data[fiber->stackstart];
} else if (janet_checktypes(callee, JANET_TFLAG_SYMBOL | JANET_TFLAG_KEYWORD)) {
if (argn != 1) vm_throw("bad arity");
ds = fiber->data[fiber->stackstart];
key = callee;
} else {
expected_types = JANET_TFLAG_CALLABLE;
retreg = callee;
goto vm_type_error;
}
fiber->stacktop = fiber->stackstart;
status = janet_get(ds, key, &retreg);
if (status == -2) {
vm_throw("expected integer key");
} else if (status == -1) {
vm_throw("cannot look up in data structure");
}
janet_fiber_popframe(fiber);
if (fiber->frame == 0) goto vm_exit;
goto vm_reset;
}
expected_types = JANET_TFLAG_CALLABLE;
retreg = callee;
goto vm_type_error;
}
VM_OP(JOP_RESUME)

View File

@ -568,7 +568,7 @@ JANET_API int janet_checkint64(Janet x);
#define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x))
#define janet_wrap_integer(x) janet_wrap_number((int32_t)(x))
#define janet_checktypes(x, tps) (!((janet_type(x) << 1) & (tps)))
#define janet_checktypes(x, tps) ((1 << janet_type(x)) & (tps))
/* Hold components of arguments passed to JanetCFunction. */
struct JanetArgs {

View File

@ -103,4 +103,12 @@
(assert (= 55 (fibasm 10)) "fibasm 3")
(assert (= 6765 (fibasm 20)) "fibasm 4")
# Calling non functions
(assert (= 1 ({:ok 1} :ok)) "calling struct")
(assert (= 1 (:ok {:ok 1})) "calling keyword")
(assert (= 2 (@{:ok 2} :ok)) "calling table")
(assert (= :bad (try (@{:ok 2} :ok :no) ([err] :bad))) "calling table too many arguments")
(assert (= :bad (try (:ok @{:ok 2} :no) ([err] :bad))) "calling keyword too many arguments")
(end-suite)