mirror of
https://github.com/janet-lang/janet
synced 2025-01-10 23:50:26 +00:00
Refactor dst_view_* functions.
This commit is contained in:
parent
ad323795c0
commit
547529ebb2
2
Makefile
2
Makefile
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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, ¶ms, ¶mcount)) {
|
||||
if (dst_indexed_view(paramv, ¶ms, ¶mcount)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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)];
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user