add PIC_ENABLE_FLOAT and PIC_WORD_BOXING
This commit is contained in:
@@ -30,7 +30,6 @@ extern "C" {
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -38,12 +37,15 @@ extern "C" {
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "picrin/config.h"
|
||||
#include "picrin/util.h"
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#include "picrin/xvect.h"
|
||||
#include "picrin/xhash.h"
|
||||
#include "picrin/xfile.h"
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
/** switch internal value representation */
|
||||
/* #define PIC_NAN_BOXING 1 */
|
||||
|
||||
/** enable word boxing */
|
||||
/* #define PIC_WORD_BOXING 0 */
|
||||
|
||||
/** enable floating point number support */
|
||||
/* #define PIC_ENABLE_FLOAT 1 */
|
||||
|
||||
/** treat false value as none */
|
||||
/* #define PIC_NONE_IS_FALSE 1 */
|
||||
|
||||
@@ -50,12 +56,36 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PIC_NAN_BOXING
|
||||
# if __x86_64__ && (defined(__GNUC__) || defined(__clang__)) && __STRICT_ANSI__ != 1
|
||||
# define PIC_NAN_BOXING 1
|
||||
#if PIC_NAN_BOXING && PIC_WORD_BOXING
|
||||
# error cannot enable both PIC_NAN_BOXING and PIC_WORD_BOXING simultaneously
|
||||
#endif
|
||||
|
||||
#if PIC_WORD_BOXING && PIC_ENABLE_FLOAT
|
||||
# error cannot enable both PIC_WORD_BOXING and PIC_ENABLE_FLOAT simultaneously
|
||||
#endif
|
||||
|
||||
#ifndef PIC_WORD_BOXING
|
||||
# define PIC_WORD_BOXING 0
|
||||
#endif
|
||||
|
||||
#if ! PIC_WORD_BOXING
|
||||
# ifndef PIC_NAN_BOXING
|
||||
# if __x86_64__ && (defined(__GNUC__) || defined(__clang__)) && __STRICT_ANSI__ != 1
|
||||
# define PIC_NAN_BOXING 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PIC_ENABLE_FLOAT
|
||||
# if ! PIC_WORD_BOXING
|
||||
# define PIC_ENABLE_FLOAT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if PIC_NAN_BOXING && defined(PIC_ENABLE_FLOAT) && ! PIC_ENABLE_FLOAT
|
||||
# error cannot disable float support when nan boxing is on
|
||||
#endif
|
||||
|
||||
#ifndef PIC_NONE_IS_FALSE
|
||||
# define PIC_NONE_IS_FALSE 1
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,9 @@ enum pic_vtype {
|
||||
PIC_VTYPE_TRUE,
|
||||
PIC_VTYPE_FALSE,
|
||||
PIC_VTYPE_UNDEF,
|
||||
#if PIC_ENABLE_FLOAT
|
||||
PIC_VTYPE_FLOAT,
|
||||
#endif
|
||||
PIC_VTYPE_INT,
|
||||
PIC_VTYPE_CHAR,
|
||||
PIC_VTYPE_EOF,
|
||||
@@ -28,6 +30,8 @@ enum pic_vtype {
|
||||
|
||||
#if PIC_NAN_BOXING
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* value representation by nan-boxing:
|
||||
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
|
||||
@@ -65,13 +69,55 @@ pic_int(pic_value v)
|
||||
|
||||
#define pic_char(v) ((v) & 0xfffffffful)
|
||||
|
||||
#elif PIC_WORD_BOXING
|
||||
|
||||
typedef unsigned long pic_value;
|
||||
|
||||
#define pic_ptr(v) ((void *)(v))
|
||||
#define pic_init_value(v,vtype) do { \
|
||||
v = (vtype << 3) + 7; \
|
||||
} while (0)
|
||||
|
||||
PIC_INLINE enum pic_vtype
|
||||
pic_vtype(pic_value v)
|
||||
{
|
||||
if ((v & 1) == 0) {
|
||||
return PIC_VTYPE_HEAP;
|
||||
}
|
||||
if ((v & 2) == 0) {
|
||||
return PIC_VTYPE_INT;
|
||||
}
|
||||
if ((v & 4) == 0) {
|
||||
return PIC_VTYPE_CHAR;
|
||||
}
|
||||
return v >> 3;
|
||||
}
|
||||
|
||||
PIC_INLINE int
|
||||
pic_int(pic_value v)
|
||||
{
|
||||
v >>= 2;
|
||||
if ((v & ((ULONG_MAX >> 3) + 1)) != 0) {
|
||||
v |= ULONG_MAX - (ULONG_MAX >> 2);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
PIC_INLINE char
|
||||
pic_char(pic_value v)
|
||||
{
|
||||
return v >> 3;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
enum pic_vtype type;
|
||||
union {
|
||||
void *data;
|
||||
#if PIC_ENABLE_FLOAT
|
||||
double f;
|
||||
#endif
|
||||
int i;
|
||||
char c;
|
||||
} u;
|
||||
@@ -81,7 +127,9 @@ typedef struct {
|
||||
#define pic_vtype(v) ((v).type)
|
||||
#define pic_init_value(v,vtype) ((v).type = (vtype), (v).u.data = NULL)
|
||||
|
||||
#define pic_float(v) ((v).u.f)
|
||||
#if PIC_ENABLE_FLOAT
|
||||
# define pic_float(v) ((v).u.f)
|
||||
#endif
|
||||
#define pic_int(v) ((v).u.i)
|
||||
#define pic_char(v) ((v).u.c)
|
||||
|
||||
@@ -91,7 +139,9 @@ enum pic_tt {
|
||||
/* immediate */
|
||||
PIC_TT_NIL,
|
||||
PIC_TT_BOOL,
|
||||
#if PIC_ENABLE_FLOAT
|
||||
PIC_TT_FLOAT,
|
||||
#endif
|
||||
PIC_TT_INT,
|
||||
PIC_TT_CHAR,
|
||||
PIC_TT_EOF,
|
||||
@@ -161,7 +211,21 @@ PIC_INLINE const char *pic_type_repr(enum pic_tt);
|
||||
pic_errorf(pic, "expected " #type ", but got ~s", v); \
|
||||
}
|
||||
|
||||
PIC_INLINE bool pic_valid_int(double);
|
||||
#if PIC_ENABLE_FLOAT
|
||||
PIC_INLINE bool
|
||||
pic_valid_int(double v)
|
||||
{
|
||||
return INT_MIN <= v && v <= INT_MAX;
|
||||
}
|
||||
|
||||
#else
|
||||
PIC_INLINE bool
|
||||
pic_valid_int(int v)
|
||||
{
|
||||
PIC_UNUSED(v);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
PIC_INLINE pic_value pic_nil_value();
|
||||
PIC_INLINE pic_value pic_true_value();
|
||||
@@ -169,7 +233,9 @@ PIC_INLINE pic_value pic_false_value();
|
||||
PIC_INLINE pic_value pic_bool_value(bool);
|
||||
PIC_INLINE pic_value pic_undef_value();
|
||||
PIC_INLINE pic_value pic_obj_value(void *);
|
||||
#if PIC_ENABLE_FLOAT
|
||||
PIC_INLINE pic_value pic_float_value(double);
|
||||
#endif
|
||||
PIC_INLINE pic_value pic_int_value(int);
|
||||
PIC_INLINE pic_value pic_size_value(size_t);
|
||||
PIC_INLINE pic_value pic_char_value(char c);
|
||||
@@ -190,8 +256,10 @@ pic_type(pic_value v)
|
||||
return PIC_TT_BOOL;
|
||||
case PIC_VTYPE_UNDEF:
|
||||
return PIC_TT_UNDEF;
|
||||
#if PIC_ENABLE_FLOAT
|
||||
case PIC_VTYPE_FLOAT:
|
||||
return PIC_TT_FLOAT;
|
||||
#endif
|
||||
case PIC_VTYPE_INT:
|
||||
return PIC_TT_INT;
|
||||
case PIC_VTYPE_CHAR:
|
||||
@@ -213,8 +281,10 @@ pic_type_repr(enum pic_tt tt)
|
||||
return "nil";
|
||||
case PIC_TT_BOOL:
|
||||
return "boolean";
|
||||
#if PIC_ENABLE_FLOAT
|
||||
case PIC_TT_FLOAT:
|
||||
return "float";
|
||||
#endif
|
||||
case PIC_TT_INT:
|
||||
return "int";
|
||||
case PIC_TT_SYMBOL:
|
||||
@@ -257,12 +327,6 @@ pic_type_repr(enum pic_tt tt)
|
||||
PIC_UNREACHABLE();
|
||||
}
|
||||
|
||||
PIC_INLINE bool
|
||||
pic_valid_int(double v)
|
||||
{
|
||||
return INT_MIN <= v && v <= INT_MAX;
|
||||
}
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_nil_value()
|
||||
{
|
||||
@@ -302,11 +366,13 @@ pic_bool_value(bool b)
|
||||
PIC_INLINE pic_value
|
||||
pic_size_value(size_t s)
|
||||
{
|
||||
#if PIC_ENABLE_FLOAT
|
||||
if (sizeof(unsigned) < sizeof(size_t)) {
|
||||
if (s > (size_t)INT_MAX) {
|
||||
return pic_float_value(s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return pic_int_value((int)s);
|
||||
}
|
||||
|
||||
@@ -358,6 +424,26 @@ pic_char_value(char c)
|
||||
return v;
|
||||
}
|
||||
|
||||
#elif PIC_WORD_BOXING
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_obj_value(void *ptr)
|
||||
{
|
||||
return (pic_value)ptr;
|
||||
}
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_int_value(int i)
|
||||
{
|
||||
return (i << 2) + 1;
|
||||
}
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_char_value(char c)
|
||||
{
|
||||
return (c << 3) + 3;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
PIC_INLINE pic_value
|
||||
@@ -370,6 +456,8 @@ pic_obj_value(void *ptr)
|
||||
return v;
|
||||
}
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_float_value(double f)
|
||||
{
|
||||
@@ -380,6 +468,8 @@ pic_float_value(double f)
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PIC_INLINE pic_value
|
||||
pic_int_value(int i)
|
||||
{
|
||||
@@ -421,7 +511,7 @@ pic_none_value()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PIC_NAN_BOXING
|
||||
#if PIC_NAN_BOXING || PIC_WORD_BOXING
|
||||
|
||||
PIC_INLINE bool
|
||||
pic_eq_p(pic_value x, pic_value y)
|
||||
@@ -464,8 +554,10 @@ pic_eqv_p(pic_value x, pic_value y)
|
||||
return true;
|
||||
case PIC_TT_BOOL:
|
||||
return pic_vtype(x) == pic_vtype(y);
|
||||
#if PIC_ENABLE_FLOAT
|
||||
case PIC_TT_FLOAT:
|
||||
return pic_float(x) == pic_float(y);
|
||||
#endif
|
||||
case PIC_TT_INT:
|
||||
return pic_int(x) == pic_int(y);
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user