mirror of
https://github.com/CPunch/Cosmo.git
synced 2026-07-27 07:20:03 +00:00
added clang-format
This commit is contained in:
93
src/cvalue.h
93
src/cvalue.h
@@ -3,7 +3,8 @@
|
||||
|
||||
#include "cosmo.h"
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
COSMO_TNUMBER, // number has to be 0 because NaN box
|
||||
COSMO_TBOOLEAN,
|
||||
COSMO_TREF,
|
||||
@@ -18,8 +19,8 @@ typedef double cosmo_Number;
|
||||
|
||||
#ifdef NAN_BOXXED
|
||||
/*
|
||||
NaN box, this is great for fitting more in the cpu cache on x86_64 or ARM64 architectures. If you don't know how this works please reference these
|
||||
two articles:
|
||||
NaN box, this is great for fitting more in the cpu cache on x86_64 or ARM64 architectures.
|
||||
If you don't know how this works please reference these two articles:
|
||||
|
||||
https://leonardschuetz.ch/blog/nan-boxing/ and https://piotrduperas.com/posts/nan-boxing/
|
||||
|
||||
@@ -27,83 +28,88 @@ typedef double cosmo_Number;
|
||||
|
||||
TL;DR: we can store payloads in the NaN value in the IEEE 754 standard.
|
||||
*/
|
||||
union CValue {
|
||||
union CValue
|
||||
{
|
||||
uint64_t data;
|
||||
cosmo_Number num;
|
||||
};
|
||||
|
||||
#define MASK_TYPE ((uint64_t)0x0007000000000000)
|
||||
#define MASK_PAYLOAD ((uint64_t)0x0000ffffffffffff)
|
||||
# define MASK_TYPE ((uint64_t)0x0007000000000000)
|
||||
# define MASK_PAYLOAD ((uint64_t)0x0000ffffffffffff)
|
||||
|
||||
// 3 bits (low bits) are reserved for the type
|
||||
#define MAKE_PAYLOAD(x) ((uint64_t)(x) & MASK_PAYLOAD)
|
||||
#define READ_PAYLOAD(x) ((x).data & MASK_PAYLOAD)
|
||||
# define MAKE_PAYLOAD(x) ((uint64_t)(x)&MASK_PAYLOAD)
|
||||
# define READ_PAYLOAD(x) ((x).data & MASK_PAYLOAD)
|
||||
|
||||
// The bits that must be set to indicate a quiet NaN.
|
||||
#define MASK_QUIETNAN ((uint64_t)0x7ff8000000000000)
|
||||
# define MASK_QUIETNAN ((uint64_t)0x7ff8000000000000)
|
||||
|
||||
#define GET_TYPE(x) \
|
||||
((((x).data & MASK_QUIETNAN) == MASK_QUIETNAN) ? (((x).data & MASK_TYPE) >> 48) : COSMO_TNUMBER)
|
||||
# define GET_TYPE(x) \
|
||||
((((x).data & MASK_QUIETNAN) == MASK_QUIETNAN) ? (((x).data & MASK_TYPE) >> 48) \
|
||||
: COSMO_TNUMBER)
|
||||
|
||||
#define SIG_MASK (MASK_QUIETNAN | MASK_TYPE)
|
||||
#define BOOL_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TBOOLEAN) << 48))
|
||||
#define OBJ_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TREF) << 48))
|
||||
#define NIL_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TNIL) << 48))
|
||||
# define SIG_MASK (MASK_QUIETNAN | MASK_TYPE)
|
||||
# define BOOL_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TBOOLEAN) << 48))
|
||||
# define OBJ_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TREF) << 48))
|
||||
# define NIL_SIG (MASK_QUIETNAN | ((uint64_t)(COSMO_TNIL) << 48))
|
||||
|
||||
#define cosmoV_newNumber(x) ((CValue){.num = x})
|
||||
#define cosmoV_newBoolean(x) ((CValue){.data = MAKE_PAYLOAD(x) | BOOL_SIG})
|
||||
#define cosmoV_newRef(x) ((CValue){.data = MAKE_PAYLOAD((uintptr_t)x) | OBJ_SIG})
|
||||
#define cosmoV_newNil() ((CValue){.data = NIL_SIG})
|
||||
# define cosmoV_newNumber(x) ((CValue){.num = x})
|
||||
# define cosmoV_newBoolean(x) ((CValue){.data = MAKE_PAYLOAD(x) | BOOL_SIG})
|
||||
# define cosmoV_newRef(x) ((CValue){.data = MAKE_PAYLOAD((uintptr_t)x) | OBJ_SIG})
|
||||
# define cosmoV_newNil() ((CValue){.data = NIL_SIG})
|
||||
|
||||
#define cosmoV_readNumber(x) ((x).num)
|
||||
#define cosmoV_readBoolean(x) ((bool)READ_PAYLOAD(x))
|
||||
#define cosmoV_readRef(x) ((CObj*)READ_PAYLOAD(x))
|
||||
# define cosmoV_readNumber(x) ((x).num)
|
||||
# define cosmoV_readBoolean(x) ((bool)READ_PAYLOAD(x))
|
||||
# define cosmoV_readRef(x) ((CObj *)READ_PAYLOAD(x))
|
||||
|
||||
#define IS_NUMBER(x) (((x).data & MASK_QUIETNAN) != MASK_QUIETNAN)
|
||||
#define IS_BOOLEAN(x) (((x).data & SIG_MASK) == BOOL_SIG)
|
||||
#define IS_NIL(x) (((x).data & SIG_MASK) == NIL_SIG)
|
||||
#define IS_REF(x) (((x).data & SIG_MASK) == OBJ_SIG)
|
||||
# define IS_NUMBER(x) (((x).data & MASK_QUIETNAN) != MASK_QUIETNAN)
|
||||
# define IS_BOOLEAN(x) (((x).data & SIG_MASK) == BOOL_SIG)
|
||||
# define IS_NIL(x) (((x).data & SIG_MASK) == NIL_SIG)
|
||||
# define IS_REF(x) (((x).data & SIG_MASK) == OBJ_SIG)
|
||||
|
||||
#else
|
||||
/*
|
||||
Tagged union, this is the best platform independent solution
|
||||
*/
|
||||
struct CValue {
|
||||
struct CValue
|
||||
{
|
||||
CosmoType type;
|
||||
union {
|
||||
union
|
||||
{
|
||||
cosmo_Number num;
|
||||
bool b; // boolean
|
||||
CObj *obj;
|
||||
} val;
|
||||
};
|
||||
|
||||
#define GET_TYPE(x) ((x).type)
|
||||
# define GET_TYPE(x) ((x).type)
|
||||
|
||||
// create CValues
|
||||
|
||||
#define cosmoV_newNumber(x) ((CValue){COSMO_TNUMBER, {.num = (x)}})
|
||||
#define cosmoV_newBoolean(x) ((CValue){COSMO_TBOOLEAN, {.b = (x)}})
|
||||
#define cosmoV_newRef(x) ((CValue){COSMO_TREF, {.obj = (CObj*)(x)}})
|
||||
#define cosmoV_newNil() ((CValue){COSMO_TNIL, {.num = 0}})
|
||||
# define cosmoV_newNumber(x) ((CValue){COSMO_TNUMBER, {.num = (x)}})
|
||||
# define cosmoV_newBoolean(x) ((CValue){COSMO_TBOOLEAN, {.b = (x)}})
|
||||
# define cosmoV_newRef(x) ((CValue){COSMO_TREF, {.obj = (CObj *)(x)}})
|
||||
# define cosmoV_newNil() ((CValue){COSMO_TNIL, {.num = 0}})
|
||||
|
||||
// read CValues
|
||||
|
||||
#define cosmoV_readNumber(x) ((cosmo_Number)(x).val.num)
|
||||
#define cosmoV_readBoolean(x) ((bool)(x).val.b)
|
||||
# define cosmoV_readNumber(x) ((cosmo_Number)(x).val.num)
|
||||
# define cosmoV_readBoolean(x) ((bool)(x).val.b)
|
||||
|
||||
// grabs the CObj* pointer from the CValue
|
||||
#define cosmoV_readRef(x) ((CObj*)(x).val.obj)
|
||||
# define cosmoV_readRef(x) ((CObj *)(x).val.obj)
|
||||
|
||||
#define IS_NUMBER(x) (GET_TYPE(x) == COSMO_TNUMBER)
|
||||
#define IS_BOOLEAN(x) (GET_TYPE(x) == COSMO_TBOOLEAN)
|
||||
#define IS_NIL(x) (GET_TYPE(x) == COSMO_TNIL)
|
||||
#define IS_REF(x) (GET_TYPE(x) == COSMO_TREF)
|
||||
# define IS_NUMBER(x) (GET_TYPE(x) == COSMO_TNUMBER)
|
||||
# define IS_BOOLEAN(x) (GET_TYPE(x) == COSMO_TBOOLEAN)
|
||||
# define IS_NIL(x) (GET_TYPE(x) == COSMO_TNIL)
|
||||
# define IS_REF(x) (GET_TYPE(x) == COSMO_TREF)
|
||||
|
||||
#endif
|
||||
|
||||
typedef CValue* StkPtr;
|
||||
typedef CValue *StkPtr;
|
||||
|
||||
struct CValueArray {
|
||||
struct CValueArray
|
||||
{
|
||||
size_t capacity;
|
||||
size_t count;
|
||||
CValue *values;
|
||||
@@ -117,6 +123,7 @@ void printValue(CValue val);
|
||||
COSMO_API bool cosmoV_equal(CState *state, CValue valA, CValue valB);
|
||||
COSMO_API CObjString *cosmoV_toString(CState *state, CValue val);
|
||||
COSMO_API cosmo_Number cosmoV_toNumber(CState *state, CValue val);
|
||||
COSMO_API const char *cosmoV_typeStr(CValue val); // return constant char array for corresponding type
|
||||
COSMO_API const char *
|
||||
cosmoV_typeStr(CValue val); // return constant char array for corresponding type
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user