mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	New capi janet_get_permissive
The janet_get_permissive function implements the core semantics of the 'get' function. The original janet_get implements the semantics of the 'in' function and also the OP_GET opcode. This slight oddity is to avoid a backwards incompatible change.
This commit is contained in:
		| @@ -262,59 +262,15 @@ static Janet janet_core_setdyn(int32_t argc, Janet *argv) { | |||||||
|     return argv[1]; |     return argv[1]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // XXX inline asm function with a new op - OP_GET_PERMISSIVE? | ||||||
|  | // This would match up with OP_GET which is used for 'in'. | ||||||
| static Janet janet_core_get(int32_t argc, Janet *argv) { | static Janet janet_core_get(int32_t argc, Janet *argv) { | ||||||
|     janet_arity(argc, 2, 3); |     janet_arity(argc, 2, 3); | ||||||
|     Janet ds = argv[0]; |     Janet result = janet_get_permissive(argv[0], argv[1]); | ||||||
|     Janet key = argv[1]; |     if (argc == 3 && janet_checktype(result, JANET_NIL)) { | ||||||
|     Janet dflt = argc == 3 ? argv[2] : janet_wrap_nil(); |         return argv[2]; | ||||||
|     JanetType t = janet_type(argv[0]); |  | ||||||
|     switch (t) { |  | ||||||
|         default: |  | ||||||
|             return dflt; |  | ||||||
|         case JANET_STRING: |  | ||||||
|         case JANET_SYMBOL: |  | ||||||
|         case JANET_KEYWORD: { |  | ||||||
|             if (!janet_checkint(key)) return dflt; |  | ||||||
|             int32_t index = janet_unwrap_integer(key); |  | ||||||
|             if (index < 0) return dflt; |  | ||||||
|             const uint8_t *str = janet_unwrap_string(ds); |  | ||||||
|             if (index >= janet_string_length(str)) return dflt; |  | ||||||
|             return janet_wrap_integer(str[index]); |  | ||||||
|         } |  | ||||||
|         case JANET_ABSTRACT: { |  | ||||||
|             void *abst = janet_unwrap_abstract(ds); |  | ||||||
|             JanetAbstractType *type = (JanetAbstractType *)janet_abstract_type(abst); |  | ||||||
|             if (!type->get) return dflt; |  | ||||||
|             return (type->get)(abst, key); |  | ||||||
|         } |  | ||||||
|         case JANET_ARRAY: |  | ||||||
|         case JANET_TUPLE: { |  | ||||||
|             if (!janet_checkint(key)) return dflt; |  | ||||||
|             int32_t index = janet_unwrap_integer(key); |  | ||||||
|             if (index < 0) return dflt; |  | ||||||
|             if (t == JANET_ARRAY) { |  | ||||||
|                 JanetArray *a = janet_unwrap_array(ds); |  | ||||||
|                 if (index >= a->count) return dflt; |  | ||||||
|                 return a->data[index]; |  | ||||||
|             } else { |  | ||||||
|                 const Janet *t = janet_unwrap_tuple(ds); |  | ||||||
|                 if (index >= janet_tuple_length(t)) return dflt; |  | ||||||
|                 return t[index]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         case JANET_TABLE: { |  | ||||||
|             JanetTable *flag = NULL; |  | ||||||
|             Janet ret = janet_table_get_ex(janet_unwrap_table(ds), key, &flag); |  | ||||||
|             if (flag == NULL) return dflt; |  | ||||||
|             return ret; |  | ||||||
|         } |  | ||||||
|         case JANET_STRUCT: { |  | ||||||
|             const JanetKV *st = janet_unwrap_struct(ds); |  | ||||||
|             Janet ret = janet_struct_get(st, key); |  | ||||||
|             if (janet_checktype(ret, JANET_NIL)) return dflt; |  | ||||||
|             return ret; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Janet janet_core_native(int32_t argc, Janet *argv) { | static Janet janet_core_native(int32_t argc, Janet *argv) { | ||||||
|   | |||||||
| @@ -207,6 +207,52 @@ Janet janet_get(Janet ds, Janet key) { | |||||||
|     return value; |     return value; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Janet janet_get_permissive(Janet ds, Janet key) { | ||||||
|  |     JanetType t = janet_type(ds); | ||||||
|  |     switch (t) { | ||||||
|  |         default: | ||||||
|  |             return janet_wrap_nil(); | ||||||
|  |         case JANET_STRING: | ||||||
|  |         case JANET_SYMBOL: | ||||||
|  |         case JANET_KEYWORD: { | ||||||
|  |             if (!janet_checkint(key)) return janet_wrap_nil(); | ||||||
|  |             int32_t index = janet_unwrap_integer(key); | ||||||
|  |             if (index < 0) return janet_wrap_nil(); | ||||||
|  |             const uint8_t *str = janet_unwrap_string(ds); | ||||||
|  |             if (index >= janet_string_length(str)) return janet_wrap_nil(); | ||||||
|  |             return janet_wrap_integer(str[index]); | ||||||
|  |         } | ||||||
|  |         case JANET_ABSTRACT: { | ||||||
|  |             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); | ||||||
|  |         } | ||||||
|  |         case JANET_ARRAY: | ||||||
|  |         case JANET_TUPLE: { | ||||||
|  |             if (!janet_checkint(key)) return janet_wrap_nil(); | ||||||
|  |             int32_t index = janet_unwrap_integer(key); | ||||||
|  |             if (index < 0) return janet_wrap_nil(); | ||||||
|  |             if (t == JANET_ARRAY) { | ||||||
|  |                 JanetArray *a = janet_unwrap_array(ds); | ||||||
|  |                 if (index >= a->count) return janet_wrap_nil(); | ||||||
|  |                 return a->data[index]; | ||||||
|  |             } else { | ||||||
|  |                 const Janet *t = janet_unwrap_tuple(ds); | ||||||
|  |                 if (index >= janet_tuple_length(t)) return janet_wrap_nil(); | ||||||
|  |                 return t[index]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         case JANET_TABLE: { | ||||||
|  |             return janet_table_get(janet_unwrap_table(ds), key); | ||||||
|  |         } | ||||||
|  |         case JANET_STRUCT: { | ||||||
|  |             const JanetKV *st = janet_unwrap_struct(ds); | ||||||
|  |             return janet_struct_get(st, key); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| Janet janet_getindex(Janet ds, int32_t index) { | Janet janet_getindex(Janet ds, int32_t index) { | ||||||
|     Janet value; |     Janet value; | ||||||
|     if (index < 0) janet_panic("expected non-negative index"); |     if (index < 0) janet_panic("expected non-negative index"); | ||||||
|   | |||||||
| @@ -1285,6 +1285,7 @@ JANET_API int32_t janet_hash(Janet x); | |||||||
| JANET_API int janet_compare(Janet x, Janet y); | JANET_API int janet_compare(Janet x, Janet y); | ||||||
| JANET_API int janet_cstrcmp(const uint8_t *str, const char *other); | JANET_API int janet_cstrcmp(const uint8_t *str, const char *other); | ||||||
| JANET_API Janet janet_get(Janet ds, Janet key); | JANET_API Janet janet_get(Janet ds, Janet key); | ||||||
|  | JANET_API Janet janet_get_permissive(Janet ds, Janet key); | ||||||
| JANET_API Janet janet_getindex(Janet ds, int32_t index); | JANET_API Janet janet_getindex(Janet ds, int32_t index); | ||||||
| JANET_API int32_t janet_length(Janet x); | JANET_API int32_t janet_length(Janet x); | ||||||
| JANET_API Janet janet_lengthv(Janet x); | JANET_API Janet janet_lengthv(Janet x); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andrew Chambers
					Andrew Chambers