2#define REDUCT_HANDLE_H 1
36#define REDUCT_HANDLE_NONE 0x0000000000000000ULL
38#define REDUCT_HANDLE_OFFSET_FLOAT 0x0007000000000000ULL
40#define REDUCT_HANDLE_TAG_INT 0x0006000000000000ULL
41#define REDUCT_HANDLE_TAG_ITEM 0x0000000000000000ULL
43#define REDUCT_HANDLE_MASK_TAG 0xFFFF000000000000ULL
44#define REDUCT_HANDLE_MASK_VAL 0x0000FFFFFFFFFFFFULL
45#define REDUCT_HANDLE_MASK_PTR REDUCT_HANDLE_MASK_VAL
46#define REDUCT_HANDLE_MASK_FLAGS 0x00000000000000FFULL
54#define REDUCT_HANDLE_FROM_INT(_val) (REDUCT_HANDLE_TAG_INT | ((reduct_handle_t)(_val) & REDUCT_HANDLE_MASK_VAL))
62#define REDUCT_HANDLE_FROM_FLOAT(_val) \
68 REDUCT_HANDLE_OFFSET_FLOAT)
76#define REDUCT_HANDLE_FROM_ITEM(_ptr) \
77 (REDUCT_HANDLE_TAG_ITEM | ((reduct_handle_t)(void*)(_ptr) & REDUCT_HANDLE_MASK_PTR))
85#define REDUCT_HANDLE_FROM_ATOM(_atom) REDUCT_HANDLE_FROM_ITEM(REDUCT_CONTAINER_OF(_atom, reduct_item_t, atom))
93#define REDUCT_HANDLE_FROM_LIST(_list) REDUCT_HANDLE_FROM_ITEM(REDUCT_CONTAINER_OF(_list, reduct_item_t, list))
101#define REDUCT_HANDLE_FROM_FUNCTION(_func) REDUCT_HANDLE_FROM_ITEM(REDUCT_CONTAINER_OF(_func, reduct_item_t, function))
109#define REDUCT_HANDLE_FROM_CLOSURE(_closure) \
110 REDUCT_HANDLE_FROM_ITEM(REDUCT_CONTAINER_OF(_closure, reduct_item_t, closure))
118#define REDUCT_HANDLE_IS_INT(_handle) (((*(_handle)) & REDUCT_HANDLE_MASK_TAG) == REDUCT_HANDLE_TAG_INT)
126#define REDUCT_HANDLE_IS_FLOAT(_handle) ((*(_handle)) >= REDUCT_HANDLE_OFFSET_FLOAT)
134#define REDUCT_HANDLE_IS_INT_SHAPED(_handle) \
135 ((REDUCT_HANDLE_IS_INT(_handle) || (REDUCT_HANDLE_GET_FLAGS(_handle) & REDUCT_ITEM_FLAG_INT_SHAPED)) && \
136 !(REDUCT_HANDLE_GET_FLAGS(_handle) & REDUCT_ITEM_FLAG_QUOTED))
144#define REDUCT_HANDLE_IS_FLOAT_SHAPED(_handle) \
145 ((REDUCT_HANDLE_IS_FLOAT(_handle) || (REDUCT_HANDLE_GET_FLAGS(_handle) & REDUCT_ITEM_FLAG_FLOAT_SHAPED)) && \
146 !(REDUCT_HANDLE_GET_FLAGS(_handle) & REDUCT_ITEM_FLAG_QUOTED))
153#define REDUCT_HANDLE_GET_TYPE(_handle) \
154 (REDUCT_HANDLE_IS_ITEM(_handle) ? REDUCT_HANDLE_TO_ITEM(_handle)->type : REDUCT_ITEM_TYPE_ATOM)
162#define REDUCT_HANDLE_IS_NUMBER_SHAPED(_handle) \
163 (REDUCT_HANDLE_IS_INT_SHAPED(_handle) || REDUCT_HANDLE_IS_FLOAT_SHAPED(_handle))
171#define REDUCT_HANDLE_IS_ITEM(_handle) (((*(_handle)) & REDUCT_HANDLE_MASK_TAG) == REDUCT_HANDLE_TAG_ITEM)
179#define REDUCT_HANDLE_IS_ATOM(_handle) (REDUCT_HANDLE_GET_TYPE(_handle) == REDUCT_ITEM_TYPE_ATOM)
187#define REDUCT_HANDLE_IS_LIST(_handle) (REDUCT_HANDLE_GET_TYPE(_handle) == REDUCT_ITEM_TYPE_LIST)
195#define REDUCT_HANDLE_IS_FUNCTION(_handle) (REDUCT_HANDLE_GET_TYPE(_handle) == REDUCT_ITEM_TYPE_FUNCTION)
203#define REDUCT_HANDLE_IS_CLOSURE(_handle) (REDUCT_HANDLE_GET_TYPE(_handle) == REDUCT_ITEM_TYPE_CLOSURE)
211#define REDUCT_HANDLE_IS_LAMBDA(_handle) (REDUCT_HANDLE_IS_FUNCTION(_handle) || REDUCT_HANDLE_IS_CLOSURE(_handle))
219#define REDUCT_HANDLE_IS_NATIVE(_handle) \
220 (REDUCT_HANDLE_IS_ITEM(_handle) && (REDUCT_HANDLE_GET_FLAGS(_handle) & REDUCT_ITEM_FLAG_NATIVE))
228#define REDUCT_HANDLE_IS_CALLABLE(_handle) (REDUCT_HANDLE_IS_LAMBDA(_handle) || REDUCT_HANDLE_IS_NATIVE(_handle))
236#define REDUCT_HANDLE_TO_INT(_handle) (((reduct_int64_t)((*(_handle)) << 16)) >> 16)
244#define REDUCT_HANDLE_TO_FLOAT(_handle) \
248 }){.u = (*(_handle)) - REDUCT_HANDLE_OFFSET_FLOAT}) \
257#define REDUCT_HANDLE_TO_ITEM(_handle) ((reduct_item_t*)(void*)((*(_handle)) & REDUCT_HANDLE_MASK_PTR))
265#define REDUCT_HANDLE_GET_FLAGS(_handle) (REDUCT_HANDLE_IS_ITEM(_handle) ? REDUCT_HANDLE_TO_ITEM(_handle)->flags : 0)
267#define REDUCT_HANDLE_FALSE() REDUCT_HANDLE_FROM_INT(0)
269#define REDUCT_HANDLE_TRUE() REDUCT_HANDLE_FROM_INT(1)
276#define REDUCT_HANDLE_FROM_BOOL(_cond) ((_cond) ? REDUCT_HANDLE_TRUE() : REDUCT_HANDLE_FALSE())
287#define REDUCT_HANDLE_COMPARE_FAST(_reduct, _a, _b, _op) \
288 (((((*(_a)) ^ REDUCT_HANDLE_TAG_INT) | ((*(_b)) ^ REDUCT_HANDLE_TAG_INT)) & REDUCT_HANDLE_MASK_TAG) == 0 \
289 ? (REDUCT_HANDLE_TO_INT(_a) _op REDUCT_HANDLE_TO_INT(_b)) \
290 : (((*(_a)) >= REDUCT_HANDLE_OFFSET_FLOAT && (*(_b)) >= REDUCT_HANDLE_OFFSET_FLOAT) \
291 ? (REDUCT_HANDLE_TO_FLOAT(_a) _op REDUCT_HANDLE_TO_FLOAT(_b)) \
292 : (reduct_handle_compare(_reduct, _a, _b) _op 0)))
303#define REDUCT_HANDLE_ARITHMETIC_FAST(_reduct, _a, _b, _c, _op) \
306 reduct_handle_t _bVal = *(_b); \
307 reduct_handle_t _cVal = *(_c); \
309 (((_bVal ^ REDUCT_HANDLE_TAG_INT) | (_cVal ^ REDUCT_HANDLE_TAG_INT)) & REDUCT_HANDLE_MASK_TAG) == 0)) \
311 *(_a) = REDUCT_HANDLE_FROM_INT(REDUCT_HANDLE_TO_INT(&_bVal) _op REDUCT_HANDLE_TO_INT(&_cVal)); \
313 else if (REDUCT_HANDLE_IS_FLOAT(&_bVal) && REDUCT_HANDLE_IS_FLOAT(&_cVal)) \
315 *(_a) = REDUCT_HANDLE_FROM_FLOAT(REDUCT_HANDLE_TO_FLOAT(&_bVal) _op REDUCT_HANDLE_TO_FLOAT(&_cVal)); \
319 reduct_promotion_t prom; \
320 reduct_handle_promote(_reduct, _b, _c, &prom); \
321 if (prom.type == REDUCT_PROMOTION_TYPE_INT) \
323 *(_a) = REDUCT_HANDLE_FROM_INT(prom.a.intVal _op prom.b.intVal); \
327 *(_a) = REDUCT_HANDLE_FROM_FLOAT(prom.a.floatVal _op prom.b.floatVal); \
338#define REDUCT_HANDLE_IS_TRUTHY(_handle) \
339 (REDUCT_HANDLE_IS_INT(_handle) \
340 ? (REDUCT_HANDLE_TO_INT(_handle) != 0) \
341 : (REDUCT_HANDLE_IS_FLOAT(_handle) \
342 ? (REDUCT_HANDLE_TO_FLOAT(_handle) != 0.0) \
343 : (REDUCT_HANDLE_IS_ITEM(_handle) \
344 ? ((*(_handle)) != REDUCT_HANDLE_NONE && \
345 !(REDUCT_HANDLE_TO_ITEM(_handle)->flags & REDUCT_ITEM_FLAG_FALSY)) \
reduct_bool_t
Boolean type.
reduct_uint64_t reduct_handle_t
Handle type.
REDUCT_API reduct_handle_t reduct_handle_e(struct reduct *reduct)
Get the constant E handle.
REDUCT_API reduct_handle_t reduct_handle_pi(struct reduct *reduct)
Get the constant PI handle.
REDUCT_API void reduct_handle_promote(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b, reduct_promotion_t *out)
Promote two handles to a common numeric type.
REDUCT_API reduct_handle_t reduct_handle_nil(struct reduct *reduct)
Get the constant nil handle.
REDUCT_API void reduct_handle_ensure_item(struct reduct *reduct, reduct_handle_t *handle)
Ensure that a handle is an item handle.
REDUCT_API reduct_bool_t reduct_handle_is_equal(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b)
Check if two items are exactly equal string-wise or structurally.
reduct_promotion_type_t
Promotion types for numeric operations.
REDUCT_API struct reduct_item * reduct_handle_item(struct reduct *reduct, reduct_handle_t *handle)
Ensure that a handle is an item and return the pointer.
REDUCT_API void reduct_handle_get_string_params(struct reduct *reduct, reduct_handle_t *handle, char **outStr, reduct_size_t *outLen)
Get the string pointer and length from an atom handle.
REDUCT_API reduct_int64_t reduct_handle_compare(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b)
Compare two items for ordering (less than, equal, or greater than).
@ REDUCT_PROMOTION_TYPE_NONE
@ REDUCT_PROMOTION_TYPE_INT
@ REDUCT_PROMOTION_TYPE_FLOAT