picrin/lib/object.h

213 lines
5.3 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"
2017-04-11 13:54:03 -04:00
#define OBJECT_HEADER \
2017-03-28 10:09:40 -04:00
unsigned char tt;
2017-04-09 06:14:02 -04:00
2017-04-11 13:54:03 -04:00
#define TYPE_MASK 0x7f
#define GC_MARK 0x80
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-05-12 10:08:46 -04:00
struct blob {
OBJECT_HEADER
unsigned char *data;
int len;
};
struct string {
OBJECT_HEADER
struct rope *rope;
};
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;
};
2017-05-12 10:08:46 -04:00
struct vector {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2017-05-12 10:08:46 -04:00
pic_value *data;
2016-02-18 10:20:15 -05:00
int len;
};
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-04-29 11:23:38 -04:00
KHASH_DECLARE(attr, struct object *, pic_value)
2017-03-28 10:09:40 -04:00
2017-04-29 11:23:38 -04:00
struct attr {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2017-04-29 11:23:38 -04:00
khash_t(attr) hash;
struct attr *prev; /* for GC */
2016-02-10 07:50:39 -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-04-14 10:40:07 -04:00
enum {
OP_HALT = 0x00, /* 0x00 OP_HALT */
OP_CALL = 0x01, /* 0x01 0x** OP_CALL argc */
OP_PROC = 0x02, /* 0x02 0x** 0x** OP_PROC dest irep */
OP_LOAD = 0x03, /* 0x03 0x** 0x** OP_LOAD dest i */
OP_LREF = 0x04, /* 0x04 0x** 0x** 0x** OP_LREF dest n i */
OP_LSET = 0x05, /* 0x05 0x** 0x** 0x** OP_LSET src n i */
OP_GREF = 0x06, /* 0x06 0x** 0x** OP_GREF dest i */
OP_GSET = 0x07, /* 0x07 0x** 0x** OP_GSET src i */
OP_COND = 0x08, /* 0x08 0x** 0x** 0x** OP_COND c offset */
OP_LOADT = 0x09, /* 0x09 0x** OP_LOADT dest */
OP_LOADF = 0x0A, /* 0x0A 0x** OP_LOADF dest */
OP_LOADN = 0x0B, /* 0x0B 0x** OP_LOADN dest */
OP_LOADU = 0x0C, /* 0x0C 0x** OP_LOADU dest */
2017-04-15 02:45:28 -04:00
OP_LOADI = 0x0D /* 0x0D 0x** 0x** OP_LOADI dest i */
2017-04-14 10:40:07 -04:00
};
typedef unsigned char code_t;
#define IREP_VARG 1
#define IREP_CODE_STATIC 2
2017-03-30 10:29:08 -04:00
struct irep {
OBJECT_HEADER
2017-04-14 10:40:07 -04:00
unsigned char argc;
unsigned char flags;
unsigned char frame_size;
unsigned char irepc, objc;
2017-04-22 20:16:40 -04:00
size_t codec;
2017-03-30 10:29:08 -04:00
struct irep **irep;
2017-04-14 10:40:07 -04:00
pic_value *obj;
const code_t *code;
2017-03-30 10:29:08 -04:00
};
2017-04-09 02:49:04 -04:00
struct frame {
2016-02-23 12:36:09 -05:00
OBJECT_HEADER
2017-04-14 10:40:07 -04:00
unsigned char regc;
2017-04-09 02:49:04 -04:00
pic_value *regs;
struct frame *up;
2016-02-18 10:56:56 -05:00
};
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;
2017-04-14 10:40:07 -04:00
struct frame *env;
2016-02-18 10:56:56 -05:00
};
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_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
PIC_STATIC_INLINE int
2017-05-05 23:53:20 -04:00
obj_type(void *ptr)
2017-04-09 06:14:02 -04:00
{
2017-05-05 23:53:20 -04:00
return ((struct basic *) ptr)->tt & TYPE_MASK;
}
PIC_STATIC_INLINE pic_value
2017-05-05 23:53:20 -04:00
obj_value(pic_state *pic, void *ptr)
{
2017-05-05 23:53:20 -04:00
return pic_obj_value(pic, ptr, obj_type(ptr));
}
2017-05-06 12:36:56 -04:00
#define DEFPTR(name,type) \
PIC_STATIC_INLINE type * \
name##_ptr(pic_state *pic, pic_value o) { \
assert(pic_##name##_p(pic,o)); \
return (type *) pic_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))
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)
2017-04-29 11:23:38 -04:00
DEFPTR(attr, struct attr)
2017-04-01 11:12:24 -04:00
DEFPTR(data, struct data)
DEFPTR(proc, struct proc)
DEFPTR(rec, struct record)
DEFPTR(irep, struct irep)
#undef pic_data_p
2017-03-28 18:11:27 -04:00
2017-04-12 00:18:06 -04:00
struct object *pic_obj_alloc(pic_state *, int type);
2017-04-14 10:40:07 -04:00
struct object *pic_obj_alloc_unsafe(pic_state *, int type);
2017-03-28 18:11:27 -04:00
2017-04-14 10:40:07 -04:00
struct frame *pic_make_frame_unsafe(pic_state *, int n);
pic_value pic_make_proc_irep_unsafe(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);
2017-04-20 16:28:15 -04:00
pic_value pic_make_cont(pic_state *pic, pic_value k);
2017-05-09 11:49:15 -04:00
int pic_str_hash(pic_state *pic, pic_value str);
int pic_str_cmp(pic_state *pic, pic_value str1, pic_value str2);
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-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