1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-25 22:53:16 +00:00

Change c function macros to be explicitly non functional by

capitalizing them.
This commit is contained in:
Calvin Rose 2018-05-12 20:31:28 -04:00
parent 70e52d91c4
commit dafc121f4d
22 changed files with 549 additions and 513 deletions

View File

@ -45,29 +45,29 @@ static int sql_open(DstArgs args) {
sqlite3 **conn; sqlite3 **conn;
const uint8_t *filename; const uint8_t *filename;
int status; int status;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_string(filename, args, 0); DST_ARG_STRING(filename, args, 0);
conn = (sqlite3 **) dst_abstract(&sql_conn_type, sizeof(sqlite3 *)); conn = (sqlite3 **) dst_abstract(&sql_conn_type, sizeof(sqlite3 *));
status = sqlite3_open((const char *)filename, conn); status = sqlite3_open((const char *)filename, conn);
if (status == SQLITE_OK) { if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_abstract(conn)); DST_RETURN_ABSTRACT(args, conn);
} else { } else {
const char *err = sqlite3_errmsg(*conn); const char *err = sqlite3_errmsg(*conn);
return dst_throw(args, err); DST_THROW(args, err);
} }
} }
static int sql_close(DstArgs args) { static int sql_close(DstArgs args) {
sqlite3 **conn; sqlite3 **conn;
int status; int status;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_checkabstract(args, 0, &sql_conn_type); DST_CHECKABSTRACT(args, 0, &sql_conn_type);
conn = (sqlite3 **)dst_unwrap_abstract(args.v[0]); conn = (sqlite3 **)dst_unwrap_abstract(args.v[0]);
status = sqlite3_close_v2(*conn); status = sqlite3_close_v2(*conn);
if (status == SQLITE_OK) { if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_nil()); DST_RETURN_NIL(args);
} else { } else {
return dst_throw(args, "unable to close the sqlite3 connection"); DST_THROW(args, "unable to close the sqlite3 connection");
} }
} }
@ -100,9 +100,9 @@ static int sql_sql(DstArgs args) {
rows, rows,
&errmsg); &errmsg);
if (status == SQLITE_OK) { if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_array(rows)); DST_RETURN_ARRAY(args, rows);
} else { } else {
return dst_throw(args, errmsg); DST_THROW(args, errmsg);
} }
} }

View File

@ -148,26 +148,35 @@ static const DstInstructionDef dst_ops[] = {
{"yield", DOP_YIELD} {"yield", DOP_YIELD}
}; };
/* Check a dst string against a bunch of test_strings. Return the /* Typename aliases for tchck instruction */
* index of the matching test_string, or -1 if not found. */ typedef struct TypeAlias {
static int32_t strsearch(const uint8_t *str, const char *const *test_strings) { const char *name;
int32_t len = dst_string_length(str); int32_t mask;
int index; } TypeAlias;
for (index = 0; ; index++) {
int32_t i; static const TypeAlias type_aliases[] = {
const char *testword = test_strings[index]; {":abstract", DST_TFLAG_ABSTRACT},
if (NULL == testword) {":array", DST_TFLAG_ARRAY},
break; {":boolean", DST_TFLAG_BOOLEAN},
for (i = 0; i < len; i++) { {":buffer", DST_TFLAG_BUFFER},
if (testword[i] != str[i]) {":callable", DST_TFLAG_CALLABLE},
goto nextword; {":cfunction", DST_TFLAG_CFUNCTION},
} {":dictionary", DST_TFLAG_DICTIONARY},
return index; {":false", DST_TFLAG_FALSE},
nextword: {":fiber", DST_TFLAG_FIBER},
continue; {":function", DST_TFLAG_FUNCTION},
} {":indexed", DST_TFLAG_INDEXED},
return -1; {":integer", DST_TFLAG_INTEGER},
} {":nil", DST_TFLAG_NIL},
{":number", DST_TFLAG_NUMBER},
{":real", DST_TFLAG_REAL},
{":string", DST_TFLAG_STRING},
{":struct", DST_TFLAG_STRUCT},
{":symbol", DST_TFLAG_SYMBOL},
{":table", DST_TFLAG_BOOLEAN},
{":true", DST_TFLAG_TRUE},
{":tuple", DST_TFLAG_BOOLEAN}
};
/* Deinitialize an Assembler. Does not deinitialize the parents. */ /* Deinitialize an Assembler. Does not deinitialize the parents. */
static void dst_asm_deinit(DstAssembler *a) { static void dst_asm_deinit(DstAssembler *a) {
@ -295,9 +304,13 @@ static int32_t doarg_1(
dst_asm_errorv(a, dst_formatc("unknown name %q", x)); dst_asm_errorv(a, dst_formatc("unknown name %q", x));
} }
} else if (argtype == DST_OAT_TYPE || argtype == DST_OAT_SIMPLETYPE) { } else if (argtype == DST_OAT_TYPE || argtype == DST_OAT_SIMPLETYPE) {
int32_t index = strsearch(dst_unwrap_symbol(x), dst_type_names); const TypeAlias *alias = dst_strbinsearch(
if (index != -1) { &type_aliases,
ret = index; sizeof(type_aliases)/sizeof(TypeAlias),
sizeof(TypeAlias),
dst_unwrap_symbol(x));
if (alias) {
ret = alias->mask;
} else { } else {
dst_asm_errorv(a, dst_formatc("unknown type %q", x)); dst_asm_errorv(a, dst_formatc("unknown type %q", x));
} }
@ -890,21 +903,20 @@ Dst dst_disasm(DstFuncDef *def) {
/* C Function for assembly */ /* C Function for assembly */
int dst_asm_cfun(DstArgs args) { int dst_asm_cfun(DstArgs args) {
DstAssembleResult res; DstAssembleResult res;
if (args.n < 1) return dst_throw(args, "expected assembly source"); DST_FIXARITY(args, 1);
res = dst_asm(args.v[0], 0); res = dst_asm(args.v[0], 0);
if (res.status == DST_ASSEMBLE_OK) { if (res.status == DST_ASSEMBLE_OK) {
return dst_return(args, dst_wrap_function(dst_thunk(res.funcdef))); DST_RETURN_FUNCTION(args, dst_thunk(res.funcdef));
} else { } else {
return dst_throwv(args, dst_wrap_string(res.error)); DST_THROWV(args, dst_wrap_string(res.error));
} }
} }
int dst_disasm_cfun(DstArgs args) { int dst_disasm_cfun(DstArgs args) {
DstFunction *f; DstFunction *f;
if (args.n < 1 || !dst_checktype(args.v[0], DST_FUNCTION)) DST_FIXARITY(args, 1);
return dst_throw(args, "expected function"); DST_ARG_FUNCTION(f, args, 0);
f = dst_unwrap_function(args.v[0]); DST_RETURN(args, dst_disasm(f->def));
return dst_return(args, dst_disasm(f->def));
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -74,19 +74,34 @@
(defn pos? [x] (> x 0)) (defn pos? [x] (> x 0))
(defn neg? [x] (< x 0)) (defn neg? [x] (< x 0))
(defn one? [x] (== x 1)) (defn one? [x] (== x 1))
(defn integer? [x] (= (type x) :integer))
(defn real? [x] (= (type x) :real))
(defn number? [x]
(def t (type x))
(if (= t :integer) true (= t :real)))
(defn fiber? [x] (= (type x) :fiber))
(defn function? [x] (= (type x) :function))
(defn cfunction? [x] (= (type x) :cfunction))
(defn abstract? [x] (= (type x) :abstract))
(defn table? [x] (= (type x) :table )) (defn table? [x] (= (type x) :table ))
(defn struct? [x] (= (type x) :struct)) (defn struct? [x] (= (type x) :struct))
(defn array? [x] (= (type x) :array)) (defn array? [x] (= (type x) :array))
(defn tuple? [x] (= (type x) :tuple)) (defn tuple? [x] (= (type x) :tuple))
(defn boolean? [x] (= (type x) :boolean)) (defn boolean? [x] (= (type x) :boolean))
(defn bytes? [x]
(def t (type x))
(if (= t :string) true (if (= t :symbol) true (= t :buffer))))
(defn dictionary? [x]
(def t (type x))
(if (= t :table) true (= t :struct)))
(defn indexed? [x] (defn indexed? [x]
(def t (type x)) (def t (type x))
(if (= t :array) true (= t :tuple))) (if (= t :array) true (= t :tuple)))
(defn function? [x] (defn callable? [x]
(def t (type x)) (def t (type x))
(if (= t :function) true (= t :cfunction))) (if (= t :function) true (= t :cfunction)))
(defn true? [x] (= (type x) true)) (defn true? [x] (= x true))
(defn false? [x] (= (type x) false)) (defn false? [x] (= x false))
(defn nil? [x] (= x nil)) (defn nil? [x] (= x nil))
(def atomic? (do (def atomic? (do
(def non-atomic-types { (def non-atomic-types {
@ -923,7 +938,10 @@ onvalue."
(defn default-error-handler (defn default-error-handler
[t x f] [t x f]
(file.write stdout (string t " error: ")) (file.write stdout (string t " error: "))
(pp x) (if (bytes? x)
(do (file.write stdout x)
(file.write stdout "\n"))
(pp x))
(when f (when f
(def st (fiber.stack f)) (def st (fiber.stack f))
(def len (length st)) (def len (length st))

View File

@ -996,20 +996,17 @@ int dst_compile_cfun(DstArgs args) {
DstCompileResult res; DstCompileResult res;
DstTable *t; DstTable *t;
DstTable *env; DstTable *env;
if (args.n < 2) DST_FIXARITY(args, 2);
return dst_throw(args, "expected at least 2 arguments"); DST_ARG_TABLE(env, args, 1);
if (!dst_checktype(args.v[1], DST_TABLE)) return dst_throw(args, "expected table as environment");
env = dst_unwrap_table(args.v[1]);
res = dst_compile(args.v[0], env, 0); res = dst_compile(args.v[0], env, 0);
if (res.status == DST_COMPILE_OK) { if (res.status == DST_COMPILE_OK) {
DstFunction *fun = dst_thunk(res.funcdef); DST_RETURN_FUNCTION(args, dst_thunk(res.funcdef));
return dst_return(args, dst_wrap_function(fun));
} else { } else {
t = dst_table(2); t = dst_table(2);
dst_table_put(t, dst_csymbolv(":error"), dst_wrap_string(res.error)); dst_table_put(t, dst_csymbolv(":error"), dst_wrap_string(res.error));
dst_table_put(t, dst_csymbolv(":error-start"), dst_wrap_integer(res.error_start)); dst_table_put(t, dst_csymbolv(":error-start"), dst_wrap_integer(res.error_start));
dst_table_put(t, dst_csymbolv(":error-end"), dst_wrap_integer(res.error_end)); dst_table_put(t, dst_csymbolv(":error-end"), dst_wrap_integer(res.error_end));
return dst_return(args, dst_wrap_table(t)); DST_RETURN_TABLE(args, t);
} }
} }

View File

@ -108,57 +108,58 @@ Dst dst_array_peek(DstArray *array) {
static int cfun_new(DstArgs args) { static int cfun_new(DstArgs args) {
int32_t cap; int32_t cap;
DstArray *array; DstArray *array;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_integer(cap, args, 0); DST_ARG_INTEGER(cap, args, 0);
array = dst_array(cap); array = dst_array(cap);
return dst_return(args, dst_wrap_array(array)); DST_RETURN_ARRAY(args, array);
} }
static int cfun_pop(DstArgs args) { static int cfun_pop(DstArgs args) {
dst_fixarity(args, 1); DstArray *array;
dst_check(args, 0, DST_ARRAY); DST_FIXARITY(args, 1);
return dst_return(args, dst_array_pop(dst_unwrap_array(args.v[0]))); DST_ARG_ARRAY(array, args, 0);
DST_RETURN(args, dst_array_pop(array));
} }
static int cfun_peek(DstArgs args) { static int cfun_peek(DstArgs args) {
dst_fixarity(args, 1); DstArray *array;
dst_check(args, 0, DST_ARRAY); DST_FIXARITY(args, 1);
return dst_return(args, dst_array_peek(dst_unwrap_array(args.v[0]))); DST_ARG_ARRAY(array, args, 0);
DST_RETURN(args, dst_array_peek(array));
} }
static int cfun_push(DstArgs args) { static int cfun_push(DstArgs args) {
DstArray *array; DstArray *array;
int32_t newcount; int32_t newcount;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_check(args, 0, DST_ARRAY); DST_ARG_ARRAY(array, args, 0);
array = dst_unwrap_array(args.v[0]);
newcount = array->count - 1 + args.n; newcount = array->count - 1 + args.n;
dst_array_ensure(array, newcount); dst_array_ensure(array, newcount);
if (args.n > 1) memcpy(array->data + array->count, args.v + 1, (args.n - 1) * sizeof(Dst)); if (args.n > 1) memcpy(array->data + array->count, args.v + 1, (args.n - 1) * sizeof(Dst));
array->count = newcount; array->count = newcount;
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_setcount(DstArgs args) { static int cfun_setcount(DstArgs args) {
DstArray *array;
int32_t newcount; int32_t newcount;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_check(args, 0, DST_ARRAY); DST_ARG_ARRAY(array, args, 0);
dst_check(args, 1, DST_INTEGER); DST_ARG_INTEGER(newcount, args, 1);
newcount = dst_unwrap_integer(args.v[1]); if (newcount < 0) DST_THROW(args, "expected positive integer");
if (newcount < 0) return dst_throw(args, "expected positive integer"); dst_array_setcount(array, newcount);
dst_array_setcount(dst_unwrap_array(args.v[0]), newcount); DST_RETURN(args, args.v[0]);
return dst_return(args, args.v[0]);
} }
static int cfun_ensure(DstArgs args) { static int cfun_ensure(DstArgs args) {
DstArray *array;
int32_t newcount; int32_t newcount;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_check(args, 0, DST_ARRAY); DST_ARG_ARRAY(array, args, 0);
dst_check(args, 1, DST_INTEGER); DST_ARG_INTEGER(newcount, args, 1);
newcount = dst_unwrap_integer(args.v[1]); if (newcount < 0) DST_THROW(args, "expected positive integer");
if (newcount < 0) return dst_throw(args, "expected positive integer"); dst_array_ensure(array, newcount);
dst_array_ensure(dst_unwrap_array(args.v[0]), newcount); DST_RETURN(args, args.v[0]);
return dst_return(args, args.v[0]);
} }
static int cfun_slice(DstArgs args) { static int cfun_slice(DstArgs args) {
@ -166,17 +167,17 @@ static int cfun_slice(DstArgs args) {
int32_t len; int32_t len;
DstArray *ret; DstArray *ret;
int32_t start, end; int32_t start, end;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_maxarity(args, 3); DST_MAXARITY(args, 3);
if (!dst_seq_view(args.v[0], &vals, &len)) if (!dst_seq_view(args.v[0], &vals, &len))
return dst_throw(args, "expected array|tuple"); DST_THROW(args, "expected array|tuple");
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) { } else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]); start = dst_unwrap_integer(args.v[1]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
@ -184,7 +185,7 @@ static int cfun_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) { } else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]); end = dst_unwrap_integer(args.v[2]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;
@ -198,15 +199,14 @@ static int cfun_slice(DstArgs args) {
} else { } else {
ret = dst_array(0); ret = dst_array(0);
} }
return dst_return(args, dst_wrap_array(ret)); DST_RETURN_ARRAY(args, ret);
} }
static int cfun_concat(DstArgs args) { static int cfun_concat(DstArgs args) {
int32_t i; int32_t i;
DstArray *array; DstArray *array;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_check(args, 0, DST_ARRAY); DST_ARG_ARRAY(array, args, 0);
array = dst_unwrap_array(args.v[0]);
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
switch (dst_type(args.v[i])) { switch (dst_type(args.v[i])) {
default: default:
@ -224,7 +224,7 @@ static int cfun_concat(DstArgs args) {
break; break;
} }
} }
return dst_return(args, args.v[0]); DST_RETURN_ARRAY(args, array);
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -161,91 +161,89 @@ int dst_buffer_push_u64(DstBuffer *buffer, uint64_t x) {
static int cfun_new(DstArgs args) { static int cfun_new(DstArgs args) {
int32_t cap; int32_t cap;
DstBuffer *buffer; DstBuffer *buffer;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_integer(cap, args, 0); DST_ARG_INTEGER(cap, args, 0);
buffer = dst_buffer(cap); buffer = dst_buffer(cap);
return dst_return(args, dst_wrap_buffer(buffer)); DST_RETURN_BUFFER(args, buffer);
} }
static int cfun_u8(DstArgs args) { static int cfun_u8(DstArgs args) {
int32_t i; int32_t i;
DstBuffer *buffer; DstBuffer *buffer;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_arg_buffer(buffer, args, 0); DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
int32_t integer; int32_t integer;
dst_arg_integer(integer, args, i); DST_ARG_INTEGER(integer, args, i);
if (dst_buffer_push_u8(buffer, (uint8_t) (integer & 0xFF))) if (dst_buffer_push_u8(buffer, (uint8_t) (integer & 0xFF)))
return dst_throw(args, "buffer overflow"); DST_THROW(args, "buffer overflow");
} }
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_int(DstArgs args) { static int cfun_int(DstArgs args) {
int32_t i; int32_t i;
DstBuffer *buffer; DstBuffer *buffer;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_arg_buffer(buffer, args, 0); DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
int32_t integer; int32_t integer;
dst_arg_integer(integer, args, i); DST_ARG_INTEGER(integer, args, i);
if (dst_buffer_push_u32(buffer, (uint32_t) integer)) if (dst_buffer_push_u32(buffer, (uint32_t) integer))
return dst_throw(args, "buffer overflow"); DST_THROW(args, "buffer overflow");
} }
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_chars(DstArgs args) { static int cfun_chars(DstArgs args) {
int32_t i; int32_t i;
DstBuffer *buffer; DstBuffer *buffer;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_arg_buffer(buffer, args, 0); DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
int32_t len; int32_t len;
const uint8_t *str; const uint8_t *str;
if (!dst_chararray_view(args.v[i], &str, &len)) DST_ARG_BYTES(str, len, args, i);
return dst_throw(args, "expected string|symbol|buffer");
if (dst_buffer_push_bytes(buffer, str, len)) if (dst_buffer_push_bytes(buffer, str, len))
return dst_throw(args, "buffer overflow"); DST_THROW(args, "buffer overflow");
} }
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_clear(DstArgs args) { static int cfun_clear(DstArgs args) {
DstBuffer *buffer; DstBuffer *buffer;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_buffer(buffer, args, 0); DST_ARG_BUFFER(buffer, args, 0);
buffer->count = 0; buffer->count = 0;
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_popn(DstArgs args) { static int cfun_popn(DstArgs args) {
DstBuffer *buffer; DstBuffer *buffer;
int32_t n; int32_t n;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_arg_buffer(buffer, args, 0); DST_ARG_BUFFER(buffer, args, 0);
dst_arg_integer(n, args, 1); DST_ARG_INTEGER(n, args, 1);
if (buffer->count < n) { if (buffer->count < n) {
buffer->count = 0; buffer->count = 0;
} else { } else {
buffer->count -= n; buffer->count -= n;
} }
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_slice(DstArgs args) { static int cfun_slice(DstArgs args) {
const uint8_t *data; const uint8_t *data;
int32_t len, start, end; int32_t len, start, end;
DstBuffer *ret; DstBuffer *ret;
if (args.n < 1 || !dst_chararray_view(args.v[0], &data, &len)) DST_ARG_BYTES(data, len, args, 0);
return dst_throw(args, "expected buffer/string");
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) { } else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]); start = dst_unwrap_integer(args.v[1]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
@ -253,7 +251,7 @@ static int cfun_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) { } else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]); end = dst_unwrap_integer(args.v[2]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;
@ -264,7 +262,7 @@ static int cfun_slice(DstArgs args) {
} else { } else {
ret = dst_buffer(0); ret = dst_buffer(0);
} }
return dst_return(args, dst_wrap_buffer(ret)); DST_RETURN_BUFFER(args, ret);
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -35,7 +35,7 @@ int dst_core_print(DstArgs args) {
} }
} }
putc('\n', stdout); putc('\n', stdout);
return 0; DST_RETURN_NIL();
} }
int dst_core_describe(DstArgs args) { int dst_core_describe(DstArgs args) {
@ -92,15 +92,15 @@ int dst_core_buffer(DstArgs args) {
len = dst_string_length(str); len = dst_string_length(str);
dst_buffer_push_bytes(b, str, len); dst_buffer_push_bytes(b, str, len);
} }
return dst_return(args, dst_wrap_buffer(b)); DST_RETURN_BUFFER(args, b);
} }
int dst_core_format(DstArgs args) { int dst_core_format(DstArgs args) {
const uint8_t *format; const uint8_t *format;
int32_t i, len, n; int32_t i, len, n;
DstBuffer buf; DstBuffer buf;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_arg_bytes(format, len, args, 0); DST_ARG_BYTES(format, len, args, 0);
n = 1; n = 1;
dst_buffer_init(&buf, len); dst_buffer_init(&buf, len);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
@ -128,33 +128,33 @@ int dst_core_format(DstArgs args) {
return 0; return 0;
noarg: noarg:
dst_buffer_deinit(&buf); dst_buffer_deinit(&buf);
return dst_throw(args, "not enough arguments to format"); DST_THROW(args, "not enough arguments to format");
} }
int dst_core_scannumber(DstArgs args) { int dst_core_scannumber(DstArgs args) {
const uint8_t *data; const uint8_t *data;
Dst x; Dst x;
int32_t len; int32_t len;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_bytes(data, len, args, 0); DST_ARG_BYTES(data, len, args, 0);
x = dst_scan_number(data, len); x = dst_scan_number(data, len);
if (!dst_checktype(x, DST_INTEGER) && !dst_checktype(x, DST_REAL)) { if (dst_checktype(x, DST_NIL)) {
return dst_throw(args, "error parsing number"); DST_THROW(args, "error parsing number");
} }
return dst_return(args, x); DST_RETURN(args, x);
} }
int dst_core_scaninteger(DstArgs args) { int dst_core_scaninteger(DstArgs args) {
const uint8_t *data; const uint8_t *data;
int32_t len, ret; int32_t len, ret;
int err = 0; int err = 0;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_bytes(data, len, args, 0); DST_ARG_BYTES(data, len, args, 0);
ret = dst_scan_integer(data, len, &err); ret = dst_scan_integer(data, len, &err);
if (err) { if (err) {
return dst_throw(args, "error parsing integer"); DST_THROW(args, "error parsing integer");
} }
return dst_return(args, dst_wrap_integer(ret)); DST_RETURN_INTEGER(args, ret);
} }
int dst_core_scanreal(DstArgs args) { int dst_core_scanreal(DstArgs args) {
@ -162,78 +162,82 @@ int dst_core_scanreal(DstArgs args) {
int32_t len; int32_t len;
double ret; double ret;
int err = 0; int err = 0;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_bytes(data, len, args, 0); DST_ARG_BYTES(data, len, args, 0);
ret = dst_scan_real(data, len, &err); ret = dst_scan_real(data, len, &err);
if (err) { if (err) {
return dst_throw(args, "error parsing real"); DST_THROW(args, "error parsing real");
} }
return dst_return(args, dst_wrap_real(ret)); DST_RETURN_REAL(args, ret);
} }
int dst_core_tuple(DstArgs args) { int dst_core_tuple(DstArgs args) {
return dst_return(args, dst_wrap_tuple(dst_tuple_n(args.v, args.n))); DST_RETURN_TUPLE(args, dst_tuple_n(args.v, args.n));
} }
int dst_core_array(DstArgs args) { int dst_core_array(DstArgs args) {
DstArray *array = dst_array(args.n); DstArray *array = dst_array(args.n);
array->count = args.n; array->count = args.n;
memcpy(array->data, args.v, args.n * sizeof(Dst)); memcpy(array->data, args.v, args.n * sizeof(Dst));
return dst_return(args, dst_wrap_array(array)); DST_RETURN_ARRAY(args, array);
} }
int dst_core_table(DstArgs args) { int dst_core_table(DstArgs args) {
int32_t i; int32_t i;
DstTable *table = dst_table(args.n >> 1); DstTable *table = dst_table(args.n >> 1);
if (args.n & 1) return dst_throw(args, "expected even number of arguments"); if (args.n & 1)
DST_THROW(args, "expected even number of arguments");
for (i = 0; i < args.n; i += 2) { for (i = 0; i < args.n; i += 2) {
dst_table_put(table, args.v[i], args.v[i + 1]); dst_table_put(table, args.v[i], args.v[i + 1]);
} }
return dst_return(args, dst_wrap_table(table)); DST_RETURN_TABLE(args, table);
} }
int dst_core_struct(DstArgs args) { int dst_core_struct(DstArgs args) {
int32_t i; int32_t i;
DstKV *st = dst_struct_begin(args.n >> 1); DstKV *st = dst_struct_begin(args.n >> 1);
if (args.n & 1) return dst_throw(args, "expected even number of arguments"); if (args.n & 1)
DST_THROW(args, "expected even number of arguments");
for (i = 0; i < args.n; i += 2) { for (i = 0; i < args.n; i += 2) {
dst_struct_put(st, args.v[i], args.v[i + 1]); dst_struct_put(st, args.v[i], args.v[i + 1]);
} }
return dst_return(args, dst_wrap_struct(dst_struct_end(st))); DST_RETURN_STRUCT(args, dst_struct_end(st));
} }
int dst_core_gensym(DstArgs args) { int dst_core_gensym(DstArgs args) {
dst_maxarity(args, 1); DST_MAXARITY(args, 1);
if (args.n == 0) { if (args.n == 0) {
return dst_return(args, dst_wrap_symbol(dst_symbol_gen(NULL, 0))); DST_RETURN_SYMBOL(args, dst_symbol_gen(NULL, 0));
} else { } else {
const uint8_t *s = dst_to_string(args.v[0]); const uint8_t *s;
return dst_return(args, dst_wrap_symbol(dst_symbol_gen(s, dst_string_length(s)))); int32_t len;
DST_ARG_BYTES(s, len, args, 0);
DST_RETURN_SYMBOL(args, dst_symbol_gen(s, len));
} }
} }
int dst_core_length(DstArgs args) { int dst_core_length(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
return dst_return(args, dst_wrap_integer(dst_length(args.v[0]))); DST_RETURN_INTEGER(args, dst_length(args.v[0]));
} }
int dst_core_get(DstArgs args) { int dst_core_get(DstArgs args) {
int32_t i; int32_t i;
Dst ds; Dst ds;
dst_minarity(args, 1); DST_MINARITY(args, 1);
ds = args.v[0]; ds = args.v[0];
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
ds = dst_get(ds, args.v[i]); ds = dst_get(ds, args.v[i]);
if (dst_checktype(ds, DST_NIL)) if (dst_checktype(ds, DST_NIL))
break; break;
} }
return dst_return(args, ds); DST_RETURN(args, ds);
} }
int dst_core_put(DstArgs args) { int dst_core_put(DstArgs args) {
Dst ds, key, value; Dst ds, key, value;
DstArgs subargs = args; DstArgs subargs = args;
dst_minarity(args, 3); DST_MINARITY(args, 3);
subargs.n -= 2; subargs.n -= 2;
if (dst_core_get(subargs)) return 1; if (dst_core_get(subargs)) return 1;
ds = *args.ret; ds = *args.ret;
@ -251,34 +255,33 @@ int dst_core_gccollect(DstArgs args) {
int dst_core_gcsetinterval(DstArgs args) { int dst_core_gcsetinterval(DstArgs args) {
int32_t val; int32_t val;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_check(args, 0, DST_INTEGER); DST_ARG_INTEGER(val, args, 0);
val = dst_unwrap_integer(args.v[0]);
if (val < 0) if (val < 0)
return dst_throw(args, "expected non-negative integer"); DST_THROW(args, "expected non-negative integer");
dst_vm_gc_interval = val; dst_vm_gc_interval = val;
return dst_return(args, args.v[0]); DST_RETURN_NIL(args);
} }
int dst_core_gcinterval(DstArgs args) { int dst_core_gcinterval(DstArgs args) {
dst_fixarity(args, 0); DST_FIXARITY(args, 0);
return dst_return(args, dst_wrap_integer(dst_vm_gc_interval)); DST_RETURN_INTEGER(args, dst_vm_gc_interval);
} }
int dst_core_type(DstArgs args) { int dst_core_type(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
if (dst_checktype(args.v[0], DST_ABSTRACT)) { if (dst_checktype(args.v[0], DST_ABSTRACT)) {
return dst_return(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name)); DST_RETURN(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name));
} else { } else {
return dst_return(args, dst_csymbolv(dst_type_names[dst_type(args.v[0])])); DST_RETURN(args, dst_csymbolv(dst_type_names[dst_type(args.v[0])]));
} }
} }
int dst_core_next(DstArgs args) { int dst_core_next(DstArgs args) {
Dst ds; Dst ds;
const DstKV *kv; const DstKV *kv;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_checkmany(args, 0, DST_TFLAG_DICTIONARY); DST_CHECKMANY(args, 0, DST_TFLAG_DICTIONARY);
ds = args.v[0]; ds = args.v[0];
if (dst_checktype(ds, DST_TABLE)) { if (dst_checktype(ds, DST_TABLE)) {
DstTable *t = dst_unwrap_table(ds); DstTable *t = dst_unwrap_table(ds);
@ -293,31 +296,30 @@ int dst_core_next(DstArgs args) {
} }
kv = dst_next(ds, kv); kv = dst_next(ds, kv);
if (kv) { if (kv) {
return dst_return(args, kv->key); DST_RETURN(args, kv->key);
} }
return dst_return(args, dst_wrap_nil()); DST_RETURN_NIL(args);
} }
int dst_core_hash(DstArgs args) { int dst_core_hash(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
return dst_return(args, dst_wrap_integer(dst_hash(args.v[0]))); DST_RETURN_INTEGER(args, dst_hash(args.v[0]));
} }
int dst_core_string_slice(DstArgs args) { int dst_core_string_slice(DstArgs args) {
const uint8_t *data; const uint8_t *data;
int32_t len, start, end; int32_t len, start, end;
const uint8_t *ret; const uint8_t *ret;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_maxarity(args, 3); DST_MAXARITY(args, 3);
if (!dst_chararray_view(args.v[0], &data, &len)) DST_ARG_BYTES(data, len, args, 0);
return dst_throw(args, "expected buffer|string|symbol");
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) { } else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]); start = dst_unwrap_integer(args.v[1]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
@ -325,7 +327,7 @@ int dst_core_string_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) { } else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]); end = dst_unwrap_integer(args.v[2]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;
@ -334,5 +336,5 @@ int dst_core_string_slice(DstArgs args) {
} else { } else {
ret = dst_cstring(""); ret = dst_cstring("");
} }
return dst_return(args, dst_wrap_string(ret)); DST_RETURN_STRING(args, ret);
} }

View File

@ -260,19 +260,20 @@ void dst_fiber_popframe(DstFiber *fiber) {
static int cfun_new(DstArgs args) { static int cfun_new(DstArgs args) {
DstFiber *fiber; DstFiber *fiber;
dst_minarity(args, 1); DstFunction *func;
dst_maxarity(args, 2); DST_MINARITY(args, 1);
dst_check(args, 0, DST_FUNCTION); DST_MAXARITY(args, 2);
fiber = dst_fiber(dst_unwrap_function(args.v[0]), 64); DST_ARG_FUNCTION(func, args, 0);
fiber = dst_fiber(func, 64);
if (args.n == 2) { if (args.n == 2) {
const uint8_t *flags; const uint8_t *flags;
int32_t len, i; int32_t len, i;
dst_arg_bytes(flags, len, args, 1); DST_ARG_BYTES(flags, len, args, 1);
fiber->flags |= DST_FIBER_MASK_ERROR | DST_FIBER_MASK_YIELD; fiber->flags |= DST_FIBER_MASK_ERROR | DST_FIBER_MASK_YIELD;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
switch (flags[i]) { switch (flags[i]) {
default: default:
return dst_throw(args, "invalid flag, expected d, e, or y"); DST_THROW(args, "invalid flag, expected d, e, or y");
case ':': case ':':
break; break;
case 'd': case 'd':
@ -287,14 +288,15 @@ static int cfun_new(DstArgs args) {
} }
} }
} }
return dst_return(args, dst_wrap_fiber(fiber)); DST_RETURN_FIBER(args, fiber);
} }
static int cfun_status(DstArgs args) { static int cfun_status(DstArgs args) {
DstFiber *fiber;
const char *status = ""; const char *status = "";
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_check(args, 0, DST_FIBER); DST_ARG_FIBER(fiber, args, 0);
switch(dst_unwrap_fiber(args.v[0])->status) { switch(fiber->status) {
case DST_FIBER_PENDING: case DST_FIBER_PENDING:
status = ":pending"; status = ":pending";
break; break;
@ -314,7 +316,7 @@ static int cfun_status(DstArgs args) {
status = ":debug"; status = ":debug";
break; break;
} }
return dst_return(args, dst_csymbolv(status)); DST_RETURN_CSYMBOL(args, status);
} }
/* Extract info from one stack frame */ /* Extract info from one stack frame */
@ -354,9 +356,8 @@ static Dst doframe(DstStackFrame *frame) {
static int cfun_stack(DstArgs args) { static int cfun_stack(DstArgs args) {
DstFiber *fiber; DstFiber *fiber;
DstArray *array; DstArray *array;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_check(args, 0, DST_FIBER); DST_ARG_FIBER(fiber, args, 0);
fiber = dst_unwrap_fiber(args.v[0]);
array = dst_array(0); array = dst_array(0);
{ {
int32_t i = fiber->frame; int32_t i = fiber->frame;
@ -367,26 +368,25 @@ static int cfun_stack(DstArgs args) {
i = frame->prevframe; i = frame->prevframe;
} }
} }
return dst_return(args, dst_wrap_array(array)); DST_RETURN_ARRAY(args, array);
} }
static int cfun_current(DstArgs args) { static int cfun_current(DstArgs args) {
dst_fixarity(args, 0); DST_FIXARITY(args, 0);
return dst_return(args, dst_wrap_fiber(dst_vm_fiber)); DST_RETURN_FIBER(args, dst_vm_fiber);
} }
static int cfun_lineage(DstArgs args) { static int cfun_lineage(DstArgs args) {
DstFiber *fiber; DstFiber *fiber;
DstArray *array; DstArray *array;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_check(args, 0, DST_FIBER); DST_ARG_FIBER(fiber, args, 0);
fiber = dst_unwrap_fiber(args.v[0]);
array = dst_array(0); array = dst_array(0);
while (fiber) { while (fiber) {
dst_array_push(array, dst_wrap_fiber(fiber)); dst_array_push(array, dst_wrap_fiber(fiber));
fiber = fiber->child; fiber = fiber->child;
} }
return dst_return(args, dst_wrap_array(array)); DST_RETURN_ARRAY(args, array);
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -117,19 +117,6 @@ static DstBuffer *checkbuffer(DstArgs args, int32_t n, int optional) {
return dst_unwrap_abstract(args.v[n]); return dst_unwrap_abstract(args.v[n]);
} }
/* Check char array argument */
static int checkchars(DstArgs args, int32_t n, const uint8_t **str, int32_t *len) {
if (n >= args.n) {
*args.ret = dst_cstringv("expected string/buffer");
return 0;
}
if (!dst_chararray_view(args.v[n], str, len)) {
*args.ret = dst_cstringv("expected string/buffer");
return 0;
}
return 1;
}
static Dst makef(FILE *f, int flags) { static Dst makef(FILE *f, int flags) {
IOFile *iof = (IOFile *) dst_abstract(&dst_io_filetype, sizeof(IOFile)); IOFile *iof = (IOFile *) dst_abstract(&dst_io_filetype, sizeof(IOFile));
iof->file = f; iof->file = f;
@ -143,14 +130,13 @@ static int dst_io_popen(DstArgs args) {
int32_t modelen; int32_t modelen;
FILE *f; FILE *f;
int flags; int flags;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_maxarity(args, 2); DST_MAXARITY(args, 2);
dst_check(args, 0, DST_STRING); DST_ARG_STRING(fname, args, 0);
fname = dst_unwrap_string(args.v[0]);
if (args.n == 2) { if (args.n == 2) {
if (!dst_checktype(args.v[1], DST_STRING) && if (!dst_checktype(args.v[1], DST_STRING) &&
!dst_checktype(args.v[1], DST_SYMBOL)) !dst_checktype(args.v[1], DST_SYMBOL))
return dst_throw(args, "expected string mode"); DST_THROW(args, "expected string mode");
fmode = dst_unwrap_string(args.v[1]); fmode = dst_unwrap_string(args.v[1]);
modelen = dst_string_length(fmode); modelen = dst_string_length(fmode);
} else { } else {
@ -162,7 +148,7 @@ static int dst_io_popen(DstArgs args) {
modelen--; modelen--;
} }
if (modelen != 1 || !(fmode[0] == 'r' || fmode[0] == 'w')) { if (modelen != 1 || !(fmode[0] == 'r' || fmode[0] == 'w')) {
return dst_throw(args, "invalid file mode"); DST_THROW(args, "invalid file mode");
} }
flags = (fmode[0] == 'r') ? IO_PIPED | IO_READ : IO_PIPED | IO_WRITE; flags = (fmode[0] == 'r') ? IO_PIPED | IO_READ : IO_PIPED | IO_WRITE;
#ifdef DST_WINDOWS #ifdef DST_WINDOWS
@ -172,11 +158,11 @@ static int dst_io_popen(DstArgs args) {
#endif #endif
if (!f) { if (!f) {
if (errno == EMFILE) { if (errno == EMFILE) {
return dst_throw(args, "too many streams are open"); DST_THROW(args, "too many streams are open");
} }
return dst_throw(args, "could not open file"); DST_THROW(args, "could not open file");
} }
return dst_return(args, makef(f, flags)); DST_RETURN(args, makef(f, flags));
} }
/* Open a a file and return a userdata wrapper around the C file API. */ /* Open a a file and return a userdata wrapper around the C file API. */
@ -185,14 +171,13 @@ static int dst_io_fopen(DstArgs args) {
int32_t modelen; int32_t modelen;
FILE *f; FILE *f;
int flags; int flags;
dst_minarity(args, 1); DST_MINARITY(args, 1);
dst_maxarity(args, 2); DST_MAXARITY(args, 2);
dst_check(args, 0, DST_STRING); DST_ARG_STRING(fname, args, 0);
fname = dst_unwrap_string(args.v[0]);
if (args.n == 2) { if (args.n == 2) {
if (!dst_checktype(args.v[1], DST_STRING) && if (!dst_checktype(args.v[1], DST_STRING) &&
!dst_checktype(args.v[1], DST_SYMBOL)) !dst_checktype(args.v[1], DST_SYMBOL))
return dst_throw(args, "expected string mode"); DST_THROW(args, "expected string mode");
fmode = dst_unwrap_string(args.v[1]); fmode = dst_unwrap_string(args.v[1]);
modelen = dst_string_length(fmode); modelen = dst_string_length(fmode);
} else { } else {
@ -203,10 +188,12 @@ static int dst_io_fopen(DstArgs args) {
fmode++; fmode++;
modelen--; modelen--;
} }
if ((flags = checkflags(fmode, modelen)) < 0) return dst_throw(args, "invalid file mode"); if ((flags = checkflags(fmode, modelen)) < 0) {
DST_THROW(args, "invalid file mode");
}
f = fopen((const char *)fname, (const char *)fmode); f = fopen((const char *)fname, (const char *)fmode);
if (!f) return dst_throw(args, "could not open file"); if (!f) DST_THROW(args, "could not open file");
return dst_return(args, makef(f, flags)); DST_RETURN(args, makef(f, flags));
} }
/* Read a certain number of bytes into memory */ /* Read a certain number of bytes into memory */
@ -217,7 +204,7 @@ static int dst_io_fread(DstArgs args) {
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (iof->flags & IO_CLOSED) if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed"); DST_THROW(args, "file is closed");
b = checkbuffer(args, 2, 1); b = checkbuffer(args, 2, 1);
if (!b) return 1; if (!b) return 1;
if (dst_checktype(args.v[1], DST_SYMBOL)) { if (dst_checktype(args.v[1], DST_SYMBOL)) {
@ -228,33 +215,34 @@ static int dst_io_fread(DstArgs args) {
fseek(iof->file, 0, SEEK_END); fseek(iof->file, 0, SEEK_END);
fsize = ftell(iof->file); fsize = ftell(iof->file);
fseek(iof->file, 0, SEEK_SET); fseek(iof->file, 0, SEEK_SET);
if (fsize > INT32_MAX) return dst_throw(args, "buffer overflow"); if (fsize > INT32_MAX) DST_THROW(args, "buffer overflow");
len = fsize; len = fsize;
/* Fall through to normal code */ /* Fall through to normal code */
} else if (!dst_cstrcmp(sym, ":line")) { } else if (!dst_cstrcmp(sym, ":line")) {
for (;;) { for (;;) {
int x = fgetc(iof->file); int x = fgetc(iof->file);
if (x != EOF && dst_buffer_push_u8(b, (uint8_t)x)) return dst_throw(args, "buffer overflow"); if (x != EOF && dst_buffer_push_u8(b, (uint8_t)x))
DST_THROW(args, "buffer overflow");
if (x == EOF || x == '\n') break; if (x == EOF || x == '\n') break;
} }
return dst_return(args, dst_wrap_buffer(b)); DST_RETURN(args, dst_wrap_buffer(b));
} else { } else {
return dst_throw(args, "expected one of :all, :line"); DST_THROW(args, "expected one of :all, :line");
} }
} else if (!dst_checktype(args.v[1], DST_INTEGER)) { } else if (!dst_checktype(args.v[1], DST_INTEGER)) {
return dst_throw(args, "expected positive integer"); DST_THROW(args, "expected positive integer");
} else { } else {
len = dst_unwrap_integer(args.v[1]); len = dst_unwrap_integer(args.v[1]);
if (len < 0) return dst_throw(args, "expected positive integer"); if (len < 0) DST_THROW(args, "expected positive integer");
} }
if (!(iof->flags & (IO_READ | IO_UPDATE))) return dst_throw(args, "file is not readable"); if (!(iof->flags & (IO_READ | IO_UPDATE))) DST_THROW(args, "file is not readable");
/* Ensure buffer size */ /* Ensure buffer size */
if (dst_buffer_extra(b, len)) return dst_throw(args, "buffer overflow"); if (dst_buffer_extra(b, len)) DST_THROW(args, "buffer overflow");
ntoread = len; ntoread = len;
nread = fread((char *)(b->data + b->count), 1, ntoread, iof->file); nread = fread((char *)(b->data + b->count), 1, ntoread, iof->file);
if (nread != ntoread && ferror(iof->file)) return dst_throw(args, "could not read file"); if (nread != ntoread && ferror(iof->file)) DST_THROW(args, "could not read file");
b->count += nread; b->count += nread;
return dst_return(args, dst_wrap_buffer(b)); DST_RETURN(args, dst_wrap_buffer(b));
} }
/* Write bytes to a file */ /* Write bytes to a file */
@ -264,16 +252,19 @@ static int dst_io_fwrite(DstArgs args) {
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (iof->flags & IO_CLOSED) if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed"); DST_THROW(args, "file is closed");
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE))) if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
return dst_throw(args, "file is not writeable"); DST_THROW(args, "file is not writeable");
for (i = 1; i < args.n; i++) { for (i = 1; i < args.n; i++) {
if (!checkchars(args, i, &str, &len)) return 1; DST_CHECKMANY(args, i, DST_TFLAG_BYTES);
}
for (i = 1; i < args.n; i++) {
DST_ARG_BYTES(str, len, args, i);
if (len) { if (len) {
if (!fwrite(str, len, 1, iof->file)) return dst_throw(args, "error writing to file"); if (!fwrite(str, len, 1, iof->file)) DST_THROW(args, "error writing to file");
} }
} }
return dst_return(args, dst_wrap_abstract(iof)); DST_RETURN(args, dst_wrap_abstract(iof));
} }
/* Flush the bytes in the file */ /* Flush the bytes in the file */
@ -281,11 +272,11 @@ static int dst_io_fflush(DstArgs args) {
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (iof->flags & IO_CLOSED) if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed"); DST_THROW(args, "file is closed");
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE))) if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
return dst_throw(args, "file is not flushable"); DST_THROW(args, "file is not flushable");
if (fflush(iof->file)) return dst_throw(args, "could not flush file"); if (fflush(iof->file)) DST_THROW(args, "could not flush file");
return dst_return(args, dst_wrap_abstract(iof)); DST_RETURN(args, dst_wrap_abstract(iof));
} }
/* Cleanup a file */ /* Cleanup a file */
@ -303,20 +294,20 @@ static int dst_io_fclose(DstArgs args) {
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (iof->flags & (IO_CLOSED)) if (iof->flags & (IO_CLOSED))
return dst_throw(args, "file already closed"); DST_THROW(args, "file already closed");
if (iof->flags & (IO_NOT_CLOSEABLE)) if (iof->flags & (IO_NOT_CLOSEABLE))
return dst_throw(args, "file not closable"); DST_THROW(args, "file not closable");
if (iof->flags & IO_PIPED) { if (iof->flags & IO_PIPED) {
#ifdef DST_WINDOWS #ifdef DST_WINDOWS
if (_pclose(iof->file)) return dst_throw(args, "could not close file"); if (_pclose(iof->file)) DST_THROW(args, "could not close file");
#else #else
if (pclose(iof->file)) return dst_throw(args, "could not close file"); if (pclose(iof->file)) DST_THROW(args, "could not close file");
#endif #endif
} else { } else {
if (fclose(iof->file)) return dst_throw(args, "could not close file"); if (fclose(iof->file)) DST_THROW(args, "could not close file");
} }
iof->flags |= IO_CLOSED; iof->flags |= IO_CLOSED;
return dst_return(args, dst_wrap_abstract(iof)); DST_RETURN(args, dst_wrap_abstract(iof));
} }
/* Seek a file */ /* Seek a file */
@ -326,11 +317,11 @@ static int dst_io_fseek(DstArgs args) {
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (iof->flags & IO_CLOSED) if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed"); DST_THROW(args, "file is closed");
if (args.n >= 2) { if (args.n >= 2) {
const uint8_t *whence_sym; const uint8_t *whence_sym;
if (!dst_checktype(args.v[1], DST_SYMBOL)) if (!dst_checktype(args.v[1], DST_SYMBOL))
return dst_throw(args, "expected symbol"); DST_THROW(args, "expected symbol");
whence_sym = dst_unwrap_symbol(args.v[1]); whence_sym = dst_unwrap_symbol(args.v[1]);
if (!dst_cstrcmp(whence_sym, ":cur")) { if (!dst_cstrcmp(whence_sym, ":cur")) {
whence = SEEK_CUR; whence = SEEK_CUR;
@ -339,17 +330,17 @@ static int dst_io_fseek(DstArgs args) {
} else if (!dst_cstrcmp(whence_sym, ":end")) { } else if (!dst_cstrcmp(whence_sym, ":end")) {
whence = SEEK_END; whence = SEEK_END;
} else { } else {
return dst_throw(args, "expected one of :cur, :set, :end"); DST_THROW(args, "expected one of :cur, :set, :end");
} }
if (args.n >= 3) { if (args.n >= 3) {
if (!dst_checktype(args.v[2], DST_INTEGER)) if (!dst_checktype(args.v[2], DST_INTEGER))
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
offset = dst_unwrap_integer(args.v[2]); offset = dst_unwrap_integer(args.v[2]);
} }
} }
if (fseek(iof->file, offset, whence)) if (fseek(iof->file, offset, whence))
return dst_throw(args, "error seeking file"); DST_THROW(args, "error seeking file");
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -25,26 +25,26 @@
/* Get a random number */ /* Get a random number */
int dst_rand(DstArgs args) { int dst_rand(DstArgs args) {
dst_fixarity(args, 0); DST_FIXARITY(args, 0);
double r = (rand() % RAND_MAX) / ((double) RAND_MAX); double r = (rand() % RAND_MAX) / ((double) RAND_MAX);
return dst_return(args, dst_wrap_real(r)); DST_RETURN_REAL(args, r);
} }
/* Seed the random number generator */ /* Seed the random number generator */
int dst_srand(DstArgs args) { int dst_srand(DstArgs args) {
int32_t x = 0; int32_t x = 0;
dst_fixarity(args, 0); DST_FIXARITY(args, 1);
dst_arg_integer(x, args, 0); DST_ARG_INTEGER(x, args, 0);
srand((unsigned) x); srand((unsigned) x);
return 0; return 0;
} }
/* Convert a number to an integer */ /* Convert a number to an integer */
int dst_int(DstArgs args) { int dst_int(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
switch (dst_type(args.v[0])) { switch (dst_type(args.v[0])) {
default: default:
return dst_throw(args, "could not convert to integer"); DST_THROW(args, "could not convert to integer");
case DST_REAL: case DST_REAL:
*args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0])); *args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0]));
break; break;
@ -57,10 +57,10 @@ int dst_int(DstArgs args) {
/* Convert a number to a real number */ /* Convert a number to a real number */
int dst_real(DstArgs args) { int dst_real(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
switch (dst_type(args.v[0])) { switch (dst_type(args.v[0])) {
default: default:
return dst_throw(args, "could not convert to real"); DST_THROW(args, "could not convert to real");
case DST_REAL: case DST_REAL:
*args.ret = args.v[0]; *args.ret = args.v[0];
break; break;
@ -200,34 +200,34 @@ DST_DEFINE_BITOP(bxor, ^=, 0)
int dst_lshift(DstArgs args) { int dst_lshift(DstArgs args) {
int32_t lhs, rhs; int32_t lhs, rhs;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_arg_integer(lhs, args, 0); DST_ARG_INTEGER(lhs, args, 0);
dst_arg_integer(rhs, args, 1); DST_ARG_INTEGER(rhs, args, 1);
return dst_return(args, dst_wrap_integer(lhs >> rhs)); DST_RETURN_INTEGER(args, lhs >> rhs);
} }
int dst_rshift(DstArgs args) { int dst_rshift(DstArgs args) {
int32_t lhs, rhs; int32_t lhs, rhs;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_arg_integer(lhs, args, 0); DST_ARG_INTEGER(lhs, args, 0);
dst_arg_integer(rhs, args, 1); DST_ARG_INTEGER(rhs, args, 1);
return dst_return(args, dst_wrap_integer(lhs << rhs)); DST_RETURN_INTEGER(args, lhs << rhs);
} }
int dst_lshiftu(DstArgs args) { int dst_lshiftu(DstArgs args) {
int32_t lhs, rhs; int32_t lhs, rhs;
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_arg_integer(lhs, args, 0); DST_ARG_INTEGER(lhs, args, 0);
dst_arg_integer(rhs, args, 1); DST_ARG_INTEGER(rhs, args, 1);
return dst_return(args, dst_wrap_integer((int32_t)((uint32_t)lhs << rhs))); DST_RETURN_INTEGER(args, (int32_t)((uint32_t)lhs << rhs));
} }
#define DST_DEFINE_MATHOP(name, fop)\ #define DST_DEFINE_MATHOP(name, fop)\
int dst_##name(DstArgs args) {\ int dst_##name(DstArgs args) {\
double x;\ double x;\
dst_fixarity(args, 1);\ DST_FIXARITY(args, 1);\
dst_arg_number(x, args, 0);\ DST_ARG_NUMBER(x, args, 0);\
return dst_return(args, dst_wrap_real(fop(x)));\ DST_RETURN_REAL(args, fop(x));\
} }
DST_DEFINE_MATHOP(acos, acos) DST_DEFINE_MATHOP(acos, acos)
@ -250,10 +250,10 @@ DST_DEFINE_MATHOP(floor, floor)
#define DST_DEFINE_MATH2OP(name, fop)\ #define DST_DEFINE_MATH2OP(name, fop)\
int dst_##name(DstArgs args) {\ int dst_##name(DstArgs args) {\
double lhs, rhs;\ double lhs, rhs;\
dst_fixarity(args, 2);\ DST_FIXARITY(args, 2);\
dst_arg_number(lhs, args, 0);\ DST_ARG_NUMBER(lhs, args, 0);\
dst_arg_number(rhs, args, 1);\ DST_ARG_NUMBER(rhs, args, 1);\
return dst_return(args, dst_wrap_real(fop(lhs, rhs)));\ DST_RETURN_REAL(args, fop(lhs, rhs));\
}\ }\
DST_DEFINE_MATH2OP(atan2, atan2) DST_DEFINE_MATH2OP(atan2, atan2)
@ -263,13 +263,12 @@ DST_DEFINE_MATH2OP(fmod, fmod)
int dst_modf(DstArgs args) { int dst_modf(DstArgs args) {
double x, intpart; double x, intpart;
Dst *tup; Dst *tup;
dst_fixarity(args, 1); DST_FIXARITY(args, 2);
dst_arg_number(x, args, 0); DST_ARG_NUMBER(x, args, 0);
tup = dst_tuple_begin(2); tup = dst_tuple_begin(2);
tup[0] = dst_wrap_real(modf(x, &intpart)); tup[0] = dst_wrap_real(modf(x, &intpart));
tup[1] = dst_wrap_real(intpart); tup[1] = dst_wrap_real(intpart);
*args.ret = dst_wrap_tuple(dst_tuple_end(tup)); DST_RETURN_TUPLE(args, dst_tuple_end(tup));
return 0;
} }
/* Comparison */ /* Comparison */
@ -278,12 +277,10 @@ static int dst_##name(DstArgs args) {\
int32_t i;\ int32_t i;\
for (i = 0; i < args.n - 1; i++) {\ for (i = 0; i < args.n - 1; i++) {\
if (dst_compare(args.v[i], args.v[i+1]) pred) {\ if (dst_compare(args.v[i], args.v[i+1]) pred) {\
*args.ret = dst_wrap_false();\ DST_RETURN_FALSE(args);\
return 0;\
}\ }\
}\ }\
*args.ret = dst_wrap_true();\ DST_RETURN_TRUE(args);\
return 0;\
} }
DST_DEFINE_COMPARATOR(ascending, >= 0) DST_DEFINE_COMPARATOR(ascending, >= 0)
@ -296,25 +293,25 @@ static int dst_strict_equal(DstArgs args) {
int32_t i; int32_t i;
for (i = 0; i < args.n - 1; i++) { for (i = 0; i < args.n - 1; i++) {
if (!dst_equals(args.v[i], args.v[i+1])) { if (!dst_equals(args.v[i], args.v[i+1])) {
return dst_return(args, dst_wrap_false()); DST_RETURN(args, dst_wrap_false());
} }
} }
return dst_return(args, dst_wrap_true()); DST_RETURN(args, dst_wrap_true());
} }
static int dst_strict_notequal(DstArgs args) { static int dst_strict_notequal(DstArgs args) {
int32_t i; int32_t i;
for (i = 0; i < args.n - 1; i++) { for (i = 0; i < args.n - 1; i++) {
if (dst_equals(args.v[i], args.v[i+1])) { if (dst_equals(args.v[i], args.v[i+1])) {
return dst_return(args, dst_wrap_false()); DST_RETURN(args, dst_wrap_false());
} }
} }
return dst_return(args, dst_wrap_true()); DST_RETURN(args, dst_wrap_true());
} }
static int dst_not(DstArgs args) { static int dst_not(DstArgs args) {
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
return dst_return(args, dst_wrap_boolean(!dst_truthy(args.v[0]))); DST_RETURN_BOOLEAN(args, !dst_truthy(args.v[0]));
} }
#define DEF_NUMERIC_COMP(name, op) \ #define DEF_NUMERIC_COMP(name, op) \
@ -322,13 +319,13 @@ int dst_numeric_##name(DstArgs args) { \
int32_t i; \ int32_t i; \
for (i = 1; i < args.n; i++) { \ for (i = 1; i < args.n; i++) { \
double x = 0, y = 0; \ double x = 0, y = 0; \
dst_arg_number(x, args, i-1);\ DST_ARG_NUMBER(x, args, i-1);\
dst_arg_number(y, args, i);\ DST_ARG_NUMBER(y, args, i);\
if (!(x op y)) { \ if (!(x op y)) { \
return dst_return(args, dst_wrap_false()); \ DST_RETURN(args, dst_wrap_false()); \
} \ } \
} \ } \
return dst_return(args, dst_wrap_true()); \ DST_RETURN(args, dst_wrap_true()); \
} }
DEF_NUMERIC_COMP(gt, >) DEF_NUMERIC_COMP(gt, >)

View File

@ -64,19 +64,12 @@ DstCFunction dst_native(const char *name, const uint8_t **error) {
int dst_core_native(DstArgs args) { int dst_core_native(DstArgs args) {
DstCFunction init; DstCFunction init;
const uint8_t *error = NULL; const uint8_t *error = NULL;
if (args.n < 1) { const uint8_t *path = NULL;
*args.ret = dst_cstringv("expected at least one argument"); DST_FIXARITY(args, 1);
return 1; DST_ARG_STRING(path, args, 0);
} init = dst_native((const char *)path, &error);
if (!dst_checktype(args.v[0], DST_STRING)) {
*args.ret = dst_cstringv("expected string");
return 1;
}
init = dst_native((const char *)dst_unwrap_string(args.v[0]), &error);
if (!init) { if (!init) {
*args.ret = dst_wrap_string(error); DST_THROWV(args, dst_wrap_string(error));
return 1;
} }
*args.ret = dst_wrap_cfunction(init); DST_RETURN_CFUNCTION(args, init);
return 0;
} }

View File

@ -23,6 +23,13 @@
#include <dst/dst.h> #include <dst/dst.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#ifdef DST_WINDOWS
#include <Windows.h>
#else
#include <unistd.h>
#endif
static int os_execute(DstArgs args) { static int os_execute(DstArgs args) {
int nofirstarg = (args.n < 1 || !dst_checktype(args.v[0], DST_STRING)); int nofirstarg = (args.n < 1 || !dst_checktype(args.v[0], DST_STRING));
@ -30,28 +37,28 @@ static int os_execute(DstArgs args) {
? NULL ? NULL
: (const char *) dst_unwrap_string(args.v[0]); : (const char *) dst_unwrap_string(args.v[0]);
int stat = system(cmd); int stat = system(cmd);
return dst_return(args, cmd DST_RETURN(args, cmd
? dst_wrap_integer(stat) ? dst_wrap_integer(stat)
: dst_wrap_boolean(stat)); : dst_wrap_boolean(stat));
} }
static int os_getenv(DstArgs args) { static int os_getenv(DstArgs args) {
if (args.n != 1 || !dst_checktype(args.v[0], DST_STRING)) if (args.n != 1 || !dst_checktype(args.v[0], DST_STRING))
return dst_throw(args, "expected string"); DST_THROW(args, "expected string");
const char *cstr = (const char *) dst_unwrap_string(args.v[0]); const char *cstr = (const char *) dst_unwrap_string(args.v[0]);
const char *res = getenv(cstr); const char *res = getenv(cstr);
return dst_return(args, cstr DST_RETURN(args, cstr
? dst_cstringv(res) ? dst_cstringv(res)
: dst_wrap_nil()); : dst_wrap_nil());
} }
static int os_setenv(DstArgs args) { static int os_setenv(DstArgs args) {
int t2; int t2;
if (args.n < 2) return dst_throw(args, "expected 2 arguments"); if (args.n < 2) DST_THROW(args, "expected 2 arguments");
t2 = dst_type(args.v[1]); t2 = dst_type(args.v[1]);
if (!dst_checktype(args.v[0], DST_STRING) if (!dst_checktype(args.v[0], DST_STRING)
|| (t2 != DST_STRING && t2 != DST_NIL)) || (t2 != DST_STRING && t2 != DST_NIL))
return dst_throw(args, "expected string"); DST_THROW(args, "expected string");
const char *k = (const char *) dst_unwrap_string(args.v[0]); const char *k = (const char *) dst_unwrap_string(args.v[0]);
#ifdef DST_WINDOWS #ifdef DST_WINDOWS
if (t2 == DST_NIL) { if (t2 == DST_NIL) {
@ -73,16 +80,39 @@ static int os_setenv(DstArgs args) {
} }
static int os_exit(DstArgs args) { static int os_exit(DstArgs args) {
if (args.n == 0) { DST_MAXARITY(args, 1);
exit(EXIT_SUCCESS); if (args.n == 0) {
} else if (dst_checktype(args.v[0], DST_TRUE) exit(EXIT_SUCCESS);
|| dst_checktype(args.v[0], DST_FALSE)) { } else if (dst_checktype(args.v[0], DST_TRUE)
exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE); || dst_checktype(args.v[0], DST_FALSE)) {
return 0; exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE);
} else { return 0;
exit(dst_hash(args.v[0])); } else {
} exit(dst_hash(args.v[0]));
return 0; }
return 0;
}
static int os_clock(DstArgs args) {
DST_FIXARITY(args, 0);
clock_t time = clock();
double dtime = time / (double) (CLOCKS_PER_SEC);
DST_RETURN_REAL(args, dtime);
}
static int os_sleep(DstArgs args) {
int32_t delay;
DST_FIXARITY(args, 1);
DST_ARG_INTEGER(delay, args, 0);
if (delay < 0) {
DST_THROW(args, "invalid argument to sleep");
}
#ifdef DST_WINDOWS
Sleep(delay);
#else
sleep((unsigned int) delay);
#endif
return 0;
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {
@ -90,6 +120,8 @@ static const DstReg cfuns[] = {
{"os.exit", os_exit}, {"os.exit", os_exit},
{"os.getenv", os_getenv}, {"os.getenv", os_getenv},
{"os.setenv", os_setenv}, {"os.setenv", os_setenv},
{"os.clock", os_clock},
{"os.sleep", os_sleep},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -1,33 +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.
*/
#ifndef DST_OS_H
#define DST_OS_H
#include <dst/dst.h>
int dst_os_execute(DstArgs args);
int dst_os_getenv(DstArgs args);
int dst_os_setenv(DstArgs args);
int dst_os_exit(DstArgs args);
#endif

View File

@ -468,7 +468,7 @@ const uint8_t *dst_formatc(const char *format, ...) {
} }
case 't': case 't':
{ {
dst_buffer_push_cstring(bufp, dst_type_names[va_arg(args, DstType)]); dst_buffer_push_cstring(bufp, dst_type_names[va_arg(args, DstType)] + 1);
break; break;
} }
case 'V': case 'V':

View File

@ -240,43 +240,46 @@ void dst_table_merge_struct(DstTable *table, const DstKV *other) {
static int cfun_new(DstArgs args) { static int cfun_new(DstArgs args) {
DstTable *t; DstTable *t;
int32_t cap; int32_t cap;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_integer(cap, args, 0); DST_ARG_INTEGER(cap, args, 0);
t = dst_table(cap); t = dst_table(cap);
return dst_return(args, dst_wrap_table(t)); DST_RETURN_TABLE(args, t);
} }
static int cfun_getproto(DstArgs args) { static int cfun_getproto(DstArgs args) {
DstTable *t; DstTable *t;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_check(args, 0, DST_TABLE); DST_ARG_TABLE(t, args, 0);
t = dst_unwrap_table(args.v[0]); DST_RETURN(args, t->proto
return dst_return(args, t->proto
? dst_wrap_table(t->proto) ? dst_wrap_table(t->proto)
: dst_wrap_nil()); : dst_wrap_nil());
} }
static int cfun_setproto(DstArgs args) { static int cfun_setproto(DstArgs args) {
dst_fixarity(args, 2); DstTable *table, *proto;
dst_check(args, 0, DST_TABLE); DST_FIXARITY(args, 2);
dst_checkmany(args, 1, DST_TFLAG_TABLE | DST_TFLAG_NIL); DST_ARG_TABLE(table, args, 0);
dst_unwrap_table(args.v[0])->proto = dst_checktype(args.v[1], DST_TABLE) if (dst_checktype(args.v[1], DST_NIL)) {
? dst_unwrap_table(args.v[1]) proto = NULL;
: NULL; } else {
return dst_return(args, args.v[0]); DST_ARG_TABLE(proto, args, 1);
}
table->proto = proto;
DST_RETURN_TABLE(args, table);
} }
static int cfun_tostruct(DstArgs args) { static int cfun_tostruct(DstArgs args) {
DstTable *t; DstTable *t;
dst_fixarity(args, 1); DST_FIXARITY(args, 1);
dst_arg_table(t, args, 0); DST_ARG_TABLE(t, args, 0);
return dst_return(args, dst_wrap_struct(dst_table_to_struct(t))); DST_RETURN_STRUCT(args, dst_table_to_struct(t));
} }
static int cfun_rawget(DstArgs args) { static int cfun_rawget(DstArgs args) {
dst_fixarity(args, 2); DstTable *table;
dst_check(args, 0, DST_TABLE); DST_FIXARITY(args, 2);
return dst_return(args, dst_table_rawget(dst_unwrap_table(args.v[0]), args.v[1])); DST_ARG_TABLE(table, args, 0);
DST_RETURN(args, dst_table_rawget(table, args.v[1]));
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {

View File

@ -94,14 +94,15 @@ static int cfun_slice(DstArgs args) {
int32_t len; int32_t len;
Dst *ret; Dst *ret;
int32_t start, end; 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);
if (!dst_seq_view(args.v[0], &vals, &len)) DST_THROW(args, "expected array/tuple");
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) { } else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]); start = dst_unwrap_integer(args.v[1]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
@ -109,7 +110,7 @@ static int cfun_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) { } else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]); end = dst_unwrap_integer(args.v[2]);
} else { } else {
return dst_throw(args, "expected integer"); DST_THROW(args, "expected integer");
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;
@ -122,31 +123,31 @@ static int cfun_slice(DstArgs args) {
} else { } else {
ret = dst_tuple_begin(0); ret = dst_tuple_begin(0);
} }
return dst_return(args, dst_wrap_tuple(dst_tuple_end(ret))); DST_RETURN_TUPLE(args, dst_tuple_end(ret));
} }
static int cfun_prepend(DstArgs args) { static int cfun_prepend(DstArgs args) {
const Dst *t; const Dst *t;
int32_t len; int32_t len;
Dst *n; Dst *n;
if (args.n != 2) return dst_throw(args, "expected 2 arguments"); DST_FIXARITY(args, 2);
if (!dst_seq_view(args.v[0], &t, &len)) return dst_throw(args, "expected tuple/array"); if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
n = dst_tuple_begin(len + 1); n = dst_tuple_begin(len + 1);
memcpy(n + 1, t, sizeof(Dst) * len); memcpy(n + 1, t, sizeof(Dst) * len);
n[0] = args.v[1]; n[0] = args.v[1];
return dst_return(args, dst_wrap_tuple(dst_tuple_end(n))); DST_RETURN_TUPLE(args, dst_tuple_end(n));
} }
static int cfun_append(DstArgs args) { static int cfun_append(DstArgs args) {
const Dst *t; const Dst *t;
int32_t len; int32_t len;
Dst *n; Dst *n;
if (args.n != 2) return dst_throw(args, "expected 2 arguments"); DST_FIXARITY(args, 2);
if (!dst_seq_view(args.v[0], &t, &len)) return dst_throw(args, "expected tuple/array"); if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array");
n = dst_tuple_begin(len + 1); n = dst_tuple_begin(len + 1);
memcpy(n, t, sizeof(Dst) * len); memcpy(n, t, sizeof(Dst) * len);
n[len] = args.v[1]; n[len] = args.v[1];
return dst_return(args, dst_wrap_tuple(dst_tuple_end(n))); DST_RETURN_TUPLE(args, dst_tuple_end(n));
} }
/* Load the tuple module */ /* Load the tuple module */

View File

@ -35,8 +35,8 @@ const char dst_base64[65] =
* mnemonics instead of a bit pattern for type checking */ * mnemonics instead of a bit pattern for type checking */
const char *const dst_type_names[16] = { const char *const dst_type_names[16] = {
":nil", ":nil",
":false", ":boolean",
":true", ":boolean",
":fiber", ":fiber",
":integer", ":integer",
":real", ":real",
@ -209,18 +209,18 @@ int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap)
/* Get actual type name of a value for debugging purposes */ /* Get actual type name of a value for debugging purposes */
static const char *typestr(DstArgs args, int32_t n) { static const char *typestr(DstArgs args, int32_t n) {
DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL; DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL;
return (actual == DST_ABSTRACT) return ((actual == DST_ABSTRACT)
? dst_abstract_type(dst_unwrap_abstract(args.v[n]))->name ? dst_abstract_type(dst_unwrap_abstract(args.v[n]))->name
: dst_type_names[actual]; : dst_type_names[actual]) + 1;
} }
int dst_type_err(DstArgs args, int32_t n, DstType expected) { int dst_type_err(DstArgs args, int32_t n, DstType expected) {
const uint8_t *message = dst_formatc( const uint8_t *message = dst_formatc(
"bad argument #%d, expected %t, got %s", "bad slot #%d, expected %t, got %s",
n, n,
expected, expected,
typestr(args, n)); typestr(args, n));
return dst_throwv(args, dst_wrap_string(message)); DST_THROWV(args, dst_wrap_string(message));
} }
int dst_typemany_err(DstArgs args, int32_t n, int expected) { int dst_typemany_err(DstArgs args, int32_t n, int expected) {
@ -229,7 +229,7 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) {
const uint8_t *message; const uint8_t *message;
DstBuffer buf; DstBuffer buf;
dst_buffer_init(&buf, 20); dst_buffer_init(&buf, 20);
dst_buffer_push_string(&buf, dst_formatc("bad argument #%d, expected ", n)); dst_buffer_push_string(&buf, dst_formatc("bad slot #%d, expected ", n));
i = 0; i = 0;
while (expected) { while (expected) {
if (1 & expected) { if (1 & expected) {
@ -247,19 +247,19 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) {
dst_buffer_push_cstring(&buf, typestr(args, n)); dst_buffer_push_cstring(&buf, typestr(args, n));
message = dst_string(buf.data, buf.count); message = dst_string(buf.data, buf.count);
dst_buffer_deinit(&buf); dst_buffer_deinit(&buf);
return dst_throwv(args, dst_wrap_string(message)); DST_THROWV(args, dst_wrap_string(message));
} }
int dst_arity_err(DstArgs args, int32_t n, const char *prefix) { int dst_arity_err(DstArgs args, int32_t n, const char *prefix) {
return dst_throwv(args, DST_THROWV(args,
dst_wrap_string(dst_formatc( dst_wrap_string(dst_formatc(
"expected %s%d argument%s, got %d", "expected %s%d argument%s, got %d",
prefix, n, n == 1 ? "" : "s", args.n))); prefix, n, n == 1 ? "" : "s", args.n)));
} }
int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at) { int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at) {
return dst_throwv(args, DST_THROWV(args,
dst_wrap_string(dst_formatc( dst_wrap_string(dst_formatc(
"bad argument #%d, expected %s, got %s", "bad slot #%d, expected %s, got %s",
n, at->name, typestr(args, n)))); n, at->name, typestr(args, n))));
} }

View File

@ -224,7 +224,13 @@ static void *op_lookup[255] = {
goto vm_error; goto vm_error;
VM_OP(DOP_TYPECHECK) VM_OP(DOP_TYPECHECK)
vm_assert((1 << dst_type(stack[oparg(1, 0xFF)])) & oparg(2, 0xFFFF), "typecheck failed"); if (!((1 << dst_type(stack[oparg(1, 0xFF)])) & oparg(2, 0xFFFF))) {
DstArgs tempargs;
tempargs.n = oparg(1, 0xFF) + 1;
tempargs.v = stack;
dst_typemany_err(tempargs, oparg(1, 0xFF), oparg(2, 0xFFFF));
goto vm_error;
}
pc++; pc++;
vm_next(); vm_next();
@ -922,7 +928,7 @@ Dst dst_resume(DstFiber *fiber, int32_t argn, const Dst *argv) {
return dst_run(fiber); return dst_run(fiber);
} }
/* Setup functions */ /* Setup VM */
int dst_init() { int dst_init() {
/* Garbage collection */ /* Garbage collection */
dst_vm_blocks = NULL; dst_vm_blocks = NULL;

View File

@ -202,34 +202,36 @@ int dst_arity_err(DstArgs args, int32_t n, const char *prefix);
int dst_type_err(DstArgs args, int32_t n, DstType expected); int dst_type_err(DstArgs args, int32_t n, DstType expected);
int dst_typemany_err(DstArgs args, int32_t n, int expected); int dst_typemany_err(DstArgs args, int32_t n, int expected);
int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at); int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at);
#define dst_throw(a, e) (*((a).ret) = dst_cstringv(e), 1)
#define dst_throwv(a, v) (*((a).ret) = (v), 1) /* Macros */
#define dst_return(a, v) (*((a).ret) = (v), 0) #define DST_THROW(a, e) return (*((a).ret) = dst_cstringv(e), 1)
#define DST_THROWV(a, v) return (*((a).ret) = (v), 1)
#define DST_RETURN(a, v) return (*((a).ret) = (v), 0)
/* Early exit macros */ /* Early exit macros */
#define dst_maxarity(A, N) do { if ((A).n > (N))\ #define DST_MAXARITY(A, N) do { if ((A).n > (N))\
return dst_arity_err(A, N, "at most "); } while (0) return dst_arity_err(A, N, "at most "); } while (0)
#define dst_minarity(A, N) do { if ((A).n < (N))\ #define DST_MINARITY(A, N) do { if ((A).n < (N))\
return dst_arity_err(A, N, "at least "); } while (0) return dst_arity_err(A, N, "at least "); } while (0)
#define dst_fixarity(A, N) do { if ((A).n != (N))\ #define DST_FIXARITY(A, N) do { if ((A).n != (N))\
return dst_arity_err(A, N, ""); } while (0) return dst_arity_err(A, N, ""); } while (0)
#define dst_check(A, N, T) do {\ #define DST_CHECK(A, N, T) do {\
if ((A).n > (N)) {\ if ((A).n > (N)) {\
if (!dst_checktype((A).v[(N)], (T))) return dst_type_err(A, N, T);\ if (!dst_checktype((A).v[(N)], (T))) return dst_type_err(A, N, T);\
} else {\ } else {\
if ((T) != DST_NIL) return dst_type_err(A, N, T);\ if ((T) != DST_NIL) return dst_type_err(A, N, T);\
}\ }\
} while (0) } while (0)
#define dst_checkmany(A, N, TS) do {\ #define DST_CHECKMANY(A, N, TS) do {\
if ((A).n > (N)) {\ if ((A).n > (N)) {\
DstType t = dst_type((A).v[(N)]);\ DstType t = dst_type((A).v[(N)]);\
if (!((1 << t) & (TS))) return dst_typemany_err(A, N, TS);\ if (!((1 << t) & (TS))) return dst_typemany_err(A, N, TS);\
} else {\ } else {\
if (!((TS) & DST_NIL)) return dst_type_err(A, N, TS);\ if (!((TS) & DST_NIL)) return dst_typemany_err(A, N, TS);\
}\ }\
} while (0) } while (0)
#define dst_checkabstract(A, N, AT) do {\ #define DST_CHECKABSTRACT(A, N, AT) do {\
if ((A).n > (N)) {\ if ((A).n > (N)) {\
Dst x = (A).v[(N)];\ Dst x = (A).v[(N)];\
if (!dst_checktype(x, DST_ABSTRACT) ||\ if (!dst_checktype(x, DST_ABSTRACT) ||\
@ -240,42 +242,69 @@ int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at);
}\ }\
} while (0) } while (0)
#define dst_arg_number(DEST, A, N) do { \ #define DST_ARG_NUMBER(DEST, A, N) do { \
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\ if ((A).n <= (N)) \
return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\
Dst val = (A).v[(N)];\ Dst val = (A).v[(N)];\
if (dst_checktype(val, DST_REAL)) { DEST = dst_unwrap_real(val); }\ if (dst_checktype(val, DST_REAL)) { \
else if (dst_checktype(val, DST_INTEGER)) { DEST = (double) dst_unwrap_integer(val); }\ DEST = dst_unwrap_real(val); \
else return dst_typemany_err(A, N, DST_TFLAG_NUMBER); } while (0) } else if (dst_checktype(val, DST_INTEGER)) {\
DEST = (double) dst_unwrap_integer(val);\
}\
else return dst_typemany_err(A, N, DST_TFLAG_NUMBER); \
} while (0)
#define dst_arg_boolean(DEST, A, N) do { \ #define DST_ARG_BOOLEAN(DEST, A, N) do { \
dst_checkmany(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\ DST_CHECKMANY(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\
DEST = dst_unwrap_boolean((A).v[(N)]); } while (0) DEST = dst_unwrap_boolean((A).v[(N)]); \
} while (0)
#define _dst_arg(TYPE, NAME, DEST, A, N) do { \ #define DST_ARG_BYTES(DESTBYTES, DESTLEN, A, N) do {\
dst_check(A, N, TYPE);\
DEST = dst_unwrap_##NAME((A).v[(N)]); } while (0)
#define dst_arg_bytes(DESTBYTES, DESTLEN, A, N) do {\
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\ if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
if (!dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\ if (!dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
return dst_typemany_err(A, N, DST_TFLAG_BYTES);\ return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
}\ }\
} while (0) } while (0)
#define dst_arg_fiber(DEST, A, N) _dst_arg(DST_FIBER, fiber, DEST, A, N) #define _DST_ARG(TYPE, NAME, DEST, A, N) do { \
#define dst_arg_integer(DEST, A, N) _dst_arg(DST_INTEGER, integer, DEST, A, N) DST_CHECK(A, N, TYPE);\
#define dst_arg_real(DEST, A, N) _dst_arg(DST_REAL, real, DEST, A, N) DEST = dst_unwrap_##NAME((A).v[(N)]); \
#define dst_arg_string(DEST, A, N) _dst_arg(DST_STRING, string, DEST, A, N) } while (0)
#define dst_arg_symbol(DEST, A, N) _dst_arg(DST_SYMBOL, symbol, DEST, A, N)
#define dst_arg_array(DEST, A, N) _dst_arg(DST_ARRAY, array, DEST, A, N)
#define dst_arg_tuple(DEST, A, N) _dst_arg(DST_TUPLE, tuple, DEST, A, N)
#define dst_arg_table(DEST, A, N) _dst_arg(DST_TABLE, table, DEST, A, N)
#define dst_arg_struct(DEST, A, N) _dst_arg(DST_STRUCT, st, DEST, A, N)
#define dst_arg_buffer(DEST, A, N) _dst_arg(DST_BUFFER, buffer, DEST, A, N)
#define dst_arg_function(DEST, A, N) _dst_arg(DST_FUNCTION, function, DEST, A, N)
#define dst_arg_cfunction(DEST, A, N) _dst_arg(DST_CFUNCTION, cfunction, DEST, A, N)
#define dst_arg_abstract(DEST, A, N) _dst_arg(DST_ABSTRACT, abstract, DEST, A, N) #define DST_ARG_FIBER(DEST, A, N) _DST_ARG(DST_FIBER, fiber, DEST, A, N)
#define DST_ARG_INTEGER(DEST, A, N) _DST_ARG(DST_INTEGER, integer, DEST, A, N)
#define DST_ARG_REAL(DEST, A, N) _DST_ARG(DST_REAL, real, DEST, A, N)
#define DST_ARG_STRING(DEST, A, N) _DST_ARG(DST_STRING, string, DEST, A, N)
#define DST_ARG_SYMBOL(DEST, A, N) _DST_ARG(DST_SYMBOL, symbol, DEST, A, N)
#define DST_ARG_ARRAY(DEST, A, N) _DST_ARG(DST_ARRAY, array, DEST, A, N)
#define DST_ARG_TUPLE(DEST, A, N) _DST_ARG(DST_TUPLE, tuple, DEST, A, N)
#define DST_ARG_TABLE(DEST, A, N) _DST_ARG(DST_TABLE, table, DEST, A, N)
#define DST_ARG_STRUCT(DEST, A, N) _DST_ARG(DST_STRUCT, st, DEST, A, N)
#define DST_ARG_BUFFER(DEST, A, N) _DST_ARG(DST_BUFFER, buffer, DEST, A, N)
#define DST_ARG_FUNCTION(DEST, A, N) _DST_ARG(DST_FUNCTION, function, DEST, A, N)
#define DST_ARG_CFUNCTION(DEST, A, N) _DST_ARG(DST_CFUNCTION, cfunction, DEST, A, N)
#define DST_ARG_ABSTRACT(DEST, A, N) _DST_ARG(DST_ABSTRACT, abstract, DEST, A, N)
#define DST_RETURN_NIL(A) return 0
#define DST_RETURN_FALSE(A) DST_RETURN(A, dst_wrap_false())
#define DST_RETURN_TRUE(A) DST_RETURN(A, dst_wrap_true())
#define DST_RETURN_BOOLEAN(A, X) DST_RETURN(A, dst_wrap_boolean(X))
#define DST_RETURN_FIBER(A, X) DST_RETURN(A, dst_wrap_fiber(X))
#define DST_RETURN_INTEGER(A, X) DST_RETURN(A, dst_wrap_integer(X))
#define DST_RETURN_REAL(A, X) DST_RETURN(A, dst_wrap_real(X))
#define DST_RETURN_STRING(A, X) DST_RETURN(A, dst_wrap_string(X))
#define DST_RETURN_SYMBOL(A, X) DST_RETURN(A, dst_wrap_symbol(X))
#define DST_RETURN_ARRAY(A, X) DST_RETURN(A, dst_wrap_array(X))
#define DST_RETURN_TUPLE(A, X) DST_RETURN(A, dst_wrap_tuple(X))
#define DST_RETURN_TABLE(A, X) DST_RETURN(A, dst_wrap_table(X))
#define DST_RETURN_STRUCT(A, X) DST_RETURN(A, dst_wrap_struct(X))
#define DST_RETURN_BUFFER(A, X) DST_RETURN(A, dst_wrap_buffer(X))
#define DST_RETURN_FUNCTION(A, X) DST_RETURN(A, dst_wrap_function(X))
#define DST_RETURN_CFUNCTION(A, X) DST_RETURN(A, dst_wrap_cfunction(X))
#define DST_RETURN_ABSTRACT(A, X) DST_RETURN(A, dst_wrap_abstract(X))
#define DST_RETURN_CSTRING(A, X) DST_RETURN(A, dst_cstringv(X))
#define DST_RETURN_CSYMBOL(A, X) DST_RETURN(A, dst_csymbolv(X))
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,13 +24,13 @@
/* Common */ /* Common */
int dst_line_getter(DstArgs args) { int dst_line_getter(DstArgs args) {
dst_fixarity(args, 2); DST_FIXARITY(args, 2);
dst_check(args, 0, DST_STRING); DST_CHECK(args, 0, DST_STRING);
dst_check(args, 1, DST_BUFFER); DST_CHECK(args, 1, DST_BUFFER);
dst_line_get( dst_line_get(
dst_unwrap_string(args.v[0]), dst_unwrap_string(args.v[0]),
dst_unwrap_buffer(args.v[1])); dst_unwrap_buffer(args.v[1]));
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static void simpleline(DstBuffer *buffer) { static void simpleline(DstBuffer *buffer) {

View File

@ -32,7 +32,7 @@ static int dst_ast_gcmark(void *p, size_t size) {
/* AST type */ /* AST type */
static DstAbstractType dst_ast_type = { static DstAbstractType dst_ast_type = {
":parse.ast", ":parser.ast",
NULL, NULL,
dst_ast_gcmark dst_ast_gcmark
}; };

View File

@ -447,6 +447,7 @@ static int ampersand(DstParser *p, DstParseState *state, uint8_t c) {
return 0; return 0;
} }
/* The root state of the parser */
static int root(DstParser *p, DstParseState *state, uint8_t c) { static int root(DstParser *p, DstParseState *state, uint8_t c) {
switch (c) { switch (c) {
default: default:
@ -575,43 +576,21 @@ static int parsergc(void *p, size_t size) {
} }
DstAbstractType dst_parse_parsertype = { DstAbstractType dst_parse_parsertype = {
":parse.parser", ":parser.parser",
parsergc, parsergc,
parsermark parsermark
}; };
/* C Function parser */ /* C Function parser */
static int cfun_parser(DstArgs args) { static int cfun_parser(DstArgs args) {
int flags; int flags = 0;
if (args.n > 1) return dst_throw(args, "expected 1 argument"); DST_MAXARITY(args, 1);
if (args.n) { if (args.n == 1) {
if (!dst_checktype(args.v[0], DST_INTEGER)) return dst_throw(args, "expected integer"); DST_ARG_INTEGER(flags, args, 0);
flags = dst_unwrap_integer(args.v[0]);
} else {
flags = 0;
} }
DstParser *p = dst_abstract(&dst_parse_parsertype, sizeof(DstParser)); DstParser *p = dst_abstract(&dst_parse_parsertype, sizeof(DstParser));
dst_parser_init(p, flags); dst_parser_init(p, flags);
return dst_return(args, dst_wrap_abstract(p)); DST_RETURN_ABSTRACT(args, p);
}
/* Check file argument */
static DstParser *checkparser(DstArgs args) {
DstParser *p;
if (args.n == 0) {
*args.ret = dst_cstringv("expected parse.parser");
return NULL;
}
if (!dst_checktype(args.v[0], DST_ABSTRACT)) {
*args.ret = dst_cstringv("expected parse.parser");
return NULL;
}
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
if (dst_abstract_type(p) != &dst_parse_parsertype) {
*args.ret = dst_cstringv("expected parse.parser");
return NULL;
}
return p;
} }
static int cfun_consume(DstArgs args) { static int cfun_consume(DstArgs args) {
@ -619,10 +598,10 @@ static int cfun_consume(DstArgs args) {
int32_t len; int32_t len;
DstParser *p; DstParser *p;
int32_t i; int32_t i;
if (args.n != 2) return dst_throw(args, "expected 2 arguments"); DST_FIXARITY(args, 2);
p = checkparser(args); DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
if (!p) return 1; p = (DstParser *) dst_unwrap_abstract(args.v[0]);
if (!dst_chararray_view(args.v[1], &bytes, &len)) return dst_throw(args, "expected string/buffer"); DST_ARG_BYTES(bytes, len, args, 1);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
dst_parser_consume(p, bytes[i]); dst_parser_consume(p, bytes[i]);
switch (dst_parser_status(p)) { switch (dst_parser_status(p)) {
@ -633,27 +612,30 @@ static int cfun_consume(DstArgs args) {
{ {
DstBuffer *b = dst_buffer(len - i); DstBuffer *b = dst_buffer(len - i);
dst_buffer_push_bytes(b, bytes + i + 1, len - i - 1); dst_buffer_push_bytes(b, bytes + i + 1, len - i - 1);
return dst_return(args, dst_wrap_buffer(b)); DST_RETURN_BUFFER(args, b);
} }
} }
} }
return dst_return(args, dst_wrap_nil()); DST_RETURN(args, dst_wrap_nil());
} }
static int cfun_byte(DstArgs args) { static int cfun_byte(DstArgs args) {
int32_t i;
DstParser *p; DstParser *p;
if (args.n != 2) return dst_throw(args, "expected 2 arguments"); DST_FIXARITY(args, 2);
p = checkparser(args); DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
if (!p) return 1; p = (DstParser *) dst_unwrap_abstract(args.v[0]);
if (!dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected integer"); DST_ARG_INTEGER(i, args, 1);
dst_parser_consume(p, 0xFF & dst_unwrap_integer(args.v[1])); dst_parser_consume(p, 0xFF & i);
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_status(DstArgs args) { static int cfun_status(DstArgs args) {
const char *stat = NULL; const char *stat = NULL;
DstParser *p = checkparser(args); DstParser *p;
if (!p) return 1; DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
switch (dst_parser_status(p)) { switch (dst_parser_status(p)) {
case DST_PARSE_FULL: case DST_PARSE_FULL:
stat = ":full"; stat = ":full";
@ -668,42 +650,50 @@ static int cfun_status(DstArgs args) {
stat = ":root"; stat = ":root";
break; break;
} }
return dst_return(args, dst_csymbolv(stat)); DST_RETURN_CSYMBOL(args, stat);
} }
static int cfun_error(DstArgs args) { static int cfun_error(DstArgs args) {
const char *err; const char *err;
DstParser *p = checkparser(args); DstParser *p;
if (!p) return 1; DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
err = dst_parser_error(p); err = dst_parser_error(p);
if (err) { if (err) {
return dst_return(args, dst_cstringv(err)); DST_RETURN_CSYMBOL(args, err);
} else { } else {
return dst_return(args, dst_wrap_nil()); DST_RETURN_NIL(args);
} }
} }
static int cfun_produce(DstArgs args) { static int cfun_produce(DstArgs args) {
Dst val; Dst val;
DstParser *p = checkparser(args); DstParser *p;
if (!p) return 1; DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
val = dst_parser_produce(p); val = dst_parser_produce(p);
return dst_return(args, val); DST_RETURN(args, val);
} }
static int cfun_flush(DstArgs args) { static int cfun_flush(DstArgs args) {
DstParser *p = checkparser(args); DstParser *p;
if (!p) return 1; DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
dst_parser_flush(p); dst_parser_flush(p);
return dst_return(args, args.v[0]); DST_RETURN(args, args.v[0]);
} }
static int cfun_state(DstArgs args) { static int cfun_state(DstArgs args) {
int32_t i; int32_t i;
uint8_t *buf = NULL; uint8_t *buf = NULL;
const uint8_t *str; const uint8_t *str;
DstParser *p = checkparser(args); DstParser *p;
if (!p) return 1; DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
for (i = 0; i < dst_v_count(p->states); i++) { for (i = 0; i < dst_v_count(p->states); i++) {
DstParseState *s = p->states + i; DstParseState *s = p->states + i;
if (s->flags & PFLAG_PARENS) { if (s->flags & PFLAG_PARENS) {
@ -723,30 +713,30 @@ static int cfun_state(DstArgs args) {
} }
str = dst_string(buf, dst_v_count(buf)); str = dst_string(buf, dst_v_count(buf));
dst_v_free(buf); dst_v_free(buf);
return dst_return(args, dst_wrap_string(str)); DST_RETURN_STRING(args, str);
} }
/* AST */ /* AST */
static int cfun_unwrap1(DstArgs args) { static int cfun_unwrap1(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected 1 argument"); DST_FIXARITY(args, 1);
return dst_return(args, dst_ast_unwrap1(args.v[0])); DST_RETURN(args, dst_ast_unwrap1(args.v[0]));
} }
static int cfun_unwrap(DstArgs args) { static int cfun_unwrap(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected 1 argument"); DST_FIXARITY(args, 1);
return dst_return(args, dst_ast_unwrap(args.v[0])); DST_RETURN(args, dst_ast_unwrap(args.v[0]));
} }
static int cfun_wrap(DstArgs args) { static int cfun_wrap(DstArgs args) {
if (args.n != 1) return dst_throw(args, "expected 1 argument"); DST_FIXARITY(args, 1);
return dst_return(args, dst_ast_wrap(args.v[0], -1, -1)); DST_RETURN(args, dst_ast_wrap(args.v[0], -1, -1));
} }
static int cfun_node(DstArgs args) { static int cfun_node(DstArgs args) {
DstAst *ast; DstAst *ast;
Dst *tup; Dst *tup;
int32_t start, end; int32_t start, end;
if (args.n != 1) return dst_throw(args, "expected 1 argument"); DST_FIXARITY(args, 1);
ast = dst_ast_node(args.v[0]); ast = dst_ast_node(args.v[0]);
if (ast) { if (ast) {
start = ast->source_start; start = ast->source_start;
@ -758,7 +748,7 @@ static int cfun_node(DstArgs args) {
tup = dst_tuple_begin(2); tup = dst_tuple_begin(2);
tup[0] = dst_wrap_integer(start); tup[0] = dst_wrap_integer(start);
tup[1] = dst_wrap_integer(end); tup[1] = dst_wrap_integer(end);
return dst_return(args, dst_wrap_tuple(dst_tuple_end(tup))); DST_RETURN_TUPLE(args, dst_tuple_end(tup));
} }
static const DstReg cfuns[] = { static const DstReg cfuns[] = {