aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/value.h
diff options
context:
space:
mode:
Diffstat (limited to 'clox/src/value.h')
-rw-r--r--clox/src/value.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/clox/src/value.h b/clox/src/value.h
index 7dbf99e..ea76d86 100644
--- a/clox/src/value.h
+++ b/clox/src/value.h
@@ -1,11 +1,54 @@
#ifndef clox_value_h
#define clox_value_h
+#include <string.h>
+
#include "common.h"
typedef struct Obj Obj;
typedef struct ObjString ObjString;
+#ifdef NAN_BOXING
+
+#define SIGN_BIT ((uint64_t)0x8000000000000000)
+#define QNAN ((uint64_t)0x7ffc000000000000)
+
+#define TAG_NIL 1 /* 01 */
+#define TAG_FALSE 2 /* 10 */
+#define TAG_TRUE 3 /* 11 */
+
+typedef uint64_t Value;
+
+#define IS_BOOL(value) (((value) | 1) == TRUE_VAL)
+#define IS_NIL(value) ((value) == NIL_VAL)
+#define IS_NUMBER(value) (((value)&QNAN) != QNAN)
+#define IS_OBJ(value) (((value) & (QNAN | SIGN_BIT)) == (QNAN | SIGN_BIT))
+
+#define AS_BOOL(value) ((value) == TRUE_VAL)
+#define AS_NUMBER(value) valueToNum(value)
+#define AS_OBJ(value) ((Obj *)(uintptr_t)((value) & ~(SIGN_BIT | QNAN)))
+
+#define BOOL_VAL(b) ((b) ? TRUE_VAL : FALSE_VAL)
+#define FALSE_VAL ((Value)(uint64_t)(QNAN | TAG_FALSE))
+#define TRUE_VAL ((Value)(uint64_t)(QNAN | TAG_TRUE))
+#define NIL_VAL ((Value)(uint64_t)(QNAN | TAG_NIL))
+#define NUMBER_VAL(num) numToValue(num)
+#define OBJ_VAL(obj) (Value)(SIGN_BIT | QNAN | (uint64_t)(uintptr_t)(obj))
+
+static inline double valueToNum(Value value) {
+ double num;
+ memcpy(&num, &value, sizeof(Value));
+ return num;
+}
+
+static inline Value numToValue(double num) {
+ Value value;
+ memcpy(&value, &num, sizeof(double));
+ return value;
+}
+
+#else
+
typedef enum {
VAL_BOOL,
VAL_NIL,
@@ -36,6 +79,8 @@ typedef struct {
#define NUMBER_VAL(value) ((Value){VAL_NUMBER, {.number = value}})
#define OBJ_VAL(value) ((Value){VAL_OBJ, {.obj = (Obj *)value}})
+#endif // NAN_BOXING
+
typedef struct {
int capacity;
int count;