1
0
mirror of https://github.com/janet-lang/janet synced 2025-12-03 15:18:10 +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

@@ -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) {
(void) args;
dst_collect();
@@ -252,13 +221,14 @@ int dst_core_next(DstArgs args) {
kv = dst_checktype(args.v[1], DST_NIL)
? NULL
: dst_table_find(t, args.v[1]);
kv = dst_table_next(t, kv);
} else {
const DstKV *st = dst_unwrap_struct(ds);
kv = dst_checktype(args.v[1], DST_NIL)
? NULL
: dst_struct_find(st, args.v[1]);
kv = dst_struct_next(st, kv);
}
kv = dst_next(ds, kv);
if (kv) {
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 to nil */
Dst dst_env_resolve(DstTable *env, const char *name) {
/* Resolve a symbol in the environment */
DstBindingType dst_env_resolve(DstTable *env, const uint8_t *sym, Dst *out) {
Dst ref;
Dst entry = dst_table_get(env, dst_csymbolv(name));
if (dst_checktype(entry, DST_NIL)) return dst_wrap_nil();
ref = dst_get(entry, dst_csymbolv(":ref"));
if (dst_checktype(ref, DST_ARRAY)) {
return dst_getindex(ref, 0);
DstTable *entry_table;
Dst entry = dst_table_get(env, dst_wrap_symbol(sym));
if (!dst_checktype(entry, DST_TABLE))
return DST_BINDING_NONE;
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 */

View File

@@ -154,163 +154,3 @@ int dst_compare(Dst x, Dst y) {
}
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)
dst_put(stack[oparg(1, 0xFF)],
stack[oparg(2, 0xFF)],
stack[oparg(3, 0xFF)]);
++pc;
vm_checkgc_next();
{
Dst ds = stack[oparg(1, 0xFF)];
Dst key = stack[oparg(2, 0xFF)];
Dst value = stack[oparg(3, 0xFF)];
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)
dst_setindex(stack[oparg(1, 0xFF)],
stack[oparg(2, 0xFF)],
oparg(3, 0xFF));
++pc;
vm_checkgc_next();
{
Dst ds = stack[oparg(1, 0xFF)];
Dst value = stack[oparg(2, 0xFF)];
int32_t index = oparg(3, 0xFF);
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)
stack[oparg(1, 0xFF)] = dst_get(
stack[oparg(2, 0xFF)],
stack[oparg(3, 0xFF)]);
++pc;
vm_next();
{
Dst ds = stack[oparg(2, 0xFF)];
Dst key = stack[oparg(3, 0xFF)];
Dst value;
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)
stack[oparg(1, 0xFF)] = dst_getindex(
stack[oparg(2, 0xFF)],
oparg(3, 0xFF));
++pc;
vm_next();
{
Dst ds = stack[oparg(2, 0xFF)];
int32_t index = oparg(3, 0xFF);
Dst value;
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)
stack[oparg(1, 0xFF)] = dst_wrap_integer(dst_length(stack[oparg(2, 0xFFFF)]));
++pc;
vm_next();
{
Dst x = stack[oparg(2, 0xFFFF)];
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 */
vm_return_cfunc:
@@ -808,7 +1012,7 @@ static void *op_lookup[255] = {
if (fiber->frame == 0) goto vm_exit;
stack = fiber->data + fiber->frame;
stack[oparg(1, 0xFF)] = retreg;
pc++;
++pc;
vm_checkgc_next();
}