More work on nanbox implementation.

This commit is contained in:
Calvin Rose 2017-11-29 15:17:56 -05:00
parent b568a6bc88
commit eceb6e5a77
16 changed files with 161 additions and 119 deletions

3
.gitignore vendored
View File

@ -11,6 +11,9 @@ dst
# Tools
xxd
# Swap files
*.swp
# Tags
tags

View File

@ -79,7 +79,7 @@ CCU_FLAGS = $(CFLAGS) -DDST_UNIT_TEST
DST_UNIT_BINARIES=$(addprefix unittests/,\
asm_test.out array_test.out buffer_test.out fiber_test.out \
nanbox_test.out parse_test.out table_test.out)
parse_test.out table_test.out)
%.out: %.c $(DST_CORE_OBJECTS) $(DST_ALL_HEADERS) unittests/unit.h
$(CC) $(CCU_FLAGS) $(DST_CORE_OBJECTS) $< -o $@
@ -89,7 +89,6 @@ unit: $(DST_UNIT_BINARIES)
unittests/asm_test.out
unittests/buffer_test.out
unittests/fiber_test.out
unittests/nanbox_test.out
unittests/parse_test.out
unittests/table_test.out

View File

@ -60,12 +60,13 @@ void dst_array_ensure(DstArray *array, int32_t capacity) {
/* Set the count of an array. Extend with nil if needed. */
void dst_array_setcount(DstArray *array, int32_t count) {
if (count < 0)
return;
if (count > array->count) {
dst_array_ensure(array, count + 1);
dst_memempty(array->data + array->count, count - array->count);
}
if (count > 0)
array->count = count;
array->count = count;
}
/* Push a value to the top of the array */

View File

@ -172,7 +172,7 @@ static void dst_mark_funcdef(DstFuncDef *def) {
for (i = 0; i < count; ++i) {
DstValue v = def->constants[i];
/* Funcdefs use nil literals to store other funcdefs */
if (v.type == DST_NIL) {
if (dst_checktype(v, DST_NIL)) {
dst_mark_funcdef((DstFuncDef *) dst_unwrap_pointer(v));
} else {
dst_mark(v);

View File

@ -319,13 +319,14 @@ void dst_short_description_b(DstBuffer *buffer, DstValue x) {
}
}
/* Helper structure for stringifying deeply nested structures */
/* Helper structure for stringifying nested structures */
typedef struct DstPrinter DstPrinter;
struct DstPrinter {
DstBuffer buffer;
DstTable seen;
uint32_t flags;
int64_t next;
uint32_t state;
int32_t next;
int32_t indent;
int32_t indent_size;
int32_t token_line_limit;
@ -399,7 +400,7 @@ static void dst_print_hashtable_inner(DstPrinter *p, const DstValue *data, int32
dst_buffer_push_u8(&p->buffer, '\n');
p->indent++;
for (i = 0; i < cap; i += 2) {
if (dst_checktype(data[i], DST_NIL)) {
if (!dst_checktype(data[i], DST_NIL)) {
dst_print_indent(p);
dst_description_helper(p, data[i]);
dst_buffer_push_u8(&p->buffer, ' ');
@ -412,7 +413,7 @@ static void dst_print_hashtable_inner(DstPrinter *p, const DstValue *data, int32
} else {
int isfirst = 1;
for (i = 0; i < cap; i += 2) {
if (dst_checktype(data[i], DST_NIL)) {
if (!dst_checktype(data[i], DST_NIL)) {
if (isfirst)
isfirst = 0;
else
@ -462,52 +463,57 @@ static void dst_print_seq_inner(DstPrinter *p, const DstValue *data, int32_t len
/* Static debug print helper */
static void dst_description_helper(DstPrinter *p, DstValue x) {
const char *open;
const char *close;
int32_t len, cap;
const DstValue *data;
DstValue check;
p->depth--;
DstValue check = dst_table_get(&p->seen, x);
switch (dst_type(x)) {
default:
if (p->flags & DST_PRINTFLAG_COLORIZE) {
dst_buffer_push_cstring(&p->buffer, dst_type_colors[dst_type(x)]);
dst_short_description_b(&p->buffer, x);
dst_buffer_push_cstring(&p->buffer, "\x1B[0m");
} else {
dst_short_description_b(&p->buffer, x);
}
p->depth++;
return;
case DST_STRUCT:
open = "{"; close = "}";
break;
case DST_TABLE:
open = "@{"; close = "}";
break;
case DST_TUPLE:
open = "("; close = ")";
break;
case DST_ARRAY:
open = "["; close = "]";
break;
}
if (!p->state) {
dst_table_init(&p->seen, 10);
p->state = 1;
}
check = dst_table_get(&p->seen, x);
if (dst_checktype(check, DST_INTEGER)) {
dst_buffer_push_cstring(&p->buffer, "<cycle ");
integer_to_string_b(&p->buffer, dst_unwrap_integer(check));
dst_buffer_push_cstring(&p->buffer, ">");
} else {
const char *open;
const char *close;
int32_t len, cap;
const DstValue *data;
switch (dst_type(x)) {
default:
if (p->flags & DST_PRINTFLAG_COLORIZE) {
dst_buffer_push_cstring(&p->buffer, dst_type_colors[dst_type(x)]);
dst_short_description_b(&p->buffer, x);
dst_buffer_push_cstring(&p->buffer, "\x1B[0m");
} else {
dst_short_description_b(&p->buffer, x);
}
p->depth++;
return;
case DST_STRUCT:
open = "{"; close = "}";
break;
case DST_TABLE:
open = "@{"; close = "}";
break;
case DST_TUPLE:
open = "("; close = ")";
break;
case DST_ARRAY:
open = "["; close = "]";
break;
}
dst_table_put(&p->seen, x, dst_wrap_integer(p->next++));
dst_buffer_push_cstring(&p->buffer, open);
if (p->depth == 0) {
dst_buffer_push_cstring(&p->buffer, "...");
} else if (dst_hashtable_view(x, &data, &len, &cap)) {
dst_print_hashtable_inner(p, data, len, cap);
} else if (dst_seq_view(x, &data, &len)) {
dst_print_seq_inner(p, data, len);
}
dst_buffer_push_cstring(&p->buffer, close);
return;
}
dst_table_put(&p->seen, x, dst_wrap_integer(p->next++));
dst_buffer_push_cstring(&p->buffer, open);
if (p->depth == 0) {
dst_buffer_push_cstring(&p->buffer, "...");
} else if (dst_hashtable_view(x, &data, &len, &cap)) {
dst_print_hashtable_inner(p, data, len, cap);
} else if (dst_seq_view(x, &data, &len)) {
dst_print_seq_inner(p, data, len);
}
dst_buffer_push_cstring(&p->buffer, close);
/* Remove from seen as we know that printing completes, we
* can print in multiple times and we know we are not recursing */
dst_table_remove(&p->seen, x);
@ -530,16 +536,16 @@ const uint8_t *dst_description(DstValue x) {
const uint8_t *ret;
dst_printer_defaults(&printer);
printer.state = 0;
dst_buffer_init(&printer.buffer, 0);
dst_table_init(&printer.seen, 10);
/* Only print description up to a depth of 4 */
dst_description_helper(&printer, x);
ret = dst_string(printer.buffer.data, printer.buffer.count);
dst_buffer_deinit(&printer.buffer);
dst_table_deinit(&printer.seen);
if (printer.state)
dst_table_deinit(&printer.seen);
return ret;
}
@ -564,6 +570,7 @@ const uint8_t *dst_formatc(const char *format, ...) {
const uint8_t *ret;
DstPrinter printer;
DstBuffer *bufp = &printer.buffer;
printer.state = 0;
/* Calculate length */
while (format[len]) len++;
@ -607,13 +614,10 @@ const uint8_t *dst_formatc(const char *format, ...) {
case 'c':
dst_buffer_push_u8(bufp, va_arg(args, int64_t));
break;
case 'p':
case 'v':
{
dst_printer_defaults(&printer);
dst_table_init(&printer.seen, 10);
/* Only print description up to a depth of 4 */
dst_description_helper(&printer, va_arg(args, DstValue));
dst_table_deinit(&printer.seen);
break;
}
case 'q':
@ -629,14 +633,7 @@ const uint8_t *dst_formatc(const char *format, ...) {
}
case 'V':
{
const uint8_t *str = dst_short_description(va_arg(args, DstValue));
dst_buffer_push_bytes(bufp, str, dst_string_length(str));
break;
}
case 'v':
{
const uint8_t *str = dst_description(va_arg(args, DstValue));
dst_buffer_push_bytes(bufp, str, dst_string_length(str));
dst_short_description_b(bufp, va_arg(args, DstValue));
break;
}
}
@ -648,6 +645,8 @@ const uint8_t *dst_formatc(const char *format, ...) {
ret = dst_string(printer.buffer.data, printer.buffer.count);
dst_buffer_deinit(&printer.buffer);
if (printer.state)
dst_table_deinit(&printer.seen);
return ret;
}

View File

@ -22,6 +22,8 @@
#include <dst/dst.h>
#define dst_struct_maphash(cap, hash) (((uint32_t)(hash) % (cap)) & 0xFFFFFFFE);
/* Begin creation of a struct */
DstValue *dst_struct_begin(int32_t count) {
/* This expression determines size of structs. It must be a pure
@ -30,10 +32,11 @@ DstValue *dst_struct_begin(int32_t count) {
* sizeof(int32_t) * 2 + 2 * count * sizeof(DstValue). Adding more space
* ensures that structs are less likely to have hash collisions. If more space
* is added or s is changed, change the macro dst_struct_capacity in internal.h */
size_t s = sizeof(int32_t) * 2 + 4 * count * sizeof(DstValue);
int32_t capacity = 4 * count;
size_t s = sizeof(int32_t) * 2 + (capacity * sizeof(DstValue));
char *data = dst_alloc(DST_MEMORY_STRUCT, s);
memset(data, 0, s);
DstValue *st = (DstValue *) (data + 2 * sizeof(int32_t));
dst_memempty(st, capacity);
dst_struct_length(st) = count;
/* Use the hash storage space as a counter to see how many items
* were successfully added. If this number is not equal to the
@ -46,13 +49,13 @@ DstValue *dst_struct_begin(int32_t count) {
/* Find an item in a struct */
static const DstValue *dst_struct_find(const DstValue *st, DstValue key) {
int32_t cap = dst_struct_capacity(st);
int32_t index = (dst_hash(key) % cap) & (~1);
int32_t index = dst_struct_maphash(cap, dst_hash(key));
int32_t i;
for (i = index; i < cap; i += 2)
if (st[i].type == DST_NIL || dst_equals(st[i], key))
if (dst_checktype(st[i], DST_NIL) || dst_equals(st[i], key))
return st + i;
for (i = 0; i < index; i += 2)
if (st[i].type == DST_NIL || dst_equals(st[i], key))
if (dst_checktype(st[i], DST_NIL) || dst_equals(st[i], key))
return st + i;
return NULL;
}
@ -63,10 +66,10 @@ static const DstValue *dst_struct_find(const DstValue *st, DstValue key) {
void dst_struct_put(DstValue *st, DstValue key, DstValue value) {
int32_t cap = dst_struct_capacity(st);
int32_t hash = dst_hash(key);
int32_t index = (hash % cap) & (~1);
int32_t index = dst_struct_maphash(cap, hash);
int32_t i, j, dist;
int32_t bounds[4] = {index, cap, 0, index};
if (key.type == DST_NIL || value.type == DST_NIL) return;
if (dst_checktype(key, DST_NIL) || dst_checktype(value, DST_NIL)) return;
/* Avoid extra items */
if (dst_struct_hash(st) == dst_struct_length(st)) return;
for (dist = 0, j = 0; j < 4; j += 2)
@ -75,7 +78,7 @@ void dst_struct_put(DstValue *st, DstValue key, DstValue value) {
int32_t otherhash;
int32_t otherindex, otherdist;
/* We found an empty slot, so just add key and value */
if (st[i].type == DST_NIL) {
if (dst_checktype(st[i], DST_NIL)) {
st[i] = key;
st[i + 1] = value;
/* Update the temporary count */
@ -88,7 +91,7 @@ void dst_struct_put(DstValue *st, DstValue key, DstValue value) {
* with different order have the same internal layout, and therefor
* will compare properly - i.e., {1 2 3 4} should equal {3 4 1 2}. */
otherhash = dst_hash(st[i]);
otherindex = (otherhash % cap) & (~1);
otherindex = dst_struct_maphash(cap, otherhash);
otherdist = (i + cap - otherindex) % cap;
if (dist < otherdist)
status = -1;
@ -131,27 +134,25 @@ const DstValue *dst_struct_end(DstValue *st) {
DstValue *newst;
realCount = 0;
for (i = 0; i < dst_struct_capacity(st); i += 2) {
realCount += st[i].type != DST_NIL;
realCount += dst_checktype(st[i], DST_NIL) ? 1 : 0;
}
newst = dst_struct_begin(realCount);
for (i = 0; i < dst_struct_capacity(st); i += 2) {
if (st[i].type != DST_NIL) {
if (!dst_checktype(st[i], DST_NIL)) {
dst_struct_put(newst, st[i], st[i + 1]);
}
}
st = newst;
}
dst_struct_hash(st) = 0;
dst_struct_hash(st) = dst_array_calchash(st, dst_struct_capacity(st));
return (const DstValue *)st;
}
/* Get an item from a struct */
DstValue dst_struct_get(const DstValue *st, DstValue key) {
const DstValue *bucket = dst_struct_find(st, key);
if (!bucket || bucket[0].type == DST_NIL) {
DstValue ret;
ret.type = DST_NIL;
return ret;
if (NULL == bucket || dst_checktype(*bucket, DST_NIL)) {
return dst_wrap_nil();
} else {
return bucket[1];
}
@ -161,16 +162,16 @@ DstValue dst_struct_get(const DstValue *st, DstValue key) {
DstValue dst_struct_next(const DstValue *st, DstValue key) {
const DstValue *bucket, *end;
end = st + dst_struct_capacity(st);
if (key.type == DST_NIL) {
if (dst_checktype(key, DST_NIL)) {
bucket = st;
} else {
bucket = dst_struct_find(st, key);
if (!bucket || bucket[0].type == DST_NIL)
if (NULL == bucket || dst_checktype(*bucket, DST_NIL))
return dst_wrap_nil();
bucket += 2;
}
for (; bucket < end; bucket += 2) {
if (bucket[0].type != DST_NIL)
if (!dst_checktype(bucket[0], DST_NIL))
return bucket[0];
}
return dst_wrap_nil();
@ -181,7 +182,7 @@ DstTable *dst_struct_to_table(const DstValue *st) {
DstTable *table = dst_table(dst_struct_capacity(st));
int32_t i;
for (i = 0; i < dst_struct_capacity(st); i += 2) {
if (st[i].type != DST_NIL) {
if (!dst_checktype(st[i], DST_NIL)) {
dst_table_put(table, st[i], st[i + 1]);
}
}
@ -235,3 +236,5 @@ int dst_struct_compare(const DstValue *lhs, const DstValue *rhs) {
}
return 0;
}
#undef dst_struct_maphash

View File

@ -64,13 +64,13 @@ static const uint8_t **dst_symcache_findmem(
int32_t len,
int32_t hash,
int *success) {
int32_t bounds[4];
int32_t i, j, index;
uint32_t bounds[4];
uint32_t i, j, index;
const uint8_t **firstEmpty = NULL;
/* We will search two ranges - index to the end,
* and 0 to the index. */
index = hash % dst_vm_cache_capacity;
index = (uint32_t)hash % dst_vm_cache_capacity;
bounds[0] = index;
bounds[1] = dst_vm_cache_capacity;
bounds[2] = 0;
@ -110,8 +110,8 @@ static const uint8_t **dst_symcache_findmem(
dst_symcache_findmem((str), dst_string_length(str), dst_string_hash(str), (success))
/* Resize the cache. */
static void dst_cache_resize(int32_t newCapacity) {
int32_t i, oldCapacity;
static void dst_cache_resize(uint32_t newCapacity) {
uint32_t i, oldCapacity;
const uint8_t **oldCache = dst_vm_cache;
const uint8_t **newCache = calloc(1, newCapacity * sizeof(const uint8_t **));
if (newCache == NULL) {

View File

@ -109,7 +109,7 @@ int dst_sys_get(DstValue *argv, int32_t argn) {
ds = argv[0];
for (i = 1; i < argn; i++) {
ds = dst_get(ds, argv[i]);
if (ds.type == DST_NIL)
if (dst_checktype(ds, DST_NIL))
break;
}
dst_vm_fiber->ret = ds;

View File

@ -22,11 +22,13 @@
#include <dst/dst.h>
#define dst_table_maphash(cap, hash) (((uint32_t)(hash) % (cap)) & 0xFFFFFFFE)
/* Initialize a table */
DstTable *dst_table_init(DstTable *table, int32_t capacity) {
DstValue *data;
if (capacity < 2) capacity = 2;
data = calloc(sizeof(DstValue), capacity);
data = (DstValue *) dst_memalloc_empty(capacity);
if (NULL == data) {
DST_OUT_OF_MEMORY;
}
@ -51,7 +53,7 @@ DstTable *dst_table(int32_t capacity) {
/* Find the bucket that contains the given key. Will also return
* bucket where key should go if not in the table. */
static DstValue *dst_table_find(DstTable *t, DstValue key) {
int32_t index = (dst_hash(key) % t->capacity) & (~1);
int32_t index = dst_table_maphash(t->capacity, dst_hash(key));
int32_t i, j;
int32_t start[2], end[2];
start[0] = index; end[0] = t->capacity;
@ -74,7 +76,7 @@ static DstValue *dst_table_find(DstTable *t, DstValue key) {
/* Resize the dictionary table. */
static void dst_table_rehash(DstTable *t, int32_t size) {
DstValue *olddata = t->data;
DstValue *newdata = calloc(sizeof(DstValue), size);
DstValue *newdata = (DstValue *) dst_memalloc_empty(size);
if (NULL == newdata) {
DST_OUT_OF_MEMORY;
}
@ -179,3 +181,5 @@ const DstValue *dst_table_to_struct(DstTable *t) {
}
return dst_struct_end(st);
}
#undef dst_table_maphash

View File

@ -30,12 +30,12 @@ DstValue *dst_tuple_begin(int32_t length) {
char *data = dst_alloc(DST_MEMORY_TUPLE, 2 * sizeof(int32_t) + length * sizeof(DstValue));
DstValue *tuple = (DstValue *)(data + (2 * sizeof(int32_t)));
dst_tuple_length(tuple) = length;
dst_tuple_hash(tuple) = 0;
return tuple;
}
/* Finish building a tuple */
const DstValue *dst_tuple_end(DstValue *tuple) {
dst_tuple_hash(tuple) = dst_array_calchash(tuple, dst_tuple_length(tuple));
return (const DstValue *)tuple;
}
@ -53,14 +53,14 @@ int dst_tuple_equal(const DstValue *lhs, const DstValue *rhs) {
int32_t rlen = dst_tuple_length(rhs);
int32_t lhash = dst_tuple_hash(lhs);
int32_t rhash = dst_tuple_hash(rhs);
if (llen != rlen)
return 0;
if (lhash == 0)
lhash = dst_tuple_hash(lhs) = dst_array_calchash(lhs, llen);
if (rhash == 0)
rhash = dst_tuple_hash(rhs) = dst_array_calchash(rhs, rlen);
if (lhash != rhash)
return 0;
if (llen != rlen)
return 0;
for (index = 0; index < llen; index++) {
if (!dst_equals(lhs[index], rhs[index]))
return 0;

View File

@ -73,18 +73,10 @@ int32_t dst_hash(DstValue x) {
hash = dst_string_hash(dst_unwrap_string(x));
break;
case DST_TUPLE:
if (0 == dst_tuple_hash(dst_unwrap_tuple(x)))
hash = dst_tuple_hash(dst_unwrap_tuple(x)) =
dst_array_calchash(dst_unwrap_tuple(x), dst_tuple_length(dst_unwrap_tuple(x)));
else
hash = dst_tuple_hash(dst_unwrap_tuple(x));
hash = dst_tuple_hash(dst_unwrap_tuple(x));
break;
case DST_STRUCT:
if (0 == dst_struct_hash(dst_unwrap_struct(x)))
hash = dst_struct_hash(dst_unwrap_struct(x)) =
dst_array_calchash(dst_unwrap_struct(x), dst_struct_capacity(dst_unwrap_struct(x)));
else
hash = dst_struct_hash(dst_unwrap_struct(x));
hash = dst_struct_hash(dst_unwrap_struct(x));
break;
default:
if (sizeof(double) == sizeof(void *)) {

View File

@ -24,7 +24,7 @@
#ifdef DST_NANBOX
void *dst_nanbox_to_pointer(dst_t x) {
void *dst_nanbox_to_pointer(DstValue x) {
/* We need to do this shift to keep the higher bits of the pointer
* the same as bit 47 as required by the x86 architecture. We may save
* an instruction if we do x.u64 & DST_NANBOX_POINTERBITS, but this 0s
@ -41,6 +41,14 @@ DstValue dst_nanbox_from_pointer(void *p, uint64_t tagmask) {
return ret;
}
DstValue dst_nanbox_from_cpointer(const void *p, uint64_t tagmask) {
DstValue ret;
ret.cpointer = p;
ret.u64 &= DST_NANBOX_POINTERBITS;
ret.u64 |= tagmask;
return ret;
}
DstValue dst_nanbox_from_double(double d) {
DstValue ret;
ret.real = d;
@ -51,13 +59,23 @@ DstValue dst_nanbox_from_double(double d) {
}
DstValue dst_nanbox_from_bits(uint64_t bits) {
dst_t ret;
DstValue ret;
ret.u64 = bits;
return ret;
}
void dst_nanbox_memempty(DstValue *mem, uint32_t count) {
uint32_t i;
void *dst_nanbox_memalloc_empty(int32_t count) {
int32_t i;
void *mem = malloc(count * sizeof(DstValue));
DstValue *mmem = (DstValue *)mem;
for (i = 0; i < count; i++) {
mmem[i] = dst_wrap_nil();
}
return mem;
}
void dst_nanbox_memempty(DstValue *mem, int32_t count) {
int32_t i;
for (i = 0; i < count; i++) {
mem[i] = dst_wrap_nil();
}
@ -74,24 +92,28 @@ void dst_nanbox_memempty(DstValue *mem, uint32_t count) {
DstValue dst_wrap_nil() {
DstValue y;
y.type = DST_NIL;
y.as.u64 = 0;
return y;
}
DstValue dst_wrap_true() {
DstValue y;
y.type = DST_TRUE;
y.as.u64 = 0;
return y;
}
DstValue dst_wrap_false() {
DstValue y;
y.type = DST_TRUE;
y.type = DST_FALSE;
y.as.u64 = 0;
return y;
}
DstValue dst_wrap_boolean(int x) {
DstValue y;
y.type = x ? DST_TRUE : DST_FALSE;
y.as.u64 = 0;
return y;
}

View File

@ -104,6 +104,8 @@
* ands crashing (the parser). Instead, error out. */
#define DST_RECURSION_GUARD 1000
/* #define DST_NANBOX */
#ifdef DST_NANBOX
typedef union DstValue DstValue;
#else
@ -171,10 +173,13 @@ typedef enum DstType {
#ifdef DST_NANBOX
#include <math.h>
union DstValue {
uint64_t u64;
int64_t i64;
void *pointer;
const void *cpointer;
double real;
};
@ -228,11 +233,14 @@ union DstValue {
void *dst_nanbox_to_pointer(DstValue x);
void dst_nanbox_memempty(DstValue *mem, int32_t count);
void *dst_nanbox_memalloc_empty(int32_t count);
DstValue dst_nanbox_from_pointer(void *p, uint64_t tagmask);
DstValue dst_nanbox_from_cpointer(const void *p, uint64_t tagmask);
DstValue dst_nanbox_from_double(double d);
DstValue dst_nanbox_from_bits(uint64_t bits);
#define dst_memempty dst_nanbox_memempty
#define dst_memempty(mem, len) dst_nanbox_memempty((mem), (len))
#define dst_memalloc_empty(count) dst_nanbox_memalloc_empty(count)
/* Todo - check for single mask operation */
#define dst_truthy(x) \
@ -244,6 +252,9 @@ DstValue dst_nanbox_from_bits(uint64_t bits);
#define dst_nanbox_wrap_(p, t) \
dst_nanbox_from_pointer((p), dst_nanbox_tag(t) | 0x7FF8000000000000lu)
#define dst_nanbox_wrap_c(p, t) \
dst_nanbox_from_cpointer((p), dst_nanbox_tag(t) | 0x7FF8000000000000lu)
/* Wrap the simple types */
#define dst_wrap_nil() dst_nanbox_from_payload(DST_NIL, 1)
#define dst_wrap_true() dst_nanbox_from_payload(DST_TRUE, 1)
@ -260,14 +271,14 @@ DstValue dst_nanbox_from_bits(uint64_t bits);
#define dst_unwrap_real(x) ((x).real)
/* Wrap the pointer types */
#define dst_wrap_struct(s) dst_nanbox_wrap_((s), DST_STRUCT)
#define dst_wrap_tuple(s) dst_nanbox_wrap_((s), DST_TUPLE)
#define dst_wrap_struct(s) dst_nanbox_wrap_c((s), DST_STRUCT)
#define dst_wrap_tuple(s) dst_nanbox_wrap_c((s), DST_TUPLE)
#define dst_wrap_fiber(s) dst_nanbox_wrap_((s), DST_FIBER)
#define dst_wrap_array(s) dst_nanbox_wrap_((s), DST_ARRAY)
#define dst_wrap_table(s) dst_nanbox_wrap_((s), DST_TABLE)
#define dst_wrap_buffer(s) dst_nanbox_wrap_((s), DST_BUFFER)
#define dst_wrap_string(s) dst_nanbox_wrap_((s), DST_STRING)
#define dst_wrap_symbol(s) dst_nanbox_wrap_((s), DST_SYMBOL)
#define dst_wrap_string(s) dst_nanbox_wrap_c((s), DST_STRING)
#define dst_wrap_symbol(s) dst_nanbox_wrap_c((s), DST_SYMBOL)
#define dst_wrap_userdata(s) dst_nanbox_wrap_((s), DST_USERDATA)
#define dst_wrap_function(s) dst_nanbox_wrap_((s), DST_FUNCTION)
#define dst_wrap_cfunction(s) dst_nanbox_wrap_((s), DST_CFUNCTION)
@ -303,6 +314,7 @@ struct DstValue {
#define dst_u64(x) ((x).as.u64)
#define dst_memempty(mem, count) memset((mem), 0, sizeof(DstValue) * (count))
#define dst_memalloc_empty(count) calloc((count), sizeof(DstValue))
#define dst_type(x) ((x).type)
#define dst_checktype(x, t) ((x).type == (t))
#define dst_truthy(x) \

View File

@ -3,7 +3,7 @@
int main() {
int64_t i;
int32_t i;
dst_init();
DstArray *array = dst_array(10);
assert(array->capacity == 10);
@ -11,7 +11,8 @@ int main() {
for (i = 0; i < 500; ++i)
dst_array_push(array, dst_wrap_integer(i));
for (i = 0; i < 500; ++i)
assert(array->data[i].type == DST_INTEGER && array->data[i].as.integer == i);
assert(dst_checktype(array->data[i], DST_INTEGER) &&
dst_unwrap_integer(array->data[i]) == i);
for (i = 0; i < 200; ++i)
dst_array_pop(array);
assert(array->count == 300);

View File

@ -7,6 +7,8 @@ int main() {
DstAssembleResult ares;
DstFunction *func;
printf("sizeof(DstValue) = %lu\n", sizeof(DstValue));
FILE *f = fopen("./dsts/minimal.dsts", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
@ -30,6 +32,7 @@ int main() {
assert(pres.status == DST_PARSE_OK);
dst_puts(dst_formatc("\nparse result: %v\n\n", pres.result.value));
/*
opts.flags = 0;
opts.source = pres.result.value;
opts.parsemap = dst_wrap_nil();
@ -45,6 +48,9 @@ int main() {
dst_run(dst_wrap_function(func));
dst_puts(dst_formatc("result: %v\n", dst_vm_fiber->ret));
*/
dst_deinit();
return 0;
}

View File

@ -10,7 +10,7 @@ int main() {
pres = dst_parsec("'(+ 1 () [] 3 5 :hello \"hi\\h41\")");
assert(pres.status == DST_PARSE_OK);
assert(pres.result.value.type == DST_TUPLE);
assert(dst_checktype(pres.result.value, DST_TUPLE));
str = dst_to_string(pres.result.value);
printf("%.*s\n", dst_string_length(str), (const char *) str);