picrin/lib/object.h

286 lines
6.2 KiB
C
Raw Normal View History

2016-02-10 07:50:39 -05:00
/**
* See Copyright Notice in picrin.h
*/
2016-02-18 10:03:34 -05:00
#ifndef PICRIN_OBJECT_H
#define PICRIN_OBJECT_H
2016-02-10 07:50:39 -05:00
#if defined(__cplusplus)
extern "C" {
#endif
2017-03-28 10:09:40 -04:00
#include "khash.h"
#if PIC_BITMAP_GC
# define OBJECT_HEADER \
unsigned char tt;
#else
# define OBJECT_HEADER \
2017-04-09 06:14:02 -04:00
unsigned char tt;
#endif
#if !PIC_BITMAP_GC
# define GC_MARK 0x80
2017-03-28 10:09:40 -04:00
#endif
2016-02-18 11:05:28 -05:00
2016-02-21 06:32:00 -05:00
struct object; /* defined in gc.c */
2016-02-20 02:33:51 -05:00
2016-02-21 06:32:00 -05:00
struct basic {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
};
2017-04-04 01:54:58 -04:00
struct symbol {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2017-04-04 01:54:58 -04:00
struct string *str;
2016-02-19 05:08:45 -05:00
};
2016-02-18 12:29:40 -05:00
2016-02-21 06:32:00 -05:00
struct pair {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 12:29:40 -05:00
pic_value car;
pic_value cdr;
};
2016-02-21 06:32:00 -05:00
struct blob {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:20:15 -05:00
unsigned char *data;
int len;
};
2016-02-21 06:32:00 -05:00
struct string {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-21 06:32:00 -05:00
struct rope *rope;
2016-02-18 10:14:50 -05:00
};
2017-04-04 01:54:58 -04:00
KHASH_DECLARE(dict, struct symbol *, pic_value)
2017-03-28 10:09:40 -04:00
2016-02-21 06:32:00 -05:00
struct dict {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:40:35 -05:00
khash_t(dict) hash;
};
2017-03-28 10:09:40 -04:00
KHASH_DECLARE(weak, struct object *, pic_value)
2016-02-21 06:32:00 -05:00
struct weak {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-10 07:50:39 -05:00
khash_t(weak) hash;
2016-02-21 06:32:00 -05:00
struct weak *prev; /* for GC */
2016-02-10 07:50:39 -05:00
};
2016-02-21 06:32:00 -05:00
struct vector {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-19 05:08:45 -05:00
pic_value *data;
int len;
};
2016-02-18 10:50:13 -05:00
2016-02-21 06:32:00 -05:00
struct data {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:50:13 -05:00
const pic_data_type *type;
void *data;
};
struct record {
OBJECT_HEADER
2017-04-09 04:34:56 -04:00
struct symbol *type;
pic_value datum;
};
2017-03-30 10:29:08 -04:00
struct irep {
OBJECT_HEADER
int argc, localc, capturec;
bool varg;
struct code *code;
struct irep **irep;
int *ints;
double *nums;
struct object **pool;
size_t ncode, nirep, nints, nnums, npool;
};
2017-04-09 02:49:04 -04:00
struct frame {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:56:56 -05:00
int regc;
2017-04-09 02:49:04 -04:00
pic_value *regs;
struct frame *up;
2016-02-18 10:56:56 -05:00
pic_value storage[1];
};
2016-02-21 06:32:00 -05:00
struct proc {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:56:56 -05:00
union {
pic_func_t func;
struct irep *irep;
2016-02-18 10:56:56 -05:00
} u;
struct frame *fp;
2016-02-18 10:56:56 -05:00
};
2017-03-28 10:09:40 -04:00
enum {
FILE_READ = 01,
FILE_WRITE = 02,
FILE_UNBUF = 04,
FILE_EOF = 010,
FILE_ERR = 020,
FILE_LNBUF = 040
};
2016-02-21 06:32:00 -05:00
struct port {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2017-03-28 10:09:40 -04:00
struct file {
/* buffer */
char buf[1]; /* fallback buffer */
long cnt; /* characters left */
char *ptr; /* next character position */
char *base; /* location of the buffer */
/* operators */
2017-03-28 18:11:27 -04:00
void *cookie;
const pic_port_type *vtable;
2017-03-28 10:09:40 -04:00
int flag; /* mode of the file access */
} file;
2016-02-18 15:58:34 -05:00
};
struct error {
OBJECT_HEADER
2017-04-04 01:54:58 -04:00
struct symbol *type;
struct string *msg;
pic_value irrs;
};
2016-02-23 08:53:20 -05:00
#define TYPENAME_int "integer"
#define TYPENAME_blob "bytevector"
#define TYPENAME_char "character"
#define TYPENAME_sym "symbol"
#define TYPENAME_error "error"
#define TYPENAME_proc "procedure"
#define TYPENAME_str "string"
#define TYPENAME_vec "vector"
#define TYPE_CHECK(pic, v, type) do { \
if (! pic_##type##_p(pic, v)) \
pic_error(pic, TYPENAME_##type " required", 1, v); \
} while (0)
2016-02-19 07:56:45 -05:00
#define VALID_INDEX(pic, len, i) do { \
2016-02-22 14:03:42 -05:00
if (i < 0 || len <= i) pic_error(pic, "index out of range", 1, pic_int_value(pic, i)); \
2016-02-19 07:56:45 -05:00
} while (0)
#define VALID_RANGE(pic, len, s, e) do { \
2016-02-22 14:03:42 -05:00
if (s < 0 || len < s) pic_error(pic, "invalid start index", 1, pic_int_value(pic, s)); \
if (e < s || len < e) pic_error(pic, "invalid end index", 1, pic_int_value(pic, e)); \
2016-02-19 07:56:45 -05:00
} while (0)
2016-02-22 14:03:42 -05:00
#define VALID_ATRANGE(pic, tolen, at, fromlen, s, e) do { \
VALID_INDEX(pic, tolen, at); \
VALID_RANGE(pic, fromlen, s, e); \
if (tolen - at < e - s) pic_error(pic, "invalid range", 0); \
2016-02-19 07:56:45 -05:00
} while (0)
2017-04-09 06:14:02 -04:00
#if PIC_BITMAP_GC
PIC_STATIC_INLINE int
2017-04-09 06:14:02 -04:00
obj_type(pic_state *PIC_UNUSED(pic), void *ptr)
{
2017-03-28 18:11:27 -04:00
return ((struct basic *)ptr)->tt;
}
2017-04-09 06:14:02 -04:00
#else
PIC_STATIC_INLINE int
obj_type(pic_state *PIC_UNUSED(pic), void *ptr)
{
return ((struct basic *)ptr)->tt & ~GC_MARK;
}
#endif
#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;
}
PIC_STATIC_INLINE pic_value
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
{
2017-04-09 06:14:02 -04:00
pic_value v = pic_make_value(obj_type(pic, ptr));
v.u.data = ptr;
return v;
}
#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)
{
2017-04-09 06:14:02 -04:00
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); \
2017-03-28 18:11:27 -04:00
}
2017-04-01 11:12:24 -04:00
#define pic_data_p(pic,o) (pic_data_p(pic,o,NULL))
#define pic_port_p(pic,o) (pic_port_p(pic,o,NULL))
2017-04-04 01:54:58 -04:00
DEFPTR(sym, struct symbol)
2017-04-01 11:12:24 -04:00
DEFPTR(str, struct string)
DEFPTR(blob, struct blob)
DEFPTR(pair, struct pair)
DEFPTR(vec, struct vector)
DEFPTR(dict, struct dict)
DEFPTR(weak, struct weak)
DEFPTR(data, struct data)
DEFPTR(proc, struct proc)
DEFPTR(port, struct port)
DEFPTR(error, struct error)
DEFPTR(rec, struct record)
DEFPTR(irep, struct irep)
#undef pic_data_p
#undef pic_port_p
2017-03-28 18:11:27 -04:00
struct object *pic_obj_alloc(pic_state *, size_t, int type);
2017-04-09 02:05:59 -04:00
pic_value pic_make_proc_func(pic_state *, pic_func_t, int, pic_value *);
2017-04-09 02:49:04 -04:00
pic_value pic_make_proc_irep(pic_state *, struct irep *, struct frame *);
2017-03-28 10:09:40 -04:00
pic_value pic_make_record(pic_state *, pic_value type, pic_value datum);
2017-04-04 01:54:58 -04:00
pic_value pic_record_type(pic_state *pic, pic_value record);
pic_value pic_record_datum(pic_state *pic, pic_value record);
2016-02-19 02:58:39 -05:00
2016-02-26 11:38:07 -05:00
struct rope *pic_rope_incref(struct rope *);
2016-02-21 06:32:00 -05:00
void pic_rope_decref(pic_state *, struct rope *);
2016-02-19 02:58:39 -05:00
2016-02-23 08:48:06 -05:00
struct cont *pic_alloca_cont(pic_state *);
pic_value pic_make_cont(pic_state *, struct cont *);
void pic_save_point(pic_state *, struct cont *, PIC_JMPBUF *);
2016-02-23 08:42:03 -05:00
void pic_exit_point(pic_state *);
2016-02-20 05:47:46 -05:00
2017-03-31 01:39:01 -04:00
void pic_warnf(pic_state *pic, const char *fmt, ...); /* deprecated */
2016-02-10 07:50:39 -05:00
#if defined(__cplusplus)
}
#endif
#endif