mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +00:00
Rename DstValue to Dst for easier access. Move vector.c into
util.c and make public API smaller. Pad strings and symbols with extra 0 byte for better interop with C.
This commit is contained in:
parent
2771171658
commit
605848b217
4
Makefile
4
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)
|
||||
|
@ -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));
|
||||
|
16
core/array.c
16
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 {
|
||||
|
71
core/asm.c
71
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 {
|
||||
|
150
core/compile.c
150
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);
|
||||
|
@ -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
|
||||
|
24
core/fiber.c
24
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;
|
||||
|
28
core/gc.c
28
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++) {
|
||||
|
82
core/io.c
Normal file
82
core/io.c
Normal file
@ -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());
|
||||
}
|
36
core/math.c
36
core/math.c
@ -24,7 +24,7 @@
|
||||
#include <math.h>
|
||||
|
||||
/* 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;
|
||||
|
50
core/parse.c
50
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
50
core/stl.c
50
core/stl.c
@ -23,7 +23,7 @@
|
||||
#include <dst/dst.h>
|
||||
#include <dst/dststl.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -23,12 +23,14 @@
|
||||
#include <dst/dst.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <dst/dst.h>
|
||||
#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();
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <dst/dst.h>
|
||||
#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) {
|
||||
|
11
core/table.c
11
core/table.c
@ -22,6 +22,7 @@
|
||||
|
||||
#include <dst/dst.h>
|
||||
#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);
|
||||
|
23
core/tuple.c
23
core/tuple.c
@ -23,32 +23,33 @@
|
||||
#include <dst/dst.h>
|
||||
#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);
|
||||
|
71
core/util.c
71
core/util.c
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <dst/dst.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -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 <dst/dst.h>
|
||||
|
||||
/* 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 <dst/dst.h>
|
||||
|
||||
#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)
|
22
core/value.c
22
core/value.c
@ -23,11 +23,11 @@
|
||||
#include <dst/dst.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -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 <dst/dst.h>
|
||||
#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;
|
||||
}
|
||||
}
|
22
core/vm.c
22
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 {
|
||||
|
40
core/wrap.c
40
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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 <math.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user