mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Fix janet_opt* api.
Inverted conditional made behavior incorrect. These were not used in the core library, so were not tested.
This commit is contained in:
		| @@ -86,13 +86,23 @@ type janet_get##name(const Janet *argv, int32_t n) { \ | ||||
|         janet_panic_type(x, n, JANET_TFLAG_##NAME); \ | ||||
|     } \ | ||||
|     return janet_unwrap_##name(x); \ | ||||
| } \ | ||||
| } | ||||
|  | ||||
| #define DEFINE_OPT(name, NAME, type) \ | ||||
| type janet_opt##name(const Janet *argv, int32_t argc, int32_t n, type dflt) { \ | ||||
|     if (argc >= n) return dflt; \ | ||||
|     if (n >= argc) return dflt; \ | ||||
|     if (janet_checktype(argv[n], JANET_NIL)) return dflt; \ | ||||
|     return janet_get##name(argv, n); \ | ||||
| } | ||||
|  | ||||
| #define DEFINE_OPTLEN(name, NAME, type) \ | ||||
| type janet_opt##name(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len) { \ | ||||
|     if (n >= argc || janet_checktype(argv[n], JANET_NIL)) {\ | ||||
|         return janet_##name(dflt_len); \ | ||||
|     }\ | ||||
|     return janet_get##name(argv, n); \ | ||||
| } | ||||
|  | ||||
| Janet janet_getmethod(const uint8_t *method, const JanetMethod *methods) { | ||||
|     while (methods->name) { | ||||
|         if (!janet_cstrcmp(method, methods->name)) | ||||
| @@ -117,6 +127,26 @@ DEFINE_GETTER(cfunction, CFUNCTION, JanetCFunction) | ||||
| DEFINE_GETTER(boolean, BOOLEAN, int) | ||||
| DEFINE_GETTER(pointer, POINTER, void *) | ||||
|  | ||||
| DEFINE_OPT(number, NUMBER, double) | ||||
| DEFINE_OPT(tuple, TUPLE, const Janet *) | ||||
| DEFINE_OPT(struct, STRUCT, const JanetKV *) | ||||
| DEFINE_OPT(string, STRING, const uint8_t *) | ||||
| DEFINE_OPT(keyword, KEYWORD, const uint8_t *) | ||||
| DEFINE_OPT(symbol, SYMBOL, const uint8_t *) | ||||
| DEFINE_OPT(fiber, FIBER, JanetFiber *) | ||||
| DEFINE_OPT(function, FUNCTION, JanetFunction *) | ||||
| DEFINE_OPT(cfunction, CFUNCTION, JanetCFunction) | ||||
| DEFINE_OPT(boolean, BOOLEAN, int) | ||||
| DEFINE_OPT(pointer, POINTER, void *) | ||||
|  | ||||
| DEFINE_OPTLEN(buffer, BUFFER, JanetBuffer *) | ||||
| DEFINE_OPTLEN(table, TABLE, JanetTable *) | ||||
| DEFINE_OPTLEN(array, ARRAY, JanetArray *) | ||||
|  | ||||
| #undef DEFINE_GETTER | ||||
| #undef DEFINE_OPT | ||||
| #undef DEFINE_OPTLEN | ||||
|  | ||||
| const char *janet_getcstring(const Janet *argv, int32_t n) { | ||||
|     const uint8_t *jstr = janet_getstring(argv, n); | ||||
|     const char *cstr = (const char *)jstr; | ||||
| @@ -126,6 +156,16 @@ const char *janet_getcstring(const Janet *argv, int32_t n) { | ||||
|     return cstr; | ||||
| } | ||||
|  | ||||
| int32_t janet_getnat(const Janet *argv, int32_t n) { | ||||
|     Janet x = argv[n]; | ||||
|     if (!janet_checkint(x)) goto bad; | ||||
|     int32_t ret = janet_unwrap_integer(x); | ||||
|     if (ret < 0) goto bad; | ||||
|     return ret; | ||||
| bad: | ||||
|     janet_panicf("bad slot #%d, expected non-negative 32 bit signed integer, got %v", n, x); | ||||
| } | ||||
|  | ||||
| int32_t janet_getinteger(const Janet *argv, int32_t n) { | ||||
|     Janet x = argv[n]; | ||||
|     if (!janet_checkint(x)) { | ||||
| @@ -269,6 +309,12 @@ uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags) { | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| int32_t janet_optnat(const Janet *argv, int32_t argc, int32_t n, int32_t dflt) { | ||||
|     if (argc <= n) return dflt; | ||||
|     if (janet_checktype(argv[n], JANET_NIL)) return dflt; | ||||
|     return janet_getnat(argv, n); | ||||
| } | ||||
|  | ||||
| int32_t janet_optinteger(const Janet *argv, int32_t argc, int32_t n, int32_t dflt) { | ||||
|     if (argc <= n) return dflt; | ||||
|     if (janet_checktype(argv[n], JANET_NIL)) return dflt; | ||||
|   | ||||
| @@ -115,15 +115,15 @@ static Janet cfun_rng_int(int32_t argc, Janet *argv) { | ||||
|         uint32_t word = janet_rng_u32(rng) >> 1; | ||||
|         return janet_wrap_integer(word); | ||||
|     } else { | ||||
|         int32_t max = janet_getinteger(argv, 1); | ||||
|         if (max <= 0) return janet_wrap_number(0); | ||||
|         int32_t max = janet_optnat(argv, argc, 1, INT32_MAX); | ||||
|         if (max == 0) return janet_wrap_number(0.0); | ||||
|         uint32_t modulo = (uint32_t) max; | ||||
|         uint32_t bad = UINT32_MAX % modulo; | ||||
|         uint32_t maxgen = INT32_MAX; | ||||
|         uint32_t maxword = maxgen - (maxgen % modulo); | ||||
|         uint32_t word; | ||||
|         do { | ||||
|             word = janet_rng_u32(rng); | ||||
|         } while (word > UINT32_MAX - bad); | ||||
|         word >>= 1; | ||||
|             word = janet_rng_u32(rng) >> 1; | ||||
|         } while (word > maxword); | ||||
|         return janet_wrap_integer(word % modulo); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1289,7 +1289,6 @@ JANET_API int32_t janet_length(Janet x); | ||||
| JANET_API Janet janet_lengthv(Janet x); | ||||
| JANET_API void janet_put(Janet ds, Janet key, Janet value); | ||||
| JANET_API void janet_putindex(Janet ds, int32_t index, Janet value); | ||||
| JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags); | ||||
| #define janet_flag_at(F, I) ((F) & ((1ULL) << (I))) | ||||
| JANET_API Janet janet_wrap_number_safe(double x); | ||||
|  | ||||
| @@ -1363,6 +1362,7 @@ JANET_API JanetCFunction janet_getcfunction(const Janet *argv, int32_t n); | ||||
| JANET_API int janet_getboolean(const Janet *argv, int32_t n); | ||||
| JANET_API void *janet_getpointer(const Janet *argv, int32_t n); | ||||
|  | ||||
| JANET_API int32_t janet_getnat(const Janet *argv, int32_t n); | ||||
| JANET_API int32_t janet_getinteger(const Janet *argv, int32_t n); | ||||
| JANET_API int64_t janet_getinteger64(const Janet *argv, int32_t n); | ||||
| JANET_API size_t janet_getsize(const Janet *argv, int32_t n); | ||||
| @@ -1373,28 +1373,32 @@ JANET_API void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstr | ||||
| JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv); | ||||
| JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which); | ||||
| JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); | ||||
| JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags); | ||||
|  | ||||
| /* Optionals */ | ||||
| JANET_API double janet_optnumber(const Janet *argv, int32_t argc, int32_t n, double dflt); | ||||
| JANET_API JanetArray *janet_optarray(const Janet *argv, int32_t argc, int32_t n, JanetArray *dflt); | ||||
| JANET_API const Janet *janet_opttuple(const Janet *argv, int32_t argc, int32_t n, const Janet *dflt); | ||||
| JANET_API JanetTable *janet_opttable(const Janet *argv, int32_t argc, int32_t n, JanetTable *dflt); | ||||
| JANET_API const JanetKV *janet_optstruct(const Janet *argv, int32_t argc, int32_t n, const JanetKV *dflt); | ||||
| JANET_API const uint8_t *janet_optstring(const Janet *argv, int32_t argc, int32_t n, const uint8_t *dflt); | ||||
| JANET_API const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const char *dflt); | ||||
| JANET_API const uint8_t *janet_optsymbol(const Janet *argv, int32_t argc, int32_t n, const uint8_t *dflt); | ||||
| JANET_API const uint8_t *janet_optkeyword(const Janet *argv, int32_t argc, int32_t n, const uint8_t *dflt); | ||||
| JANET_API JanetBuffer *janet_optbuffer(const Janet *argv, int32_t argc, int32_t n, JanetBuffer *dflt); | ||||
| JANET_API JanetFiber *janet_optfiber(const Janet *argv, int32_t argc, int32_t n, JanetFiber *dflt); | ||||
| JANET_API JanetFunction *janet_optfunction(const Janet *argv, int32_t argc, int32_t n, JanetFunction *dflt); | ||||
| JANET_API JanetCFunction janet_optcfunction(const Janet *argv, int32_t argc, int32_t n, JanetCFunction dflt); | ||||
| JANET_API int janet_optboolean(const Janet *argv, int32_t argc, int32_t n, int dflt); | ||||
| JANET_API void *janet_optpointer(const Janet *argv, int32_t argc, int32_t n, void *dflt); | ||||
| JANET_API int32_t janet_optnat(const Janet *argv, int32_t argc, int32_t n, int32_t dflt); | ||||
| JANET_API int32_t janet_optinteger(const Janet *argv, int32_t argc, int32_t n, int32_t dflt); | ||||
| JANET_API int64_t janet_optinteger64(const Janet *argv, int32_t argc, int32_t n, int64_t dflt); | ||||
| JANET_API size_t janet_optsize(const Janet *argv, int32_t argc, int32_t n, size_t dflt); | ||||
| JANET_API void *janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetAbstractType *at, void *dflt); | ||||
|  | ||||
| /* Mutable optional types specify a size default, and construct a new value if none is provided */ | ||||
| JANET_API JanetBuffer *janet_optbuffer(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len); | ||||
| JANET_API JanetTable *janet_opttable(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len); | ||||
| JANET_API JanetArray *janet_optarray(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len); | ||||
|  | ||||
| JANET_API Janet janet_dyn(const char *name); | ||||
| JANET_API void janet_setdyn(const char *name, Janet value); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose