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:
commit
8ecf359bbe
@ -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[] = {
|
||||||
|
@ -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) {
|
||||||
|
@ -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 */
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user