Refactor dst_view_* functions.

This commit is contained in:
Calvin Rose 2018-07-04 13:15:52 -04:00
parent ad323795c0
commit 547529ebb2
12 changed files with 65 additions and 69 deletions

View File

@ -32,7 +32,7 @@ BINDIR=$(PREFIX)/bin
# TODO - when api is finalized, only export public symbols instead of using rdynamic
# which exports all symbols. Saves a few KB in binary.
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -fpic -Os -s
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -fpic -O2
CLIBS=-lm -ldl
PREFIX=/usr/local
DST_TARGET=dst

View File

@ -183,7 +183,7 @@ static int cfun_slice(DstArgs args) {
int32_t start, end;
DST_MINARITY(args, 1);
DST_MAXARITY(args, 3);
if (!dst_seq_view(args.v[0], &vals, &len))
if (!dst_indexed_view(args.v[0], &vals, &len))
DST_THROW(args, "expected array|tuple");
/* Get start */
if (args.n < 2) {
@ -231,7 +231,7 @@ static int cfun_concat(DstArgs args) {
{
int32_t j, len;
const Dst *vals;
dst_seq_view(args.v[i], &vals, &len);
dst_indexed_view(args.v[i], &vals, &len);
for (j = 0; j < len; j++)
dst_array_push(array, vals[j]);
}

View File

@ -554,7 +554,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
/* Create slot aliases */
x = dst_get(s, dst_csymbolv("slots"));
if (dst_seq_view(x, &arr, &count)) {
if (dst_indexed_view(x, &arr, &count)) {
for (i = 0; i < count; i++) {
Dst v = arr[i];
if (dst_checktype(v, DST_TUPLE)) {
@ -575,7 +575,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
/* Parse constants */
x = dst_get(s, dst_csymbolv("constants"));
if (dst_seq_view(x, &arr, &count)) {
if (dst_indexed_view(x, &arr, &count)) {
def->constants_length = count;
def->constants = malloc(sizeof(Dst) * count);
if (NULL == def->constants) {
@ -610,7 +610,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
/* Parse sub funcdefs */
x = dst_get(s, dst_csymbolv("closures"));
if (dst_seq_view(x, &arr, &count)) {
if (dst_indexed_view(x, &arr, &count)) {
int32_t i;
for (i = 0; i < count; i++) {
DstAssembleResult subres;
@ -640,7 +640,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
/* Parse bytecode and labels */
x = dst_get(s, dst_csymbolv("bytecode"));
if (dst_seq_view(x, &arr, &count)) {
if (dst_indexed_view(x, &arr, &count)) {
/* Do labels and find length */
int32_t blength = 0;
for (i = 0; i < count; ++i) {
@ -696,7 +696,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
/* Check for source mapping */
x = dst_get(s, dst_csymbolv("sourcemap"));
if (dst_seq_view(x, &arr, &count)) {
if (dst_indexed_view(x, &arr, &count)) {
dst_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode");
def->sourcemap = malloc(sizeof(DstSourceMapping) * count);
for (i = 0; i < count; i++) {

View File

@ -48,24 +48,6 @@ void dstc_cerror(DstCompiler *c, const char *m) {
dstc_error(c, dst_cstring(m));
}
/* Check error */
int dstc_iserr(DstFopts *opts) {
return (opts->compiler->result.status == DST_COMPILE_ERROR);
}
/* Get the next key in an associative data structure. Used for iterating through an
* associative data structure. */
const DstKV *dstc_next(Dst ds, const DstKV *kv) {
switch(dst_type(ds)) {
default:
return NULL;
case DST_TABLE:
return (const DstKV *) dst_table_next(dst_unwrap_table(ds), kv);
case DST_STRUCT:
return dst_struct_next(dst_unwrap_struct(ds), kv);
}
}
/* Free a slot */
void dstc_freeslot(DstCompiler *c, DstSlot s) {
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF | DST_SLOT_NAMED)) return;
@ -318,11 +300,14 @@ DstSlot *dstc_toslots(DstCompiler *c, const Dst *vals, int32_t len) {
/* Get a bunch of slots for function arguments */
DstSlot *dstc_toslotskv(DstCompiler *c, Dst ds) {
DstSlot *ret = NULL;
const DstKV *kv = NULL;
DstFopts subopts = dstc_fopts_default(c);
while ((kv = dstc_next(ds, kv))) {
dst_v_push(ret, dstc_value(subopts, kv->key));
dst_v_push(ret, dstc_value(subopts, kv->value));
const DstKV *kvs = NULL;
int32_t cap, i, len;
dst_dictionary_view(ds, &kvs, &len, &cap);
for (i = 0; i < cap; i++) {
if (dst_checktype(kvs[i].key, DST_NIL)) continue;
dst_v_push(ret, dstc_value(subopts, kvs[i].key));
dst_v_push(ret, dstc_value(subopts, kvs[i].value));
}
return ret;
}
@ -500,7 +485,7 @@ DstSlot dstc_value(DstFopts opts, Dst x) {
c->recursion_guard--;
/* Guard against previous errors and unbounded recursion */
if (dstc_iserr(&opts)) return dstc_cslot(dst_wrap_nil());
if (c->result.status == DST_COMPILE_ERROR) return dstc_cslot(dst_wrap_nil());
if (c->recursion_guard <= 0) {
dstc_cerror(c, "recursed too deeply");
return dstc_cslot(dst_wrap_nil());
@ -509,8 +494,10 @@ DstSlot dstc_value(DstFopts opts, Dst x) {
/* Macro expand. Also gets possible special form and
* refines source mapping cursor if possible. */
const DstSpecial *spec = NULL;
int macroi = DST_RECURSION_GUARD;
while (macroi && !dstc_iserr(&opts) && macroexpand1(c, x, &x, &spec))
int macroi = DST_MAX_MACRO_EXPAND;
while (macroi &&
c->result.status != DST_COMPILE_ERROR &&
macroexpand1(c, x, &x, &spec))
macroi--;
if (macroi == 0) {
dstc_cerror(c, "recursed too deeply in macro expansion");
@ -559,13 +546,11 @@ DstSlot dstc_value(DstFopts opts, Dst x) {
}
}
if (dstc_iserr(&opts)) {
if (c->result.status == DST_COMPILE_ERROR)
return dstc_cslot(dst_wrap_nil());
}
c->current_mapping = last_mapping;
if (opts.flags & DST_FOPTS_TAIL) {
if (opts.flags & DST_FOPTS_TAIL)
ret = dstc_return(opts.compiler, ret);
}
if (opts.flags & DST_FOPTS_HINT) {
dstc_copy(opts.compiler, opts.hint, ret);
ret = opts.hint;

View File

@ -175,12 +175,6 @@ const DstFunOptimizer *dstc_funopt(uint32_t flags);
/* Get a special. Return NULL if none exists */
const DstSpecial *dstc_special(const uint8_t *name);
/* Check error */
int dstc_iserr(DstFopts *opts);
/* Helper for iterating tables and structs */
const DstKV *dstc_next(Dst ds, const DstKV *kv);
void dstc_freeslot(DstCompiler *c, DstSlot s);
void dstc_nameslot(DstCompiler *c, const uint8_t *sym, DstSlot s);
DstSlot dstc_farslot(DstCompiler *c);

View File

@ -57,7 +57,7 @@ static int destructure(DstCompiler *c,
{
int32_t i, len;
const Dst *values;
dst_seq_view(left, &values, &len);
dst_indexed_view(left, &values, &len);
for (i = 0; i < len; i++) {
DstSlot nextright = dstc_farslot(c);
Dst subval = values[i];
@ -75,12 +75,15 @@ static int destructure(DstCompiler *c,
case DST_TABLE:
case DST_STRUCT:
{
const DstKV *kv = NULL;
while ((kv = dstc_next(left, kv))) {
const DstKV *kvs = NULL;
int32_t i, cap, len;
dst_dictionary_view(left, &kvs, &len, &cap);
for (i = 0; i < cap; i++) {
if (dst_checktype(kvs[i].key, DST_NIL)) continue;
DstSlot nextright = dstc_farslot(c);
DstSlot k = dstc_value(dstc_fopts_default(c), kv->key);
DstSlot k = dstc_value(dstc_fopts_default(c), kvs[i].key);
dstc_emit_sss(c, DOP_GET, nextright, right, k, 1);
if (destructure(c, kv->value, nextright, leaf, attr))
if (destructure(c, kvs[i].value, nextright, leaf, attr))
dstc_freeslot(c, nextright);
}
}
@ -190,7 +193,8 @@ DstSlot dstc_var(DstFopts opts, int32_t argn, const Dst *argv) {
DstCompiler *c = opts.compiler;
Dst head;
DstSlot ret = dohead(c, opts, &head, argn, argv);
if (dstc_iserr(&opts)) return dstc_cslot(dst_wrap_nil());
if (c->result.status == DST_COMPILE_ERROR)
return dstc_cslot(dst_wrap_nil());
if (destructure(c, argv[0], ret, varleaf, handleattr(c, argn, argv)))
dstc_freeslot(c, ret);
return dstc_cslot(dst_wrap_nil());
@ -223,7 +227,8 @@ DstSlot dstc_def(DstFopts opts, int32_t argn, const Dst *argv) {
Dst head;
opts.flags &= ~DST_FOPTS_HINT;
DstSlot ret = dohead(c, opts, &head, argn, argv);
if (dstc_iserr(&opts)) return dstc_cslot(dst_wrap_nil());
if (c->result.status == DST_COMPILE_ERROR)
return dstc_cslot(dst_wrap_nil());
if (destructure(c, argv[0], ret, defleaf, handleattr(c, argn, argv)))
dstc_freeslot(c, ret);
return dstc_cslot(dst_wrap_nil());
@ -454,7 +459,7 @@ DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) {
goto error;
}
paramv = argv[parami];
if (dst_seq_view(paramv, &params, &paramcount)) {
if (dst_indexed_view(paramv, &params, &paramcount)) {
int32_t i;
for (i = 0; i < paramcount; i++) {
Dst param = params[i];
@ -494,7 +499,7 @@ DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) {
} else for (argi = parami + 1; argi < argn; argi++) {
subopts.flags = (argi == (argn - 1)) ? DST_FOPTS_TAIL : DST_FOPTS_DROP;
dstc_value(subopts, argv[argi]);
if (dstc_iserr(&opts))
if (c->result.status == DST_COMPILE_ERROR)
goto error2;
}

View File

@ -937,7 +937,7 @@ static int cfun_join(DstArgs args) {
for (i = 0; i < partslen; i++) {
const uint8_t *chunk;
int32_t chunklen = 0;
if (!dst_chararray_view(parts[i], &chunk, &chunklen)) {
if (!dst_bytes_view(parts[i], &chunk, &chunklen)) {
DST_THROW(args, "expected string|symbol|buffer");
}
if (i) finallen += joinerlen;
@ -951,7 +951,7 @@ static int cfun_join(DstArgs args) {
memcpy(out, joiner, joinerlen);
out += joinerlen;
}
dst_chararray_view(parts[i], &chunk, &chunklen);
dst_bytes_view(parts[i], &chunk, &chunklen);
memcpy(out, chunk, chunklen);
out += chunklen;
}

View File

@ -44,7 +44,7 @@ const Dst *dst_tuple_end(Dst *tuple) {
}
/* Build a tuple with n values */
const Dst *dst_tuple_n(Dst *values, int32_t n) {
const Dst *dst_tuple_n(const Dst *values, int32_t n) {
Dst *t = dst_tuple_begin(n);
memcpy(t, values, sizeof(Dst) * n);
return dst_tuple_end(t);
@ -97,7 +97,7 @@ static int cfun_slice(DstArgs args) {
Dst *ret;
int32_t start, end;
DST_MINARITY(args, 1);
if (!dst_seq_view(args.v[0], &vals, &len)) DST_THROW(args, "expected array/tuple");
if (!dst_indexed_view(args.v[0], &vals, &len)) DST_THROW(args, "expected array/tuple");
/* Get start */
if (args.n < 2) {
start = 0;
@ -133,7 +133,7 @@ static int cfun_prepend(DstArgs args) {
int32_t len;
Dst *n;
DST_FIXARITY(args, 2);
if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
if (!dst_indexed_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
n = dst_tuple_begin(len + 1);
memcpy(n + 1, t, sizeof(Dst) * len);
n[0] = args.v[1];
@ -145,7 +145,7 @@ static int cfun_append(DstArgs args) {
int32_t len;
Dst *n;
DST_FIXARITY(args, 2);
if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
if (!dst_indexed_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
n = dst_tuple_begin(len + 1);
memcpy(n, t, sizeof(Dst) * len);
n[len] = args.v[1];

View File

@ -202,7 +202,7 @@ DstTable *dst_env_arg(DstArgs args) {
/* Read both tuples and arrays as c pointers + int32_t length. Return 1 if the
* view can be constructed, 0 if an invalid type. */
int dst_seq_view(Dst seq, const Dst **data, int32_t *len) {
int dst_indexed_view(Dst seq, const Dst **data, int32_t *len) {
if (dst_checktype(seq, DST_ARRAY)) {
*data = dst_unwrap_array(seq)->data;
*len = dst_unwrap_array(seq)->count;
@ -217,7 +217,7 @@ int dst_seq_view(Dst seq, const Dst **data, int32_t *len) {
/* Read both strings and buffer as unsigned character array + int32_t len.
* Returns 1 if the view can be constructed and 0 if the type is invalid. */
int dst_chararray_view(Dst str, const uint8_t **data, int32_t *len) {
int dst_bytes_view(Dst str, const uint8_t **data, int32_t *len) {
if (dst_checktype(str, DST_STRING) || dst_checktype(str, DST_SYMBOL)) {
*data = dst_unwrap_string(str);
*len = dst_string_length(dst_unwrap_string(str));
@ -233,7 +233,7 @@ int dst_chararray_view(Dst str, const uint8_t **data, int32_t *len) {
/* Read both structs and tables as the entries of a hashtable with
* identical structure. Returns 1 if the view can be constructed and
* 0 if the type is invalid. */
int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap) {
int dst_dictionary_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap) {
if (dst_checktype(tab, DST_TABLE)) {
*data = dst_unwrap_table(tab)->data;
*cap = dst_unwrap_table(tab)->capacity;

View File

@ -708,7 +708,7 @@ static void *op_lookup[255] = {
{
const Dst *vals;
int32_t len;
if (dst_seq_view(stack[oparg(1, 0xFFFFFF)], &vals, &len)) {
if (dst_indexed_view(stack[oparg(1, 0xFFFFFF)], &vals, &len)) {
dst_fiber_pushn(fiber, vals, len);
} else {
retreg = stack[oparg(1, 0xFFFFFF)];

View File

@ -136,13 +136,21 @@ extern "C" {
/* Maximum depth to follow table prototypes before giving up and returning nil. */
#define DST_MAX_PROTO_DEPTH 200
/* Maximum depth to follow table prototypes before giving up and returning nil. */
#define DST_MAX_MACRO_EXPAND 200
/* Define max stack size for stacks before raising a stack overflow error.
* If this is not defined, fiber stacks can grow without limit (until memory
* runs out) */
#define DST_STACK_MAX 8192
/* Use nanboxed values - uses 8 bytes per value instead of 12 or 16. */
/* Use nanboxed values - uses 8 bytes per value instead of 12 or 16.
* To turn of nanboxing, for debugging purposes or for certain
* architectures (Nanboxing only tested on x86 and x64), comment out
* the DST_NANBOX define.*/
#define DST_NANBOX
/* Further refines the type of nanboxing to use. */
#define DST_NANBOX_47
/* Alignment for pointers */
@ -895,7 +903,7 @@ int dst_buffer_push_u64(DstBuffer *buffer, uint64_t x);
#define dst_tuple_sm_col(t) ((dst_tuple_raw(t)[3]))
Dst *dst_tuple_begin(int32_t length);
const Dst *dst_tuple_end(Dst *tuple);
const Dst *dst_tuple_n(Dst *values, int32_t n);
const Dst *dst_tuple_n(const Dst *values, int32_t n);
int dst_tuple_equal(const Dst *lhs, const Dst *rhs);
int dst_tuple_compare(const Dst *lhs, const Dst *rhs);
@ -965,9 +973,9 @@ DstFiber *dst_fiber(DstFunction *callee, int32_t capacity);
#define dst_fiber_status(f) (((f)->flags & DST_FIBER_STATUS_MASK) >> DST_FIBER_STATUS_OFFSET)
/* Treat similar types through uniform interfaces for iteration */
int dst_seq_view(Dst seq, const Dst **data, int32_t *len);
int dst_chararray_view(Dst str, const uint8_t **data, int32_t *len);
int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap);
int dst_indexed_view(Dst seq, const Dst **data, int32_t *len);
int dst_bytes_view(Dst str, const uint8_t **data, int32_t *len);
int dst_dictionary_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap);
/* Abstract */
#define dst_abstract_header(u) ((DstAbstractHeader *)(u) - 1)
@ -1107,14 +1115,14 @@ int dst_lib_compile(DstArgs args);
#define DST_ARG_BYTES(DESTBYTES, DESTLEN, A, N) do {\
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
if (!dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
if (!dst_bytes_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
}\
} while (0)
#define DST_ARG_INDEXED(DESTVALS, DESTLEN, A, N) do {\
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_INDEXED);\
if (!dst_seq_view((A).v[(N)], &(DESTVALS), &(DESTLEN))) {\
if (!dst_indexed_view((A).v[(N)], &(DESTVALS), &(DESTLEN))) {\
return dst_typemany_err(A, N, DST_TFLAG_INDEXED);\
}\
} while (0)

View File

@ -194,4 +194,8 @@
(assert (= 7 (case :a :b 5 :c 6 :u 10 7)), "case with default")
# Testing the loop and for macros
(def xs (apply1 tuple (for [x :range [0 10] :when (even? x)] (tuple (/ x 2) x))))
(assert (= xs '((0 0) (1 2) (2 4) (3 6) (4 8))) "for macro 1")
(end-suite)