picrin/lib/object.h

296 lines
6.8 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 \
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-21 06:32:00 -05:00
struct identifier {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 11:05:28 -05:00
union {
2016-02-21 06:32:00 -05:00
struct string *str;
struct identifier *id;
2016-02-18 11:05:28 -05:00
} u;
2016-02-21 06:32:00 -05:00
struct env *env;
2016-02-18 11:05:28 -05:00
};
2017-03-28 10:09:40 -04:00
typedef struct identifier symbol;
KHASH_DECLARE(env, struct identifier *, symbol *)
2016-02-21 06:32:00 -05:00
struct env {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-19 05:08:45 -05:00
khash_t(env) map;
2016-02-21 06:32:00 -05:00
struct env *up;
struct string *lib;
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-03-28 10:09:40 -04:00
KHASH_DECLARE(dict, symbol *, pic_value)
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;
};
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];
};
2016-02-21 06:32:00 -05:00
struct record {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-18 10:59:45 -05:00
pic_value type;
pic_value datum;
};
2016-02-21 06:32:00 -05:00
struct error {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
symbol *type;
2016-02-21 06:32:00 -05:00
struct string *msg;
2016-02-18 11:34:13 -05:00
pic_value irrs;
2016-02-21 06:32:00 -05:00
struct string *stack;
2016-02-18 11:34:13 -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
};
2016-02-21 06:32:00 -05:00
struct checkpoint {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2016-02-21 06:32:00 -05:00
struct proc *in;
struct proc *out;
int depth;
2016-02-21 06:32:00 -05:00
struct checkpoint *prev;
};
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_id "identifier"
#define TYPENAME_env "environment"
#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)
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;
}
#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)
{
pic_value v = pic_make_value(obj_tt(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)
{
pic_value v = pic_make_value(obj_tt(pic, ptr));
v.v |= 0x3ffffffffffful & ((uint64_t)ptr >> 2);
return v;
}
#endif /* NAN_BOXING */
2017-03-28 18:11:27 -04:00
#define DEFPTR(name,type) \
PIC_STATIC_INLINE type *name(pic_state *PIC_UNUSED(pic), pic_value o) { \
return (type *) obj_ptr(pic, o); \
2017-03-28 18:11:27 -04:00
}
DEFPTR(pic_id_ptr, struct identifier)
DEFPTR(pic_sym_ptr, symbol)
DEFPTR(pic_str_ptr, struct string)
DEFPTR(pic_blob_ptr, struct blob)
DEFPTR(pic_pair_ptr, struct pair)
DEFPTR(pic_vec_ptr, struct vector)
DEFPTR(pic_dict_ptr, struct dict)
DEFPTR(pic_weak_ptr, struct weak)
DEFPTR(pic_data_ptr, struct data)
DEFPTR(pic_proc_ptr, struct proc)
DEFPTR(pic_env_ptr, struct env)
DEFPTR(pic_port_ptr, struct port)
DEFPTR(pic_error_ptr, struct error)
DEFPTR(pic_rec_ptr, struct record)
DEFPTR(pic_cp_ptr, struct checkpoint)
struct object *pic_obj_alloc(pic_state *, size_t, int type);
2016-02-20 02:33:51 -05:00
pic_value pic_make_identifier(pic_state *, pic_value id, pic_value env);
2016-02-19 10:03:16 -05:00
pic_value pic_make_proc(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 *);
2016-02-20 02:33:51 -05:00
pic_value pic_make_env(pic_state *, pic_value env);
2017-03-28 10:09:40 -04:00
pic_value pic_make_record(pic_state *, pic_value type, pic_value datum);
2016-02-19 02:58:39 -05:00
2016-02-20 02:33:51 -05:00
pic_value pic_add_identifier(pic_state *, pic_value id, pic_value env);
2016-02-22 09:49:39 -05:00
void pic_put_identifier(pic_state *, pic_value id, pic_value uid, pic_value env);
2016-02-20 02:33:51 -05:00
pic_value pic_find_identifier(pic_state *, pic_value id, pic_value env);
2016-02-20 01:59:06 -05:00
pic_value pic_id_name(pic_state *, pic_value id);
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-21 06:32:00 -05:00
void pic_wind(pic_state *, struct checkpoint *, struct checkpoint *);
2016-02-23 06:50:26 -05:00
pic_value pic_dynamic_wind(pic_state *, pic_value in, pic_value thunk, pic_value out);
2016-02-20 05:47:46 -05:00
2016-02-23 08:42:03 -05:00
pic_value pic_dynamic_bind(pic_state *, pic_value var, pic_value val, pic_value thunk);
2016-02-19 02:58:39 -05:00
2016-02-23 08:55:15 -05:00
pic_value pic_library_environment(pic_state *, const char *);
2016-02-10 07:50:39 -05:00
#if defined(__cplusplus)
}
#endif
#endif