add value.c and value.h

This commit is contained in:
Yuichi Nishiwaki 2017-05-06 12:53:20 +09:00
parent 282c8cc2f4
commit 1fdc0bcc8c
29 changed files with 464 additions and 363 deletions

View File

@ -15,6 +15,7 @@ LIBPICRIN_SRCS = \
state.c\
string.c\
symbol.c\
value.c\
var.c\
vector.c\
ext/cont.c\
@ -31,9 +32,9 @@ LIBPICRIN_HEADERS = \
include/picconf.h\
include/picrin/extra.h\
include/picrin/setup.h\
include/picrin/value.h\
khash.h\
object.h\
value.h\
state.h
override CFLAGS += -I./include -Wall -Wextra -g

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
KHASH_DEFINE(attr, struct object *, pic_value, kh_ptr_hash_func, kh_ptr_hash_equal)
@ -15,7 +16,7 @@ attr_call(pic_state *pic)
n = pic_get_args(pic, "&o|o", &self, &key, &val);
if (! obj_p(pic, key)) {
if (! pic_obj_p(pic, key)) {
pic_error(pic, "attempted to set a non-object key", 1, key);
}
@ -53,7 +54,7 @@ pic_attr_ref(pic_state *pic, pic_value attr, pic_value key)
khash_t(attr) *h = &attr_ptr(pic, proc_ptr(pic, attr)->env->regs[0])->hash;
int it;
it = kh_get(attr, h, obj_ptr(pic, key));
it = kh_get(attr, h, pic_ptr(pic, key));
if (it == kh_end(h)) {
pic_error(pic, "element not found for given key", 1, key);
}
@ -67,7 +68,7 @@ pic_attr_set(pic_state *pic, pic_value attr, pic_value key, pic_value val)
int ret;
int it;
it = kh_put(attr, h, obj_ptr(pic, key), &ret);
it = kh_put(attr, h, pic_ptr(pic, key), &ret);
kh_val(h, it) = val;
}
@ -76,7 +77,7 @@ pic_attr_has(pic_state *pic, pic_value attr, pic_value key)
{
khash_t(attr) *h = &attr_ptr(pic, proc_ptr(pic, attr)->env->regs[0])->hash;
return kh_get(attr, h, obj_ptr(pic, key)) != kh_end(h);
return kh_get(attr, h, pic_ptr(pic, key)) != kh_end(h);
}
void
@ -85,7 +86,7 @@ pic_attr_del(pic_state *pic, pic_value attr, pic_value key)
khash_t(attr) *h = &attr_ptr(pic, proc_ptr(pic, attr)->env->regs[0])->hash;
int it;
it = kh_get(attr, h, obj_ptr(pic, key));
it = kh_get(attr, h, pic_ptr(pic, key));
if (it == kh_end(h)) {
pic_error(pic, "element not found for given key", 1, key);
}

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
pic_value

View File

