From 1fdc0bcc8ca3200b31fcc9ab34747f75943e9bc1 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sat, 6 May 2017 12:53:20 +0900 Subject: [PATCH] add value.c and value.h --- lib/Makefile | 3 +- lib/attr.c | 11 +- lib/blob.c | 1 + lib/bool.c | 34 +---- lib/char.c | 1 + lib/data.c | 2 + lib/dict.c | 1 + lib/ext/cont.c | 1 + lib/ext/error.c | 1 + lib/ext/file.c | 1 + lib/ext/read.c | 1 + lib/ext/write.c | 5 +- lib/gc.c | 21 +-- lib/include/picrin.h | 5 +- lib/include/picrin/value.h | 265 ------------------------------------ lib/number.c | 1 + lib/object.h | 50 +------ lib/pair.c | 1 + lib/port.c | 1 + lib/proc.c | 1 + lib/record.c | 1 + lib/serialize.c | 1 + lib/state.c | 3 +- lib/string.c | 1 + lib/symbol.c | 1 + lib/value.c | 139 +++++++++++++++++++ lib/value.h | 272 +++++++++++++++++++++++++++++++++++++ lib/var.c | 1 + lib/vector.c | 1 + 29 files changed, 464 insertions(+), 363 deletions(-) delete mode 100644 lib/include/picrin/value.h create mode 100644 lib/value.c create mode 100644 lib/value.h diff --git a/lib/Makefile b/lib/Makefile index 3f0972ce..4098acbe 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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 diff --git a/lib/attr.c b/lib/attr.c index 1b986059..9ebc4fd5 100644 --- a/lib/attr.c +++ b/lib/attr.c @@ -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); } diff --git a/lib/blob.c b/lib/blob.c index b3b00cbf..5b94ad86 100644 --- a/lib/blob.c +++ b/lib/blob.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" pic_value diff --git a/lib/bool.c b/lib/bool.c index 6f8d693c..3dbe050a 100644 --- a/lib/bool.c +++ b/lib/bool.c @@ -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) { diff --git a/lib/char.c b/lib/char.c index 8537ac99..21e63e93 100644 --- a/lib/char.c +++ b/lib/char.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" static pic_value diff --git a/lib/data.c b/lib/data.c index 122a46ea..d194eaab 100644 --- a/lib/data.c +++ b/lib/data.c @@ -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) diff --git a/lib/dict.c b/lib/dict.c index 54a01ac6..f7765e77 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -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) diff --git a/lib/ext/cont.c b/lib/ext/cont.c index 5598e9cf..f7e4b650 100644 --- a/lib/ext/cont.c +++ b/lib/ext/cont.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "../value.h" #include "../object.h" #include "../state.h" diff --git a/lib/ext/error.c b/lib/ext/error.c index 02b4adac..fef446d5 100644 --- a/lib/ext/error.c +++ b/lib/ext/error.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "../value.h" #include "../object.h" #include "../state.h" diff --git a/lib/ext/file.c b/lib/ext/file.c index d2b5b5c3..4dc55229 100644 --- a/lib/ext/file.c +++ b/lib/ext/file.c @@ -5,6 +5,7 @@ #include #include "picrin.h" +#include "../value.h" #include "../object.h" #if PIC_USE_FILE diff --git a/lib/ext/read.c b/lib/ext/read.c index b374e3d8..507394f6 100644 --- a/lib/ext/read.c +++ b/lib/ext/read.c @@ -4,6 +4,7 @@ #include "picrin.h" #include "picrin/extra.h" +#include "../value.h" #include "../object.h" #if PIC_USE_READ diff --git a/lib/ext/write.c b/lib/ext/write.c index de54b788..8e5f384b 100644 --- a/lib/ext/write.c +++ b/lib/ext/write.c @@ -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; } diff --git a/lib/gc.c b/lib/gc.c index ea9493f5..62e65a59 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -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; diff --git a/lib/include/picrin.h b/lib/include/picrin.h index 0e81485c..a1676416 100644 --- a/lib/include/picrin.h +++ b/lib/include/picrin.h @@ -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 */ diff --git a/lib/include/picrin/value.h b/lib/include/picrin/value.h deleted file mode 100644 index 56fa45c7..00000000 --- a/lib/include/picrin/value.h +++ /dev/null @@ -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 diff --git a/lib/number.c b/lib/number.c index 14b2a50d..bf066282 100644 --- a/lib/number.c +++ b/lib/number.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" static pic_value diff --git a/lib/object.h b/lib/object.h index 7a741306..dc00abc7 100644 --- a/lib/object.h +++ b/lib/object.h @@ -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)) diff --git a/lib/pair.c b/lib/pair.c index 39c8643e..acaa2f09 100644 --- a/lib/pair.c +++ b/lib/pair.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" pic_value diff --git a/lib/port.c b/lib/port.c index a68802f4..1b2de81a 100644 --- a/lib/port.c +++ b/lib/port.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" #include "state.h" diff --git a/lib/proc.c b/lib/proc.c index 3f320a96..b08694cf 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" #include "state.h" diff --git a/lib/record.c b/lib/record.c index 09fb2e1f..1306d27a 100644 --- a/lib/record.c +++ b/lib/record.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" pic_value diff --git a/lib/serialize.c b/lib/serialize.c index c5dffd75..f5e2b174 100644 --- a/lib/serialize.c +++ b/lib/serialize.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" static void diff --git a/lib/state.c b/lib/state.c index 926a2d5a..bfdcf009 100644 --- a/lib/state.c +++ b/lib/state.c @@ -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(); diff --git a/lib/string.c b/lib/string.c index f5ae1549..596aac97 100644 --- a/lib/string.c +++ b/lib/string.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" struct rope { diff --git a/lib/symbol.c b/lib/symbol.c index 35ad7ada..2df1db57 100644 --- a/lib/symbol.c +++ b/lib/symbol.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" #include "state.h" diff --git a/lib/value.c b/lib/value.c new file mode 100644 index 00000000..70f738fb --- /dev/null +++ b/lib/value.c @@ -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); +} diff --git a/lib/value.h b/lib/value.h new file mode 100644 index 00000000..792a8a6a --- /dev/null +++ b/lib/value.h @@ -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 diff --git a/lib/var.c b/lib/var.c index ba39e32e..050f3c5b 100644 --- a/lib/var.c +++ b/lib/var.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" #include "state.h" diff --git a/lib/vector.c b/lib/vector.c index b5ecc23a..3fed5856 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -3,6 +3,7 @@ */ #include "picrin.h" +#include "value.h" #include "object.h" pic_value