1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-26 08:20:27 +00:00

Convert get, put and length to normal functions, not c functions.

This commit is contained in:
Calvin Rose 2018-06-17 13:55:02 -04:00
parent 0cf10946b0
commit 363a17ff8c
11 changed files with 330 additions and 268 deletions

View File

@ -475,6 +475,18 @@ static uint32_t read_instruction(
return instr; return instr;
} }
/* Helper to get from a structure */
static Dst dst_get(Dst ds, Dst key) {
switch (dst_type(ds)) {
default:
return dst_wrap_nil();
case DST_TABLE:
return dst_table_get(dst_unwrap_table(ds), key);
case DST_STRUCT:
return dst_struct_get(dst_unwrap_struct(ds), key);
}
}
/* Helper to assembly. Return the assembly result */ /* Helper to assembly. Return the assembly result */
static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) { static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
DstAssembleResult result; DstAssembleResult result;

View File

@ -66,6 +66,19 @@ int dstc_iserr(DstFopts *opts) {
return (opts->compiler->result.status == DST_COMPILE_ERROR); return (opts->compiler->result.status == DST_COMPILE_ERROR);
} }
/* Get the next key in an associative data structure. Used for iterating through an
* associative data structure. */
const DstKV *dstc_next(Dst ds, const DstKV *kv) {
switch(dst_type(ds)) {
default:
return NULL;
case DST_TABLE:
return (const DstKV *) dst_table_next(dst_unwrap_table(ds), kv);
case DST_STRUCT:
return dst_struct_next(dst_unwrap_struct(ds), kv);
}
}
/* Allocate a slot index */ /* Allocate a slot index */
int32_t dstc_lsloti(DstCompiler *c) { int32_t dstc_lsloti(DstCompiler *c) {
DstScope *scope = &dst_v_last(c->scopes); DstScope *scope = &dst_v_last(c->scopes);
@ -257,22 +270,24 @@ DstSlot dstc_resolve(
/* Symbol not found - check for global */ /* Symbol not found - check for global */
{ {
Dst check = dst_table_get(c->env, dst_wrap_symbol(sym)); Dst check;
Dst ref; DstBindingType btype = dst_env_resolve(c->env, sym, &check);
if (!(dst_checktype(check, DST_STRUCT) || dst_checktype(check, DST_TABLE))) { switch (btype) {
dstc_error(c, ast, dst_formatc("unknown symbol %q", sym)); default:
return dstc_cslot(dst_wrap_nil()); case DST_BINDING_NONE:
} dstc_error(c, ast, dst_formatc("unknown symbol %q", sym));
ref = dst_get(check, dst_csymbolv(":ref")); return dstc_cslot(dst_wrap_nil());
if (dst_checktype(ref, DST_ARRAY)) { case DST_BINDING_DEF:
DstSlot ret = dstc_cslot(ref); case DST_BINDING_MACRO: /* Macro should function like defs when not in calling pos */
/* TODO save type info */ return dstc_cslot(check);
ret.flags |= DST_SLOT_REF | DST_SLOT_NAMED | DST_SLOT_MUTABLE | DST_SLOTTYPE_ANY; case DST_BINDING_VAR:
ret.flags &= ~DST_SLOT_CONSTANT; {
return ret; DstSlot ret = dstc_cslot(check);
} else { /* TODO save type info */
Dst value = dst_get(check, dst_csymbolv(":value")); ret.flags |= DST_SLOT_REF | DST_SLOT_NAMED | DST_SLOT_MUTABLE | DST_SLOTTYPE_ANY;
return dstc_cslot(value); ret.flags &= ~DST_SLOT_CONSTANT;
return ret;
}
} }
} }
@ -627,7 +642,7 @@ DstSM *dstc_toslotskv(DstCompiler *c, Dst ds) {
DstSM *ret = NULL; DstSM *ret = NULL;
const DstKV *kv = NULL; const DstKV *kv = NULL;
DstFopts subopts = dstc_fopts_default(c); DstFopts subopts = dstc_fopts_default(c);
while ((kv = dst_next(ds, kv))) { while ((kv = dstc_next(ds, kv))) {
DstSM km, vm; DstSM km, vm;
km.slot = dstc_value(subopts, kv->key); km.slot = dstc_value(subopts, kv->key);
km.map = dst_ast_node(kv->key); km.map = dst_ast_node(kv->key);
@ -807,25 +822,22 @@ recur:
/* Symbols could be specials */ /* Symbols could be specials */
headval = dst_ast_unwrap1(tup[0]); headval = dst_ast_unwrap1(tup[0]);
if (dst_checktype(headval, DST_SYMBOL)) { if (dst_checktype(headval, DST_SYMBOL)) {
const DstSpecial *s = dstc_special(dst_unwrap_symbol(headval)); const uint8_t *headsym = dst_unwrap_symbol(headval);
const DstSpecial *s = dstc_special(headsym);
if (NULL != s) { if (NULL != s) {
ret = s->compile(opts, ast, dst_tuple_length(tup) - 1, tup + 1); ret = s->compile(opts, ast, dst_tuple_length(tup) - 1, tup + 1);
compiled = 1; compiled = 1;
} else { } else {
/* Check macro */ /* Check macro */
DstTable *env = c->env; Dst macVal;
Dst fn; DstBindingType btype = dst_env_resolve(c->env, headsym, &macVal);
Dst entry = dst_table_get(env, headval); if (btype == DST_BINDING_MACRO &&
for (;;) { dst_checktype(macVal, DST_FUNCTION)) {
if (dst_checktype(entry, DST_NIL)) break;
if (dst_checktype(dst_get(entry, dst_csymbolv(":macro")), DST_NIL)) break;
fn = dst_get(entry, dst_csymbolv(":value"));
if (!dst_checktype(fn, DST_FUNCTION)) break;
if (macrorecur++ > DST_RECURSION_GUARD) { if (macrorecur++ > DST_RECURSION_GUARD) {
dstc_cerror(c, ast, "macro expansion recursed too deeply"); dstc_cerror(c, ast, "macro expansion recursed too deeply");
return dstc_cslot(dst_wrap_nil()); return dstc_cslot(dst_wrap_nil());
} else { } else {
DstFunction *f = dst_unwrap_function(fn); DstFunction *f = dst_unwrap_function(macVal);
int lock = dst_gclock(); int lock = dst_gclock();
DstSignal status = dst_call(f, dst_tuple_length(tup) - 1, tup + 1, &x); DstSignal status = dst_call(f, dst_tuple_length(tup) - 1, tup + 1, &x);
dst_gcunlock(lock); dst_gcunlock(lock);
@ -843,6 +855,7 @@ recur:
/* Compile the head of the tuple */ /* Compile the head of the tuple */
subopts.flags = DST_FUNCTION | DST_CFUNCTION; subopts.flags = DST_FUNCTION | DST_CFUNCTION;
head = dstc_value(subopts, tup[0]); head = dstc_value(subopts, tup[0]);
/* Add compile function call */
ret = dstc_call(opts, ast, dstc_toslots(c, tup + 1, dst_tuple_length(tup) - 1), head); ret = dstc_call(opts, ast, dstc_toslots(c, tup + 1, dst_tuple_length(tup) - 1), head);
} }
} }

View File

@ -154,6 +154,9 @@ const DstSpecial *dstc_special(const uint8_t *name);
/* Check error */ /* Check error */
int dstc_iserr(DstFopts *opts); int dstc_iserr(DstFopts *opts);
/* Helper for iterating tables and structs */
const DstKV *dstc_next(Dst ds, const DstKV *kv);
/* Allocate a slot index */ /* Allocate a slot index */
int32_t dstc_lsloti(DstCompiler *c); int32_t dstc_lsloti(DstCompiler *c);

View File

@ -65,10 +65,11 @@ static void destructure(DstCompiler *c, Dst left, DstSlot right,
case DST_ARRAY: case DST_ARRAY:
{ {
int32_t i, len, localright, localsub; int32_t i, len, localright, localsub;
len = dst_length(left); const Dst *values;
dst_seq_view(left, &values, &len);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
DstSlot newright; DstSlot newright;
Dst subval = dst_getindex(left, i); Dst subval = values[i];
localright = dstc_preread(c, ast, 0xFF, 1, right); localright = dstc_preread(c, ast, 0xFF, 1, right);
localsub = dstc_lslotn(c, 0xFF, 3); localsub = dstc_lslotn(c, 0xFF, 3);
if (i < 0x100) { if (i < 0x100) {
@ -104,7 +105,7 @@ static void destructure(DstCompiler *c, Dst left, DstSlot right,
{ {
int32_t localright, localsub; int32_t localright, localsub;
const DstKV *kv = NULL; const DstKV *kv = NULL;
while ((kv = dst_next(left, kv))) { while ((kv = dstc_next(left, kv))) {
DstSlot newright; DstSlot newright;
DstSlot kslot = dstc_cslot(dst_ast_unwrap(kv->key)); DstSlot kslot = dstc_cslot(dst_ast_unwrap(kv->key));
Dst subval = kv->value; Dst subval = kv->value;

View File

@ -46,9 +46,6 @@ static const DstReg cfuns[] = {
{"struct", dst_core_struct}, {"struct", dst_core_struct},
{"buffer", dst_core_buffer}, {"buffer", dst_core_buffer},
{"gensym", dst_core_gensym}, {"gensym", dst_core_gensym},
{"get", dst_core_get},
{"put", dst_core_put},
{"length", dst_core_length},
{"gccollect", dst_core_gccollect}, {"gccollect", dst_core_gccollect},
{"gcsetinterval", dst_core_gcsetinterval}, {"gcsetinterval", dst_core_gcsetinterval},
{"gcinterval", dst_core_gcinterval}, {"gcinterval", dst_core_gcinterval},
@ -100,6 +97,18 @@ DstTable *dst_stl_env(int flags) {
DOP_RESUME | (1 << 24), DOP_RESUME | (1 << 24),
DOP_RETURN DOP_RETURN
}; };
static uint32_t get_asm[] = {
DOP_GET | (1 << 24),
DOP_RETURN
};
static uint32_t put_asm[] = {
DOP_PUT | (1 << 16) | (2 << 24),
DOP_RETURN
};
static uint32_t length_asm[] = {
DOP_LENGTH,
DOP_RETURN
};
DstTable *env = dst_table(0); DstTable *env = dst_table(0);
Dst ret = dst_wrap_table(env); Dst ret = dst_wrap_table(env);
@ -112,6 +121,9 @@ DstTable *dst_stl_env(int flags) {
dst_env_def(env, "apply1", dst_wrap_function(dst_quick_asm("apply1", 2, 0, 2, apply_asm, sizeof(apply_asm)))); dst_env_def(env, "apply1", dst_wrap_function(dst_quick_asm("apply1", 2, 0, 2, apply_asm, sizeof(apply_asm))));
dst_env_def(env, "yield", dst_wrap_function(dst_quick_asm("yield", 1, 0, 2, yield_asm, sizeof(yield_asm)))); dst_env_def(env, "yield", dst_wrap_function(dst_quick_asm("yield", 1, 0, 2, yield_asm, sizeof(yield_asm))));
dst_env_def(env, "resume", dst_wrap_function(dst_quick_asm("resume", 2, 0, 2, resume_asm, sizeof(resume_asm)))); dst_env_def(env, "resume", dst_wrap_function(dst_quick_asm("resume", 2, 0, 2, resume_asm, sizeof(resume_asm))));
dst_env_def(env, "get", dst_wrap_function(dst_quick_asm("get", 2, 0, 2, get_asm, sizeof(get_asm))));
dst_env_def(env, "put", dst_wrap_function(dst_quick_asm("put", 3, 0, 3, put_asm, sizeof(put_asm))));
dst_env_def(env, "length", dst_wrap_function(dst_quick_asm("length", 1, 0, 1, length_asm, sizeof(length_asm))));
dst_env_def(env, "VERSION", dst_cstringv(DST_VERSION)); dst_env_def(env, "VERSION", dst_cstringv(DST_VERSION));

View File

@ -180,37 +180,6 @@ int dst_core_gensym(DstArgs args) {
} }
} }
int dst_core_length(DstArgs args) {
DST_FIXARITY(args, 1);
DST_RETURN_INTEGER(args, dst_length(args.v[0]));
}
int dst_core_get(DstArgs args) {
int32_t i;
Dst ds;
DST_MINARITY(args, 1);
ds = args.v[0];
for (i = 1; i < args.n; i++) {
ds = dst_get(ds, args.v[i]);
if (dst_checktype(ds, DST_NIL))
break;
}
DST_RETURN(args, ds);
}
int dst_core_put(DstArgs args) {
Dst ds, key, value;
DstArgs subargs = args;
DST_MINARITY(args, 3);
subargs.n -= 2;
if (dst_core_get(subargs)) return 1;
ds = *args.ret;
key = args.v[args.n - 2];
value = args.v[args.n - 1];
dst_put(ds, key, value);
return 0;
}
int dst_core_gccollect(DstArgs args) { int dst_core_gccollect(DstArgs args) {
(void) args; (void) args;
dst_collect(); dst_collect();
@ -252,13 +221,14 @@ int dst_core_next(DstArgs args) {
kv = dst_checktype(args.v[1], DST_NIL) kv = dst_checktype(args.v[1], DST_NIL)
? NULL ? NULL
: dst_table_find(t, args.v[1]); : dst_table_find(t, args.v[1]);
kv = dst_table_next(t, kv);
} else { } else {
const DstKV *st = dst_unwrap_struct(ds); const DstKV *st = dst_unwrap_struct(ds);
kv = dst_checktype(args.v[1], DST_NIL) kv = dst_checktype(args.v[1], DST_NIL)
? NULL ? NULL
: dst_struct_find(st, args.v[1]); : dst_struct_find(st, args.v[1]);
kv = dst_struct_next(st, kv);
} }
kv = dst_next(ds, kv);
if (kv) { if (kv) {
DST_RETURN(args, kv->key); DST_RETURN(args, kv->key);
} }

View File

@ -138,17 +138,27 @@ void dst_env_cfuns(DstTable *env, const DstReg *cfuns) {
} }
} }
/* Resolve a symbol in the environment. Undefined symbols will /* Resolve a symbol in the environment */
* resolve to nil */ DstBindingType dst_env_resolve(DstTable *env, const uint8_t *sym, Dst *out) {
Dst dst_env_resolve(DstTable *env, const char *name) {
Dst ref; Dst ref;
Dst entry = dst_table_get(env, dst_csymbolv(name)); DstTable *entry_table;
if (dst_checktype(entry, DST_NIL)) return dst_wrap_nil(); Dst entry = dst_table_get(env, dst_wrap_symbol(sym));
ref = dst_get(entry, dst_csymbolv(":ref")); if (!dst_checktype(entry, DST_TABLE))
if (dst_checktype(ref, DST_ARRAY)) { return DST_BINDING_NONE;
return dst_getindex(ref, 0); entry_table = dst_unwrap_table(entry);
if (!dst_checktype(
dst_table_get(entry_table, dst_csymbolv(":macro")),
DST_NIL)) {
*out = dst_table_get(entry_table, dst_csymbolv(":value"));
return DST_BINDING_MACRO;
} }
return dst_get(entry, dst_csymbolv(":value")); ref = dst_table_get(entry_table, dst_csymbolv(":ref"));
if (dst_checktype(ref, DST_ARRAY)) {
*out = ref;
return DST_BINDING_VAR;
}
*out = dst_table_get(entry_table, dst_csymbolv(":value"));
return DST_BINDING_DEF;
} }
/* Get module from the arguments passed to library */ /* Get module from the arguments passed to library */

View File

@ -154,163 +154,3 @@ int dst_compare(Dst x, Dst y) {
} }
return (dst_type(x) < dst_type(y)) ? -1 : 1; return (dst_type(x) < dst_type(y)) ? -1 : 1;
} }
/* Get a value out af an associated data structure. For invalid
* data structure or invalid key, returns nil. */
Dst dst_get(Dst ds, Dst key) {
switch (dst_type(ds)) {
case DST_ARRAY:
if (dst_checktype(key, DST_INTEGER) &&
dst_unwrap_integer(key) >= 0 &&
dst_unwrap_integer(key) < dst_unwrap_array(ds)->count)
return dst_unwrap_array(ds)->data[dst_unwrap_integer(key)];
break;
case DST_TUPLE:
if (dst_checktype(key, DST_INTEGER) &&
dst_unwrap_integer(key) >= 0 &&
dst_unwrap_integer(key) < dst_tuple_length(dst_unwrap_tuple(ds)))
return dst_unwrap_tuple(ds)[dst_unwrap_integer(key)];
break;
case DST_BUFFER:
if (dst_checktype(key, DST_INTEGER) &&
dst_unwrap_integer(key) >= 0 &&
dst_unwrap_integer(key) < dst_unwrap_buffer(ds)->count)
return dst_wrap_integer(dst_unwrap_buffer(ds)->data[dst_unwrap_integer(key)]);
break;
case DST_STRING:
case DST_SYMBOL:
if (dst_checktype(key, DST_INTEGER) &&
dst_unwrap_integer(key) >= 0 &&
dst_unwrap_integer(key) < dst_string_length(dst_unwrap_string(ds)))
return dst_wrap_integer(dst_unwrap_string(ds)[dst_unwrap_integer(key)]);
break;
case DST_STRUCT:
return dst_struct_get(dst_unwrap_struct(ds), key);
case DST_TABLE:
return dst_table_get(dst_unwrap_table(ds), key);
default:
break;
}
return dst_wrap_nil();
}
/* Set a value in an associative data structure. Returns possible
* error message, and NULL if no error. */
void dst_put(Dst ds, Dst key, Dst value) {
switch (dst_type(ds)) {
case DST_ARRAY:
{
int32_t index;
DstArray *array = dst_unwrap_array(ds);
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
return;
index = dst_unwrap_integer(key);
if (index == INT32_MAX) return;
if (index >= array->count) {
dst_array_setcount(array, index + 1);
}
array->data[index]= value;
return;
}
case DST_BUFFER:
{
int32_t index;
DstBuffer *buffer = dst_unwrap_buffer(ds);
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
return;
index = dst_unwrap_integer(key);
if (index == INT32_MAX) return;
if (!dst_checktype(value, DST_INTEGER))
return;
if (index >= buffer->count) {
dst_buffer_setcount(buffer, index + 1);
}
buffer->data[index] = (uint8_t) (dst_unwrap_integer(value) & 0xFF);
return;
}
case DST_TABLE:
dst_table_put(dst_unwrap_table(ds), key, value);
return;
default:
return;
}
}
/* Get the next key in an associative data structure. Used for iterating through an
* associative data structure. */
const DstKV *dst_next(Dst ds, const DstKV *kv) {
switch(dst_type(ds)) {
default:
return NULL;
case DST_TABLE:
return (const DstKV *) dst_table_next(dst_unwrap_table(ds), kv);
case DST_STRUCT:
return dst_struct_next(dst_unwrap_struct(ds), kv);
}
}
/* Get the length of an object. Returns errors for invalid types */
int32_t dst_length(Dst x) {
switch (dst_type(x)) {
default:
return 0;
case DST_STRING:
case DST_SYMBOL:
return dst_string_length(dst_unwrap_string(x));
case DST_ARRAY:
return dst_unwrap_array(x)->count;
case DST_BUFFER:
return dst_unwrap_buffer(x)->count;
case DST_TUPLE:
return dst_tuple_length(dst_unwrap_tuple(x));
case DST_STRUCT:
return dst_struct_length(dst_unwrap_struct(x));
case DST_TABLE:
return dst_unwrap_table(x)->count;
}
}
/* Index into a data structure. Returns nil for out of bounds or invlalid data structure */
Dst dst_getindex(Dst ds, int32_t index) {
switch (dst_type(ds)) {
default:
return dst_wrap_nil();
case DST_STRING:
case DST_SYMBOL:
if (index >= dst_string_length(dst_unwrap_string(ds))) return dst_wrap_nil();
return dst_wrap_integer(dst_unwrap_string(ds)[index]);
case DST_ARRAY:
if (index >= dst_unwrap_array(ds)->count) return dst_wrap_nil();
return dst_unwrap_array(ds)->data[index];
case DST_BUFFER:
if (index >= dst_unwrap_buffer(ds)->count) return dst_wrap_nil();
return dst_wrap_integer(dst_unwrap_buffer(ds)->data[index]);
case DST_TUPLE:
if (index >= dst_tuple_length(dst_unwrap_tuple(ds))) return dst_wrap_nil();
return dst_unwrap_tuple(ds)[index];
}
}
/* Set an index in a linear data structure. Does nothing if data structure
* is invalid */
void dst_setindex(Dst ds, Dst value, int32_t index) {
switch (dst_type(ds)) {
default:
return;
case DST_ARRAY:
if (index >= dst_unwrap_array(ds)->count) {
dst_array_ensure(dst_unwrap_array(ds), 2 * index);
dst_unwrap_array(ds)->count = index + 1;
}
dst_unwrap_array(ds)->data[index] = value;
return;
case DST_BUFFER:
if (!dst_checktype(value, DST_INTEGER)) return;
if (index >= dst_unwrap_buffer(ds)->count) {
dst_buffer_ensure(dst_unwrap_buffer(ds), 2 * index);
dst_unwrap_buffer(ds)->count = index + 1;
}
dst_unwrap_buffer(ds)->data[index] = dst_unwrap_integer(value);
return;
}
}

View File

@ -769,37 +769,241 @@ static void *op_lookup[255] = {
} }
VM_OP(DOP_PUT) VM_OP(DOP_PUT)
dst_put(stack[oparg(1, 0xFF)], {
stack[oparg(2, 0xFF)], Dst ds = stack[oparg(1, 0xFF)];
stack[oparg(3, 0xFF)]); Dst key = stack[oparg(2, 0xFF)];
++pc; Dst value = stack[oparg(3, 0xFF)];
vm_checkgc_next(); switch (dst_type(ds)) {
default:
vm_throw("expected mutable data structure");
case DST_ARRAY:
{
int32_t index;
DstArray *array = dst_unwrap_array(ds);
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
vm_throw("expected non-negative integer key");
index = dst_unwrap_integer(key);
if (index == INT32_MAX)
vm_throw("key too large");
if (index >= array->count) {
dst_array_setcount(array, index + 1);
}
array->data[index] = value;
break;
}
case DST_BUFFER:
{
int32_t index;
DstBuffer *buffer = dst_unwrap_buffer(ds);
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
vm_throw("expected non-negative integer key");
index = dst_unwrap_integer(key);
if (index == INT32_MAX)
vm_throw("key too large");
if (!dst_checktype(value, DST_INTEGER))
vm_throw("expected integer value");
if (index >= buffer->count) {
dst_buffer_setcount(buffer, index + 1);
}
buffer->data[index] = (uint8_t) (dst_unwrap_integer(value) & 0xFF);
break;
}
case DST_TABLE:
dst_table_put(dst_unwrap_table(ds), key, value);
break;
}
++pc;
vm_checkgc_next();
}
VM_OP(DOP_PUT_INDEX) VM_OP(DOP_PUT_INDEX)
dst_setindex(stack[oparg(1, 0xFF)], {
stack[oparg(2, 0xFF)], Dst ds = stack[oparg(1, 0xFF)];
oparg(3, 0xFF)); Dst value = stack[oparg(2, 0xFF)];
++pc; int32_t index = oparg(3, 0xFF);
vm_checkgc_next(); switch (dst_type(ds)) {
default:
vm_throw("expected mutable indexed data structure");
case DST_ARRAY:
if (index >= dst_unwrap_array(ds)->count) {
dst_array_ensure(dst_unwrap_array(ds), 2 * index);
dst_unwrap_array(ds)->count = index + 1;
}
dst_unwrap_array(ds)->data[index] = value;
break;
case DST_BUFFER:
if (!dst_checktype(value, DST_INTEGER))\
vm_throw("expected integer to set in buffer");
if (index >= dst_unwrap_buffer(ds)->count) {
dst_buffer_ensure(dst_unwrap_buffer(ds), 2 * index);
dst_unwrap_buffer(ds)->count = index + 1;
}
dst_unwrap_buffer(ds)->data[index] = dst_unwrap_integer(value);
break;
}
++pc;
vm_checkgc_next();
}
VM_OP(DOP_GET) VM_OP(DOP_GET)
stack[oparg(1, 0xFF)] = dst_get( {
stack[oparg(2, 0xFF)], Dst ds = stack[oparg(2, 0xFF)];
stack[oparg(3, 0xFF)]); Dst key = stack[oparg(3, 0xFF)];
++pc; Dst value;
vm_next(); switch (dst_type(ds)) {
default:
vm_throw("expected data structure");
case DST_STRUCT:
value = dst_struct_get(dst_unwrap_struct(ds), key);
break;
case DST_TABLE:
value = dst_table_get(dst_unwrap_table(ds), key);
break;
case DST_ARRAY:
{
DstArray *array = dst_unwrap_array(ds);
int32_t index;
if (!dst_checktype(key, DST_INTEGER))
vm_throw("expected integer key");
index = dst_unwrap_integer(key);
if (index < 0 || index >= array->count) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = array->data[index];
}
break;
}
case DST_TUPLE:
{
const Dst *tuple = dst_unwrap_tuple(ds);
int32_t index;
if (!dst_checktype(key, DST_INTEGER))
vm_throw("expected integer key");
index = dst_unwrap_integer(key);
if (index < 0 || index >= dst_tuple_length(tuple)) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = tuple[index];
}
break;
}
case DST_BUFFER:
{
DstBuffer *buffer = dst_unwrap_buffer(ds);
int32_t index;
if (!dst_checktype(key, DST_INTEGER))
vm_throw("expected integer key");
index = dst_unwrap_integer(key);
if (index < 0 || index >= buffer->count) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_wrap_integer(buffer->data[index]);
}
break;
}
case DST_STRING:
case DST_SYMBOL:
{
const uint8_t *str = dst_unwrap_string(ds);
int32_t index;
if (!dst_checktype(key, DST_INTEGER))
vm_throw("expected integer key");
index = dst_unwrap_integer(key);
if (index < 0 || index >= dst_string_length(str)) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_wrap_integer(str[index]);
}
break;
}
}
stack[oparg(1, 0xFF)] = value;
++pc;
vm_next();
}
VM_OP(DOP_GET_INDEX) VM_OP(DOP_GET_INDEX)
stack[oparg(1, 0xFF)] = dst_getindex( {
stack[oparg(2, 0xFF)], Dst ds = stack[oparg(2, 0xFF)];
oparg(3, 0xFF)); int32_t index = oparg(3, 0xFF);
++pc; Dst value;
vm_next(); switch (dst_type(ds)) {
default:
vm_throw("expected indexed data structure");
case DST_STRING:
case DST_SYMBOL:
if (index >= dst_string_length(dst_unwrap_string(ds))) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_wrap_integer(dst_unwrap_string(ds)[index]);
}
break;
case DST_ARRAY:
if (index >= dst_unwrap_array(ds)->count) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_unwrap_array(ds)->data[index];
}
break;
case DST_BUFFER:
if (index >= dst_unwrap_buffer(ds)->count) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_wrap_integer(dst_unwrap_buffer(ds)->data[index]);
}
break;
case DST_TUPLE:
if (index >= dst_tuple_length(dst_unwrap_tuple(ds))) {
/*vm_throw("index out of bounds");*/
value = dst_wrap_nil();
} else {
value = dst_unwrap_tuple(ds)[index];
}
break;
}
stack[oparg(1, 0xFF)] = value;
++pc;
vm_next();
}
VM_OP(DOP_LENGTH) VM_OP(DOP_LENGTH)
stack[oparg(1, 0xFF)] = dst_wrap_integer(dst_length(stack[oparg(2, 0xFFFF)])); {
++pc; Dst x = stack[oparg(2, 0xFFFF)];
vm_next(); int32_t len;
switch (dst_type(x)) {
default:
vm_throw("expected data structure");
case DST_STRING:
case DST_SYMBOL:
len = dst_string_length(dst_unwrap_string(x));
break;
case DST_ARRAY:
len = dst_unwrap_array(x)->count;
break;
case DST_BUFFER:
len = dst_unwrap_buffer(x)->count;
break;
case DST_TUPLE:
len = dst_tuple_length(dst_unwrap_tuple(x));
break;
case DST_STRUCT:
len = dst_struct_length(dst_unwrap_struct(x));
break;
case DST_TABLE:
len = dst_unwrap_table(x)->count;
break;
}
stack[oparg(1, 0xFF)] = dst_wrap_integer(len);
++pc;
vm_next();
}
/* Return from c function. Simpler than returning from dst function */ /* Return from c function. Simpler than returning from dst function */
vm_return_cfunc: vm_return_cfunc:
@ -808,7 +1012,7 @@ static void *op_lookup[255] = {
if (fiber->frame == 0) goto vm_exit; if (fiber->frame == 0) goto vm_exit;
stack = fiber->data + fiber->frame; stack = fiber->data + fiber->frame;
stack[oparg(1, 0xFF)] = retreg; stack[oparg(1, 0xFF)] = retreg;
pc++; ++pc;
vm_checkgc_next(); vm_checkgc_next();
} }

View File

@ -173,12 +173,6 @@ int dst_verify(DstFuncDef *def);
int dst_equals(Dst x, Dst y); int dst_equals(Dst x, Dst y);
int32_t dst_hash(Dst x); int32_t dst_hash(Dst x);
int dst_compare(Dst x, Dst y); 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);
Dst dst_getindex(Dst ds, int32_t index);
void dst_setindex(Dst ds, Dst value, int32_t index);
int dst_cstrcmp(const uint8_t *str, const char *other); int dst_cstrcmp(const uint8_t *str, const char *other);
/* VM functions */ /* VM functions */
@ -189,10 +183,16 @@ DstSignal dst_continue(DstFiber *fiber, Dst in, Dst *out);
DstSignal dst_call(DstFunction *fun, int32_t argn, const Dst *argv, Dst *out); DstSignal dst_call(DstFunction *fun, int32_t argn, const Dst *argv, Dst *out);
/* Env helpers */ /* Env helpers */
typedef enum {
DST_BINDING_NONE,
DST_BINDING_DEF,
DST_BINDING_VAR,
DST_BINDING_MACRO
} DstBindingType;
void dst_env_def(DstTable *env, const char *name, Dst val); void dst_env_def(DstTable *env, const char *name, Dst val);
void dst_env_var(DstTable *env, const char *name, Dst val); void dst_env_var(DstTable *env, const char *name, Dst val);
void dst_env_cfuns(DstTable *env, const DstReg *cfuns); void dst_env_cfuns(DstTable *env, const DstReg *cfuns);
Dst dst_env_resolve(DstTable *env, const char *name); DstBindingType dst_env_resolve(DstTable *env, const uint8_t *sym, Dst *out);
DstTable *dst_env_arg(DstArgs args); DstTable *dst_env_arg(DstArgs args);
/* STL */ /* STL */

View File

@ -80,9 +80,6 @@ int dst_core_table(DstArgs args);
int dst_core_struct(DstArgs args); int dst_core_struct(DstArgs args);
int dst_core_buffer(DstArgs args); int dst_core_buffer(DstArgs args);
int dst_core_gensym(DstArgs args); int dst_core_gensym(DstArgs args);
int dst_core_length(DstArgs args);
int dst_core_get(DstArgs args);
int dst_core_put(DstArgs args);
int dst_core_type(DstArgs args); int dst_core_type(DstArgs args);
int dst_core_next(DstArgs args); int dst_core_next(DstArgs args);
int dst_core_hash(DstArgs args); int dst_core_hash(DstArgs args);