@ -3,48 +3,22 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#if !PIC_NAN_BOXING
#include "state.h"
bool
pic_eq_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
if (pic_type(pic, x) != pic_type(pic, y))
return false;
switch (pic_type(pic, x)) {
case PIC_TYPE_NIL:
return true;
case PIC_TYPE_TRUE: case PIC_TYPE_FALSE:
return pic_type(pic, x) == pic_type(pic, y);
default:
return obj_ptr(pic, x) == obj_ptr(pic, y);
}
return value_eq_p(&x, &y);
}
bool
pic_eqv_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
if (pic_type(pic, x) != pic_type(pic, y))
return false;
switch (pic_type(pic, x)) {
case PIC_TYPE_NIL:
return true;
case PIC_TYPE_TRUE: case PIC_TYPE_FALSE:
return pic_type(pic, x) == pic_type(pic, y);
case PIC_TYPE_FLOAT:
return pic_float(pic, x) == pic_float(pic, y);
case PIC_TYPE_INT:
return pic_int(pic, x) == pic_int(pic, y);
default:
return obj_ptr(pic, x) == obj_ptr(pic, y);
}
return value_eq_p(&x, &y);
}
#endif
bool
pic_equal_p(pic_state *pic, pic_value x, pic_value y)
{

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
static pic_value

View File

@ -3,7 +3,9 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"
bool
pic_data_p(pic_state *pic, pic_value obj, const pic_data_type *type)

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
KHASH_DEFINE(dict, struct symbol *, pic_value, kh_ptr_hash_func, kh_ptr_hash_equal)

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "../value.h"
#include "../object.h"
#include "../state.h"

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "../value.h"
#include "../object.h"
#include "../state.h"

View File

@ -5,6 +5,7 @@
#include <stdio.h>
#include "picrin.h"
#include "../value.h"
#include "../object.h"
#if PIC_USE_FILE

View File

@ -4,6 +4,7 @@
#include "picrin.h"
#include "picrin/extra.h"
#include "../value.h"
#include "../object.h"
#if PIC_USE_READ

View File

@ -4,6 +4,7 @@
#include "picrin.h"
#include "picrin/extra.h"
#include "../value.h"
#include "../object.h"
#if PIC_USE_WRITE
@ -94,7 +95,7 @@ static bool
is_shared_object(pic_state *pic, pic_value obj, struct writer_control *p) {
pic_value shared = p->shared;
if (! obj_p(pic, obj)) {
if (! pic_obj_p(pic, obj)) {
return false;
}
if (! pic_attr_has(pic, shared, obj)) {
@ -413,7 +414,7 @@ write_core(pic_state *pic, pic_value obj, pic_value port, struct writer_control
write_record(pic, obj, port, p);
break;
default:
pic_fprintf(pic, port, "#<%s %p>", typename(pic, obj), obj_ptr(pic, obj));
pic_fprintf(pic, port, "#<%s %p>", typename(pic, obj), pic_ptr(pic, obj));
break;
}

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"
@ -159,10 +160,10 @@ gc_protect(pic_state *pic, struct object *obj)
pic_value
pic_protect(pic_state *pic, pic_value v)
{
if (! obj_p(pic, v))
if (! pic_obj_p(pic, v))
return v;
gc_protect(pic, obj_ptr(pic, v));
gc_protect(pic, pic_ptr(pic, v));
return v;
}
@ -205,10 +206,10 @@ static void gc_mark_object(pic_state *, struct object *);
static void
gc_mark(pic_state *pic, pic_value v)
{
if (! obj_p(pic, v))
if (! pic_obj_p(pic, v))
return;
gc_mark_object(pic, obj_ptr(pic, v));
gc_mark_object(pic, pic_ptr(pic, v));
}
static void
@ -223,11 +224,11 @@ gc_mark_object(pic_state *pic, struct object *obj)
#define LOOP(o) obj = (struct object *)(o); goto loop
switch (obj_type(pic, obj)) {
switch (obj_type(obj)) {
case PIC_TYPE_PAIR: {
gc_mark(pic, obj->u.pair.car);
if (obj_p(pic, obj->u.pair.cdr)) {
LOOP(obj_ptr(pic, obj->u.pair.cdr));
if (pic_obj_p(pic, obj->u.pair.cdr)) {
LOOP(pic_ptr(pic, obj->u.pair.cdr));
}
break;
}
@ -367,7 +368,7 @@ gc_mark_phase(pic_state *pic)
key = kh_key(h, it);
val = kh_val(h, it);
if (is_alive(key)) {
if (obj_p(pic, val) && ! is_alive(obj_ptr(pic, val))) {
if (pic_obj_p(pic, val) && ! is_alive(pic_ptr(pic, val))) {
gc_mark(pic, val);
++j;
}
@ -383,7 +384,7 @@ gc_mark_phase(pic_state *pic)
static void
gc_finalize_object(pic_state *pic, struct object *obj)
{
switch (obj_type(pic, obj)) {
switch (obj_type(obj)) {
case PIC_TYPE_VECTOR: {
pic_free(pic, obj->u.vec.data);
break;
@ -561,7 +562,7 @@ gc_sweep_page(pic_state *pic, struct heap_page *page)
goto escape;
}
obj = (struct object *) p;
nunits = unitsof(obj_type(pic, obj));
nunits = unitsof(obj_type(obj));
if (obj->u.basic.tt & GC_MARK) {
obj->u.basic.tt &= ~GC_MARK;
alive += nunits;

View File

@ -36,7 +36,7 @@ extern "C" {
typedef struct pic_state pic_state;
typedef struct {
typedef struct value {
#if PIC_NAN_BOXING
uint64_t v;
#else
@ -51,9 +51,6 @@ typedef struct {
} pic_value;
#include "picrin/value.h" /* inline definitions */
/*
* state manipulation
*/

View File

@ -1,265 +0,0 @@
/**
* 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_PORT = 25,
PIC_TYPE_IREP = 27,
PIC_TYPE_FRAME = 28,
PIC_TYPE_PROC_FUNC = 29,
PIC_TYPE_PROC_IREP = 30,
PIC_TYPE_MAX = 63
};
PIC_STATIC_INLINE bool pic_int_p(pic_state *, pic_value);
PIC_STATIC_INLINE bool pic_float_p(pic_state *, pic_value);
PIC_STATIC_INLINE bool pic_char_p(pic_state *, pic_value);
#if !PIC_NAN_BOXING
PIC_STATIC_INLINE pic_value
pic_make_value(int type)
{
pic_value v;
v.type = type;
v.u.data = NULL;
return v;
}
PIC_STATIC_INLINE int
pic_type(pic_state *PIC_UNUSED(pic), pic_value v)
{
return (int)(v.type);
}
PIC_STATIC_INLINE int
pic_int(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_int_p(pic, v));
return v.u.i;
}
PIC_STATIC_INLINE double
pic_float(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_float_p(pic, v));
return v.u.f;
}
PIC_STATIC_INLINE char
pic_char(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_char_p(pic, v));
return v.u.c;
}
PIC_STATIC_INLINE pic_value
pic_int_value(pic_state *PIC_UNUSED(pic), int i)
{
pic_value v = pic_make_value(PIC_TYPE_INT);
v.u.i = i;
return v;
}
PIC_STATIC_INLINE pic_value
pic_float_value(pic_state *PIC_UNUSED(pic), double f)
{
pic_value v = pic_make_value(PIC_TYPE_FLOAT);
v.u.f = f;
return v;
}
PIC_STATIC_INLINE pic_value
pic_char_value(pic_state *PIC_UNUSED(pic), char c)
{
pic_value v = pic_make_value(PIC_TYPE_CHAR);
v.u.c = c;
return v;
}
#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 pic_value
pic_make_value(int type)
{
pic_value v;
v.v = 0xfff0000000000000ul | ((uint64_t)(type) << 46);
return v;
}
PIC_STATIC_INLINE int
pic_type(pic_state *PIC_UNUSED(pic), pic_value v)
{
return 0xfff0000000000000ul >= v.v ? PIC_TYPE_FLOAT : ((v.v >> 46) & 0x3f);
}
PIC_STATIC_INLINE int
pic_int(pic_state *PIC_UNUSED(pic), pic_value v)
{
union { int i; unsigned u; } u;
assert(pic_int_p(pic, v));
u.u = v.v & 0xfffffffful;
return u.i;
}
PIC_STATIC_INLINE double
pic_float(pic_state *PIC_UNUSED(pic), pic_value v)
{
union { double f; uint64_t i; } u;
assert(pic_float_p(pic, v));
u.i = v.v;
return u.f;
}
PIC_STATIC_INLINE char
pic_char(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_char_p(pic, v));
return v.v & 0xfffffffful;
}
PIC_STATIC_INLINE pic_value
pic_int_value(pic_state *PIC_UNUSED(pic), int i)
{
pic_value v = pic_make_value(PIC_TYPE_INT);
v.v |= (unsigned)i;
return v;
}
PIC_STATIC_INLINE pic_value
pic_float_value(pic_state *PIC_UNUSED(pic), double f)
{
union { double f; uint64_t i; } u;
pic_value v;
if (f != f) {
v.v = 0x7ff8000000000000ul;
} else {
u.f = f;
v.v = u.i;
}
return v;
}
PIC_STATIC_INLINE pic_value
pic_char_value(pic_state *PIC_UNUSED(pic), char c)
{
pic_value v = pic_make_value(PIC_TYPE_CHAR);
v.v |= (unsigned char)c;
return v;
}
#endif /* NAN_BOXING end */
#define DEFVAL(name, type) \
PIC_STATIC_INLINE pic_value name(pic_state *PIC_UNUSED(pic)) { \
return pic_make_value(type); \
}
DEFVAL(pic_nil_value, PIC_TYPE_NIL)
DEFVAL(pic_eof_object, PIC_TYPE_EOF)
DEFVAL(pic_true_value, PIC_TYPE_TRUE)
DEFVAL(pic_false_value, PIC_TYPE_FALSE)
DEFVAL(pic_undef_value, PIC_TYPE_UNDEF)
DEFVAL(pic_invalid_value, PIC_TYPE_INVALID)
PIC_STATIC_INLINE pic_value
pic_bool_value(pic_state *PIC_UNUSED(pic), bool b)
{
return pic_make_value(b ? PIC_TYPE_TRUE : PIC_TYPE_FALSE);
}
#define DEFPRED(name, type) \
PIC_STATIC_INLINE bool name(pic_state *pic, pic_value obj) { \
return pic_type(pic, obj) == type; \
}
DEFPRED(pic_invalid_p, PIC_TYPE_INVALID)
DEFPRED(pic_float_p, PIC_TYPE_FLOAT)
DEFPRED(pic_int_p, PIC_TYPE_INT)
DEFPRED(pic_char_p, PIC_TYPE_CHAR)
DEFPRED(pic_eof_p, PIC_TYPE_EOF)
DEFPRED(pic_undef_p, PIC_TYPE_UNDEF)
DEFPRED(pic_true_p, PIC_TYPE_TRUE)
DEFPRED(pic_nil_p, PIC_TYPE_NIL)
DEFPRED(pic_false_p, PIC_TYPE_FALSE)
DEFPRED(pic_str_p, PIC_TYPE_STRING)
DEFPRED(pic_vec_p, PIC_TYPE_VECTOR)
DEFPRED(pic_blob_p, PIC_TYPE_BLOB)
DEFPRED(pic_dict_p, PIC_TYPE_DICT)
DEFPRED(pic_attr_p, PIC_TYPE_ATTR)
DEFPRED(pic_rec_p, PIC_TYPE_RECORD)
DEFPRED(pic_sym_p, PIC_TYPE_SYMBOL)
DEFPRED(pic_pair_p, PIC_TYPE_PAIR)
DEFPRED(pic_proc_func_p, PIC_TYPE_PROC_FUNC)
DEFPRED(pic_proc_irep_p, PIC_TYPE_PROC_IREP)
DEFPRED(pic_irep_p, PIC_TYPE_IREP)
PIC_STATIC_INLINE bool
pic_bool_p(pic_state *pic, pic_value obj)
{
return pic_true_p(pic, obj) || pic_false_p(pic, obj);
}
PIC_STATIC_INLINE bool
pic_proc_p(pic_state *pic, pic_value o)
{
return pic_proc_func_p(pic, o) || pic_proc_irep_p(pic, o);
}
#if PIC_NAN_BOXING
PIC_STATIC_INLINE bool
pic_eq_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
return x.v == y.v;
}
PIC_STATIC_INLINE bool
pic_eqv_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
return x.v == y.v;
}
#endif
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
static pic_value

View File

@ -179,62 +179,22 @@ struct port {
} while (0)
PIC_STATIC_INLINE int
obj_type(pic_state *PIC_UNUSED(pic), void *ptr)
obj_type(void *ptr)
{
return ((struct basic *)ptr)->tt & TYPE_MASK;
}
#if !PIC_NAN_BOXING
PIC_STATIC_INLINE struct object *
obj_ptr(pic_state *PIC_UNUSED(pic), pic_value v)
{
return (struct object *)(v.u.data);
}
PIC_STATIC_INLINE bool
obj_p(pic_state *PIC_UNUSED(pic), pic_value v)
{
return v.type > PIC_IVAL_END;
return ((struct basic *) ptr)->tt & TYPE_MASK;
}
PIC_STATIC_INLINE pic_value
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
obj_value(pic_state *pic, void *ptr)
{
pic_value v = pic_make_value(obj_type(pic, ptr));
v.u.data = ptr;
return v;
return pic_obj_value(pic, ptr, obj_type(ptr));
}
#else /* NAN_BOXING */
PIC_STATIC_INLINE struct object *
obj_ptr(pic_state *PIC_UNUSED(pic), pic_value v)
{
return (struct object *)((0x3ffffffffffful & v.v) << 2);
}
PIC_STATIC_INLINE bool
obj_p(pic_state *PIC_UNUSED(pic), pic_value v)
{
return v.v > ((0x3ffC0ul + (0x3f & PIC_IVAL_END)) << 46);
}
PIC_STATIC_INLINE pic_value
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
{
pic_value v = pic_make_value(obj_type(pic, ptr));
v.v |= 0x3ffffffffffful & ((uint64_t)ptr >> 2);
return v;
}
#endif /* NAN_BOXING */
#define DEFPTR(name,type) \
PIC_STATIC_INLINE type * \
name##_ptr(pic_state *PIC_UNUSED(pic), pic_value o) { \
assert(pic_##name##_p(pic,o)); \
return (type *) obj_ptr(pic, o); \
return (type *) pic_ptr(pic, o); \
}
#define pic_data_p(pic,o) (pic_data_p(pic,o,NULL))

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
pic_value

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
pic_value

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
static void

View File

@ -4,6 +4,7 @@
#include "picrin.h"
#include "picrin/extra.h"
#include "value.h"
#include "object.h"
#include "state.h"
@ -389,7 +390,7 @@ pic_funcall(pic_state *pic, const char *name, int n, ...)
#if PIC_USE_LIBC
void
pic_default_panicf(pic_state *pic, const char *msg, int PIC_UNUSED(n), pic_value *PIC_UNUSED(args))
pic_default_panicf(pic_state *PIC_UNUSED(pic), const char *msg, int PIC_UNUSED(n), pic_value *PIC_UNUSED(args))
{
fprintf(stderr, "panic!: %s\n", msg);
abort();

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
struct rope {

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"

139
lib/value.c Normal file
View File

@ -0,0 +1,139 @@
/**
* See Copyright Notice in picrin.h
*/
#include "picrin.h"
#include "value.h"
#include "state.h"
int
pic_int(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_int_p(pic, v));
return value_int(&v);
}
double
pic_float(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_float_p(pic, v));
return value_float(&v);
}
char
pic_char(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_char_p(pic, v));
return value_char(&v);
}
void *
pic_ptr(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_obj_p(pic, v));
return value_ptr(&v);
}
int
pic_type(pic_state *PIC_UNUSED(pic), pic_value v)
{
return value_type(&v);
}
pic_value
pic_int_value(pic_state *PIC_UNUSED(pic), int i)
{
pic_value v;
make_int_value(&v, i);
return v;
}
pic_value
pic_float_value(pic_state *PIC_UNUSED(pic), double f)
{
pic_value v;
make_float_value(&v, f);
return v;
}
pic_value
pic_char_value(pic_state *PIC_UNUSED(pic), char c)
{
pic_value v;
make_char_value(&v, c);
return v;
}
pic_value
pic_obj_value(pic_state *PIC_UNUSED(pic), void *p, int type)
{
pic_value v;
make_obj_value(&v, p, type);
return v;
}
#define DEFVAL(name, type) \
pic_value name(pic_state *PIC_UNUSED(pic)) { \
pic_value v; \
make_value(&v, type); \
return v; \
}
DEFVAL(pic_nil_value, PIC_TYPE_NIL)
DEFVAL(pic_eof_object, PIC_TYPE_EOF)
DEFVAL(pic_true_value, PIC_TYPE_TRUE)
DEFVAL(pic_false_value, PIC_TYPE_FALSE)
DEFVAL(pic_undef_value, PIC_TYPE_UNDEF)
DEFVAL(pic_invalid_value, PIC_TYPE_INVALID)
pic_value
pic_bool_value(pic_state *PIC_UNUSED(pic), bool b)
{
pic_value v;
make_value(&v, (b ? PIC_TYPE_TRUE : PIC_TYPE_FALSE));
return v;
}
#define DEFPRED(name, type) \
bool name(pic_state *PIC_UNUSED(pic), pic_value v) { \
return pic_type(pic, v) == type; \
}
DEFPRED(pic_invalid_p, PIC_TYPE_INVALID)
DEFPRED(pic_float_p, PIC_TYPE_FLOAT)
DEFPRED(pic_int_p, PIC_TYPE_INT)
DEFPRED(pic_char_p, PIC_TYPE_CHAR)
DEFPRED(pic_eof_p, PIC_TYPE_EOF)
DEFPRED(pic_undef_p, PIC_TYPE_UNDEF)
DEFPRED(pic_true_p, PIC_TYPE_TRUE)
DEFPRED(pic_nil_p, PIC_TYPE_NIL)
DEFPRED(pic_false_p, PIC_TYPE_FALSE)
DEFPRED(pic_str_p, PIC_TYPE_STRING)
DEFPRED(pic_vec_p, PIC_TYPE_VECTOR)
DEFPRED(pic_blob_p, PIC_TYPE_BLOB)
DEFPRED(pic_dict_p, PIC_TYPE_DICT)
DEFPRED(pic_attr_p, PIC_TYPE_ATTR)
DEFPRED(pic_rec_p, PIC_TYPE_RECORD)
DEFPRED(pic_sym_p, PIC_TYPE_SYMBOL)
DEFPRED(pic_pair_p, PIC_TYPE_PAIR)
DEFPRED(pic_proc_func_p, PIC_TYPE_PROC_FUNC)
DEFPRED(pic_proc_irep_p, PIC_TYPE_PROC_IREP)
DEFPRED(pic_irep_p, PIC_TYPE_IREP)
bool
pic_bool_p(pic_state *pic, pic_value v)
{
return pic_true_p(pic, v) || pic_false_p(pic, v);
}
bool
pic_proc_p(pic_state *pic, pic_value v)
{
return pic_proc_func_p(pic, v) || pic_proc_irep_p(pic, v);
}
bool
pic_obj_p(pic_state *PIC_UNUSED(pic), pic_value v)
{
return value_obj_p(&v);
}

272
lib/value.h Normal file
View File

@ -0,0 +1,272 @@
/**
* 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_PORT = 25,
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)
DEFPRED(port, PIC_TYPE_PORT)
#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

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
#include "state.h"

View File

@ -3,6 +3,7 @@
*/
#include "picrin.h"
#include "value.h"
#include "object.h"
pic_value