diff --git a/Makefile b/Makefile index 03e06ab5..7e42f824 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ PREFIX=/usr/local DST_TARGET=dst DST_XXD=xxd DEBUGGER=lldb -DST_INTERNAL_HEADERS=$(addprefix core/,symcache.h opcodes.h strtod.h compile.h gc.h sourcemap.h vector.h) +DST_INTERNAL_HEADERS=$(addprefix core/,symcache.h opcodes.h strtod.h compile.h gc.h sourcemap.h util.h) DST_HEADERS=$(addprefix include/dst/,dst.h dstconfig.h dsttypes.h dststate.h dststl.h) ############################# @@ -50,7 +50,7 @@ DST_CORE_SOURCES=$(addprefix core/,\ abstract.c array.c asm.c buffer.c compile.c\ fiber.c gc.c math.c parse.c sourcemap.c string.c\ stl.c strtod.c struct.c symcache.c table.c tuple.c util.c\ - value.c vector.c vm.c wrap.c) + value.c vm.c wrap.c) DST_CLIENT_SOURCES=$(addprefix client/,\ main.c) diff --git a/client/main.c b/client/main.c index f1dd6b38..8a7192f6 100644 --- a/client/main.c +++ b/client/main.c @@ -30,7 +30,7 @@ #define DST_CLIENT_REPL 8 #define DST_CLIENT_UNKNOWN 16 -static DstValue env; +static Dst env; static int client_strequal(const char *a, const char *b) { while (*a) if (*a++ != *b++) return 0; @@ -115,7 +115,7 @@ static int repl() { if (cres.status == DST_COMPILE_OK) { /*dst_puts(dst_formatc("asm: %v\n", dst_disasm(cres.funcdef)));*/ DstFunction *f = dst_compile_func(cres); - DstValue ret; + Dst ret; if (dst_run(dst_wrap_function(f), &ret)) { dst_puts(dst_formatc("runtime error: %S\n", dst_to_string(ret))); } else { @@ -159,7 +159,7 @@ static void runfile(const uint8_t *src, int32_t len) { opts.env = env; cres = dst_compile(opts); if (cres.status == DST_COMPILE_OK) { - DstValue ret = dst_wrap_nil(); + Dst ret = dst_wrap_nil(); DstFunction *f = dst_compile_func(cres); if (dst_run(dst_wrap_function(f), &ret)) { dst_puts(dst_formatc("runtime error: %v\n", ret)); diff --git a/core/array.c b/core/array.c index befe16d5..8ff2060e 100644 --- a/core/array.c +++ b/core/array.c @@ -25,9 +25,9 @@ /* Iniializes an array */ DstArray *dst_array_init(DstArray *array, int32_t capacity) { - DstValue *data = NULL; + Dst *data = NULL; if (capacity > 0) { - data = (DstValue *) malloc(sizeof(DstValue) * capacity); + data = (Dst *) malloc(sizeof(Dst) * capacity); if (NULL == data) { DST_OUT_OF_MEMORY; } @@ -50,10 +50,10 @@ DstArray *dst_array(int32_t capacity) { /* Ensure the array has enough capacity for elements */ void dst_array_ensure(DstArray *array, int32_t capacity) { - DstValue *newData; - DstValue *old = array->data; + Dst *newData; + Dst *old = array->data; if (capacity <= array->capacity) return; - newData = realloc(old, capacity * sizeof(DstValue)); + newData = realloc(old, capacity * sizeof(Dst)); if (NULL == newData) { DST_OUT_OF_MEMORY; } @@ -76,7 +76,7 @@ void dst_array_setcount(DstArray *array, int32_t count) { } /* Push a value to the top of the array */ -void dst_array_push(DstArray *array, DstValue x) { +void dst_array_push(DstArray *array, Dst x) { int32_t newcount = array->count + 1; if (newcount >= array->capacity) { dst_array_ensure(array, newcount * 2); @@ -86,7 +86,7 @@ void dst_array_push(DstArray *array, DstValue x) { } /* Pop a value from the top of the array */ -DstValue dst_array_pop(DstArray *array) { +Dst dst_array_pop(DstArray *array) { if (array->count) { return array->data[--array->count]; } else { @@ -95,7 +95,7 @@ DstValue dst_array_pop(DstArray *array) { } /* Look at the last value in the array */ -DstValue dst_array_peek(DstArray *array) { +Dst dst_array_peek(DstArray *array) { if (array->count) { return array->data[array->count - 1]; } else { diff --git a/core/asm.c b/core/asm.c index f0a13dbc..d9eadb81 100644 --- a/core/asm.c +++ b/core/asm.c @@ -26,6 +26,7 @@ #include "opcodes.h" #include "gc.h" #include "sourcemap.h" +#include "util.h" /* Bytecode op argument types */ @@ -95,7 +96,7 @@ struct DstAssembler { int32_t defs_capacity; int32_t bytecode_count; /* Used for calculating labels */ - DstValue name; + Dst name; DstTable labels; /* symbol -> bytecode index */ DstTable constants; /* symbol -> constant index */ DstTable slots; /* symbol -> slot index */ @@ -214,8 +215,8 @@ static void dst_asm_errorv(DstAssembler *a, const uint8_t *m) { * to reference outer function environments, and may change the outer environment. * Returns the index of the environment in the assembler's environments, or -1 * if not found. */ -static int32_t dst_asm_addenv(DstAssembler *a, DstValue envname) { - DstValue check; +static int32_t dst_asm_addenv(DstAssembler *a, Dst envname) { + Dst check; DstFuncDef *def = a->def; int32_t envindex; int32_t res; @@ -250,7 +251,7 @@ static int32_t dst_asm_addenv(DstAssembler *a, DstValue envname) { static int32_t doarg_1( DstAssembler *a, DstOpArgType argtype, - DstValue x) { + Dst x) { int32_t ret = -1; DstTable *c; switch (argtype) { @@ -286,7 +287,7 @@ static int32_t doarg_1( break; case DST_TUPLE: { - const DstValue *t = dst_unwrap_tuple(x); + const Dst *t = dst_unwrap_tuple(x); if (argtype == DST_OAT_TYPE) { int32_t i = 0; ret = 0; @@ -301,7 +302,7 @@ static int32_t doarg_1( case DST_SYMBOL: { if (NULL != c) { - DstValue result = dst_table_get(c, x); + Dst result = dst_table_get(c, x); if (dst_checktype(result, DST_INTEGER)) { if (argtype == DST_OAT_LABEL) { ret = dst_unwrap_integer(result) - a->bytecode_count; @@ -348,7 +349,7 @@ static uint32_t doarg( int nth, int nbytes, int hassign, - DstValue x) { + Dst x) { int32_t arg = doarg_1(a, argtype, x); /* Calculate the min and max values that can be stored given * nbytes, and whether or not the storage is signed */ @@ -367,7 +368,7 @@ static uint32_t doarg( static uint32_t read_instruction( DstAssembler *a, const DstInstructionDef *idef, - const DstValue *argt) { + const Dst *argt) { uint32_t instr = idef->opcode; switch (idef->type) { case DIT_0: @@ -483,11 +484,11 @@ static uint32_t read_instruction( static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) { DstAssembleResult result; DstAssembler a; - DstValue s = opts.source; + Dst s = opts.source; DstFuncDef *def; int32_t count, i; - const DstValue *arr; - DstValue x; + const Dst *arr; + Dst x; /* Initialize funcdef */ def = dst_gcalloc(DST_MEMORY_FUNCDEF, sizeof(DstFuncDef)); @@ -560,9 +561,9 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) x = dst_get(s, dst_csymbolv("slots")); if (dst_seq_view(x, &arr, &count)) { for (i = 0; i < count; i++) { - DstValue v = arr[i]; + Dst v = arr[i]; if (dst_checktype(v, DST_TUPLE)) { - const DstValue *t = dst_unwrap_tuple(v); + const Dst *t = dst_unwrap_tuple(v); int32_t j; for (j = 0; j < dst_tuple_length(t); j++) { if (!dst_checktype(t[j], DST_SYMBOL)) @@ -581,16 +582,16 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) x = dst_get(s, dst_csymbolv("constants")); if (dst_seq_view(x, &arr, &count)) { def->constants_length = count; - def->constants = malloc(sizeof(DstValue) * count); + def->constants = malloc(sizeof(Dst) * count); if (NULL == def->constants) { DST_OUT_OF_MEMORY; } for (i = 0; i < count; i++) { - DstValue ct = arr[i]; + Dst ct = arr[i]; if (dst_checktype(ct, DST_TUPLE) && dst_tuple_length(dst_unwrap_tuple(ct)) > 1 && dst_checktype(dst_unwrap_tuple(ct)[0], DST_SYMBOL)) { - const DstValue *t = dst_unwrap_tuple(ct); + const Dst *t = dst_unwrap_tuple(ct); int32_t tcount = dst_tuple_length(t); const uint8_t *macro = dst_unwrap_symbol(t[0]); if (0 == dst_cstrcmp(macro, "quote")) { @@ -619,7 +620,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) for (i = 0; i < count; i++) { DstAssembleResult subres; DstAssembleOptions subopts; - DstValue subname; + Dst subname; int32_t newlen; subopts.source = arr[i]; subopts.flags = opts.flags; @@ -651,7 +652,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) /* Do labels and find length */ int32_t blength = 0; for (i = 0; i < count; ++i) { - DstValue instr = arr[i]; + Dst instr = arr[i]; if (dst_checktype(instr, DST_SYMBOL)) { dst_table_put(&a.labels, instr, dst_wrap_integer(blength)); } else if (dst_checktype(instr, DST_TUPLE)) { @@ -668,13 +669,13 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) } /* Do bytecode */ for (i = 0; i < count; ++i) { - DstValue instr = arr[i]; + Dst instr = arr[i]; if (dst_checktype(instr, DST_SYMBOL)) { continue; } else { uint32_t op; const DstInstructionDef *idef; - const DstValue *t; + const Dst *t; dst_asm_assert(&a, dst_checktype(instr, DST_TUPLE), "expected tuple"); t = dst_unwrap_tuple(instr); if (dst_tuple_length(t) == 0) { @@ -704,8 +705,8 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, DstAssembleOptions opts) dst_asm_assert(&a, count != 2 * def->bytecode_length, "sourcemap must have twice the length of the bytecode"); def->sourcemap = malloc(sizeof(int32_t) * 2 * count); for (i = 0; i < count; i += 2) { - DstValue start = arr[i]; - DstValue end = arr[i + 1]; + Dst start = arr[i]; + Dst end = arr[i + 1]; if (!(dst_checktype(start, DST_INTEGER) || dst_unwrap_integer(start) < 0)) { dst_asm_error(&a, "expected positive integer"); @@ -760,26 +761,26 @@ static const DstInstructionDef *dst_asm_reverse_lookup(uint32_t instr) { } /* Create some constant sized tuples */ -static DstValue tup1(DstValue x) { - DstValue *tup = dst_tuple_begin(1); +static Dst tup1(Dst x) { + Dst *tup = dst_tuple_begin(1); tup[0] = x; return dst_wrap_tuple(dst_tuple_end(tup)); } -static DstValue tup2(DstValue x, DstValue y) { - DstValue *tup = dst_tuple_begin(2); +static Dst tup2(Dst x, Dst y) { + Dst *tup = dst_tuple_begin(2); tup[0] = x; tup[1] = y; return dst_wrap_tuple(dst_tuple_end(tup)); } -static DstValue tup3(DstValue x, DstValue y, DstValue z) { - DstValue *tup = dst_tuple_begin(3); +static Dst tup3(Dst x, Dst y, Dst z) { + Dst *tup = dst_tuple_begin(3); tup[0] = x; tup[1] = y; tup[2] = z; return dst_wrap_tuple(dst_tuple_end(tup)); } -static DstValue tup4(DstValue w, DstValue x, DstValue y, DstValue z) { - DstValue *tup = dst_tuple_begin(4); +static Dst tup4(Dst w, Dst x, Dst y, Dst z) { + Dst *tup = dst_tuple_begin(4); tup[0] = w; tup[1] = x; tup[2] = y; @@ -788,9 +789,9 @@ static DstValue tup4(DstValue w, DstValue x, DstValue y, DstValue z) { } /* Given an argument, convert it to the appriate integer or symbol */ -DstValue dst_asm_decode_instruction(uint32_t instr) { +Dst dst_asm_decode_instruction(uint32_t instr) { const DstInstructionDef *def = dst_asm_reverse_lookup(instr); - DstValue name; + Dst name; if (NULL == def) { return dst_wrap_integer((int32_t)instr); } @@ -832,7 +833,7 @@ DstValue dst_asm_decode_instruction(uint32_t instr) { #undef oparg } -DstValue dst_disasm(DstFuncDef *def) { +Dst dst_disasm(DstFuncDef *def) { int32_t i; DstArray *bcode = dst_array(def->bytecode_length); DstArray *constants; @@ -856,8 +857,8 @@ DstValue dst_disasm(DstFuncDef *def) { constants = dst_array(def->constants_length); dst_table_put(ret, dst_csymbolv("constants"), dst_wrap_array(constants)); for (i = 0; i < def->constants_length; i++) { - DstValue src = def->constants[i]; - DstValue dest; + Dst src = def->constants[i]; + Dst dest; if (dst_checktype(src, DST_TUPLE)) { dest = tup2(dst_csymbolv("quote"), src); } else { diff --git a/core/compile.c b/core/compile.c index 8bf534aa..9ab878bc 100644 --- a/core/compile.c +++ b/core/compile.c @@ -25,10 +25,10 @@ #include "compile.h" #include "gc.h" #include "sourcemap.h" -#include "vector.h" +#include "util.h" /* Throw an error with a dst string. */ -void dstc_error(DstCompiler *c, const DstValue *sourcemap, const uint8_t *m) { +void dstc_error(DstCompiler *c, const Dst *sourcemap, const uint8_t *m) { /* Don't override first error */ if (c->result.status == DST_COMPILE_ERROR) { return; @@ -45,15 +45,15 @@ void dstc_error(DstCompiler *c, const DstValue *sourcemap, const uint8_t *m) { } /* Throw an error with a message in a cstring */ -void dstc_cerror(DstCompiler *c, const DstValue *sourcemap, const char *m) { +void dstc_cerror(DstCompiler *c, const Dst *sourcemap, const char *m) { dstc_error(c, sourcemap, dst_cstring(m)); } /* Use these to get sub options. They will traverse the source map so * compiler errors make sense. Then modify the returned options. */ -DstFormOptions dstc_getindex(DstFormOptions opts, int32_t index) { - const DstValue *sourcemap = dst_sourcemap_index(opts.sourcemap, index); - DstValue nextval = dst_getindex(opts.x, index); +DstFopts dstc_getindex(DstFopts opts, int32_t index) { + const Dst *sourcemap = dst_sourcemap_index(opts.sourcemap, index); + Dst nextval = dst_getindex(opts.x, index); opts.x = nextval; opts.flags = 0; opts.sourcemap = sourcemap; @@ -61,8 +61,8 @@ DstFormOptions dstc_getindex(DstFormOptions opts, int32_t index) { } /* Index into the key of a table or struct */ -DstFormOptions dstc_getkey(DstFormOptions opts, DstValue key) { - const DstValue *sourcemap = dst_sourcemap_key(opts.sourcemap, key); +DstFopts dstc_getkey(DstFopts opts, Dst key) { + const Dst *sourcemap = dst_sourcemap_key(opts.sourcemap, key); opts.x = key; opts.sourcemap = sourcemap; opts.flags = 0; @@ -70,9 +70,9 @@ DstFormOptions dstc_getkey(DstFormOptions opts, DstValue key) { } /* Index into the value of a table or struct */ -DstFormOptions dstc_getvalue(DstFormOptions opts, DstValue key) { - const DstValue *sourcemap = dst_sourcemap_value(opts.sourcemap, key); - DstValue nextval = dst_get(opts.x, key); +DstFopts dstc_getvalue(DstFopts opts, Dst key) { + const Dst *sourcemap = dst_sourcemap_value(opts.sourcemap, key); + Dst nextval = dst_get(opts.x, key); opts.x = nextval; opts.sourcemap = sourcemap; opts.flags = 0; @@ -80,7 +80,7 @@ DstFormOptions dstc_getvalue(DstFormOptions opts, DstValue key) { } /* Check error */ -static int dstc_iserr(DstFormOptions *opts) { +static int dstc_iserr(DstFopts *opts) { return (opts->compiler->result.status == DST_COMPILE_ERROR); } @@ -151,7 +151,7 @@ static void dstc_nameslot(DstCompiler *c, const uint8_t *sym, DstSlot s) { } /* Add a constant to the current scope. Return the index of the constant. */ -static int32_t dstc_const(DstCompiler *c, const DstValue *sourcemap, DstValue x) { +static int32_t dstc_const(DstCompiler *c, const Dst *sourcemap, Dst x) { DstScope *scope = &dst_v_last(c->scopes); int32_t i, len; /* Get the topmost function scope */ @@ -203,13 +203,6 @@ void dstc_popscope(DstCompiler *c) { int32_t oldcount = dst_v_count(c->scopes); dst_assert(oldcount, "could not pop scope"); scope = dst_v_last(c->scopes); - /* Move free slots to parent scope if not a new function. - * We need to know the total number of slots used when compiling the function. */ - if (!(scope.flags & (DST_SCOPE_FUNCTION | DST_SCOPE_UNUSED)) && oldcount > 1) { - DstScope *newscope = &dst_v_last(c->scopes); - if (newscope->smax < scope.smax) - newscope->smax = scope.smax; - } /* Free the scope */ dst_v_free(scope.consts); dst_v_free(scope.syms); @@ -217,10 +210,17 @@ void dstc_popscope(DstCompiler *c) { dst_v_free(scope.defs); dst_v_free(scope.slots); dst_v_pop(c->scopes); + /* Move free slots to parent scope if not a new function. + * We need to know the total number of slots used when compiling the function. */ + if (!(scope.flags & (DST_SCOPE_FUNCTION | DST_SCOPE_UNUSED)) && oldcount > 1) { + DstScope *newscope = &dst_v_last(c->scopes); + if (newscope->smax < scope.smax) + newscope->smax = scope.smax; + } } /* Create a slot with a constant */ -DstSlot dstc_cslot(DstValue x) { +DstSlot dstc_cslot(Dst x) { DstSlot ret; ret.flags = (1 << dst_type(x)) | DST_SLOT_CONSTANT; ret.index = -1; @@ -232,7 +232,7 @@ DstSlot dstc_cslot(DstValue x) { /* Allow searching for symbols. Return information about the symbol */ DstSlot dstc_resolve( DstCompiler *c, - const DstValue *sourcemap, + const Dst *sourcemap, const uint8_t *sym) { DstSlot ret = dstc_cslot(dst_wrap_nil()); @@ -261,8 +261,8 @@ DstSlot dstc_resolve( /* Symbol not found - check for global */ { - DstValue check = dst_get(c->env, dst_wrap_symbol(sym)); - DstValue ref; + Dst check = dst_get(c->env, dst_wrap_symbol(sym)); + Dst ref; if (!(dst_checktype(check, DST_STRUCT) || dst_checktype(check, DST_TABLE))) { dstc_error(c, sourcemap, dst_formatc("unknown symbol %q", sym)); return dstc_cslot(dst_wrap_nil()); @@ -275,7 +275,7 @@ DstSlot dstc_resolve( ret.flags &= ~DST_SLOT_CONSTANT; return ret; } else { - DstValue value = dst_get(check, dst_csymbolv("value")); + Dst value = dst_get(check, dst_csymbolv("value")); return dstc_cslot(value); } } @@ -333,7 +333,7 @@ DstSlot dstc_resolve( } /* Emit a raw instruction with source mapping. */ -void dstc_emit(DstCompiler *c, const DstValue *sourcemap, uint32_t instr) { +void dstc_emit(DstCompiler *c, const Dst *sourcemap, uint32_t instr) { dst_v_push(c->buffer, instr); if (NULL != sourcemap) { dst_v_push(c->mapbuffer, dst_unwrap_integer(sourcemap[0])); @@ -345,7 +345,7 @@ void dstc_emit(DstCompiler *c, const DstValue *sourcemap, uint32_t instr) { } /* Load a constant into a local slot */ -static void dstc_loadconst(DstCompiler *c, const DstValue *sourcemap, DstValue k, int32_t dest) { +static void dstc_loadconst(DstCompiler *c, const Dst *sourcemap, Dst k, int32_t dest) { switch (dst_type(k)) { case DST_NIL: dstc_emit(c, sourcemap, (dest << 8) | DOP_LOAD_NIL); @@ -384,7 +384,7 @@ static void dstc_loadconst(DstCompiler *c, const DstValue *sourcemap, DstValue k * that can be used in an instruction. */ static int32_t dstc_preread( DstCompiler *c, - const DstValue *sourcemap, + const Dst *sourcemap, int32_t max, int nth, DstSlot s) { @@ -436,7 +436,7 @@ static void dstc_postread(DstCompiler *c, DstSlot s, int32_t index) { * be writeable (not a literal). */ static void dstc_copy( DstCompiler *c, - const DstValue *sourcemap, + const Dst *sourcemap, DstSlot dest, DstSlot src) { int writeback = 0; @@ -559,7 +559,7 @@ static void dstc_copy( } /* Generate the return instruction for a slot. */ -static DstSlot dstc_return(DstCompiler *c, const DstValue *sourcemap, DstSlot s) { +static DstSlot dstc_return(DstCompiler *c, const Dst *sourcemap, DstSlot s) { if (!(s.flags & DST_SLOT_RETURNED)) { if (s.flags & DST_SLOT_CONSTANT && dst_checktype(s.constant, DST_NIL)) { dstc_emit(c, sourcemap, DOP_RETURN_NIL); @@ -575,7 +575,7 @@ static DstSlot dstc_return(DstCompiler *c, const DstValue *sourcemap, DstSlot s) /* Get a target slot for emitting an instruction. Will always return * a local slot. */ -static DstSlot dstc_gettarget(DstFormOptions opts) { +static DstSlot dstc_gettarget(DstFopts opts) { DstSlot slot; if ((opts.flags & DST_FOPTS_HINT) && (opts.hint.envindex == 0) && @@ -593,17 +593,17 @@ static DstSlot dstc_gettarget(DstFormOptions opts) { /* Slot and map pairing */ typedef struct SlotMap { DstSlot slot; - const DstValue *map; + const Dst *map; } SlotMap; /* Get a bunch of slots for function arguments */ -SlotMap *toslots(DstFormOptions opts, int32_t start) { +SlotMap *toslots(DstFopts opts, int32_t start) { int32_t i, len; SlotMap *ret = NULL; len = dst_length(opts.x); for (i = start; i < len; i++) { SlotMap sm; - DstFormOptions subopts = dstc_getindex(opts, i); + DstFopts subopts = dstc_getindex(opts, i); sm.slot = dstc_value(subopts); sm.map = subopts.sourcemap; dst_v_push(ret, sm); @@ -612,13 +612,13 @@ SlotMap *toslots(DstFormOptions opts, int32_t start) { } /* Get a bunch of slots for function arguments */ -static SlotMap *toslotskv(DstFormOptions opts) { +static SlotMap *toslotskv(DstFopts opts) { SlotMap *ret = NULL; const DstKV *kv = NULL; while (NULL != (kv = dst_next(opts.x, kv))) { SlotMap km, vm; - DstFormOptions kopts = dstc_getkey(opts, kv->key); - DstFormOptions vopts = dstc_getvalue(opts, kv->key); + DstFopts kopts = dstc_getkey(opts, kv->key); + DstFopts vopts = dstc_getvalue(opts, kv->key); km.slot = dstc_value(kopts); km.map = kopts.sourcemap; vm.slot = dstc_value(vopts); @@ -630,9 +630,9 @@ static SlotMap *toslotskv(DstFormOptions opts) { } /* Push slots load via toslots. */ -static void pushslots(DstFormOptions opts, SlotMap *sms) { +static void pushslots(DstFopts opts, SlotMap *sms) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; int32_t i; for (i = 0; i < dst_v_count(sms) - 2; i += 3) { int32_t ls1 = dstc_preread(c, sms[i].map, 0xFF, 1, sms[i].slot); @@ -666,7 +666,7 @@ static void pushslots(DstFormOptions opts, SlotMap *sms) { } /* Free slots loaded via toslots */ -static void freeslots(DstFormOptions opts, SlotMap *sms) { +static void freeslots(DstFopts opts, SlotMap *sms) { int32_t i; for (i = 0; i < dst_v_count(sms); i++) { dstc_freeslot(opts.compiler, sms[i].slot); @@ -674,7 +674,7 @@ static void freeslots(DstFormOptions opts, SlotMap *sms) { dst_v_free(sms); } -DstSlot dstc_quote(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_quote(DstFopts opts, int32_t argn, const Dst *argv) { if (argn != 1) { dstc_cerror(opts.compiler, opts.sourcemap, "expected 1 argument"); return dstc_cslot(dst_wrap_nil()); @@ -682,9 +682,9 @@ DstSlot dstc_quote(DstFormOptions opts, int32_t argn, const DstValue *argv) { return dstc_cslot(argv[0]); } -DstSlot dstc_var(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_var(DstFopts opts, int32_t argn, const Dst *argv) { DstCompiler *c = opts.compiler; - DstFormOptions subopts; + DstFopts subopts; DstSlot ret; if (argn != 2) { dstc_cerror(opts.compiler, opts.sourcemap, "expected 2 arguments"); @@ -699,7 +699,7 @@ DstSlot dstc_var(DstFormOptions opts, int32_t argn, const DstValue *argv) { ret = dstc_value(subopts); if (dst_v_last(c->scopes).flags & DST_SCOPE_TOP) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; DstSlot refslot, refarrayslot; /* Global var, generate var */ DstTable *reftab = dst_table(1); @@ -742,8 +742,8 @@ DstSlot dstc_var(DstFormOptions opts, int32_t argn, const DstValue *argv) { return ret; } -DstSlot dstc_varset(DstFormOptions opts, int32_t argn, const DstValue *argv) { - DstFormOptions subopts; +DstSlot dstc_varset(DstFopts opts, int32_t argn, const Dst *argv) { + DstFopts subopts; DstSlot ret, dest; if (argn != 2) { dstc_cerror(opts.compiler, opts.sourcemap, "expected 2 arguments"); @@ -766,9 +766,9 @@ DstSlot dstc_varset(DstFormOptions opts, int32_t argn, const DstValue *argv) { return ret; } -DstSlot dstc_def(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_def(DstFopts opts, int32_t argn, const Dst *argv) { DstCompiler *c = opts.compiler; - DstFormOptions subopts; + DstFopts subopts; DstSlot ret; if (argn != 2) { dstc_cerror(opts.compiler, opts.sourcemap, "expected 2 arguments"); @@ -785,7 +785,7 @@ DstSlot dstc_def(DstFormOptions opts, int32_t argn, const DstValue *argv) { if (dst_v_last(c->scopes).flags & DST_SCOPE_TOP) { /* Global def, generate code to store in env when executed */ DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; /* Root scope, add to def table */ DstSlot envslot = dstc_cslot(c->env); DstSlot nameslot = dstc_cslot(argv[0]); @@ -830,7 +830,7 @@ DstSlot dstc_def(DstFormOptions opts, int32_t argn, const DstValue *argv) { /* Compile some code that will be thrown away. Used to ensure * that dead code is well formed without including it in the final * bytecode. */ -static void dstc_throwaway(DstFormOptions opts) { +static void dstc_throwaway(DstFopts opts) { DstCompiler *c = opts.compiler; int32_t bufstart = dst_v_count(c->buffer); dstc_scope(c, DST_SCOPE_UNUSED); @@ -854,11 +854,11 @@ static void dstc_throwaway(DstFormOptions opts) { * ... * :done */ -DstSlot dstc_if(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_if(DstFopts opts, int32_t argn, const Dst *argv) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; int32_t labelr, labeljr, labeld, labeljd, condlocal; - DstFormOptions leftopts, rightopts, condopts; + DstFopts leftopts, rightopts, condopts; DstSlot cond, left, right, target; const int tail = opts.flags & DST_FOPTS_TAIL; const int drop = opts.flags & DST_FOPTS_DROP; @@ -893,7 +893,7 @@ DstSlot dstc_if(DstFormOptions opts, int32_t argn, const DstValue *argv) { /* Check constant condition. */ /* TODO: Use type info for more short circuits */ if ((cond.flags & DST_SLOT_CONSTANT) && !(cond.flags & DST_SLOT_REF)) { - DstFormOptions goodopts, badopts; + DstFopts goodopts, badopts; if (dst_truthy(cond.constant)) { goodopts = leftopts; badopts = rightopts; @@ -946,13 +946,13 @@ DstSlot dstc_if(DstFormOptions opts, int32_t argn, const DstValue *argv) { return target; } -DstSlot dstc_do(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_do(DstFopts opts, int32_t argn, const Dst *argv) { int32_t i; DstSlot ret; dstc_scope(opts.compiler, 0); (void) argv; for (i = 0; i < argn; i++) { - DstFormOptions subopts = dstc_getindex(opts, i + 1); + DstFopts subopts = dstc_getindex(opts, i + 1); if (i != argn - 1) { subopts.flags = DST_FOPTS_DROP; } else if (opts.flags & DST_FOPTS_TAIL) { @@ -976,9 +976,9 @@ DstSlot dstc_do(DstFormOptions opts, int32_t argn, const DstValue *argv) { * jump :whiletop * :done */ -DstSlot dstc_while(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_while(DstFopts opts, int32_t argn, const Dst *argv) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; DstSlot cond; int32_t condlocal, labelwt, labeld, labeljt, labelc, i; int infinite = 0; @@ -1016,7 +1016,7 @@ DstSlot dstc_while(DstFormOptions opts, int32_t argn, const DstValue *argv) { /* Compile body */ for (i = 1; i < argn; i++) { - DstFormOptions subopts = dstc_getindex(opts, i + 1); + DstFopts subopts = dstc_getindex(opts, i + 1); subopts.flags = DST_FOPTS_DROP; dstc_freeslot(c, dstc_value(subopts)); } @@ -1101,14 +1101,14 @@ static int32_t dstc_addfuncdef(DstCompiler *c, DstFuncDef *def) { return dst_v_count(scope->defs) - 1; } -DstSlot dstc_fn(DstFormOptions opts, int32_t argn, const DstValue *argv) { +DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; DstFuncDef *def; DstSlot ret; int32_t paramcount, argi, parami, arity, localslot, defindex; - const DstValue *params; - const DstValue *psm; + const Dst *params; + const Dst *psm; int varargs = 0; if (argn < 2) { @@ -1131,7 +1131,7 @@ DstSlot dstc_fn(DstFormOptions opts, int32_t argn, const DstValue *argv) { psm = dst_sourcemap_index(sm, parami + 1); int32_t i; for (i = 0; i < paramcount; i++) { - const DstValue *psmi = dst_sourcemap_index(psm, i); + const Dst *psmi = dst_sourcemap_index(psm, i); if (dst_checktype(params[i], DST_SYMBOL)) { DstSlot slot; /* Check for varargs */ @@ -1163,7 +1163,7 @@ DstSlot dstc_fn(DstFormOptions opts, int32_t argn, const DstValue *argv) { /* Compile function body */ for (argi = parami + 1; argi < argn; argi++) { DstSlot s; - DstFormOptions subopts = dstc_getindex(opts, argi + 1); + DstFopts subopts = dstc_getindex(opts, argi + 1); subopts.flags = argi == (argn - 1) ? DST_FOPTS_TAIL : DST_FOPTS_DROP; s = dstc_value(subopts); dstc_freeslot(c, s); @@ -1210,11 +1210,11 @@ static const DstSpecial dstc_specials[] = { }; /* Compile a tuple */ -DstSlot dstc_tuple(DstFormOptions opts) { +DstSlot dstc_tuple(DstFopts opts) { DstSlot head; - DstFormOptions subopts; + DstFopts subopts; DstCompiler *c = opts.compiler; - const DstValue *tup = dst_unwrap_tuple(opts.x); + const Dst *tup = dst_unwrap_tuple(opts.x); int headcompiled = 0; subopts = dstc_getindex(opts, 0); subopts.flags = DST_FUNCTION | DST_CFUNCTION; @@ -1268,9 +1268,9 @@ DstSlot dstc_tuple(DstFormOptions opts) { } } -static DstSlot dstc_array(DstFormOptions opts) { +static DstSlot dstc_array(DstFopts opts) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; DstSlot ctor, retslot; SlotMap *sms; int32_t localindex; @@ -1291,9 +1291,9 @@ static DstSlot dstc_array(DstFormOptions opts) { return retslot; } -static DstSlot dstc_tablector(DstFormOptions opts, DstCFunction cfun) { +static DstSlot dstc_tablector(DstFopts opts, DstCFunction cfun) { DstCompiler *c = opts.compiler; - const DstValue *sm = opts.sourcemap; + const Dst *sm = opts.sourcemap; DstSlot ctor, retslot; SlotMap *sms; int32_t localindex; @@ -1315,7 +1315,7 @@ static DstSlot dstc_tablector(DstFormOptions opts, DstCFunction cfun) { } /* Compile a single value */ -DstSlot dstc_value(DstFormOptions opts) { +DstSlot dstc_value(DstFopts opts) { DstSlot ret; if (dstc_iserr(&opts)) { return dstc_cslot(dst_wrap_nil()); @@ -1356,7 +1356,7 @@ DstSlot dstc_value(DstFormOptions opts) { } /* Initialize a compiler */ -static void dstc_init(DstCompiler *c, DstValue env) { +static void dstc_init(DstCompiler *c, Dst env) { c->scopes = NULL; c->buffer = NULL; c->mapbuffer = NULL; @@ -1382,7 +1382,7 @@ static void dstc_deinit(DstCompiler *c) { /* Compile a form. */ DstCompileResult dst_compile(DstCompileOptions opts) { DstCompiler c; - DstFormOptions fopts; + DstFopts fopts; DstSlot s; dstc_init(&c, opts.env); diff --git a/core/compile.h b/core/compile.h index 84b39a16..88479239 100644 --- a/core/compile.h +++ b/core/compile.h @@ -33,7 +33,7 @@ typedef struct FormOptions FormOptions; typedef struct SlotTracker SlotTracker; typedef struct DstScope DstScope; typedef struct DstSlot DstSlot; -typedef struct DstFormOptions DstFormOptions; +typedef struct DstFopts DstFopts; typedef struct DstCFunctionOptimizer DstCFunctionOptimizer; #define DST_SLOT_CONSTANT 0x10000 @@ -50,7 +50,7 @@ struct DstSlot { int32_t index; int32_t envindex; /* 0 is local, positive number is an upvalue */ uint32_t flags; - DstValue constant; /* If the slot has a constant value */ + Dst constant; /* If the slot has a constant value */ }; /* Special forms that need support */ @@ -80,7 +80,7 @@ typedef struct SymPair { struct DstScope { /* Constants for this funcdef */ - DstValue *consts; + Dst *consts; /* Map of symbols to slots. Use a simple linear scan for symbols. */ SymPair *syms; @@ -110,7 +110,7 @@ struct DstCompiler { int32_t *mapbuffer; /* Hold the environment */ - DstValue env; + Dst env; DstCompileResult result; }; @@ -120,10 +120,10 @@ struct DstCompiler { #define DST_FOPTS_DROP 0x40000 /* Options for compiling a single form */ -struct DstFormOptions { +struct DstFopts { DstCompiler *compiler; - DstValue x; - const DstValue *sourcemap; + Dst x; + const Dst *sourcemap; uint32_t flags; /* bit set of accepted primitive types */ DstSlot hint; }; @@ -133,40 +133,40 @@ struct DstFormOptions { * optimizations should be tried before compiling a normal function call. */ struct DstCFunctionOptimizer { DstCFunction cfun; - DstSlot (*optimize)(DstFormOptions opts, int32_t argn, const DstValue *argv); + DstSlot (*optimize)(DstFopts opts, int32_t argn, const Dst *argv); }; typedef struct DstSpecial { const char *name; - DstSlot (*compile)(DstFormOptions opts, int32_t argn, const DstValue *argv); + DstSlot (*compile)(DstFopts opts, int32_t argn, const Dst *argv); } DstSpecial; /* An array of optimizers sorted by key */ extern DstCFunctionOptimizer dstcr_optimizers[255]; /* Dispatch to correct form compiler */ -DstSlot dstc_value(DstFormOptions opts); +DstSlot dstc_value(DstFopts opts); /****************************************************/ -void dstc_error(DstCompiler *c, const DstValue *sourcemap, const uint8_t *m); -void dstc_cerror(DstCompiler *c, const DstValue *sourcemap, const char *m); +void dstc_error(DstCompiler *c, const Dst *sourcemap, const uint8_t *m); +void dstc_cerror(DstCompiler *c, const Dst *sourcemap, const char *m); /* Use these to get sub options. They will traverse the source map so * compiler errors make sense. Then modify the returned options. */ -DstFormOptions dstc_getindex(DstFormOptions opts, int32_t index); -DstFormOptions dstc_getkey(DstFormOptions opts, DstValue key); -DstFormOptions dstc_getvalue(DstFormOptions opts, DstValue key); +DstFopts dstc_getindex(DstFopts opts, int32_t index); +DstFopts dstc_getkey(DstFopts opts, Dst key); +DstFopts dstc_getvalue(DstFopts opts, Dst key); void dstc_scope(DstCompiler *c, int newfn); void dstc_popscope(DstCompiler *c); -DstSlot dstc_cslot(DstValue x); +DstSlot dstc_cslot(Dst x); void dstc_freeslot(DstCompiler *c, DstSlot slot); /* Search for a symbol */ -DstSlot dstc_resolve(DstCompiler *c, const DstValue *sourcemap, const uint8_t *sym); +DstSlot dstc_resolve(DstCompiler *c, const Dst *sourcemap, const uint8_t *sym); /* Emit instructions. */ -void dstc_emit(DstCompiler *c, const DstValue *sourcemap, uint32_t instr); +void dstc_emit(DstCompiler *c, const Dst *sourcemap, uint32_t instr); #endif diff --git a/core/fiber.c b/core/fiber.c index 0c1ac031..7fd72166 100644 --- a/core/fiber.c +++ b/core/fiber.c @@ -28,7 +28,7 @@ DstFiber *dst_fiber(int32_t capacity) { DstFiber *fiber = dst_gcalloc(DST_MEMORY_FIBER, sizeof(DstFiber)); fiber->capacity = capacity; if (capacity) { - DstValue *data = malloc(sizeof(DstValue) * capacity); + Dst *data = malloc(sizeof(Dst) * capacity); if (NULL == data) { DST_OUT_OF_MEMORY; } @@ -52,7 +52,7 @@ DstFiber *dst_fiber_reset(DstFiber *fiber) { /* Ensure that the fiber has enough extra capacity */ void dst_fiber_setcapacity(DstFiber *fiber, int32_t n) { - DstValue *newData = realloc(fiber->data, sizeof(DstValue) * n); + Dst *newData = realloc(fiber->data, sizeof(Dst) * n); if (NULL == newData) { DST_OUT_OF_MEMORY; } @@ -61,7 +61,7 @@ void dst_fiber_setcapacity(DstFiber *fiber, int32_t n) { } /* Push a value on the next stack frame */ -void dst_fiber_push(DstFiber *fiber, DstValue x) { +void dst_fiber_push(DstFiber *fiber, Dst x) { if (fiber->stacktop >= fiber->capacity) { dst_fiber_setcapacity(fiber, 2 * fiber->stacktop); } @@ -69,7 +69,7 @@ void dst_fiber_push(DstFiber *fiber, DstValue x) { } /* Push 2 values on the next stack frame */ -void dst_fiber_push2(DstFiber *fiber, DstValue x, DstValue y) { +void dst_fiber_push2(DstFiber *fiber, Dst x, Dst y) { int32_t newtop = fiber->stacktop + 2; if (newtop > fiber->capacity) { dst_fiber_setcapacity(fiber, 2 * newtop); @@ -80,7 +80,7 @@ void dst_fiber_push2(DstFiber *fiber, DstValue x, DstValue y) { } /* Push 3 values on the next stack frame */ -void dst_fiber_push3(DstFiber *fiber, DstValue x, DstValue y, DstValue z) { +void dst_fiber_push3(DstFiber *fiber, Dst x, Dst y, Dst z) { int32_t newtop = fiber->stacktop + 3; if (newtop > fiber->capacity) { dst_fiber_setcapacity(fiber, 2 * newtop); @@ -92,12 +92,12 @@ void dst_fiber_push3(DstFiber *fiber, DstValue x, DstValue y, DstValue z) { } /* Push an array on the next stack frame */ -void dst_fiber_pushn(DstFiber *fiber, const DstValue *arr, int32_t n) { +void dst_fiber_pushn(DstFiber *fiber, const Dst *arr, int32_t n) { int32_t newtop = fiber->stacktop + n; if (newtop > fiber->capacity) { dst_fiber_setcapacity(fiber, 2 * newtop); } - memcpy(fiber->data + fiber->stacktop, arr, n * sizeof(DstValue)); + memcpy(fiber->data + fiber->stacktop, arr, n * sizeof(Dst)); fiber->stacktop = newtop; } @@ -163,8 +163,8 @@ static void dst_function_detach(DstFunction *func) { /* Check for closure environment */ if (NULL != func->envs && NULL != func->envs[0]) { DstFuncEnv *env = func->envs[0]; - size_t s = sizeof(DstValue) * env->length; - DstValue *vmem = malloc(s); + size_t s = sizeof(Dst) * env->length; + Dst *vmem = malloc(s); if (NULL == vmem) { DST_OUT_OF_MEMORY; } @@ -185,14 +185,14 @@ void dst_fiber_funcframe_tail(DstFiber *fiber, DstFunction *func) { dst_fiber_setcapacity(fiber, 2 * nextstacktop); } - DstValue *stack = fiber->data + fiber->frame; - DstValue *args = fiber->data + fiber->stackstart; + Dst *stack = fiber->data + fiber->frame; + Dst *args = fiber->data + fiber->stackstart; /* Detatch old function */ if (NULL != dst_fiber_frame(fiber)->func) dst_function_detach(dst_fiber_frame(fiber)->func); - memmove(stack, args, stacksize * sizeof(DstValue)); + memmove(stack, args, stacksize * sizeof(Dst)); /* Set stack stuff */ fiber->stacktop = fiber->stackstart = nextstacktop; diff --git a/core/gc.c b/core/gc.c index 672a91d2..5a8226ba 100644 --- a/core/gc.c +++ b/core/gc.c @@ -30,7 +30,7 @@ uint32_t dst_vm_gc_interval; uint32_t dst_vm_next_collection; /* Roots */ -DstValue *dst_vm_roots; +Dst *dst_vm_roots; uint32_t dst_vm_root_count; uint32_t dst_vm_root_capacity; @@ -41,14 +41,14 @@ static void dst_mark_function(DstFunction *func); static void dst_mark_array(DstArray *array); static void dst_mark_table(DstTable *table); static void dst_mark_struct(const DstKV *st); -static void dst_mark_tuple(const DstValue *tuple); +static void dst_mark_tuple(const Dst *tuple); static void dst_mark_buffer(DstBuffer *buffer); static void dst_mark_string(const uint8_t *str); static void dst_mark_fiber(DstFiber *fiber); static void dst_mark_abstract(void *adata); /* Mark a value */ -void dst_mark(DstValue x) { +void dst_mark(Dst x) { switch (dst_type(x)) { default: break; case DST_STRING: @@ -77,8 +77,8 @@ static void dst_mark_abstract(void *adata) { } /* Mark a bunch of items in memory */ -static void dst_mark_many(const DstValue *values, int32_t n) { - const DstValue *end = values + n; +static void dst_mark_many(const Dst *values, int32_t n) { + const Dst *end = values + n; while (values < end) { dst_mark(*values); values += 1; @@ -116,7 +116,7 @@ static void dst_mark_struct(const DstKV *st) { dst_mark_kvs(st, dst_struct_capacity(st)); } -static void dst_mark_tuple(const DstValue *tuple) { +static void dst_mark_tuple(const Dst *tuple) { if (dst_gc_reachable(dst_tuple_raw(tuple))) return; dst_gc_mark(dst_tuple_raw(tuple)); @@ -305,11 +305,11 @@ void dst_collect() { /* Add a root value to the GC. This prevents the GC from removing a value * and all of its children. If gcroot is called on a value n times, unroot * must also be called n times to remove it as a gc root. */ -void dst_gcroot(DstValue root) { +void dst_gcroot(Dst root) { uint32_t newcount = dst_vm_root_count + 1; if (newcount > dst_vm_root_capacity) { uint32_t newcap = 2 * newcount; - dst_vm_roots = realloc(dst_vm_roots, sizeof(DstValue) * newcap); + dst_vm_roots = realloc(dst_vm_roots, sizeof(Dst) * newcap); if (NULL == dst_vm_roots) { DST_OUT_OF_MEMORY; } @@ -321,9 +321,9 @@ void dst_gcroot(DstValue root) { /* Remove a root value from the GC. This allows the gc to potentially reclaim * a value and all its children. */ -int dst_gcunroot(DstValue root) { - DstValue *vtop = dst_vm_roots + dst_vm_root_count; - DstValue *v = dst_vm_roots; +int dst_gcunroot(Dst root) { + Dst *vtop = dst_vm_roots + dst_vm_root_count; + Dst *v = dst_vm_roots; /* Search from top to bottom as access is most likely LIFO */ for (v = dst_vm_roots; v < vtop; v++) { if (dst_equals(root, *v)) { @@ -335,9 +335,9 @@ int dst_gcunroot(DstValue root) { } /* Remove a root value from the GC. This sets the effective reference count to 0. */ -int dst_gcunrootall(DstValue root) { - DstValue *vtop = dst_vm_roots + dst_vm_root_count; - DstValue *v = dst_vm_roots; +int dst_gcunrootall(Dst root) { + Dst *vtop = dst_vm_roots + dst_vm_root_count; + Dst *v = dst_vm_roots; int ret = 0; /* Search from top to bottom as access is most likely LIFO */ for (v = dst_vm_roots; v < vtop; v++) { diff --git a/core/io.c b/core/io.c new file mode 100644 index 00000000..80e1dda9 --- /dev/null +++ b/core/io.c @@ -0,0 +1,82 @@ + +DstAbstractType dst_stl_filetype = { + "stl.file", + NULL, + NULL, + NULL +}; + +/* Open a a file and return a userdata wrapper arounf the C file API. */ +int dst_stl_open(int32_t argn, Dst *argv, Dst *ret) { + if (argn < 2) { + *ret = dst_cstringv("expected at least 2 arguments"); + return 1; + } + const uint8_t *fname = dst_to_string(argv[0]); + const uint8_t *fmode = dst_to_string(argv[1]); + FILE *f; + FILE **fp; + f = fopen((const char *)fname, (const char *)fmode); + if (!f) + dst_c_throwc(vm, "could not open file"); + fp = dst_userdata(vm, sizeof(FILE *), &dst_stl_filetype); + *fp = f; + dst_c_return(vm, dst_wrap_userdata(fp)); +} + +/* Read an entire file into memory */ +int dst_stl_slurp(Dst *vm) { + DstBuffer *b; + long fsize; + FILE *f; + FILE **fp = dst_check_userdata(vm, 0, &dst_stl_filetype); + if (fp == NULL) dst_c_throwc(vm, "expected file"); + if (!dst_check_buffer(vm, 1, &b)) b = dst_buffer(vm, 10); + f = *fp; + /* Read whole file */ + fseek(f, 0, SEEK_END); + fsize = ftell(f); + fseek(f, 0, SEEK_SET); + /* Ensure buffer size */ + dst_buffer_ensure(vm, b, b->count + fsize); + fread((char *)(b->data + b->count), fsize, 1, f); + b->count += fsize; + dst_c_return(vm, dst_wrap_buffer(b)); +} + +/* Read a certain number of bytes into memory */ +int dst_stl_read(Dst *vm) { + DstBuffer *b; + FILE *f; + int64_t len; + FILE **fp = dst_check_userdata(vm, 0, &dst_stl_filetype); + if (fp == NULL) dst_c_throwc(vm, "expected file"); + if (!(dst_check_integer(vm, 1, &len))) dst_c_throwc(vm, "expected integer"); + if (!dst_check_buffer(vm, 2, &b)) b = dst_buffer(vm, 10); + f = *fp; + /* Ensure buffer size */ + dst_buffer_ensure(vm, b, b->count + len); + b->count += fread((char *)(b->data + b->count), len, 1, f) * len; + dst_c_return(vm, dst_wrap_buffer(b)); +} + +/* Write bytes to a file */ +int dst_stl_write(Dst *vm) { + FILE *f; + const uint8_t *data; + uint32_t len; + FILE **fp = dst_check_userdata(vm, 0, &dst_stl_filetype); + if (fp == NULL) dst_c_throwc(vm, "expected file"); + if (!dst_chararray_view(dst_arg(vm, 1), &data, &len)) dst_c_throwc(vm, "expected string|buffer"); + f = *fp; + fwrite(data, len, 1, f); + return DST_RETURN_OK; +} + +/* Close a file */ +int dst_stl_close(Dst *vm) { + FILE **fp = dst_check_userdata(vm, 0, &dst_stl_filetype); + if (fp == NULL) dst_c_throwc(vm, "expected file"); + fclose(*fp); + dst_c_return(vm, dst_wrap_nil()); +} diff --git a/core/math.c b/core/math.c index 96370119..0653aac7 100644 --- a/core/math.c +++ b/core/math.c @@ -24,7 +24,7 @@ #include /* Convert a number to an integer */ -int dst_int(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_int(int32_t argn, Dst *argv, Dst *ret) { if (argn != 1) { *ret = dst_cstringv("expected 1 argument"); return 1; @@ -44,7 +44,7 @@ int dst_int(int32_t argn, DstValue *argv, DstValue *ret) { } /* Convert a number to a real number */ -int dst_real(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_real(int32_t argn, Dst *argv, Dst *ret) { if (argn != 1) { *ret = dst_cstringv("expected 1 argument"); return 1; @@ -70,7 +70,7 @@ int dst_real(int32_t argn, DstValue *argv, DstValue *ret) { #define DIV(x, y) ((x) / (y)) #define DST_DEFINE_BINOP(name, op, rop, onerr)\ -DstValue dst_op_##name(DstValue lhs, DstValue rhs) {\ +Dst dst_op_##name(Dst lhs, Dst rhs) {\ if (!(dst_checktype(lhs, DST_INTEGER) || dst_checktype(lhs, DST_REAL))) onerr;\ if (!(dst_checktype(rhs, DST_INTEGER) || dst_checktype(rhs, DST_REAL))) onerr;\ return dst_checktype(lhs, DST_INTEGER)\ @@ -87,7 +87,7 @@ DST_DEFINE_BINOP(subtract, SUB, SUB, return dst_wrap_nil()) DST_DEFINE_BINOP(multiply, MUL, MUL, return dst_wrap_nil()) #define DST_DEFINE_DIVIDER_OP(name, op, rop)\ -DstValue dst_op_##name(DstValue lhs, DstValue rhs) {\ +Dst dst_op_##name(Dst lhs, Dst rhs) {\ if (!(dst_checktype(lhs, DST_INTEGER) || dst_checktype(lhs, DST_REAL))) return dst_wrap_nil();\ if (!(dst_checktype(rhs, DST_INTEGER) || dst_checktype(rhs, DST_REAL))) return dst_wrap_nil();\ return dst_checktype(lhs, DST_INTEGER)\ @@ -105,9 +105,9 @@ DST_DEFINE_DIVIDER_OP(divide, DIV, DIV) DST_DEFINE_DIVIDER_OP(modulo, MOD, fmod) #define DST_DEFINE_REDUCER(name, fop, start)\ -int dst_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ int32_t i;\ - DstValue accum = dst_wrap_integer(start);\ + Dst accum = dst_wrap_integer(start);\ for (i = 0; i < argn; i++) {\ accum = fop(accum, argv[i]);\ }\ @@ -123,9 +123,9 @@ DST_DEFINE_REDUCER(add, dst_op_add, 0) DST_DEFINE_REDUCER(multiply, dst_op_multiply, 1) #define DST_DEFINE_DIVIDER(name, unarystart)\ -int dst_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ int32_t i;\ - DstValue accum;\ + Dst accum;\ if (argn < 1) {\ *ret = dst_cstringv("expected at least one argument");\ return 1;\ @@ -157,7 +157,7 @@ DST_DEFINE_DIVIDER(subtract, 0) #undef MOD #undef DST_DEFINE_BINOP -int dst_bnot(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_bnot(int32_t argn, Dst *argv, Dst *ret) { if (argn != 1) { *ret = dst_cstringv("expected 1 argument"); return 1; @@ -171,11 +171,11 @@ int dst_bnot(int32_t argn, DstValue *argv, DstValue *ret) { } #define DST_DEFINE_BITOP(name, op, start)\ -int dst_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ int32_t i;\ int32_t accum = start;\ for (i = 0; i < argn; i++) {\ - DstValue arg = argv[i];\ + Dst arg = argv[i];\ if (!dst_checktype(arg, DST_INTEGER)) {\ *ret = dst_cstringv("expected integer");\ return -1;\ @@ -190,7 +190,7 @@ DST_DEFINE_BITOP(band, &=, -1) DST_DEFINE_BITOP(bor, |=, 0) DST_DEFINE_BITOP(bxor, ^=, 0) -int dst_lshift(int argn, DstValue *argv, DstValue *ret) { +int dst_lshift(int argn, Dst *argv, Dst *ret) { if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { *ret = dst_cstringv("expected 2 integers"); return 1; @@ -199,7 +199,7 @@ int dst_lshift(int argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_rshift(int argn, DstValue *argv, DstValue *ret) { +int dst_rshift(int argn, Dst *argv, Dst *ret) { if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { *ret = dst_cstringv("expected 2 integers"); return 1; @@ -208,7 +208,7 @@ int dst_rshift(int argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_lshiftu(int argn, DstValue *argv, DstValue *ret) { +int dst_lshiftu(int argn, Dst *argv, Dst *ret) { if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { *ret = dst_cstringv("expected 2 integers"); return 1; @@ -218,7 +218,7 @@ int dst_lshiftu(int argn, DstValue *argv, DstValue *ret) { } #define DST_DEFINE_MATHOP(name, fop)\ -int dst_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ if (argn != 1) {\ *ret = dst_cstringv("expected 1 argument");\ return 1;\ @@ -252,7 +252,7 @@ DST_DEFINE_MATHOP(fabs, fabs) DST_DEFINE_MATHOP(floor, floor) #define DST_DEFINE_MATH2OP(name, fop)\ -int dst_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ if (argn != 2) {\ *ret = dst_cstringv("expected 2 arguments");\ return 1;\ @@ -274,9 +274,9 @@ DST_DEFINE_MATH2OP(atan2, atan2) DST_DEFINE_MATH2OP(pow, pow) DST_DEFINE_MATH2OP(fmod, fmod) -int dst_modf(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_modf(int32_t argn, Dst *argv, Dst *ret) { double intpart; - DstValue *tup; + Dst *tup; if (argn != 1) { *ret = dst_cstringv("expected 1 argument"); return 1; diff --git a/core/parse.c b/core/parse.c index 6874ef4a..5f8121f0 100644 --- a/core/parse.c +++ b/core/parse.c @@ -34,8 +34,8 @@ static int check_str_const(const char *ref, const uint8_t *start, const uint8_t } /* Quote a value */ -static DstValue quote(DstValue x) { - DstValue *t = dst_tuple_begin(2); +static Dst quote(Dst x) { + Dst *t = dst_tuple_begin(2); t[0] = dst_csymbolv("quote"); t[1] = x; return dst_wrap_tuple(dst_tuple_end(t)); @@ -98,9 +98,7 @@ static uint32_t symchars[256] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; -/* Check if a character is a valid symbol character */ -/* TODO - allow utf8 - shouldn't be difficult, err on side - * of inclusivity +/* Check if a character is a valid symbol character * symbol chars are A-Z, a-z, 0-9, or one of !$&*+-./:<=>@\^_~| */ static int is_symbol_char(uint8_t c) { return symchars[c >> 5] & (1 << (c & 0x1F)); @@ -158,16 +156,16 @@ static int to_hex(uint8_t c) { } /* Make source mapping for atom (non recursive structure) */ -static DstValue atom_map(int32_t start, int32_t end) { - DstValue *t = dst_tuple_begin(2); +static Dst atom_map(int32_t start, int32_t end) { + Dst *t = dst_tuple_begin(2); t[0] = dst_wrap_integer(start); t[1] = dst_wrap_integer(end); return dst_wrap_tuple(dst_tuple_end(t)); } /* Create mappingd for recursive data structure */ -static DstValue ds_map(int32_t start, int32_t end, DstValue submap) { - DstValue *t = dst_tuple_begin(3); +static Dst ds_map(int32_t start, int32_t end, Dst submap) { + Dst *t = dst_tuple_begin(3); t[0] = dst_wrap_integer(start); t[1] = dst_wrap_integer(end); t[2] = submap; @@ -175,8 +173,8 @@ static DstValue ds_map(int32_t start, int32_t end, DstValue submap) { } /* Create a sourcemapping for a key value pair */ -static DstValue kv_map(DstValue k, DstValue v) { - DstValue *t = dst_tuple_begin(2); +static Dst kv_map(Dst k, Dst v) { + Dst *t = dst_tuple_begin(2); t[0] = k; t[1] = v; return dst_wrap_tuple(dst_tuple_end(t)); @@ -200,8 +198,8 @@ static const uint8_t *parse_recur( const uint8_t *end = args->end; const uint8_t *mapstart; int32_t qcount = 0; - DstValue ret; - DstValue submapping; + Dst ret; + Dst submapping; /* Prevent stack overflow */ if (recur == 0) goto too_much_recur; @@ -238,7 +236,7 @@ static const uint8_t *parse_recur( atom: { int ascii = 1; - DstValue numcheck; + Dst numcheck; const uint8_t *tokenend = src; if (!is_symbol_char(*src)) goto unexpected_character; while (tokenend < end && is_symbol_char(*tokenend)) { @@ -373,8 +371,8 @@ static const uint8_t *parse_recur( switch (close) { case ')': { - DstValue *tup = dst_tuple_begin(n); - DstValue *subtup = dst_tuple_begin(n); + Dst *tup = dst_tuple_begin(n); + Dst *subtup = dst_tuple_begin(n); for (i = n; i > 0; i--) { tup[i - 1] = dst_array_pop(&args->stack); subtup[i - 1] = dst_array_pop(&args->mapstack); @@ -408,10 +406,10 @@ static const uint8_t *parse_recur( DstTable *t = dst_table(n); DstTable *subt = dst_table(n); for (i = n; i > 0; i -= 2) { - DstValue val = dst_array_pop(&args->stack); - DstValue key = dst_array_pop(&args->stack); - DstValue subval = dst_array_pop(&args->mapstack); - DstValue subkey = dst_array_pop(&args->mapstack); + Dst val = dst_array_pop(&args->stack); + Dst key = dst_array_pop(&args->stack); + Dst subval = dst_array_pop(&args->mapstack); + Dst subkey = dst_array_pop(&args->mapstack); dst_table_put(t, key, val); dst_table_put(subt, key, kv_map(subkey, subval)); @@ -422,10 +420,10 @@ static const uint8_t *parse_recur( DstKV *st = dst_struct_begin(n >> 1); DstKV *subst = dst_struct_begin(n >> 1); for (i = n; i > 0; i -= 2) { - DstValue val = dst_array_pop(&args->stack); - DstValue key = dst_array_pop(&args->stack); - DstValue subval = dst_array_pop(&args->mapstack); - DstValue subkey = dst_array_pop(&args->mapstack); + Dst val = dst_array_pop(&args->stack); + Dst key = dst_array_pop(&args->stack); + Dst subval = dst_array_pop(&args->mapstack); + Dst subkey = dst_array_pop(&args->mapstack); dst_struct_put(st, key, val); dst_struct_put(subst, key, kv_map(subkey, subval)); @@ -458,8 +456,8 @@ static const uint8_t *parse_recur( while (qcount--) { int32_t start = mapstart - args->srcstart; int32_t end = src - args->srcstart; - DstValue sourcemap = dst_array_pop(&args->mapstack); - DstValue* tup = dst_tuple_begin(2); + Dst sourcemap = dst_array_pop(&args->mapstack); + Dst* tup = dst_tuple_begin(2); tup[0] = atom_map(start, end); tup[1] = sourcemap; ret = quote(ret); diff --git a/core/sourcemap.c b/core/sourcemap.c index 5cfc3791..1e77929a 100644 --- a/core/sourcemap.c +++ b/core/sourcemap.c @@ -25,14 +25,14 @@ /* Get the sub source map by indexing a value. Used to traverse * into arrays and tuples */ -const DstValue *dst_sourcemap_index(const DstValue *map, int32_t index) { +const Dst *dst_sourcemap_index(const Dst *map, int32_t index) { if (NULL != map && dst_tuple_length(map) >= 3) { - const DstValue *seq; + const Dst *seq; int32_t len; if (dst_seq_view(map[2], &seq, &len)) { if (index >= 0 && index < len) { if (dst_checktype(seq[index], DST_TUPLE)) { - const DstValue *ret = dst_unwrap_tuple(seq[index]); + const Dst *ret = dst_unwrap_tuple(seq[index]); if (dst_tuple_length(ret) >= 2 && dst_checktype(ret[0], DST_INTEGER) && dst_checktype(ret[1], DST_INTEGER)) { @@ -46,14 +46,14 @@ const DstValue *dst_sourcemap_index(const DstValue *map, int32_t index) { } /* Traverse into tables and structs */ -static const DstValue *dst_sourcemap_kv(const DstValue *map, DstValue key, int kv) { +static const Dst *dst_sourcemap_kv(const Dst *map, Dst key, int kv) { if (NULL != map && dst_tuple_length(map) >= 3) { - DstValue kvpair = dst_get(map[2], key); + Dst kvpair = dst_get(map[2], key); if (dst_checktype(kvpair, DST_TUPLE)) { - const DstValue *kvtup = dst_unwrap_tuple(kvpair); + const Dst *kvtup = dst_unwrap_tuple(kvpair); if (dst_tuple_length(kvtup) >= 2) { if (dst_checktype(kvtup[kv], DST_TUPLE)) { - const DstValue *ret = dst_unwrap_tuple(kvtup[kv]); + const Dst *ret = dst_unwrap_tuple(kvtup[kv]); if (dst_tuple_length(ret) >= 2 && dst_checktype(ret[0], DST_INTEGER) && dst_checktype(ret[1], DST_INTEGER)) { @@ -67,11 +67,11 @@ static const DstValue *dst_sourcemap_kv(const DstValue *map, DstValue key, int k } /* Traverse into a key of a table or struct */ -const DstValue *dst_sourcemap_key(const DstValue *map, DstValue key) { +const Dst *dst_sourcemap_key(const Dst *map, Dst key) { return dst_sourcemap_kv(map, key, 0); } /* Traverse into a value of a table or struct */ -const DstValue *dst_sourcemap_value(const DstValue *map, DstValue key) { +const Dst *dst_sourcemap_value(const Dst *map, Dst key) { return dst_sourcemap_kv(map, key, 1); } diff --git a/core/sourcemap.h b/core/sourcemap.h index 736af9ce..17b91e6c 100644 --- a/core/sourcemap.h +++ b/core/sourcemap.h @@ -27,18 +27,18 @@ /* Get the sub source map by indexing a value. Used to traverse * into arrays and tuples */ -const DstValue *dst_sourcemap_index(const DstValue *map, int32_t index); +const Dst *dst_sourcemap_index(const Dst *map, int32_t index); /* Traverse into a key of a table or struct */ -const DstValue *dst_sourcemap_key(const DstValue *map, DstValue key); +const Dst *dst_sourcemap_key(const Dst *map, Dst key); /* Traverse into a value of a table or struct */ -const DstValue *dst_sourcemap_value(const DstValue *map, DstValue key); +const Dst *dst_sourcemap_value(const Dst *map, Dst key); /* Try to rebuild a source map from given another map */ -const DstValue *dst_sourcemap_remap( - const DstValue *oldmap, - DstValue oldsource, - DstValue newsource); +const Dst *dst_sourcemap_remap( + const Dst *oldmap, + Dst oldsource, + Dst newsource); #endif diff --git a/core/stl.c b/core/stl.c index 2c2fdca8..7e87ec79 100644 --- a/core/stl.c +++ b/core/stl.c @@ -23,7 +23,7 @@ #include #include -int dst_stl_print(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_print(int32_t argn, Dst *argv, Dst *ret) { (void)ret; int32_t i; @@ -39,7 +39,7 @@ int dst_stl_print(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_describe(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_describe(int32_t argn, Dst *argv, Dst *ret) { (void)ret; int32_t i; @@ -55,7 +55,7 @@ int dst_stl_describe(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_asm(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_asm(int32_t argn, Dst *argv, Dst *ret) { DstAssembleOptions opts; DstAssembleResult res; if (argn < 1) { @@ -74,7 +74,7 @@ int dst_stl_asm(int32_t argn, DstValue *argv, DstValue *ret) { } } -int dst_stl_disasm(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_disasm(int32_t argn, Dst *argv, Dst *ret) { DstFunction *f; if (argn < 1 || !dst_checktype(argv[0], DST_FUNCTION)) { *ret = dst_cstringv("expected function"); @@ -85,20 +85,20 @@ int dst_stl_disasm(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_tuple(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_tuple(int32_t argn, Dst *argv, Dst *ret) { *ret = dst_wrap_tuple(dst_tuple_n(argv, argn)); return 0; } -int dst_stl_array(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_array(int32_t argn, Dst *argv, Dst *ret) { DstArray *array = dst_array(argn); array->count = argn; - memcpy(array->data, argv, argn * sizeof(DstValue)); + memcpy(array->data, argv, argn * sizeof(Dst)); *ret = dst_wrap_array(array); return 0; } -int dst_stl_table(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_table(int32_t argn, Dst *argv, Dst *ret) { int32_t i; DstTable *table = dst_table(argn >> 1); if (argn & 1) { @@ -112,7 +112,7 @@ int dst_stl_table(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_struct(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_struct(int32_t argn, Dst *argv, Dst *ret) { int32_t i; DstKV *st = dst_struct_begin(argn >> 1); if (argn & 1) { @@ -126,7 +126,7 @@ int dst_stl_struct(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_fiber(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_fiber(int32_t argn, Dst *argv, Dst *ret) { DstFiber *fiber; if (argn < 1) { *ret = dst_cstringv("expected at least one argument"); @@ -143,7 +143,7 @@ int dst_stl_fiber(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_buffer(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_buffer(int32_t argn, Dst *argv, Dst *ret) { DstBuffer *buffer = dst_buffer(10); int32_t i; for (i = 0; i < argn; ++i) { @@ -155,7 +155,7 @@ int dst_stl_buffer(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_gensym(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_gensym(int32_t argn, Dst *argv, Dst *ret) { if (argn > 1) { *ret = dst_cstringv("expected one argument"); return 1; @@ -169,9 +169,9 @@ int dst_stl_gensym(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_get(int32_t argn, DstValue *argv, DstValue *ret) { +int dst_stl_get(int32_t argn, Dst *argv, Dst *ret) { int32_t i; - DstValue ds; + Dst ds; if (argn < 1) { *ret = dst_cstringv("expected at least 1 argument"); return 1; @@ -186,8 +186,8 @@ int dst_stl_get(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -int dst_stl_put(int32_t argn, DstValue *argv, DstValue *ret) { - DstValue ds, key, value; +int dst_stl_put(int32_t argn, Dst *argv, Dst *ret) { + Dst ds, key, value; if (argn < 3) { *ret = dst_cstringv("expected at least 3 arguments"); return 1; @@ -202,7 +202,7 @@ int dst_stl_put(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -static int dst_stl_equal(int32_t argn, DstValue *argv, DstValue *ret) { +static int dst_stl_equal(int32_t argn, Dst *argv, Dst *ret) { int32_t i; for (i = 0; i < argn - 1; i++) { if (!dst_equals(argv[i], argv[i+1])) { @@ -214,25 +214,25 @@ static int dst_stl_equal(int32_t argn, DstValue *argv, DstValue *ret) { return 0; } -static int dst_stl_notequal(int32_t argn, DstValue *argv, DstValue *ret) { +static int dst_stl_notequal(int32_t argn, Dst *argv, Dst *ret) { int32_t i; for (i = 0; i < argn - 1; i++) { if (dst_equals(argv[i], argv[i+1])) { - *ret = dst_wrap_true(); + *ret = dst_wrap_false(); return 0; } } - *ret = dst_wrap_false(); + *ret = dst_wrap_true(); return 0; } -static int dst_stl_not(int32_t argn, DstValue *argv, DstValue *ret) { +static int dst_stl_not(int32_t argn, Dst *argv, Dst *ret) { *ret = dst_wrap_boolean(argn == 0 || !dst_truthy(argv[0])); return 0; } #define DST_DEFINE_COMPARATOR(name, pred)\ -static int dst_stl_##name(int32_t argn, DstValue *argv, DstValue *ret) {\ +static int dst_stl_##name(int32_t argn, Dst *argv, Dst *ret) {\ int32_t i;\ for (i = 0; i < argn - 1; i++) {\ if (dst_compare(argv[i], argv[i+1]) pred) {\ @@ -250,6 +250,8 @@ DST_DEFINE_COMPARATOR(notdescending, > 0) DST_DEFINE_COMPARATOR(notascending, < 0) static DstReg stl[] = { + {"int", dst_int}, + {"real", dst_real}, {"print", dst_stl_print}, {"describe", dst_stl_describe}, {"table", dst_stl_table}, @@ -296,8 +298,8 @@ static DstReg stl[] = { {"not", dst_stl_not} }; -DstValue dst_loadstl(int flags) { - DstValue ret = dst_loadreg(stl, sizeof(stl)/sizeof(DstReg)); +Dst dst_loadstl(int flags) { + Dst ret = dst_loadreg(stl, sizeof(stl)/sizeof(DstReg)); if (flags & DST_LOAD_ROOT) { dst_gcroot(ret); } diff --git a/core/string.c b/core/string.c index 6616839a..3a469aaa 100644 --- a/core/string.c +++ b/core/string.c @@ -23,12 +23,14 @@ #include #include "strtod.h" #include "gc.h" +#include "util.h" /* Begin building a string */ uint8_t *dst_string_begin(int32_t length) { - char *data = dst_gcalloc(DST_MEMORY_STRING, 2 * sizeof(int32_t) + length); + char *data = dst_gcalloc(DST_MEMORY_STRING, 2 * sizeof(int32_t) + length + 1); uint8_t *str = (uint8_t *) (data + 2 * sizeof(int32_t)); dst_string_length(str) = length; + str[length] = 0; return str; } @@ -41,9 +43,10 @@ const uint8_t *dst_string_end(uint8_t *str) { /* Load a buffer as a string */ const uint8_t *dst_string(const uint8_t *buf, int32_t len) { int32_t hash = dst_string_calchash(buf, len); - char *data = dst_gcalloc(DST_MEMORY_STRING, 2 * sizeof(int32_t) + len); + char *data = dst_gcalloc(DST_MEMORY_STRING, 2 * sizeof(int32_t) + len + 1); uint8_t *str = (uint8_t *) (data + 2 * sizeof(int32_t)); memcpy(str, buf, len); + str[len] = 0; dst_string_length(str) = len; dst_string_hash(str) = hash; return str; @@ -267,7 +270,7 @@ const uint8_t *dst_escape_string(const uint8_t *str) { } /* Returns a string pointer with the description of the string */ -const uint8_t *dst_short_description(DstValue x) { +const uint8_t *dst_short_description(Dst x) { switch (dst_type(x)) { case DST_NIL: return dst_cstring("nil"); @@ -292,7 +295,7 @@ const uint8_t *dst_short_description(DstValue x) { } } -void dst_short_description_b(DstBuffer *buffer, DstValue x) { +void dst_short_description_b(DstBuffer *buffer, Dst x) { switch (dst_type(x)) { case DST_NIL: dst_buffer_push_cstring(buffer, "nil"); @@ -357,7 +360,7 @@ static void dst_print_indent(DstPrinter *p) { } /* Check if a value is a print atom (not a printable data structure) */ -static int is_print_ds(DstValue v) { +static int is_print_ds(Dst v) { switch (dst_type(v)) { default: return 0; case DST_ARRAY: @@ -407,7 +410,7 @@ static const char *dst_type_colors[16] = { }; /* Forward declaration */ -static void dst_description_helper(DstPrinter *p, DstValue x); +static void dst_description_helper(DstPrinter *p, Dst x); /* Print a hastable view inline */ static void dst_print_hashtable_inner(DstPrinter *p, const DstKV *data, int32_t len, int32_t cap) { @@ -460,7 +463,7 @@ static void dst_print_hashtable_inner(DstPrinter *p, const DstKV *data, int32_t } /* Help print a sequence */ -static void dst_print_seq_inner(DstPrinter *p, const DstValue *data, int32_t len) { +static void dst_print_seq_inner(DstPrinter *p, const Dst *data, int32_t len) { int32_t i; int doindent = 0; if (p->flags & DST_PRINTFLAG_INDENT) { @@ -495,13 +498,13 @@ 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) { +static void dst_description_helper(DstPrinter *p, Dst x) { const char *open; const char *close; int32_t len, cap; - const DstValue *data; + const Dst *data; const DstKV *kvs; - DstValue check; + Dst check; p->depth--; switch (dst_type(x)) { default: @@ -565,7 +568,7 @@ static void dst_printer_defaults(DstPrinter *p) { } /* Debug print. Returns a description of an object as a string. */ -const uint8_t *dst_description(DstValue x) { +const uint8_t *dst_description(Dst x) { DstPrinter printer; const uint8_t *ret; @@ -587,7 +590,7 @@ const uint8_t *dst_description(DstValue x) { /* Convert any value to a dst string. Similar to description, but * strings, symbols, and buffers will return their content. */ -const uint8_t *dst_to_string(DstValue x) { +const uint8_t *dst_to_string(Dst x) { switch (dst_type(x)) { default: return dst_short_description(x); @@ -655,14 +658,14 @@ const uint8_t *dst_formatc(const char *format, ...) { case 'v': { dst_printer_defaults(&printer); - dst_description_helper(&printer, va_arg(args, DstValue)); + dst_description_helper(&printer, va_arg(args, Dst)); break; } case 'C': { dst_printer_defaults(&printer); printer.flags |= DST_PRINTFLAG_COLORIZE; - dst_description_helper(&printer, va_arg(args, DstValue)); + dst_description_helper(&printer, va_arg(args, Dst)); break; } case 'q': @@ -678,7 +681,7 @@ const uint8_t *dst_formatc(const char *format, ...) { } case 'V': { - dst_short_description_b(bufp, va_arg(args, DstValue)); + dst_short_description_b(bufp, va_arg(args, Dst)); break; } } diff --git a/core/strtod.c b/core/strtod.c index bb477394..00630f48 100644 --- a/core/strtod.c +++ b/core/strtod.c @@ -28,7 +28,7 @@ * reasonable). * * This version has been modified for much greater flexibility in parsing, such - * as choosing the radix, supporting integer output, and returning DstValues + * as choosing the radix, supporting integer output, and returning Dsts * directly. * * Numbers are of the form [-+]R[rR]I.F[eE&][-+]X where R is the radix, I is @@ -253,7 +253,6 @@ static struct DstScanRes dst_scan_impl( goto error; return res; - /* return dst_wrap_real(dst_convert_mantissa_exp(neg, mant, base, ex)); */ error: res.error = 1; @@ -303,7 +302,7 @@ double dst_scan_real( /* Scans a number from a string. Can return either an integer or a real if * the number cannot be represented as an integer. Will return nil in case of * an error. */ -DstValue dst_scan_number( +Dst dst_scan_number( const uint8_t *str, int32_t len) { struct DstScanRes res = dst_scan_impl(str, len); diff --git a/core/strtod.h b/core/strtod.h index 91e879d7..59c1f13c 100644 --- a/core/strtod.h +++ b/core/strtod.h @@ -23,7 +23,7 @@ #ifndef DST_STRTOD_H_defined #define DST_STRTOD_H_defined -DstValue dst_scan_number( +Dst dst_scan_number( const uint8_t *str, int32_t len); diff --git a/core/struct.c b/core/struct.c index b6b4165e..eb192738 100644 --- a/core/struct.c +++ b/core/struct.c @@ -22,6 +22,7 @@ #include #include "gc.h" +#include "util.h" #define dst_struct_maphash(cap, hash) ((uint32_t)(hash & (cap - 1))); @@ -43,7 +44,7 @@ DstKV *dst_struct_begin(int32_t count) { } /* Find an item in a struct */ -static const DstKV *dst_struct_find(const DstKV *st, DstValue key) { +static const DstKV *dst_struct_find(const DstKV *st, Dst key) { int32_t cap = dst_struct_capacity(st); int32_t index = dst_struct_maphash(cap, dst_hash(key)); int32_t i; @@ -59,7 +60,7 @@ static const DstKV *dst_struct_find(const DstKV *st, DstValue key) { /* Put a kv pair into a struct that has not yet been fully constructed. * Nil keys and values are ignored, extra keys are ignore, and duplicate keys are * ignored. */ -void dst_struct_put(DstKV *st, DstValue key, DstValue value) { +void dst_struct_put(DstKV *st, Dst key, Dst value) { int32_t cap = dst_struct_capacity(st); int32_t hash = dst_hash(key); int32_t index = dst_struct_maphash(cap, hash); @@ -147,7 +148,7 @@ const DstKV *dst_struct_end(DstKV *st) { } /* Get an item from a struct */ -DstValue dst_struct_get(const DstKV *st, DstValue key) { +Dst dst_struct_get(const DstKV *st, Dst key) { const DstKV *kv = dst_struct_find(st, key); if (NULL == kv || dst_checktype(kv->key, DST_NIL)) { return dst_wrap_nil(); diff --git a/core/symcache.c b/core/symcache.c index 4fb5e949..ec6d8e3b 100644 --- a/core/symcache.c +++ b/core/symcache.c @@ -27,6 +27,7 @@ #include #include "gc.h" +#include "util.h" /* Cache state */ const uint8_t **dst_vm_cache = NULL; @@ -71,7 +72,7 @@ static const uint8_t **dst_symcache_findmem( /* We will search two ranges - index to the end, * and 0 to the index. */ - index = (uint32_t)hash % dst_vm_cache_capacity; + index = (uint32_t)hash & (dst_vm_cache_capacity - 1); bounds[0] = index; bounds[1] = dst_vm_cache_capacity; bounds[2] = 0; @@ -142,9 +143,9 @@ static void dst_cache_resize(uint32_t newCapacity) { /* Add an item to the cache */ static void dst_symcache_put(const uint8_t *x, const uint8_t **bucket) { -if ((dst_vm_cache_count + dst_vm_cache_deleted) * 2 > dst_vm_cache_capacity) { + if ((dst_vm_cache_count + dst_vm_cache_deleted) * 2 > dst_vm_cache_capacity) { int status; - dst_cache_resize(dst_vm_cache_count * 4); + dst_cache_resize(dst_tablen((2 * dst_vm_cache_count + 1))); bucket = dst_symcache_find(x, &status); } /* Add x to the cache */ @@ -171,11 +172,12 @@ const uint8_t *dst_symbol(const uint8_t *str, int32_t len) { const uint8_t **bucket = dst_symcache_findmem(str, len, hash, &success); if (success) return *bucket; - newstr = dst_gcalloc(DST_MEMORY_SYMBOL, 2 * sizeof(int32_t) + len) + newstr = dst_gcalloc(DST_MEMORY_SYMBOL, 2 * sizeof(int32_t) + len + 1) + (2 * sizeof(int32_t)); dst_string_hash(newstr) = hash; dst_string_length(newstr) = len; memcpy(newstr, str, len); + newstr[len] = 0; dst_symcache_put((const uint8_t *)newstr, bucket); return newstr; } @@ -223,12 +225,13 @@ const uint8_t *dst_symbol_gen(const uint8_t *buf, int32_t len) { /* Leave spaces for 6 base 64 digits and two dashes. That means 64^6 possible suffixes, which * is enough for resolving collisions. */ int32_t newlen = len + 8; - int32_t newbufsize = newlen + 2 * sizeof(int32_t); + int32_t newbufsize = newlen + 2 * sizeof(int32_t) + 1; uint8_t *str = (uint8_t *)(dst_gcalloc(DST_MEMORY_SYMBOL, newbufsize) + 2 * sizeof(int32_t)); dst_string_length(str) = newlen; memcpy(str, buf, len); str[len] = '-'; str[len + 1] = '-'; + str[newlen] = 0; uint8_t *saltbuf = str + len + 2; int status = 1; while (status) { diff --git a/core/table.c b/core/table.c index 8a40af28..76194b99 100644 --- a/core/table.c +++ b/core/table.c @@ -22,6 +22,7 @@ #include #include "gc.h" +#include "util.h" #define dst_table_maphash(cap, hash) ((uint32_t)(hash) & (cap - 1)) @@ -58,7 +59,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 DstKV *dst_table_find(DstTable *t, DstValue key) { +static DstKV *dst_table_find(DstTable *t, Dst key) { int32_t index = dst_table_maphash(t->capacity, dst_hash(key)); int32_t i; DstKV *first_bucket = NULL; @@ -114,7 +115,7 @@ static void dst_table_rehash(DstTable *t, int32_t size) { } /* Get a value out of the object */ -DstValue dst_table_get(DstTable *t, DstValue key) { +Dst dst_table_get(DstTable *t, Dst key) { DstKV *bucket = dst_table_find(t, key); if (NULL != bucket && !dst_checktype(bucket->key, DST_NIL)) return bucket->value; @@ -124,10 +125,10 @@ DstValue dst_table_get(DstTable *t, DstValue key) { /* Remove an entry from the dictionary. Return the value that * was removed. */ -DstValue dst_table_remove(DstTable *t, DstValue key) { +Dst dst_table_remove(DstTable *t, Dst key) { DstKV *bucket = dst_table_find(t, key); if (NULL != bucket && !dst_checktype(bucket->key, DST_NIL)) { - DstValue ret = bucket->key; + Dst ret = bucket->key; t->count--; t->deleted++; bucket->key = dst_wrap_nil(); @@ -139,7 +140,7 @@ DstValue dst_table_remove(DstTable *t, DstValue key) { } /* Put a value into the object */ -void dst_table_put(DstTable *t, DstValue key, DstValue value) { +void dst_table_put(DstTable *t, Dst key, Dst value) { if (dst_checktype(key, DST_NIL)) return; if (dst_checktype(value, DST_NIL)) { dst_table_remove(t, key); diff --git a/core/tuple.c b/core/tuple.c index 6e96d1de..1bf5f309 100644 --- a/core/tuple.c +++ b/core/tuple.c @@ -23,32 +23,33 @@ #include #include "symcache.h" #include "gc.h" +#include "util.h" /* Create a new empty tuple of the given size. This will return memory - * which should be filled with DstValues. The memory will not be collected until + * which should be filled with Dsts. The memory will not be collected until * dst_tuple_end is called. */ -DstValue *dst_tuple_begin(int32_t length) { - char *data = dst_gcalloc(DST_MEMORY_TUPLE, 2 * sizeof(int32_t) + length * sizeof(DstValue)); - DstValue *tuple = (DstValue *)(data + (2 * sizeof(int32_t))); +Dst *dst_tuple_begin(int32_t length) { + char *data = dst_gcalloc(DST_MEMORY_TUPLE, 2 * sizeof(int32_t) + length * sizeof(Dst)); + Dst *tuple = (Dst *)(data + (2 * sizeof(int32_t))); dst_tuple_length(tuple) = length; return tuple; } /* Finish building a tuple */ -const DstValue *dst_tuple_end(DstValue *tuple) { +const Dst *dst_tuple_end(Dst *tuple) { dst_tuple_hash(tuple) = dst_array_calchash(tuple, dst_tuple_length(tuple)); - return (const DstValue *)tuple; + return (const Dst *)tuple; } /* Build a tuple with n values */ -const DstValue *dst_tuple_n(DstValue *values, int32_t n) { - DstValue *t = dst_tuple_begin(n); - memcpy(t, values, sizeof(DstValue) * n); +const Dst *dst_tuple_n(Dst *values, int32_t n) { + Dst *t = dst_tuple_begin(n); + memcpy(t, values, sizeof(Dst) * n); return dst_tuple_end(t); } /* Check if two tuples are equal */ -int dst_tuple_equal(const DstValue *lhs, const DstValue *rhs) { +int dst_tuple_equal(const Dst *lhs, const Dst *rhs) { int32_t index; int32_t llen = dst_tuple_length(lhs); int32_t rlen = dst_tuple_length(rhs); @@ -70,7 +71,7 @@ int dst_tuple_equal(const DstValue *lhs, const DstValue *rhs) { } /* Compare tuples */ -int dst_tuple_compare(const DstValue *lhs, const DstValue *rhs) { +int dst_tuple_compare(const Dst *lhs, const Dst *rhs) { int32_t i; int32_t llen = dst_tuple_length(lhs); int32_t rlen = dst_tuple_length(rhs); diff --git a/core/util.c b/core/util.c index b4761a1e..7a0387e2 100644 --- a/core/util.c +++ b/core/util.c @@ -21,6 +21,7 @@ */ #include +#include "util.h" /* Base 64 lookup table for digits */ const char dst_base64[65] = @@ -51,8 +52,8 @@ const char *dst_type_names[16] = { }; /* Computes hash of an array of values */ -int32_t dst_array_calchash(const DstValue *array, int32_t len) { - const DstValue *end = array + len; +int32_t dst_array_calchash(const Dst *array, int32_t len) { + const Dst *end = array + len; uint32_t hash = 5381; while (array < end) hash = (hash << 5) + hash + dst_hash(*array++); @@ -134,7 +135,7 @@ const void *dst_strbinsearch( /* 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(DstValue seq, const DstValue **data, int32_t *len) { +int dst_seq_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; @@ -149,7 +150,7 @@ int dst_seq_view(DstValue seq, const DstValue **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(DstValue str, const uint8_t **data, int32_t *len) { +int dst_chararray_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)); @@ -165,7 +166,7 @@ int dst_chararray_view(DstValue 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(DstValue tab, const DstKV **data, int32_t *len, int32_t *cap) { +int dst_hashtable_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; @@ -181,15 +182,69 @@ int dst_hashtable_view(DstValue tab, const DstKV **data, int32_t *len, int32_t * } /* Load c functions into an environment */ -DstValue dst_loadreg(DstReg *regs, size_t count) { +Dst dst_loadreg(DstReg *regs, size_t count) { size_t i; DstTable *t = dst_table(count); for (i = 0; i < count; i++) { - DstValue sym = dst_csymbolv(regs[i].name); - DstValue func = dst_wrap_cfunction(regs[i].function); + Dst sym = dst_csymbolv(regs[i].name); + Dst func = dst_wrap_cfunction(regs[i].function); DstTable *subt = dst_table(1); dst_table_put(subt, dst_csymbolv("value"), func); dst_table_put(t, sym, dst_wrap_table(subt)); } return dst_wrap_table(t); } + +/* Vector code */ + +/* Grow the buffer dynamically. Used for push operations. */ +void *dst_v_grow(void *v, int32_t increment, int32_t itemsize) { + int32_t dbl_cur = (NULL != v) ? 2 * dst_v__cap(v) : 0; + int32_t min_needed = dst_v_count(v) + increment; + int32_t m = dbl_cur > min_needed ? dbl_cur : min_needed; + int32_t *p = (int32_t *) realloc(v ? dst_v__raw(v) : 0, itemsize * m + sizeof(int32_t)*2); + if (NULL != p) { + if (!v) p[1] = 0; + p[0] = m; + return p + 2; + } else { + { + DST_OUT_OF_MEMORY; + } + return (void *) (2 * sizeof(int32_t)); // try to force a NULL pointer exception later + } +} + +/* Clone a buffer. */ +void *dst_v_copymem(void *v, int32_t itemsize) { + int32_t *p; + if (NULL == v) return NULL; + p = malloc(2 * sizeof(int32_t) + itemsize * dst_v__cap(v)); + if (NULL != p) { + memcpy(p, dst_v__raw(v), 2 * sizeof(int32_t) + itemsize * dst_v__cnt(v)); + return p + 2; + } else { + { + DST_OUT_OF_MEMORY; + } + return (void *) (2 * sizeof(int32_t)); // try to force a NULL pointer exception later + } +} + +/* Convert a buffer to normal allocated memory (forget capacity) */ +void *dst_v_flattenmem(void *v, int32_t itemsize) { + int32_t *p; + int32_t sizen; + if (NULL == v) return NULL; + sizen = itemsize * dst_v__cnt(v); + p = malloc(sizen); + if (NULL != p) { + memcpy(p, v, sizen); + return p; + } else { + { + DST_OUT_OF_MEMORY; + } + return NULL; + } +} diff --git a/core/vector.h b/core/util.h similarity index 79% rename from core/vector.h rename to core/util.h index c3a53703..b9e994ec 100644 --- a/core/vector.h +++ b/core/util.h @@ -20,11 +20,28 @@ * IN THE SOFTWARE. */ -#ifndef DST_VECTOR_H_defined -#define DST_VECTOR_H_defined +#ifndef DST_UTIL_H_defined +#define DST_UTIL_H_defined + +#include + +/* Utils internal to dst. */ + +/* Utils */ +extern const char dst_base64[65]; +int32_t dst_array_calchash(const Dst *array, int32_t len); +int32_t dst_kv_calchash(const DstKV *kvs, int32_t len); +int32_t dst_string_calchash(const uint8_t *str, int32_t len); +int32_t dst_tablen(int32_t n); +int dst_cstrcmp(const uint8_t *str, const char *other); +const void *dst_strbinsearch( + const void *tab, + size_t tabcount, + size_t itemsize, + const uint8_t *key); /* - * Modified from + * vector code modified from * https://github.com/nothings/stb/blob/master/stretchy_buffer.h */ @@ -32,8 +49,6 @@ * need vector like data structures that are not garbage collected * and used only from C */ -#include - #define dst_v_free(v) (((v) != NULL) ? (free(dst_v__raw(v)), 0) : 0) #define dst_v_push(v, x) (dst_v__maybegrow(v, 1), (v)[dst_v__cnt(v)++] = (x)) #define dst_v_pop(v) (dst_v_count(v) ? dst_v__cnt(v)-- : 0) @@ -41,7 +56,7 @@ #define dst_v_add(v, n) (dst_v__maybegrow(v, n), dst_v_cnt(v) += (n), &(v)[dst_v__cnt(v) - (n)]) #define dst_v_last(v) ((v)[dst_v__cnt(v) - 1]) #define dst_v_copy(v) (dst_v_copymem((v), sizeof(*(v)))) -#define dst_v_flatten(v) (dst_v_flattenmem((v), sizeof(*(v)))) +#define dst_v_flatten(v) (dst_v_flattenmem((v), sizeof(*(v)))) #define dst_v__raw(v) ((int32_t *)(v) - 2) #define dst_v__cap(v) dst_v__raw(v)[0] diff --git a/core/value.c b/core/value.c index 74643dee..ff4d070c 100644 --- a/core/value.c +++ b/core/value.c @@ -23,11 +23,11 @@ #include /* - * Define a number of functions that can be used internally on ANY DstValue. + * Define a number of functions that can be used internally on ANY Dst. */ /* Check if two values are equal. This is strict equality with no conversion. */ -int dst_equals(DstValue x, DstValue y) { +int dst_equals(Dst x, Dst y) { int result = 0; if (dst_type(x) != dst_type(y)) { result = 0; @@ -63,7 +63,7 @@ int dst_equals(DstValue x, DstValue y) { } /* Computes a hash value for a function */ -int32_t dst_hash(DstValue x) { +int32_t dst_hash(Dst x) { int32_t hash = 0; switch (dst_type(x)) { case DST_NIL: @@ -98,7 +98,7 @@ int32_t dst_hash(DstValue x) { /* Compares x to y. If they are equal retuns 0. If x is less, returns -1. * If y is less, returns 1. All types are comparable * and should have strict ordering. */ -int dst_compare(DstValue x, DstValue y) { +int dst_compare(Dst x, Dst y) { if (dst_type(x) == dst_type(y)) { switch (dst_type(x)) { case DST_NIL: @@ -147,7 +147,7 @@ int dst_compare(DstValue x, DstValue y) { /* Get a value out af an associated data structure. For invalid * data structure or invalid key, returns nil. */ -DstValue dst_get(DstValue ds, DstValue key) { +Dst dst_get(Dst ds, Dst key) { switch (dst_type(ds)) { case DST_ARRAY: if (dst_checktype(key, DST_INTEGER) && @@ -186,7 +186,7 @@ DstValue dst_get(DstValue ds, DstValue key) { /* Set a value in an associative data structure. Returns possible * error message, and NULL if no error. */ -void dst_put(DstValue ds, DstValue key, DstValue value) { +void dst_put(Dst ds, Dst key, Dst value) { switch (dst_type(ds)) { case DST_ARRAY: if (dst_checktype(key, DST_INTEGER) && @@ -211,7 +211,7 @@ void dst_put(DstValue ds, DstValue key, DstValue value) { /* Get the next key in an associative data structure. Used for iterating through an * associative data structure. */ -const DstKV *dst_next(DstValue ds, const DstKV *kv) { +const DstKV *dst_next(Dst ds, const DstKV *kv) { switch(dst_type(ds)) { default: return NULL; @@ -223,7 +223,7 @@ const DstKV *dst_next(DstValue ds, const DstKV *kv) { } /* Get the length of an object. Returns errors for invalid types */ -int32_t dst_length(DstValue x) { +int32_t dst_length(Dst x) { switch (dst_type(x)) { default: return 0; @@ -243,7 +243,7 @@ int32_t dst_length(DstValue x) { } /* Get the capacity of an object. Returns 0 for invalid types */ -int32_t dst_capacity(DstValue x) { +int32_t dst_capacity(Dst x) { switch (dst_type(x)) { default: return 0; @@ -263,7 +263,7 @@ int32_t dst_capacity(DstValue x) { } /* Index into a data structure. Returns nil for out of bounds or invlalid data structure */ -DstValue dst_getindex(DstValue ds, int32_t index) { +Dst dst_getindex(Dst ds, int32_t index) { switch (dst_type(ds)) { default: return dst_wrap_nil(); @@ -284,7 +284,7 @@ DstValue dst_getindex(DstValue ds, int32_t index) { /* Set an index in a linear data structure. Does nothing if data structure * is invalid */ -void dst_setindex(DstValue ds, DstValue value, int32_t index) { +void dst_setindex(Dst ds, Dst value, int32_t index) { switch (dst_type(ds)) { default: return; diff --git a/core/vector.c b/core/vector.c deleted file mode 100644 index 5603c144..00000000 --- a/core/vector.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Copyright (c) 2017 Calvin Rose -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to -* deal in the Software without restriction, including without limitation the -* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -* sell copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -* IN THE SOFTWARE. -*/ - -#include -#include "vector.h" - -void *dst_v_grow(void *v, int32_t increment, int32_t itemsize) { - int32_t dbl_cur = (NULL != v) ? 2 * dst_v__cap(v) : 0; - int32_t min_needed = dst_v_count(v) + increment; - int32_t m = dbl_cur > min_needed ? dbl_cur : min_needed; - int32_t *p = (int32_t *) realloc(v ? dst_v__raw(v) : 0, itemsize * m + sizeof(int32_t)*2); - if (NULL != p) { - if (!v) p[1] = 0; - p[0] = m; - return p + 2; - } else { - { - DST_OUT_OF_MEMORY; - } - return (void *) (2 * sizeof(int32_t)); // try to force a NULL pointer exception later - } -} - -void *dst_v_copymem(void *v, int32_t itemsize) { - int32_t *p; - if (NULL == v) return NULL; - p = malloc(2 * sizeof(int32_t) + itemsize * dst_v__cap(v)); - if (NULL != p) { - memcpy(p, dst_v__raw(v), 2 * sizeof(int32_t) + itemsize * dst_v__cnt(v)); - return p + 2; - } else { - { - DST_OUT_OF_MEMORY; - } - return (void *) (2 * sizeof(int32_t)); // try to force a NULL pointer exception later - } -} - -void *dst_v_flattenmem(void *v, int32_t itemsize) { - int32_t *p; - int32_t sizen; - if (NULL == v) return NULL; - sizen = itemsize * dst_v__cnt(v); - p = malloc(sizen); - if (NULL != p) { - memcpy(p, v, sizen); - return p; - } else { - { - DST_OUT_OF_MEMORY; - } - return NULL; - } -} diff --git a/core/vm.c b/core/vm.c index c97091e3..0ba3e8ef 100644 --- a/core/vm.c +++ b/core/vm.c @@ -52,13 +52,13 @@ static int dst_update_fiber() { } /* Start running the VM from where it left off. */ -static int dst_continue(DstValue *returnreg) { +static int dst_continue(Dst *returnreg) { /* VM state */ - DstValue *stack; + Dst *stack; uint32_t *pc; DstFunction *func; - DstValue retreg; + Dst retreg; /* Eventually use computed gotos for more effient vm loop. */ #define vm_next() continue @@ -94,8 +94,8 @@ static int dst_continue(DstValue *returnreg) { #define vm_binop(op)\ {\ - DstValue op1 = stack[oparg(2, 0xFF)];\ - DstValue op2 = stack[oparg(3, 0xFF)];\ + Dst op1 = stack[oparg(2, 0xFF)];\ + Dst op2 = stack[oparg(3, 0xFF)];\ vm_assert(dst_checktype(op1, DST_INTEGER) || dst_checktype(op1, DST_REAL), "expected number");\ vm_assert(dst_checktype(op2, DST_INTEGER) || dst_checktype(op2, DST_REAL), "expected number");\ stack[oparg(1, 0xFF)] = dst_checktype(op1, DST_INTEGER)\ @@ -216,8 +216,8 @@ static int dst_continue(DstValue *returnreg) { case DOP_DIVIDE: { - DstValue op1 = stack[oparg(2, 0xFF)]; - DstValue op2 = stack[oparg(3, 0xFF)]; + Dst op1 = stack[oparg(2, 0xFF)]; + Dst op2 = stack[oparg(3, 0xFF)]; vm_assert(dst_checktype(op1, DST_INTEGER) || dst_checktype(op1, DST_REAL), "expected number"); vm_assert(dst_checktype(op2, DST_INTEGER) || dst_checktype(op2, DST_REAL), "expected number"); if (dst_checktype(op2, DST_INTEGER) && dst_unwrap_integer(op2) == 0) @@ -469,7 +469,7 @@ static int dst_continue(DstValue *returnreg) { case DOP_CALL: { - DstValue callee = stack[oparg(2, 0xFFFF)]; + Dst callee = stack[oparg(2, 0xFFFF)]; if (dst_checktype(callee, DST_FUNCTION)) { func = dst_unwrap_function(callee); dst_stack_frame(stack)->pc = pc; @@ -494,7 +494,7 @@ static int dst_continue(DstValue *returnreg) { case DOP_TAILCALL: { - DstValue callee = stack[oparg(1, 0xFFFFFF)]; + Dst callee = stack[oparg(1, 0xFFFFFF)]; if (dst_checktype(callee, DST_FUNCTION)) { func = dst_unwrap_function(callee); dst_fiber_funcframe_tail(dst_vm_fiber, func); @@ -520,7 +520,7 @@ static int dst_continue(DstValue *returnreg) { { DstFiber *nextfiber; DstStackFrame *frame = dst_stack_frame(stack); - DstValue temp = stack[oparg(2, 0xFF)]; + Dst temp = stack[oparg(2, 0xFF)]; retreg = stack[oparg(3, 0xFF)]; vm_assert(dst_checktype(temp, DST_FIBER) || dst_checktype(temp, DST_NIL), "expected fiber"); @@ -645,7 +645,7 @@ static int dst_continue(DstValue *returnreg) { /* Run the vm with a given function. This function is * called to start the vm. */ -int dst_run(DstValue callee, DstValue *returnreg) { +int dst_run(Dst callee, Dst *returnreg) { if (NULL == dst_vm_fiber) { dst_vm_fiber = dst_fiber(0); } else { diff --git a/core/wrap.c b/core/wrap.c index df0e9788..bfeb6361 100644 --- a/core/wrap.c +++ b/core/wrap.c @@ -24,7 +24,7 @@ #ifdef DST_NANBOX -void *dst_nanbox_to_pointer(DstValue x) { +void *dst_nanbox_to_pointer(Dst 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 @@ -39,8 +39,8 @@ void *dst_nanbox_to_pointer(DstValue x) { return x.pointer; } -DstValue dst_nanbox_from_pointer(void *p, uint64_t tagmask) { - DstValue ret; +Dst dst_nanbox_from_pointer(void *p, uint64_t tagmask) { + Dst ret; ret.pointer = p; #if defined (DST_NANBOX_47) || defined (DST_32) #else @@ -50,8 +50,8 @@ 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; +Dst dst_nanbox_from_cpointer(const void *p, uint64_t tagmask) { + Dst ret; ret.cpointer = p; #if defined (DST_NANBOX_47) || defined (DST_32) #else @@ -61,8 +61,8 @@ DstValue dst_nanbox_from_cpointer(const void *p, uint64_t tagmask) { return ret; } -DstValue dst_nanbox_from_double(double d) { - DstValue ret; +Dst dst_nanbox_from_double(double d) { + Dst ret; ret.real = d; /* Normalize NaNs */ if (d != d) @@ -70,8 +70,8 @@ DstValue dst_nanbox_from_double(double d) { return ret; } -DstValue dst_nanbox_from_bits(uint64_t bits) { - DstValue ret; +Dst dst_nanbox_from_bits(uint64_t bits) { + Dst ret; ret.u64 = bits; return ret; } @@ -104,37 +104,37 @@ void dst_nanbox_memempty(DstKV *mem, int32_t count) { * leak memory, where as the stack based API ensures that all values can * be collected by the garbage collector. */ -DstValue dst_wrap_nil() { - DstValue y; +Dst dst_wrap_nil() { + Dst y; y.type = DST_NIL; y.as.u64 = 0; return y; } -DstValue dst_wrap_true() { - DstValue y; +Dst dst_wrap_true() { + Dst y; y.type = DST_TRUE; y.as.u64 = 0; return y; } -DstValue dst_wrap_false() { - DstValue y; +Dst dst_wrap_false() { + Dst y; y.type = DST_FALSE; y.as.u64 = 0; return y; } -DstValue dst_wrap_boolean(int x) { - DstValue y; +Dst dst_wrap_boolean(int x) { + Dst y; y.type = x ? DST_TRUE : DST_FALSE; y.as.u64 = 0; return y; } #define DST_WRAP_DEFINE(NAME, TYPE, DTYPE, UM)\ -DstValue dst_wrap_##NAME(TYPE x) {\ - DstValue y;\ +Dst dst_wrap_##NAME(TYPE x) {\ + Dst y;\ y.type = DTYPE;\ y.as.u64 = 0; /* zero other bits in case of 32 bit integer */ \ y.as.UM = x;\ @@ -146,7 +146,7 @@ DST_WRAP_DEFINE(integer, int32_t, DST_INTEGER, integer) DST_WRAP_DEFINE(string, const uint8_t *, DST_STRING, cpointer) DST_WRAP_DEFINE(symbol, const uint8_t *, DST_SYMBOL, cpointer) DST_WRAP_DEFINE(array, DstArray *, DST_ARRAY, pointer) -DST_WRAP_DEFINE(tuple, const DstValue *, DST_TUPLE, cpointer) +DST_WRAP_DEFINE(tuple, const Dst *, DST_TUPLE, cpointer) DST_WRAP_DEFINE(struct, const DstKV *, DST_STRUCT, cpointer) DST_WRAP_DEFINE(fiber, DstFiber *, DST_FIBER, pointer) DST_WRAP_DEFINE(buffer, DstBuffer *, DST_BUFFER, pointer) diff --git a/include/dst/dst.h b/include/dst/dst.h index 0341d374..a76a4528 100644 --- a/include/dst/dst.h +++ b/include/dst/dst.h @@ -38,9 +38,9 @@ DstArray *dst_array_init(DstArray *array, int32_t capacity); void dst_array_deinit(DstArray *array); void dst_array_ensure(DstArray *array, int32_t capacity); void dst_array_setcount(DstArray *array, int32_t count); -void dst_array_push(DstArray *array, DstValue x); -DstValue dst_array_pop(DstArray *array); -DstValue dst_array_peek(DstArray *array); +void dst_array_push(DstArray *array, Dst x); +Dst dst_array_pop(DstArray *array); +Dst dst_array_peek(DstArray *array); /* Buffer functions */ DstBuffer *dst_buffer(int32_t capacity); @@ -59,11 +59,11 @@ void dst_buffer_push_u64(DstBuffer *buffer, uint64_t x); #define dst_tuple_raw(t) ((int32_t *)(t) - 2) #define dst_tuple_length(t) (dst_tuple_raw(t)[0]) #define dst_tuple_hash(t) ((dst_tuple_raw(t)[1])) -DstValue *dst_tuple_begin(int32_t length); -const DstValue *dst_tuple_end(DstValue *tuple); -const DstValue *dst_tuple_n(DstValue *values, int32_t n); -int dst_tuple_equal(const DstValue *lhs, const DstValue *rhs); -int dst_tuple_compare(const DstValue *lhs, const DstValue *rhs); +Dst *dst_tuple_begin(int32_t length); +const Dst *dst_tuple_end(Dst *tuple); +const Dst *dst_tuple_n(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); /* String/Symbol functions */ #define dst_string_raw(s) ((int32_t *)(s) - 2) @@ -78,9 +78,10 @@ int dst_string_equal(const uint8_t *lhs, const uint8_t *rhs); int dst_string_equalconst(const uint8_t *lhs, const uint8_t *rhs, int32_t rlen, int32_t rhash); const uint8_t *dst_string_unique(const uint8_t *buf, int32_t len); const uint8_t *dst_cstring_unique(const char *s); -const uint8_t *dst_description(DstValue x); -const uint8_t *dst_short_description(DstValue x); -const uint8_t *dst_to_string(DstValue x); +const uint8_t *dst_description(Dst x); +const uint8_t *dst_short_description(Dst x); +const uint8_t *dst_to_string(Dst x); +const char *dst_to_zerostring(Dst x); #define dst_cstringv(cstr) dst_wrap_string(dst_cstring(cstr)) #define dst_stringv(str, len) dst_wrap_string(dst_string((str), (len))) const uint8_t *dst_formatc(const char *format, ...); @@ -101,9 +102,9 @@ const uint8_t *dst_symbol_gen(const uint8_t *buf, int32_t len); #define dst_struct_hash(t) (dst_struct_raw(t)[2]) /* Do something with the 4th header slot - flags? */ DstKV *dst_struct_begin(int32_t count); -void dst_struct_put(DstKV *st, DstValue key, DstValue value); +void dst_struct_put(DstKV *st, Dst key, Dst value); const DstKV *dst_struct_end(DstKV *st); -DstValue dst_struct_get(const DstKV *st, DstValue key); +Dst dst_struct_get(const DstKV *st, Dst key); const DstKV *dst_struct_next(const DstKV *st, const DstKV *kv); DstTable *dst_struct_to_table(const DstKV *st); int dst_struct_equal(const DstKV *lhs, const DstKV *rhs); @@ -113,12 +114,12 @@ int dst_struct_compare(const DstKV *lhs, const DstKV *rhs); DstTable *dst_table(int32_t capacity); DstTable *dst_table_init(DstTable *table, int32_t capacity); void dst_table_deinit(DstTable *table); -DstValue dst_table_get(DstTable *t, DstValue key); -DstValue dst_table_remove(DstTable *t, DstValue key); -void dst_table_put(DstTable *t, DstValue key, DstValue value); +Dst dst_table_get(DstTable *t, Dst key); +Dst dst_table_remove(DstTable *t, Dst key); +void dst_table_put(DstTable *t, Dst key, Dst value); const DstKV *dst_table_next(DstTable *t, const DstKV *kv); const DstKV *dst_table_to_struct(DstTable *t); -void dst_table_merge(DstTable *t, DstValue other); +void dst_table_merge(DstTable *t, Dst other); /* Fiber */ DstFiber *dst_fiber(int32_t capacity); @@ -126,10 +127,10 @@ DstFiber *dst_fiber(int32_t capacity); #define dst_fiber_frame(f) dst_stack_frame((f)->data + (f)->frame) DstFiber *dst_fiber_reset(DstFiber *fiber); void dst_fiber_setcapacity(DstFiber *fiber, int32_t n); -void dst_fiber_push(DstFiber *fiber, DstValue x); -void dst_fiber_push2(DstFiber *fiber, DstValue x, DstValue y); -void dst_fiber_push3(DstFiber *fiber, DstValue x, DstValue y, DstValue z); -void dst_fiber_pushn(DstFiber *fiber, const DstValue *arr, int32_t n); +void dst_fiber_push(DstFiber *fiber, Dst x); +void dst_fiber_push2(DstFiber *fiber, Dst x, Dst y); +void dst_fiber_push3(DstFiber *fiber, Dst x, Dst y, Dst z); +void dst_fiber_pushn(DstFiber *fiber, const Dst *arr, int32_t n); void dst_fiber_funcframe(DstFiber *fiber, DstFunction *func); void dst_fiber_funcframe_tail(DstFiber *fiber, DstFunction *func); void dst_fiber_cframe(DstFiber *fiber); @@ -138,13 +139,13 @@ void dst_fiber_popframe(DstFiber *fiber); /* Assembly */ DstAssembleResult dst_asm(DstAssembleOptions opts); DstFunction *dst_asm_func(DstAssembleResult result); -DstValue dst_disasm(DstFuncDef *def); -DstValue dst_asm_decode_instruction(uint32_t instr); +Dst dst_disasm(DstFuncDef *def); +Dst dst_asm_decode_instruction(uint32_t instr); /* Treat similar types through uniform interfaces for iteration */ -int dst_seq_view(DstValue seq, const DstValue **data, int32_t *len); -int dst_chararray_view(DstValue str, const uint8_t **data, int32_t *len); -int dst_hashtable_view(DstValue tab, const DstKV **data, int32_t *len, int32_t *cap); +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); /* Abstract */ #define dst_abstract_header(u) ((DstAbstractHeader *)(u) - 1) @@ -152,33 +153,16 @@ int dst_hashtable_view(DstValue tab, const DstKV **data, int32_t *len, int32_t * #define dst_abstract_size(u) (dst_abstract_header(u)->size) /* Value functions */ -int dst_equals(DstValue x, DstValue y); -int32_t dst_hash(DstValue x); -int dst_compare(DstValue x, DstValue y); -DstValue dst_get(DstValue ds, DstValue key); -void dst_put(DstValue ds, DstValue key, DstValue value); -const DstKV *dst_next(DstValue ds, const DstKV *kv); -int32_t dst_length(DstValue x); -int32_t dst_capacity(DstValue x); -DstValue dst_getindex(DstValue ds, int32_t index); -void dst_setindex(DstValue ds, DstValue value, int32_t index); - -/* Utils */ -extern const char dst_base64[65]; -int32_t dst_array_calchash(const DstValue *array, int32_t len); -int32_t dst_kv_calchash(const DstKV *kvs, int32_t len); -int32_t dst_string_calchash(const uint8_t *str, int32_t len); -int32_t dst_tablen(int32_t n); -DstValue dst_loadreg(DstReg *regs, size_t count); -DstValue dst_scan_number(const uint8_t *src, int32_t len); -int32_t dst_scan_integer(const uint8_t *str, int32_t len, int *err); -double dst_scan_real(const uint8_t *str, int32_t len, int *err); -int dst_cstrcmp(const uint8_t *str, const char *other); -const void *dst_strbinsearch( - const void *tab, - size_t tabcount, - size_t itemsize, - const uint8_t *key); +int dst_equals(Dst x, Dst y); +int32_t dst_hash(Dst x); +int dst_compare(Dst x, Dst y); +Dst dst_get(Dst ds, Dst key); +void dst_put(Dst ds, Dst key, Dst value); +const DstKV *dst_next(Dst ds, const DstKV *kv); +int32_t dst_length(Dst x); +int32_t dst_capacity(Dst x); +Dst dst_getindex(Dst ds, int32_t index); +void dst_setindex(Dst ds, Dst value, int32_t index); /* Parsing */ DstParseResult dst_parse(const uint8_t *src, int32_t len); @@ -187,7 +171,13 @@ DstParseResult dst_parsec(const char *src); /* VM functions */ int dst_init(); void dst_deinit(); -int dst_run(DstValue callee, DstValue *returnreg); +int dst_run(Dst callee, Dst *returnreg); + +/* Misc */ +Dst dst_loadreg(DstReg *regs, size_t count); +Dst dst_scan_number(const uint8_t *src, int32_t len); +int32_t dst_scan_integer(const uint8_t *str, int32_t len, int *err); +double dst_scan_real(const uint8_t *str, int32_t len, int *err); /* Compile */ DstCompileResult dst_compile(DstCompileOptions opts); @@ -195,16 +185,16 @@ DstFunction *dst_compile_func(DstCompileResult result); /* STL */ #define DST_LOAD_ROOT 1 -DstValue dst_loadstl(int flags); +Dst dst_loadstl(int flags); /* GC */ -void dst_mark(DstValue x); +void dst_mark(Dst x); void dst_sweep(); void dst_collect(); void dst_clear_memory(); -void dst_gcroot(DstValue root); -int dst_gcunroot(DstValue root); -int dst_gcunrootall(DstValue root); +void dst_gcroot(Dst root); +int dst_gcunroot(Dst root); +int dst_gcunrootall(Dst root); #define dst_maybe_collect() do {\ if (dst_vm_next_collection >= dst_vm_gc_interval) dst_collect(); } while (0) diff --git a/include/dst/dststate.h b/include/dst/dststate.h index d75bbf7f..9b36ea4a 100644 --- a/include/dst/dststate.h +++ b/include/dst/dststate.h @@ -45,7 +45,7 @@ extern uint32_t dst_vm_cache_count; extern uint32_t dst_vm_cache_deleted; /* GC roots */ -extern DstValue *dst_vm_roots; +extern Dst *dst_vm_roots; extern uint32_t dst_vm_root_count; extern uint32_t dst_vm_root_capacity; diff --git a/include/dst/dststl.h b/include/dst/dststl.h index d721ab11..ef136858 100644 --- a/include/dst/dststl.h +++ b/include/dst/dststl.h @@ -25,41 +25,47 @@ #include "dsttypes.h" -int dst_add(int32_t argn, DstValue *argv, DstValue *ret); -int dst_subtract(int32_t argn, DstValue *argv, DstValue *ret); -int dst_multiply(int32_t argn, DstValue *argv, DstValue *ret); -int dst_divide(int32_t argn, DstValue *argv, DstValue *ret); -int dst_modulo(int32_t argn, DstValue *argv, DstValue *ret); +/* File type definition */ +extern DstAbstractType dst_stl_filetype; -int dst_acos(int32_t argn, DstValue *argv, DstValue *ret); -int dst_asin(int32_t argn, DstValue *argv, DstValue *ret); -int dst_atan(int32_t argn, DstValue *argv, DstValue *ret); -int dst_cos(int32_t argn, DstValue *argv, DstValue *ret); -int dst_cosh(int32_t argn, DstValue *argv, DstValue *ret); -int dst_sin(int32_t argn, DstValue *argv, DstValue *ret); -int dst_sinh(int32_t argn, DstValue *argv, DstValue *ret); -int dst_tan(int32_t argn, DstValue *argv, DstValue *ret); -int dst_tanh(int32_t argn, DstValue *argv, DstValue *ret); -int dst_exp(int32_t argn, DstValue *argv, DstValue *ret); -int dst_log(int32_t argn, DstValue *argv, DstValue *ret); -int dst_log10(int32_t argn, DstValue *argv, DstValue *ret); -int dst_sqrt(int32_t argn, DstValue *argv, DstValue *ret); -int dst_ceil(int32_t argn, DstValue *argv, DstValue *ret); -int dst_fabs(int32_t argn, DstValue *argv, DstValue *ret); -int dst_floor(int32_t argn, DstValue *argv, DstValue *ret); -int dst_pow(int32_t argn, DstValue *argv, DstValue *ret); +int dst_int(int32_t argn, Dst *argv, Dst *ret); +int dst_real(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_table(int32_t argn, DstValue *argv, DstValue *ret); -int dst_stl_array(int32_t argn, DstValue *argv, DstValue *ret); -int dst_stl_struct(int32_t argn, DstValue *argv, DstValue *ret); -int dst_stl_tuple(int32_t argn, DstValue *argv, DstValue *ret); +int dst_add(int32_t argn, Dst *argv, Dst *ret); +int dst_subtract(int32_t argn, Dst *argv, Dst *ret); +int dst_multiply(int32_t argn, Dst *argv, Dst *ret); +int dst_divide(int32_t argn, Dst *argv, Dst *ret); +int dst_modulo(int32_t argn, Dst *argv, Dst *ret); -int dst_band(int32_t argn, DstValue *argv, DstValue *ret); -int dst_bor(int32_t argn, DstValue *argv, DstValue *ret); -int dst_bxor(int32_t argn, DstValue *argv, DstValue *ret); +int dst_acos(int32_t argn, Dst *argv, Dst *ret); +int dst_asin(int32_t argn, Dst *argv, Dst *ret); +int dst_atan(int32_t argn, Dst *argv, Dst *ret); +int dst_cos(int32_t argn, Dst *argv, Dst *ret); +int dst_cosh(int32_t argn, Dst *argv, Dst *ret); +int dst_sin(int32_t argn, Dst *argv, Dst *ret); +int dst_sinh(int32_t argn, Dst *argv, Dst *ret); +int dst_tan(int32_t argn, Dst *argv, Dst *ret); +int dst_tanh(int32_t argn, Dst *argv, Dst *ret); +int dst_exp(int32_t argn, Dst *argv, Dst *ret); +int dst_log(int32_t argn, Dst *argv, Dst *ret); +int dst_log10(int32_t argn, Dst *argv, Dst *ret); +int dst_sqrt(int32_t argn, Dst *argv, Dst *ret); +int dst_ceil(int32_t argn, Dst *argv, Dst *ret); +int dst_fabs(int32_t argn, Dst *argv, Dst *ret); +int dst_floor(int32_t argn, Dst *argv, Dst *ret); +int dst_pow(int32_t argn, Dst *argv, Dst *ret); -int dst_lshift(int argn, DstValue *argv, DstValue *ret); -int dst_rshift(int argn, DstValue *argv, DstValue *ret); -int dst_lshiftu(int argn, DstValue *argv, DstValue *ret); +int dst_stl_table(int32_t argn, Dst *argv, Dst *ret); +int dst_stl_array(int32_t argn, Dst *argv, Dst *ret); +int dst_stl_struct(int32_t argn, Dst *argv, Dst *ret); +int dst_stl_tuple(int32_t argn, Dst *argv, Dst *ret); + +int dst_band(int32_t argn, Dst *argv, Dst *ret); +int dst_bor(int32_t argn, Dst *argv, Dst *ret); +int dst_bxor(int32_t argn, Dst *argv, Dst *ret); + +int dst_lshift(int argn, Dst *argv, Dst *ret); +int dst_rshift(int argn, Dst *argv, Dst *ret); +int dst_lshiftu(int argn, Dst *argv, Dst *ret); #endif /* DST_MATH_H_defined */ diff --git a/include/dst/dsttypes.h b/include/dst/dsttypes.h index 69022130..acf2b44b 100644 --- a/include/dst/dsttypes.h +++ b/include/dst/dsttypes.h @@ -27,9 +27,9 @@ #include "dstconfig.h" #ifdef DST_NANBOX -typedef union DstValue DstValue; +typedef union Dst Dst; #else -typedef struct DstValue DstValue; +typedef struct Dst Dst; #endif /* All of the dst types */ @@ -47,7 +47,7 @@ typedef struct DstFuncEnv DstFuncEnv; typedef struct DstKV DstKV; typedef struct DstStackFrame DstStackFrame; typedef struct DstAbstractType DstAbstractType; -typedef int (*DstCFunction)(int32_t argn, DstValue *argv, DstValue *ret); +typedef int (*DstCFunction)(int32_t argn, Dst *argv, Dst *ret); typedef enum DstAssembleStatus DstAssembleStatus; typedef struct DstAssembleResult DstAssembleResult; @@ -78,11 +78,11 @@ typedef enum DstType { DST_ABSTRACT } DstType; -/* We provide two possible implemenations of DstValues. The preferred +/* We provide two possible implemenations of Dsts. The preferred * nanboxing approach, and the standard C version. Code in the rest of the * application must interact through exposed interface. */ -/* Required interface for DstValue */ +/* Required interface for Dst */ /* wrap and unwrap for all types */ /* Get type quickly */ /* Check against type quickly */ @@ -102,7 +102,7 @@ typedef enum DstType { #include -union DstValue { +union Dst { uint64_t u64; int64_t i64; void *pointer; @@ -177,13 +177,13 @@ union DstValue { ? dst_nanbox_isreal(x) \ : dst_nanbox_checkauxtype((x), (t))) -void *dst_nanbox_to_pointer(DstValue x); +void *dst_nanbox_to_pointer(Dst x); void dst_nanbox_memempty(DstKV *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); +Dst dst_nanbox_from_pointer(void *p, uint64_t tagmask); +Dst dst_nanbox_from_cpointer(const void *p, uint64_t tagmask); +Dst dst_nanbox_from_double(double d); +Dst dst_nanbox_from_bits(uint64_t bits); #define dst_memempty(mem, len) dst_nanbox_memempty((mem), (len)) #define dst_memalloc_empty(count) dst_nanbox_memalloc_empty(count) @@ -231,7 +231,7 @@ DstValue dst_nanbox_from_bits(uint64_t bits); /* Unwrap the pointer types */ #define dst_unwrap_struct(x) ((const DstKV *)dst_nanbox_to_pointer(x)) -#define dst_unwrap_tuple(x) ((const DstValue *)dst_nanbox_to_pointer(x)) +#define dst_unwrap_tuple(x) ((const Dst *)dst_nanbox_to_pointer(x)) #define dst_unwrap_fiber(x) ((DstFiber *)dst_nanbox_to_pointer(x)) #define dst_unwrap_array(x) ((DstArray *)dst_nanbox_to_pointer(x)) #define dst_unwrap_table(x) ((DstTable *)dst_nanbox_to_pointer(x)) @@ -247,7 +247,7 @@ DstValue dst_nanbox_from_bits(uint64_t bits); #else /* A general dst value type */ -struct DstValue { +struct Dst { union { uint64_t u64; double real; @@ -267,7 +267,7 @@ struct DstValue { ((x).type != DST_NIL && (x).type != DST_FALSE) #define dst_unwrap_struct(x) ((const DstKV *)(x).as.pointer) -#define dst_unwrap_tuple(x) ((const DstValue *)(x).as.pointer) +#define dst_unwrap_tuple(x) ((const Dst *)(x).as.pointer) #define dst_unwrap_fiber(x) ((DstFiber *)(x).as.pointer) #define dst_unwrap_array(x) ((DstArray *)(x).as.pointer) #define dst_unwrap_table(x) ((DstTable *)(x).as.pointer) @@ -282,23 +282,23 @@ struct DstValue { #define dst_unwrap_integer(x) ((x).as.integer) #define dst_unwrap_real(x) ((x).as.real) -DstValue dst_wrap_nil(); -DstValue dst_wrap_real(double x); -DstValue dst_wrap_integer(int32_t x); -DstValue dst_wrap_true(); -DstValue dst_wrap_false(); -DstValue dst_wrap_boolean(int x); -DstValue dst_wrap_string(const uint8_t *x); -DstValue dst_wrap_symbol(const uint8_t *x); -DstValue dst_wrap_array(DstArray *x); -DstValue dst_wrap_tuple(const DstValue *x); -DstValue dst_wrap_struct(const DstKV *x); -DstValue dst_wrap_fiber(DstFiber *x); -DstValue dst_wrap_buffer(DstBuffer *x); -DstValue dst_wrap_function(DstFunction *x); -DstValue dst_wrap_cfunction(DstCFunction x); -DstValue dst_wrap_table(DstTable *x); -DstValue dst_wrap_abstract(void *x); +Dst dst_wrap_nil(); +Dst dst_wrap_real(double x); +Dst dst_wrap_integer(int32_t x); +Dst dst_wrap_true(); +Dst dst_wrap_false(); +Dst dst_wrap_boolean(int x); +Dst dst_wrap_string(const uint8_t *x); +Dst dst_wrap_symbol(const uint8_t *x); +Dst dst_wrap_array(DstArray *x); +Dst dst_wrap_tuple(const Dst *x); +Dst dst_wrap_struct(const DstKV *x); +Dst dst_wrap_fiber(DstFiber *x); +Dst dst_wrap_buffer(DstBuffer *x); +Dst dst_wrap_function(DstFunction *x); +Dst dst_wrap_cfunction(DstCFunction x); +Dst dst_wrap_table(DstTable *x); +Dst dst_wrap_abstract(void *x); /* End of tagged union implementation */ #endif @@ -312,7 +312,7 @@ struct DstReg { /* A lightweight green thread in dst. Does not correspond to * operating system threads. */ struct DstFiber { - DstValue *data; + Dst *data; DstFiber *parent; int32_t frame; /* Index of the stack frame */ int32_t stackstart; /* Beginning of next args */ @@ -333,12 +333,12 @@ struct DstStackFrame { int32_t prevframe; }; -/* Number of DstValues a frame takes up in the stack */ -#define DST_FRAME_SIZE ((sizeof(DstStackFrame) + sizeof(DstValue) - 1)/ sizeof(DstValue)) +/* Number of Dsts a frame takes up in the stack */ +#define DST_FRAME_SIZE ((sizeof(DstStackFrame) + sizeof(Dst) - 1)/ sizeof(Dst)) /* A dynamic array type. */ struct DstArray { - DstValue *data; + Dst *data; int32_t count; int32_t capacity; }; @@ -360,8 +360,8 @@ struct DstTable { /* A key value pair in a struct or table */ struct DstKV { - DstValue key; - DstValue value; + Dst key; + Dst value; }; /* Some function defintion flags */ @@ -371,7 +371,7 @@ struct DstKV { /* A function definition. Contains information needed to instantiate closures. */ struct DstFuncDef { int32_t *environments; /* Which environments to capture from parent. */ - DstValue *constants; + Dst *constants; DstFuncDef **defs; uint32_t *bytecode; @@ -393,7 +393,7 @@ struct DstFuncDef { struct DstFuncEnv { union { DstFiber *fiber; - DstValue *values; + Dst *values; } as; int32_t length; /* Size of environment */ int32_t offset; /* Stack offset when values still on stack. If offset is <= 0, then @@ -428,7 +428,7 @@ enum DstAssembleStatus { }; struct DstAssembleOptions { - DstValue source; + Dst source; uint32_t flags; }; @@ -454,9 +454,9 @@ struct DstCompileResult { struct DstCompileOptions { uint32_t flags; - const DstValue *sourcemap; - DstValue source; - DstValue env; + const Dst *sourcemap; + Dst source; + Dst env; }; /* Parse structs */ @@ -468,9 +468,9 @@ enum DstParseStatus { }; struct DstParseResult { - DstValue value; + Dst value; const uint8_t *error; - const DstValue *map; + const Dst *map; int32_t bytes_read; DstParseStatus status; };