271 lines
5.3 KiB
C
271 lines
5.3 KiB
C
/**
|
|
* See Copyright Notice in picrin.h
|
|
*/
|
|
|
|
#ifndef PICRIN_VALUE_H
|
|
#define PICRIN_VALUE_H
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
enum {
|
|
PIC_TYPE_INVALID = 1,
|
|
PIC_TYPE_FLOAT = 2,
|
|
PIC_TYPE_INT = 3,
|
|
PIC_TYPE_CHAR = 4,
|
|
PIC_TYPE_EOF = 5,
|
|
PIC_TYPE_UNDEF = 6,
|
|
PIC_TYPE_TRUE = 8,
|
|
PIC_TYPE_NIL = 7,
|
|
PIC_TYPE_FALSE = 9,
|
|
PIC_IVAL_END = 10,
|
|
/* -------------------- */
|
|
PIC_TYPE_SYMBOL = 16,
|
|
PIC_TYPE_STRING = 17,
|
|
PIC_TYPE_BLOB = 18,
|
|
PIC_TYPE_DATA = 19,
|
|
PIC_TYPE_PAIR = 20,
|
|
PIC_TYPE_VECTOR = 21,
|
|
PIC_TYPE_DICT = 22,
|
|
PIC_TYPE_RECORD = 23,
|
|
PIC_TYPE_ATTR = 24,
|
|
PIC_TYPE_IREP = 27,
|
|
PIC_TYPE_FRAME = 28,
|
|
PIC_TYPE_PROC_FUNC = 29,
|
|
PIC_TYPE_PROC_IREP = 30,
|
|
PIC_TYPE_MAX = 63
|
|
};
|
|
|
|
#if !PIC_NAN_BOXING
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_value(struct value *v, int type)
|
|
{
|
|
static const struct value zero = { 0 };
|
|
*v = zero;
|
|
v->type = type;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_int_value(struct value *v, int i)
|
|
{
|
|
make_value(v, PIC_TYPE_INT);
|
|
v->u.i = i;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_float_value(struct value *v, double f)
|
|
{
|
|
make_value(v, PIC_TYPE_FLOAT);
|
|
v->u.f = f;
|
|
}
|
|
|
|
PIC_STATIC_INLINE struct value
|
|
make_char_value(struct value *v, char c)
|
|
{
|
|
make_value(v, PIC_TYPE_CHAR);
|
|
v->u.c = c;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_obj_value(struct value *v, void *p, int type)
|
|
{
|
|
make_value(v, type);
|
|
v->u.p = p;
|
|
}
|
|
|
|
PIC_STATIC_INLINE int
|
|
value_type(struct value *v)
|
|
{
|
|
return (int)(v->type);
|
|
}
|
|
|
|
PIC_STATIC_INLINE int
|
|
value_int(struct value *v)
|
|
{
|
|
return v->u.i;
|
|
}
|
|
|
|
PIC_STATIC_INLINE double
|
|
value_float(struct value *v)
|
|
{
|
|
return v->u.f;
|
|
}
|
|
|
|
PIC_STATIC_INLINE char
|
|
value_char(struct value *v)
|
|
{
|
|
return v->u.c;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void *
|
|
value_ptr(struct value *v)
|
|
{
|
|
return v->u.p;
|
|
}
|
|
|
|
PIC_STATIC_INLINE bool
|
|
value_eq_p(struct value *x, struct value *y)
|
|
{
|
|
return memcmp(x, y, sizeof(struct value)) == 0;
|
|
}
|
|
|
|
PIC_STATIC_INLINE bool
|
|
value_eqv_p(struct value *x, struct value *y)
|
|
{
|
|
return memcmp(x, y, sizeof(struct value)) == 0;
|
|
}
|
|
|
|
#else /* NAN_BOXING */
|
|
|
|
/**
|
|
* value representation by nan-boxing:
|
|
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
|
|
* ptr : 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
|
|
* int : 111111111111TTTT TT00000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
|
|
* char : 111111111111TTTT TT00000000000000 CCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCC
|
|
*/
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_value(struct value *v, int type)
|
|
{
|
|
v->v = 0xfff0000000000000ul | ((uint64_t)(type) << 46);
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_int_value(struct value *v, int i)
|
|
{
|
|
make_value(v, PIC_TYPE_INT);
|
|
v->v |= (unsigned)i;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_float_value(struct value *v, double f)
|
|
{
|
|
if (f != f) {
|
|
v->v = 0x7ff8000000000000ul;
|
|
} else {
|
|
union { double f; uint64_t i; } u;
|
|
u.f = f;
|
|
v->v = u.i;
|
|
}
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_char_value(struct value *v, char c)
|
|
{
|
|
make_value(v, PIC_TYPE_CHAR);
|
|
v->v |= (unsigned char)c;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void
|
|
make_obj_value(struct value *v, void *ptr, int type)
|
|
{
|
|
make_value(v, type);
|
|
v->v |= 0x3ffffffffffful & ((uint64_t)ptr >> 2);
|
|
}
|
|
|
|
PIC_STATIC_INLINE int
|
|
value_type(struct value *v)
|
|
{
|
|
return 0xfff0000000000000ul >= v->v ? PIC_TYPE_FLOAT : ((v->v >> 46) & 0x3f);
|
|
}
|
|
|
|
PIC_STATIC_INLINE int
|
|
value_int(struct value *v)
|
|
{
|
|
union { int i; unsigned u; } u;
|
|
u.u = v->v & 0xfffffffful;
|
|
return u.i;
|
|
}
|
|
|
|
PIC_STATIC_INLINE double
|
|
value_float(struct value *v)
|
|
{
|
|
union { double f; uint64_t i; } u;
|
|
u.i = v->v;
|
|
return u.f;
|
|
}
|
|
|
|
PIC_STATIC_INLINE char
|
|
value_char(struct value *v)
|
|
{
|
|
return v->v & 0xfffffffful;
|
|
}
|
|
|
|
PIC_STATIC_INLINE void *
|
|
value_ptr(struct value *v)
|
|
{
|
|
return (void *)((0x3ffffffffffful & v->v) << 2);
|
|
}
|
|
|
|
PIC_STATIC_INLINE bool
|
|
value_eq_p(struct value *x, struct value *y)
|
|
{
|
|
return x->v == y->v;
|
|
}
|
|
|
|
PIC_STATIC_INLINE bool
|
|
value_eqv_p(struct value *x, struct value *y)
|
|
{
|
|
return x->v == y->v;
|
|
}
|
|
|
|
#endif /* NAN_BOXING end */
|
|
|
|
|
|
#define DEFPRED(name, type) \
|
|
PIC_STATIC_INLINE bool \
|
|
value_##name##_p(struct value *v) { \
|
|
return value_type(v) == type; \
|
|
}
|
|
|
|
DEFPRED(invalid, PIC_TYPE_INVALID)
|
|
DEFPRED(float, PIC_TYPE_FLOAT)
|
|
DEFPRED(int, PIC_TYPE_INT)
|
|
DEFPRED(char, PIC_TYPE_CHAR)
|
|
DEFPRED(eof, PIC_TYPE_EOF)
|
|
DEFPRED(undef, PIC_TYPE_UNDEF)
|
|
DEFPRED(true, PIC_TYPE_TRUE)
|
|
DEFPRED(nil, PIC_TYPE_NIL)
|
|
DEFPRED(false, PIC_TYPE_FALSE)
|
|
DEFPRED(str, PIC_TYPE_STRING)
|
|
DEFPRED(vec, PIC_TYPE_VECTOR)
|
|
DEFPRED(blob, PIC_TYPE_BLOB)
|
|
DEFPRED(dict, PIC_TYPE_DICT)
|
|
DEFPRED(attr, PIC_TYPE_ATTR)
|
|
DEFPRED(rec, PIC_TYPE_RECORD)
|
|
DEFPRED(sym, PIC_TYPE_SYMBOL)
|
|
DEFPRED(pair, PIC_TYPE_PAIR)
|
|
DEFPRED(proc_func, PIC_TYPE_PROC_FUNC)
|
|
DEFPRED(proc_irep, PIC_TYPE_PROC_IREP)
|
|
DEFPRED(irep, PIC_TYPE_IREP)
|
|
DEFPRED(data, PIC_TYPE_DATA)
|
|
|
|
#undef DEFPRED
|
|
|
|
PIC_STATIC_INLINE bool
|
|
value_obj_p(struct value *v)
|
|
{
|
|
return value_type(v) > PIC_IVAL_END;
|
|
}
|
|
|
|
void *pic_ptr(pic_state *, pic_value);
|
|
int pic_type(pic_state *, pic_value);
|
|
pic_value pic_invalid_value(pic_state *);
|
|
pic_value pic_obj_value(pic_state *, void *, int);
|
|
bool pic_invalid_p(pic_state *, pic_value);
|
|
bool pic_attr_p(pic_state *, pic_value);
|
|
bool pic_rec_p(pic_state *, pic_value);
|
|
bool pic_irep_p(pic_state *, pic_value);
|
|
bool pic_proc_func_p(pic_state *, pic_value);
|
|
bool pic_proc_irep_p(pic_state *, pic_value);
|
|
bool pic_obj_p(pic_state *, pic_value);
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif
|