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
|
|
|
|
|
2016-02-20 11:13:16 -05:00
|
|
|
#include "picrin/private/khash.h"
|
2016-02-20 10:30:40 -05:00
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
typedef struct identifier symbol;
|
2016-02-20 05:10:51 -05:00
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
KHASH_DECLARE(env, struct identifier *, symbol *)
|
2016-02-21 06:21:02 -05:00
|
|
|
KHASH_DECLARE(dict, symbol *, pic_value)
|
2016-02-21 06:32:00 -05:00
|
|
|
KHASH_DECLARE(weak, struct object *, pic_value)
|
2016-02-18 11:05:28 -05:00
|
|
|
|
2016-02-20 02:12:21 -05:00
|
|
|
#define PIC_OBJECT_HEADER \
|
|
|
|
unsigned char tt; \
|
|
|
|
char gc_mark;
|
|
|
|
|
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-20 02:12:21 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct identifier {
|
2016-02-19 15:18:13 -05:00
|
|
|
PIC_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
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct env {
|
2016-02-19 05:08:45 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
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-18 12:29:40 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
pic_value car;
|
|
|
|
pic_value cdr;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct blob {
|
2016-02-18 10:20:15 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
unsigned char *data;
|
|
|
|
int len;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct string {
|
2016-02-18 10:14:50 -05:00
|
|
|
PIC_OBJECT_HEADER
|
2016-02-21 06:32:00 -05:00
|
|
|
struct rope *rope;
|
2016-02-18 10:14:50 -05:00
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct dict {
|
2016-02-18 10:40:35 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
khash_t(dict) hash;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct weak {
|
2016-02-10 07:50:39 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
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-19 05:08:45 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
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-18 10:50:13 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
const pic_data_type *type;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct context {
|
2016-02-18 10:56:56 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
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-18 10:56:56 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
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-18 10:59:45 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
pic_value type;
|
|
|
|
pic_value datum;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct error {
|
2016-02-18 11:34:13 -05:00
|
|
|
PIC_OBJECT_HEADER
|
2016-02-21 06:21:02 -05:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct port {
|
2016-02-18 15:58:34 -05:00
|
|
|
PIC_OBJECT_HEADER
|
|
|
|
xFILE *file;
|
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct checkpoint {
|
2016-02-20 02:12:21 -05:00
|
|
|
PIC_OBJECT_HEADER
|
2016-02-21 06:32:00 -05:00
|
|
|
struct proc *in;
|
|
|
|
struct proc *out;
|
2016-02-20 02:12:21 -05:00
|
|
|
int depth;
|
2016-02-21 06:32:00 -05:00
|
|
|
struct checkpoint *prev;
|
2016-02-20 02:12:21 -05:00
|
|
|
};
|
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
struct object *pic_obj_ptr(pic_value);
|
2016-02-20 05:00:41 -05:00
|
|
|
|
2016-02-21 06:32:00 -05:00
|
|
|
#define pic_id_ptr(pic, o) (assert(pic_id_p(pic, o)), (struct identifier *)pic_obj_ptr(o))
|
2016-02-21 06:21:02 -05:00
|
|
|
#define pic_sym_ptr(pic, o) (assert(pic_sym_p(pic, o)), (symbol *)pic_obj_ptr(o))
|
2016-02-21 06:32:00 -05:00
|
|
|
#define pic_str_ptr(pic, o) (assert(pic_str_p(pic, o)), (struct string *)pic_obj_ptr(o))
|
|
|
|
#define pic_blob_ptr(pic, o) (assert(pic_blob_p(pic, o)), (struct blob *)pic_obj_ptr(o))
|
|
|
|
#define pic_pair_ptr(pic, o) (assert(pic_pair_p(pic, o)), (struct pair *)pic_obj_ptr(o))
|
|
|
|
#define pic_vec_ptr(pic, o) (assert(pic_vec_p(pic, o)), (struct vector *)pic_obj_ptr(o))
|
|
|
|
#define pic_dict_ptr(pic, o) (assert(pic_dict_p(pic, o)), (struct dict *)pic_obj_ptr(o))
|
|
|
|
#define pic_weak_ptr(pic, o) (assert(pic_weak_p(pic, o)), (struct weak *)pic_obj_ptr(o))
|
|
|
|
#define pic_data_ptr(pic, o) (assert(pic_data_p(pic, o, NULL)), (struct data *)pic_obj_ptr(o))
|
|
|
|
#define pic_proc_ptr(pic, o) (assert(pic_proc_p(pic, o)), (struct proc *)pic_obj_ptr(o))
|
|
|
|
#define pic_env_ptr(pic, o) (assert(pic_env_p(pic, o)), (struct env *)pic_obj_ptr(o))
|
|
|
|
#define pic_port_ptr(pic, o) (assert(pic_port_p(pic, o)), (struct port *)pic_obj_ptr(o))
|
|
|
|
#define pic_error_ptr(pic, o) (assert(pic_error_p(pic, o)), (struct error *)pic_obj_ptr(o))
|
|
|
|
#define pic_rec_ptr(pic, o) (assert(pic_rec_p(pic, o)), (struct record *)pic_obj_ptr(o))
|
2016-02-18 15:58:34 -05:00
|
|
|
|
2016-02-20 05:00:41 -05:00
|
|
|
#define pic_obj_p(pic,v) (pic_type(pic,v) > PIC_IVAL_END)
|
2016-02-19 05:08:45 -05:00
|
|
|
#define pic_env_p(pic, v) (pic_type(pic, v) == PIC_TYPE_ENV)
|
|
|
|
#define pic_error_p(pic, v) (pic_type(pic, v) == PIC_TYPE_ERROR)
|
|
|
|
#define pic_rec_p(pic, v) (pic_type(pic, v) == PIC_TYPE_RECORD)
|
2016-02-18 15:58:34 -05:00
|
|
|
|
2016-02-20 05:00:41 -05:00
|
|
|
pic_value pic_obj_value(void *ptr);
|
2016-02-21 06:32:00 -05:00
|
|
|
struct object *pic_obj_alloc(pic_state *, size_t, int type);
|
2016-02-19 02:58:39 -05:00
|
|
|
|
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)
|
|
|
|
|
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);
|
2016-02-20 03:27:13 -05:00
|
|
|
pic_value pic_make_rec(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-21 06:32:00 -05:00
|
|
|
void pic_rope_incref(pic_state *, struct rope *);
|
|
|
|
void pic_rope_decref(pic_state *, struct rope *);
|
2016-02-19 02:58:39 -05:00
|
|
|
|
2016-02-23 06:50:26 -05:00
|
|
|
#define pic_func_p(pic, proc) (pic_type(pic, proc) == PIC_TYPE_FUNC)
|
|
|
|
#define pic_irep_p(pic, proc) (pic_type(pic, proc) == PIC_TYPE_IREP)
|
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-10 07:50:39 -05:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|