mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	Merge pull request #226 from andrewchambers/abstractget
Abstract type getters can indicate key absence.
This commit is contained in:
		| @@ -36,8 +36,8 @@ | ||||
|  | ||||
| #define MAX_INT_IN_DBL 9007199254740992ULL /* 2^53 */ | ||||
|  | ||||
| static Janet it_s64_get(void *p, Janet key); | ||||
| static Janet it_u64_get(void *p, Janet key); | ||||
| static int it_s64_get(void *p, Janet key, Janet *out); | ||||
| static int it_u64_get(void *p, Janet key, Janet *out); | ||||
|  | ||||
| static void int64_marshal(void *p, JanetMarshalContext *ctx) { | ||||
|     janet_marshal_abstract(ctx, p); | ||||
| @@ -351,18 +351,20 @@ static JanetMethod it_u64_methods[] = { | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| static Janet it_s64_get(void *p, Janet key) { | ||||
| static int it_s64_get(void *p, Janet key, Janet *out) { | ||||
|     (void) p; | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) | ||||
|         janet_panicf("expected keyword, got %v", key); | ||||
|     return janet_getmethod(janet_unwrap_keyword(key), it_s64_methods); | ||||
|         return 0; | ||||
|     *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; | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) | ||||
|         janet_panicf("expected keyword, got %v", key); | ||||
|     return janet_getmethod(janet_unwrap_keyword(key), it_u64_methods); | ||||
|         return 0; | ||||
|     *out = janet_getmethod(janet_unwrap_keyword(key), it_u64_methods); | ||||
|     return !janet_checktype(*out, JANET_NIL); | ||||
| } | ||||
|  | ||||
| static const JanetReg it_cfuns[] = { | ||||
|   | ||||
| @@ -53,7 +53,7 @@ struct IOFile { | ||||
| }; | ||||
|  | ||||
| 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 = { | ||||
|     "core/file", | ||||
| @@ -353,11 +353,12 @@ static JanetMethod io_file_methods[] = { | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| static Janet io_file_get(void *p, Janet key) { | ||||
| static int io_file_get(void *p, Janet key, Janet *out) { | ||||
|     (void) p; | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) | ||||
|         janet_panicf("expected keyword, got %v", key); | ||||
|     return janet_getmethod(janet_unwrap_keyword(key), io_file_methods); | ||||
|         return 0; | ||||
|     *out = janet_getmethod(janet_unwrap_keyword(key), io_file_methods); | ||||
|     return !janet_checktype(*out, JANET_NIL); | ||||
| } | ||||
|  | ||||
| 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 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) { | ||||
|     JanetRNG *rng = (JanetRNG *)p; | ||||
| @@ -196,10 +196,11 @@ static const JanetMethod rng_methods[] = { | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| static Janet janet_rng_get(void *p, Janet key) { | ||||
| static int janet_rng_get(void *p, Janet key, Janet *out) { | ||||
|     (void) p; | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) janet_panicf("expected keyword method"); | ||||
|     return janet_getmethod(janet_unwrap_keyword(key), rng_methods); | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) return 0; | ||||
|     *out = janet_getmethod(janet_unwrap_keyword(key), rng_methods); | ||||
|     return !janet_checktype(*out, JANET_NIL); | ||||
| } | ||||
|  | ||||
| /* Get a random number */ | ||||
|   | ||||
| @@ -730,7 +730,7 @@ static int parsergc(void *p, size_t size) { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static Janet parserget(void *p, Janet key); | ||||
| static int parserget(void *p, Janet key, Janet *out); | ||||
|  | ||||
| static JanetAbstractType janet_parse_parsertype = { | ||||
|     "core/parser", | ||||
| @@ -1055,10 +1055,11 @@ static const JanetMethod parser_methods[] = { | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| static Janet parserget(void *p, Janet key) { | ||||
| static int parserget(void *p, Janet key, Janet *out) { | ||||
|     (void) p; | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) janet_panicf("expected keyword method"); | ||||
|     return janet_getmethod(janet_unwrap_keyword(key), parser_methods); | ||||
|     if (!janet_checktype(key, JANET_KEYWORD)) return 0; | ||||
|     *out = janet_getmethod(janet_unwrap_keyword(key), parser_methods); | ||||
|     return !janet_checktype(*out, JANET_NIL); | ||||
| } | ||||
|  | ||||
| static const JanetReg parse_cfuns[] = { | ||||
|   | ||||
| @@ -166,50 +166,51 @@ static void *ta_view_unmarshal(JanetMarshalContext *ctx) { | ||||
|  | ||||
| static JanetMethod tarray_view_methods[6]; | ||||
|  | ||||
| static Janet ta_getter(void *p, Janet key) { | ||||
|     Janet value; | ||||
| static int ta_getter(void *p, Janet key, Janet *out) { | ||||
|     size_t index, i; | ||||
|     JanetTArrayView *array = p; | ||||
|     if (janet_checktype(key, JANET_KEYWORD)) | ||||
|         return janet_getmethod(janet_unwrap_keyword(key), tarray_view_methods); | ||||
|     if (janet_checktype(key, JANET_KEYWORD)) { | ||||
|         *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"); | ||||
|     index = (size_t) janet_unwrap_number(key); | ||||
|     i = index * array->stride; | ||||
|     if (index >= array->size) { | ||||
|         value = janet_wrap_nil(); | ||||
|         return 0; | ||||
|     } else { | ||||
|         switch (array->type) { | ||||
|             case JANET_TARRAY_TYPE_U8: | ||||
|                 value = janet_wrap_number(array->as.u8[i]); | ||||
|                 *out = janet_wrap_number(array->as.u8[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_S8: | ||||
|                 value = janet_wrap_number(array->as.s8[i]); | ||||
|                 *out = janet_wrap_number(array->as.s8[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_U16: | ||||
|                 value = janet_wrap_number(array->as.u16[i]); | ||||
|                 *out = janet_wrap_number(array->as.u16[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_S16: | ||||
|                 value = janet_wrap_number(array->as.s16[i]); | ||||
|                 *out = janet_wrap_number(array->as.s16[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_U32: | ||||
|                 value = janet_wrap_number(array->as.u32[i]); | ||||
|                 *out = janet_wrap_number(array->as.u32[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_S32: | ||||
|                 value = janet_wrap_number(array->as.s32[i]); | ||||
|                 *out = janet_wrap_number(array->as.s32[i]); | ||||
|                 break; | ||||
| #ifdef JANET_INT_TYPES | ||||
|             case JANET_TARRAY_TYPE_U64: | ||||
|                 value = janet_wrap_u64(array->as.u64[i]); | ||||
|                 *out = janet_wrap_u64(array->as.u64[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_S64: | ||||
|                 value = janet_wrap_s64(array->as.s64[i]); | ||||
|                 *out = janet_wrap_s64(array->as.s64[i]); | ||||
|                 break; | ||||
| #endif | ||||
|             case JANET_TARRAY_TYPE_F32: | ||||
|                 value = janet_wrap_number_safe(array->as.f32[i]); | ||||
|                 *out = janet_wrap_number_safe(array->as.f32[i]); | ||||
|                 break; | ||||
|             case JANET_TARRAY_TYPE_F64: | ||||
|                 value = janet_wrap_number_safe(array->as.f64[i]); | ||||
|                 *out = janet_wrap_number_safe(array->as.f64[i]); | ||||
|                 break; | ||||
|             default: | ||||
|                 janet_panicf("cannot get from typed array of type %s", | ||||
| @@ -217,7 +218,7 @@ static Janet ta_getter(void *p, Janet key) { | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|     return value; | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| 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); | ||||
|     if (array->data) { | ||||
|         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; | ||||
|   | ||||
| @@ -197,7 +197,8 @@ Janet janet_in(Janet ds, Janet key) { | ||||
|         case JANET_ABSTRACT: { | ||||
|             JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds)); | ||||
|             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 { | ||||
|                 janet_panicf("no getter for %v ", ds); | ||||
|             } | ||||
| @@ -223,10 +224,13 @@ Janet janet_get(Janet ds, Janet key) { | ||||
|             return janet_wrap_integer(str[index]); | ||||
|         } | ||||
|         case JANET_ABSTRACT: { | ||||
|             Janet value; | ||||
|             void *abst = janet_unwrap_abstract(ds); | ||||
|             JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst); | ||||
|             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_TUPLE: | ||||
| @@ -304,7 +308,8 @@ Janet janet_getindex(Janet ds, int32_t index) { | ||||
|         case JANET_ABSTRACT: { | ||||
|             JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(janet_unwrap_abstract(ds)); | ||||
|             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 { | ||||
|                 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)) { | ||||
|         void *abst = janet_unwrap_abstract(argv[0]); | ||||
|         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); | ||||
|         method = (type->get)(abst, janet_ckeywordv(name)); | ||||
|     } else if (janet_checktype(argv[0], JANET_TABLE)) { | ||||
|         JanetTable *table = janet_unwrap_table(argv[0]); | ||||
|         method = janet_table_get(table, janet_ckeywordv(name)); | ||||
|   | ||||
| @@ -894,7 +894,7 @@ struct JanetAbstractType { | ||||
|     const char *name; | ||||
|     int (*gc)(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 (*marshal)(void *p, JanetMarshalContext *ctx); | ||||
|     void *(*unmarshal)(JanetMarshalContext *ctx); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose