1
0
mirror of https://github.com/janet-lang/janet synced 2025-12-03 07:08:09 +00:00

Add errorhandling helper functions and macros for writing c functions.

This commit is contained in:
Calvin Rose
2018-04-28 18:10:57 -04:00
parent 344fa031b2
commit 10934bcfb9
6 changed files with 154 additions and 39 deletions

View File

@@ -106,19 +106,22 @@ Dst dst_array_peek(DstArray *array) {
/* C Functions */
static int cfun_pop(DstArgs args) {
if (args.n != 1 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
dst_fixarity(args, 1);
dst_check(args, 0, DST_ARRAY);
return dst_return(args, dst_array_pop(dst_unwrap_array(args.v[0])));
}
static int cfun_peek(DstArgs args) {
if (args.n != 1 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
dst_fixarity(args, 1);
dst_check(args, 0, DST_ARRAY);
return dst_return(args, dst_array_peek(dst_unwrap_array(args.v[0])));
}
static int cfun_push(DstArgs args) {
DstArray *array;
int32_t newcount;
if (args.n < 1 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
dst_minarity(args, 1);
dst_check(args, 0, DST_ARRAY);
array = dst_unwrap_array(args.v[0]);
newcount = array->count - 1 + args.n;
dst_array_ensure(array, newcount);
@@ -129,8 +132,9 @@ static int cfun_push(DstArgs args) {
static int cfun_setcount(DstArgs args) {
int32_t newcount;
if (args.n != 2 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
if (!dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected positive integer");
dst_fixarity(args, 2);
dst_check(args, 0, DST_ARRAY);
dst_check(args, 1, DST_INTEGER);
newcount = dst_unwrap_integer(args.v[1]);
if (newcount < 0) return dst_throw(args, "expected positive integer");
dst_array_setcount(dst_unwrap_array(args.v[0]), newcount);
@@ -139,8 +143,9 @@ static int cfun_setcount(DstArgs args) {
static int cfun_ensure(DstArgs args) {
int32_t newcount;
if (args.n != 2 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
if (!dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected positive integer");
dst_fixarity(args, 2);
dst_check(args, 0, DST_ARRAY);
dst_check(args, 1, DST_INTEGER);
newcount = dst_unwrap_integer(args.v[1]);
if (newcount < 0) return dst_throw(args, "expected positive integer");
dst_array_ensure(dst_unwrap_array(args.v[0]), newcount);
@@ -152,7 +157,10 @@ static int cfun_slice(DstArgs args) {
int32_t len;
DstArray *ret;
int32_t start, end;
if (args.n < 1 || !dst_seq_view(args.v[0], &vals, &len)) return dst_throw(args, "expected array/tuple");
dst_minarity(args, 1);
dst_maxarity(args, 3);
if (!dst_seq_view(args.v[0], &vals, &len))
return dst_throw(args, "expected array|tuple");
/* Get start */
if (args.n < 2) {
start = 0;
@@ -187,7 +195,8 @@ static int cfun_slice(DstArgs args) {
static int cfun_concat(DstArgs args) {
int32_t i;
DstArray *array;
if (args.n < 1 || !dst_checktype(args.v[0], DST_ARRAY)) return dst_throw(args, "expected array");
dst_minarity(args, 1);
dst_check(args, 0, DST_ARRAY);
array = dst_unwrap_array(args.v[0]);
for (i = 1; i < args.n; i++) {
switch (dst_type(args.v[i])) {

View File

@@ -97,6 +97,10 @@ int dst_buffer_push_bytes(DstBuffer *buffer, const uint8_t *string, int32_t leng
return 0;
}
int dst_buffer_push_string(DstBuffer *buffer, const uint8_t *string) {
return dst_buffer_push_bytes(buffer, string, dst_string_length(string));
}
/* Push a single byte to the buffer */
int dst_buffer_push_u8(DstBuffer *buffer, uint8_t byte) {
if (dst_buffer_extra(buffer, 1)) return -1;

View File

@@ -127,7 +127,7 @@ int dst_core_struct(DstArgs args) {
}
int dst_core_gensym(DstArgs args) {
if (args.n > 1) return dst_throw(args, "expected one argument");
dst_maxarity(args, 1);
if (args.n == 0) {
return dst_return(args, dst_wrap_symbol(dst_symbol_gen(NULL, 0)));
} else {
@@ -137,14 +137,14 @@ int dst_core_gensym(DstArgs args) {
}
int dst_core_length(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected at least 1 argument");
dst_checkmany(args, 0, DST_TFLAG_LENGTHABLE);
return dst_return(args, dst_wrap_integer(dst_length(args.v[0])));
}
int dst_core_get(DstArgs args) {
int32_t i;
Dst ds;
if (args.n < 1) return dst_throw(args, "expected at least 1 argument");
dst_minarity(args, 1);
ds = args.v[0];
for (i = 1; i < args.n; i++) {
ds = dst_get(ds, args.v[i]);
@@ -155,15 +155,15 @@ int dst_core_get(DstArgs args) {
}
int dst_core_rawget(DstArgs args) {
if (args.n != 2) return dst_throw(args, "expected 2 arguments");
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
dst_fixarity(args, 2);
dst_check(args, 0, DST_TABLE);
return dst_return(args, dst_table_rawget(dst_unwrap_table(args.v[0]), args.v[1]));
}
int dst_core_getproto(DstArgs args) {
DstTable *t;
if (args.n != 1) return dst_throw(args, "expected 1 argument");
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
dst_fixarity(args, 1);
dst_check(args, 0, DST_TABLE);
t = dst_unwrap_table(args.v[0]);
return dst_return(args, t->proto
? dst_wrap_table(t->proto)
@@ -171,10 +171,9 @@ int dst_core_getproto(DstArgs args) {
}
int dst_core_setproto(DstArgs args) {
if (args.n != 2) return dst_throw(args, "expected 2 arguments");
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
if (!dst_checktype(args.v[1], DST_TABLE) && !dst_checktype(args.v[1], DST_NIL))
return dst_throw(args, "expected table");
dst_fixarity(args, 2);
dst_check(args, 0, DST_TABLE);
dst_checkmany(args, 1, DST_TFLAG_TABLE | DST_TFLAG_NIL);
dst_unwrap_table(args.v[0])->proto = dst_checktype(args.v[1], DST_TABLE)
? dst_unwrap_table(args.v[1])
: NULL;
@@ -184,7 +183,7 @@ int dst_core_setproto(DstArgs args) {
int dst_core_put(DstArgs args) {
Dst ds, key, value;
DstArgs subargs = args;
if (args.n < 3) return dst_throw(args, "expected at least 3 arguments");
dst_minarity(args, 3);
subargs.n -= 2;
if (dst_core_get(subargs)) return 1;
ds = *args.ret;
@@ -201,20 +200,23 @@ int dst_core_gccollect(DstArgs args) {
}
int dst_core_gcsetinterval(DstArgs args) {
if (args.n < 1 ||
!dst_checktype(args.v[0], DST_INTEGER) ||
dst_unwrap_integer(args.v[0]) < 0)
int32_t val;
dst_fixarity(args, 1);
dst_check(args, 0, DST_INTEGER);
val = dst_unwrap_integer(args.v[0]);
if (val < 0)
return dst_throw(args, "expected non-negative integer");
dst_vm_gc_interval = dst_unwrap_integer(args.v[0]);
return dst_return(args, dst_wrap_integer(dst_vm_gc_interval));
dst_vm_gc_interval = val;
return dst_return(args, args.v[0]);
}
int dst_core_gcinterval(DstArgs args) {
dst_fixarity(args, 0);
return dst_return(args, dst_wrap_integer(dst_vm_gc_interval));
}
int dst_core_type(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected 1 argument");
dst_fixarity(args, 1);
if (dst_checktype(args.v[0], DST_ABSTRACT)) {
return dst_return(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name));
} else {
@@ -225,20 +227,19 @@ int dst_core_type(DstArgs args) {
int dst_core_next(DstArgs args) {
Dst ds;
const DstKV *kv;
if (args.n != 2) return dst_throw(args, "expected 2 arguments");
dst_fixarity(args, 2);
dst_checkmany(args, 0, DST_TFLAG_DICTIONARY);
ds = args.v[0];
if (dst_checktype(ds, DST_TABLE)) {
DstTable *t = dst_unwrap_table(ds);
kv = dst_checktype(args.v[1], DST_NIL)
? NULL
: dst_table_find(t, args.v[1]);
} else if (dst_checktype(ds, DST_STRUCT)) {
} else {
const DstKV *st = dst_unwrap_struct(ds);
kv = dst_checktype(args.v[1], DST_NIL)
? NULL
: dst_struct_find(st, args.v[1]);
} else {
return dst_throw(args, "expected table/struct");
}
kv = dst_next(ds, kv);
if (kv) {
@@ -248,7 +249,7 @@ int dst_core_next(DstArgs args) {
}
int dst_core_hash(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected 1 argument");
dst_fixarity(args, 1);
return dst_return(args, dst_wrap_integer(dst_hash(args.v[0])));
}
@@ -256,8 +257,10 @@ int dst_core_string_slice(DstArgs args) {
const uint8_t *data;
int32_t len, start, end;
const uint8_t *ret;
if (args.n < 1 || !dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected buffer/string");
dst_minarity(args, 1);
dst_maxarity(args, 3);
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected buffer|string|symbol");
/* Get start */
if (args.n < 2) {
start = 0;

View File

@@ -205,3 +205,48 @@ int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap)
}
return 0;
}
int dst_type_err(DstArgs args, int32_t n, DstType expected) {
DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL;
const uint8_t *message = dst_formatc(
"bad argument #%d, expected %t, got %t",
n,
expected,
actual);
return dst_throwv(args, dst_wrap_string(message));
}
int dst_typemany_err(DstArgs args, int32_t n, int expected) {
int i;
int first = 1;
const uint8_t *message;
DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL;
DstBuffer buf;
dst_buffer_init(&buf, 20);
dst_buffer_push_string(&buf, dst_formatc("bad argument #%d, expected ", n));
i = 0;
while (expected) {
if (1 & expected) {
if (first) {
first = 0;
} else {
dst_buffer_push_u8(&buf, '|');
}
dst_buffer_push_cstring(&buf, dst_type_names[i] + 1);
}
i++;
expected >>= 1;
}
dst_buffer_push_cstring(&buf, ", got ");
dst_buffer_push_cstring(&buf, dst_type_names[actual] + 1);
message = dst_string(buf.data, buf.count);
dst_buffer_deinit(&buf);
return dst_throwv(args, dst_wrap_string(message));
}
int dst_arity_err(DstArgs args, int32_t n, const char *prefix) {
return dst_throwv(args,
dst_wrap_string(dst_formatc(
"expected %s%d argument%s, got %d",
prefix, n, n == 1 ? "" : "s", args.n)));
}