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 \
|
|
|
|
unsigned char tt; \
|
|
|
|
char gc_mark;
|
|
|
|
#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
|
2016-02-20 02:12:21 -05:00
|
|
|
};
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2017-04-02 06:16:25 -04:00
|
|
|
struct record {
|
|
|
|
OBJECT_HEADER
|
|
|
|
pic_value type;
|
|
|
|
pic_value datum;
|
|
|
|
};
|
|
|
|
|
2017-03-30 10:29:08 -04:00
|
|
|
struct code {
|
|
|
|
int insn;
|
|
|
|
int a;
|
|
|
|
int b;
|
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct context {
|
2016-02-23 12:36:09 -05:00
|
|
|
OBJECT_HEADER
|
2016-02-18 10:56:56 -05:00
|
|
|
pic_value *regs;
|
|
|
|
int regc;
|
2016-02-21 06:32:00 -05:00
|
|
|
struct context *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 {
|
|
|
|
struct {
|
|
|
|
pic_func_t func;
|
|
|
|
int localc;
|
|
|
|
} f;
|
|
|
|
struct {
|
2016-02-21 06:32:00 -05:00
|
|
|
struct irep *irep;
|
|
|
|
struct context *cxt;
|
2016-02-18 10:56:56 -05:00
|
|
|
} i;
|
|
|
|
} u;
|
|
|
|
pic_value locals[1];
|
|
|
|
};
|
|
|
|
|
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
|
|
|
};
|
|
|
|
|
2017-04-02 06:16:25 -04:00
|
|
|
struct error {
|
|
|
|
OBJECT_HEADER
|
2017-04-04 01:54:58 -04:00
|
|
|
struct symbol *type;
|
2017-04-02 06:16:25 -04:00
|
|
|
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-03-28 19:32:28 -04:00
|
|
|
PIC_STATIC_INLINE int
|
|
|
|
obj_tt(pic_state *PIC_UNUSED(pic), void *ptr)
|
|
|
|
{
|
2017-03-28 18:11:27 -04:00
|
|
|
return ((struct basic *)ptr)->tt;
|
|
|
|
}
|
|
|
|
|
2017-03-28 18:58:08 -04:00
|
|
|
#if !PIC_NAN_BOXING
|
|
|
|
|
|
|
|
PIC_STATIC_INLINE struct object *
|
2017-03-28 19:32:28 -04:00
|
|
|
obj_ptr(pic_state *PIC_UNUSED(pic), pic_value v)
|
2017-03-28 18:58:08 -04:00
|
|
|
{
|
|
|
|
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
|
2017-03-28 19:32:28 -04:00
|
|
|
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
|
2017-03-28 18:58:08 -04:00
|
|
|
{
|
2017-03-28 19:32:28 -04:00
|
|
|
pic_value v = pic_make_value(obj_tt(pic, ptr));
|
2017-03-28 18:58:08 -04:00
|
|
|
v.u.data = ptr;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* NAN_BOXING */
|
|
|
|
|
|
|
|
PIC_STATIC_INLINE struct object *
|
2017-03-28 19:32:28 -04:00
|
|
|
obj_ptr(pic_state *PIC_UNUSED(pic), pic_value v)
|
2017-03-28 18:58:08 -04:00
|
|
|
{
|
|
|
|
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
|
2017-03-28 19:32:28 -04:00
|
|
|
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
|
2017-03-28 18:58:08 -04:00
|
|
|
{
|
2017-03-28 19:32:28 -04:00
|
|
|
pic_value v = pic_make_value(obj_tt(pic, ptr));
|
2017-03-28 18:58:08 -04:00
|
|
|
v.v |= 0x3ffffffffffful & ((uint64_t)ptr >> 2);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* NAN_BOXING */
|
|
|
|
|
2017-04-06 09:29:02 -04:00
|
|
|
#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 *);
|
2016-02-21 06:32:00 -05:00
|
|
|
pic_value pic_make_proc_irep(pic_state *, struct irep *, struct context *);
|
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
|