1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-22 21:26:51 +00:00

Merge pull request #226 from andrewchambers/abstractget

Abstract type getters can indicate key absence.
This commit is contained in:
Calvin Rose 2019-12-09 18:39:40 -06:00 committed by GitHub
commit 8ecf359bbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 43 deletions

View File

@ -36,8 +36,8 @@
#define MAX_INT_IN_DBL 9007199254740992ULL /* 2^53 */ #define MAX_INT_IN_DBL 9007199254740992ULL /* 2^53 */
static Janet it_s64_get(void *p, Janet key); static int it_s64_get(void *p, Janet key, Janet *out);
static Janet it_u64_get(void *p, Janet key); static int it_u64_get(void *p, Janet key, Janet *out);
static void int64_marshal(void *p, JanetMarshalContext *ctx) { static void int64_marshal(void *p, JanetMarshalContext *ctx) {
janet_marshal_abstract(ctx, p); janet_marshal_abstract(ctx, p);
@ -351,18 +351,20 @@ static JanetMethod it_u64_methods[] = {
{NULL, NULL} {NULL, NULL}
}; };
static Janet it_s64_get(void *p, Janet key) { static int it_s64_get(void *p, Janet key, Janet *out) {
(void) p; (void) p;
if (!janet_checktype(key, JANET_KEYWORD)) if (!janet_checktype(key, JANET_KEYWORD))
janet_panicf("expected keyword, got %v", key); return 0;
return janet_getmethod(janet_unwrap_keyword(key), it_s64_methods); *out = janet_getmethod(janet_unwrap_keyword(key), it_s64_methods);
return !janet_checktype(*out, JANET_NIL);
} }
static Janet it_u64_get(void *p, Janet key) { static int it_u64_get(void *p, Janet key, Janet *out) {
(void) p; (void) p;
if (!janet_checktype(key, JANET_KEYWORD)) if (!janet_checktype(key, JANET_KEYWORD))
janet_panicf("expected keyword, got %v", key); return 0;
return janet_getmethod(janet_unwrap_keyword(key), it_u64_methods); *out = janet_getmethod(janet_unwrap_keyword(key), it_u64_methods);
return !janet_checktype(*out, JANET_NIL);
} }
static const JanetReg it_cfuns[] = { static const JanetReg it_cfuns[] = {

View File

@ -53,7 +53,7 @@ struct IOFile {
}; };
static int cfun_io_gc(void *p, size_t len); static int cfun_io_gc(void *p, size_t len);
static Janet io_file_get(void *p, Janet); static int io_file_get(void *p, Janet key, Janet *out);
JanetAbstractType cfun_io_filetype = { JanetAbstractType cfun_io_filetype = {
"core/file", "core/file",
@ -353,11 +353,12 @@ static JanetMethod io_file_methods[] = {
{NULL, NULL} {NULL, NULL}
}; };
static Janet io_file_get(void *p, Janet key) { static int io_file_get(void *p, Janet key, Janet *out) {
(void) p; (void) p;
if (!janet_checktype(key, JANET_KEYWORD)) if (!janet_checktype(key, JANET_KEYWORD))
janet_panicf("expected keyword, got %v", key); return 0;
return janet_getmethod(janet_unwrap_keyword(key), io_file_methods); *out = janet_getmethod(janet_unwrap_keyword(key), io_file_methods);
return !janet_checktype(*out, JANET_NIL);
} }
FILE *janet_dynfile(const char *name, FILE *def) { FILE *janet_dynfile(const char *name, FILE *def) {

View File

@ -29,7 +29,7 @@
static JANET_THREAD_LOCAL JanetRNG janet_vm_rng = {0, 0, 0, 0, 0}; static JANET_THREAD_LOCAL JanetRNG janet_vm_rng = {0, 0, 0, 0, 0};
static Janet janet_rng_get(void *p, Janet key); static int janet_rng_get(void *p, Janet key, Janet *out);
static void janet_rng_marshal(void *p, JanetMarshalContext *ctx) { static void janet_rng_marshal(void *p, JanetMarshalContext *ctx) {
JanetRNG *rng = (JanetRNG *)p; JanetRNG *rng = (JanetRNG *)p;
@ -196,10 +196,11 @@ static const JanetMethod rng_methods[] = {
{NULL, NULL} {NULL, NULL}
}; };
static Janet janet_rng_get(void *p, Janet key) { static int janet_rng_get(void *p, Janet key, Janet *out) {
(void) p; (void) p;
if (!janet_checktype(key, JANET_KEYWORD)) janet_panicf("expected keyword method"); if (!janet_checktype(key, JANET_KEYWORD)) return 0;
return janet_getmethod(janet_unwrap_keyword(key), rng_methods); *out = janet_getmethod(janet_unwrap_keyword(key), rng_methods);
return !janet_checktype(*out, JANET_NIL);
} }
/* Get a random number */ /* Get a random number */

View File

@ -730,7 +730,7 @@ static int parsergc(void *p, size_t size) {
return 0; return 0;
} }
static Janet parserget(void *p, Janet key); static int parserget(void *p, Janet key, Janet *out);
static JanetAbstractType janet_parse_parsertype = { static JanetAbstractType janet_parse_parsertype = {
"core/parser", "core/parser",
@ -1055,10 +1055,11 @@ static const JanetMethod parser_methods[] = {
{NULL, NULL} {NULL, NULL}
}; };
static Janet parserget(void *p, Janet key) { static int parserget(void *p, Janet key, Janet *out) {
(void) p; (void) p;
if (!janet_checktype(key, JANET_KEYWORD)) janet_panicf("expected keyword method"); if (!janet_checktype(key, JANET_KEYWORD)) return 0;
return janet_getmethod(janet_unwrap_keyword(key), parser_methods); *out = janet_getmethod(janet_unwrap_keyword(key), parser_methods);
return !janet_checktype(*out, JANET_NIL);
} }
static const JanetReg parse_cfuns[] = { static const JanetReg parse_cfuns[] = {

View File

@ -166,50 +166,51 @@ static void *ta_view_unmarshal(JanetMarshalContext *ctx) {
static JanetMethod tarray_view_methods[6]; static JanetMethod tarray_view_methods[6];
static Janet ta_getter(void *p, Janet key) { static int ta_getter(void *p, Janet key, Janet *out) {
Janet value;
size_t index, i; size_t index, i;
JanetTArrayView *array = p; JanetTArrayView *array = p;
if (janet_checktype(key, JANET_KEYWORD)) if (janet_checktype(key, JANET_KEYWORD)) {
return janet_getmethod(janet_unwrap_keyword(key), tarray_view_methods); *out = janet_getmethod(janet_unwrap_keyword(key), tarray_view_methods);
return !janet_checktype(*out, JANET_NIL);
}
if (!janet_checksize(key)) janet_panic("expected size as key"); if (!janet_checksize(key)) janet_panic("expected size as key");
index = (size_t) janet_unwrap_number(key); index = (size_t) janet_unwrap_number(key);
i = index * array->stride; i = index * array->stride;
if (index >= array->size) { if (index >= array->size) {
value = janet_wrap_nil(); return 0;
} else { } else {
switch (array->type) { switch (array->type) {
case JANET_TARRAY_TYPE_U8: case JANET_TARRAY_TYPE_U8:
value = janet_wrap_number(array->as.u8[i]); *out = janet_wrap_number(array->as.u8[i]);
break; break;
case JANET_TARRAY_TYPE_S8: case JANET_TARRAY_TYPE_S8:
value = janet_wrap_number(array->as.s8[i]); *out = janet_wrap_number(array->as.s8[i]);
break; break;
case JANET_TARRAY_TYPE_U16: case JANET_TARRAY_TYPE_U16:
value = janet_wrap_number(array->as.u16[i]); *out = janet_wrap_number(array->as.u16[i]);
break; break;
case JANET_TARRAY_TYPE_S16: case JANET_TARRAY_TYPE_S16:
value = janet_wrap_number(array->as.s16[i]); *out = janet_wrap_number(array->as.s16[i]);
break; break;
case JANET_TARRAY_TYPE_U32: case JANET_TARRAY_TYPE_U32:
value = janet_wrap_number(array->as.u32[i]); *out = janet_wrap_number(array->as.u32[i]);
break; break;
case JANET_TARRAY_TYPE_S32: case JANET_TARRAY_TYPE_S32:
value = janet_wrap_number(array->as.s32[i]); *out = janet_wrap_number(array->as.s32[i]);
break; break;
#ifdef JANET_INT_TYPES #ifdef JANET_INT_TYPES
case JANET_TARRAY_TYPE_U64: case JANET_TARRAY_TYPE_U64:
value = janet_wrap_u64(array->as.u64[i]); *out = janet_wrap_u64(array->as.u64[i]);
break; break;
case JANET_TARRAY_TYPE_S64: case JANET_TARRAY_TYPE_S64:
value = janet_wrap_s64(array->as.s64[i]); *out = janet_wrap_s64(array->as.s64[i]);
break; break;
#endif #endif
case JANET_TARRAY_TYPE_F32: case JANET_TARRAY_TYPE_F32:
value = janet_wrap_number_safe(array->as.f32[i]); *out = janet_wrap_number_safe(array->as.f32[i]);
break; break;
case JANET_TARRAY_TYPE_F64: case JANET_TARRAY_TYPE_F64:
value = janet_wrap_number_safe(array->as.f64[i]); *out = janet_wrap_number_safe(array->as.f64[i]);
break; break;
default: default:
janet_panicf("cannot get from typed array of type %s", janet_panicf("cannot get from typed array of type %s",
@ -217,7 +218,7 @@ static Janet ta_getter(void *p, Janet key) {
break; break;
} }
} }
return value; return 1;
} }
static void ta_setter(void *p, Janet key, Janet value) { static void ta_setter(void *p, Janet key, Janet value) {
@ -450,7 +451,8 @@ static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) {
JanetArray *array = janet_array(range.end - range.start); JanetArray *array = janet_array(range.end - range.start);
if (array->data) { if (array->data) {
for (int32_t i = range.start; i < range.end; i++) { for (int32_t i = range.start; i < range.end; i++) {
array->data[i - range.start] = ta_getter(src, janet_wrap_number(i)); if (!ta_getter(src, janet_wrap_number(i), &array->data[i - range.start]))
array->data[i - range.start] = janet_wrap_nil();
} }
} }
array->count = range.end - range.start; array->count = range.end - range.start;

View File

@ -197,7 +197,8 @@ Janet janet_in(Janet ds, Janet key) {
case JANET_ABSTRACT: { case JANET_ABSTRACT: {
JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds)); JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds));
if (type->get) { if (type->get) {
value = (type->get)(janet_unwrap_abstract(ds), key); if (!(type->get)(janet_unwrap_abstract(ds), key, &value))
janet_panicf("key %v not found in %v ", key, ds);
} else { } else {
janet_panicf("no getter for %v ", ds); janet_panicf("no getter for %v ", ds);
} }
@ -223,10 +224,13 @@ Janet janet_get(Janet ds, Janet key) {
return janet_wrap_integer(str[index]); return janet_wrap_integer(str[index]);
} }
case JANET_ABSTRACT: { case JANET_ABSTRACT: {
Janet value;
void *abst = janet_unwrap_abstract(ds); void *abst = janet_unwrap_abstract(ds);
JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst); JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst);
if (!type->get) return janet_wrap_nil(); if (!type->get) return janet_wrap_nil();
return (type->get)(abst, key); if ((type->get)(abst, key, &value))
return value;
return janet_wrap_nil();
} }
case JANET_ARRAY: case JANET_ARRAY:
case JANET_TUPLE: case JANET_TUPLE:
@ -304,7 +308,8 @@ Janet janet_getindex(Janet ds, int32_t index) {
case JANET_ABSTRACT: { case JANET_ABSTRACT: {
JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds)); JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds));
if (type->get) { if (type->get) {
value = (type->get)(janet_unwrap_abstract(ds), janet_wrap_integer(index)); if (!(type->get)(janet_unwrap_abstract(ds), janet_wrap_integer(index), &value))
value = janet_wrap_nil();
} else { } else {
janet_panicf("no getter for %v ", ds); janet_panicf("no getter for %v ", ds);
} }

View File

@ -1200,9 +1200,8 @@ Janet janet_mcall(const char *name, int32_t argc, Janet *argv) {
if (janet_checktype(argv[0], JANET_ABSTRACT)) { if (janet_checktype(argv[0], JANET_ABSTRACT)) {
void *abst = janet_unwrap_abstract(argv[0]); void *abst = janet_unwrap_abstract(argv[0]);
JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst); JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst);
if (!type->get) if (!type->get || !(type->get)(abst, janet_ckeywordv(name), &method))
janet_panicf("abstract value %v does not implement :%s", argv[0], name); janet_panicf("abstract value %v does not implement :%s", argv[0], name);
method = (type->get)(abst, janet_ckeywordv(name));
} else if (janet_checktype(argv[0], JANET_TABLE)) { } else if (janet_checktype(argv[0], JANET_TABLE)) {
JanetTable *table = janet_unwrap_table(argv[0]); JanetTable *table = janet_unwrap_table(argv[0]);
method = janet_table_get(table, janet_ckeywordv(name)); method = janet_table_get(table, janet_ckeywordv(name));

View File

@ -894,7 +894,7 @@ struct JanetAbstractType {
const char *name; const char *name;
int (*gc)(void *data, size_t len); int (*gc)(void *data, size_t len);
int (*gcmark)(void *data, size_t len); int (*gcmark)(void *data, size_t len);
Janet(*get)(void *data, Janet key); int (*get)(void *data, Janet key, Janet *out);
void (*put)(void *data, Janet key, Janet value); void (*put)(void *data, Janet key, Janet value);
void (*marshal)(void *p, JanetMarshalContext *ctx); void (*marshal)(void *p, JanetMarshalContext *ctx);
void *(*unmarshal)(JanetMarshalContext *ctx); void *(*unmarshal)(JanetMarshalContext *ctx);