Chapter 30.3
This commit is contained in:
parent
b30eb232f6
commit
9080455fae
3 changed files with 65 additions and 0 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define NAN_BOXING
|
||||||
/* #define DEBUG_PRINT_CODE */
|
/* #define DEBUG_PRINT_CODE */
|
||||||
/* #define DEBUG_TRACE_EXECUTION */
|
/* #define DEBUG_TRACE_EXECUTION */
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,17 @@ void freeValueArray(ValueArray *array) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printValue(Value value) {
|
void printValue(Value value) {
|
||||||
|
#ifdef NAN_BOXING
|
||||||
|
if (IS_BOOL(value)) {
|
||||||
|
printf(AS_BOOL(value) ? "true" : "false");
|
||||||
|
} else if (IS_NIL(value)) {
|
||||||
|
printf("nil");
|
||||||
|
} else if (IS_NUMBER(value)) {
|
||||||
|
printf("%g", AS_NUMBER(value));
|
||||||
|
} else if (IS_OBJ(value)) {
|
||||||
|
printObject(value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case VAL_BOOL:
|
case VAL_BOOL:
|
||||||
printf(AS_BOOL(value) ? "true" : "false");
|
printf(AS_BOOL(value) ? "true" : "false");
|
||||||
|
@ -43,9 +54,16 @@ void printValue(Value value) {
|
||||||
printObject(value);
|
printObject(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif // NAN_BOXING
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valuesEqual(Value a, Value b) {
|
bool valuesEqual(Value a, Value b) {
|
||||||
|
#ifdef NAN_BOXING
|
||||||
|
if (IS_NUMBER(a) && IS_NUMBER(b)) {
|
||||||
|
return AS_NUMBER(a) == AS_NUMBER(b);
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
#else
|
||||||
if (a.type != b.type)
|
if (a.type != b.type)
|
||||||
return false;
|
return false;
|
||||||
switch (a.type) {
|
switch (a.type) {
|
||||||
|
@ -61,4 +79,5 @@ bool valuesEqual(Value a, Value b) {
|
||||||
default:
|
default:
|
||||||
return false; /* Unreachable */
|
return false; /* Unreachable */
|
||||||
}
|
}
|
||||||
|
#endif // NAN_BOXING
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,54 @@
|
||||||
#ifndef clox_value_h
|
#ifndef clox_value_h
|
||||||
#define clox_value_h
|
#define clox_value_h
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
typedef struct Obj Obj;
|
typedef struct Obj Obj;
|
||||||
typedef struct ObjString ObjString;
|
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 {
|
typedef enum {
|
||||||
VAL_BOOL,
|
VAL_BOOL,
|
||||||
VAL_NIL,
|
VAL_NIL,
|
||||||
|
@ -36,6 +79,8 @@ typedef struct {
|
||||||
#define NUMBER_VAL(value) ((Value){VAL_NUMBER, {.number = value}})
|
#define NUMBER_VAL(value) ((Value){VAL_NUMBER, {.number = value}})
|
||||||
#define OBJ_VAL(value) ((Value){VAL_OBJ, {.obj = (Obj *)value}})
|
#define OBJ_VAL(value) ((Value){VAL_OBJ, {.obj = (Obj *)value}})
|
||||||
|
|
||||||
|
#endif // NAN_BOXING
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int capacity;
|
int capacity;
|
||||||
int count;
|
int count;
|
||||||
|
|
Loading…
Reference in a new issue