1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-16 10:19:55 +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;
const uint8_t *filename;
int status;
dst_fixarity(args, 1);
dst_arg_string(filename, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_STRING(filename, args, 0);
conn = (sqlite3 **) dst_abstract(&sql_conn_type, sizeof(sqlite3 *));
status = sqlite3_open((const char *)filename, conn);
if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_abstract(conn));
DST_RETURN_ABSTRACT(args, conn);
} else {
const char *err = sqlite3_errmsg(*conn);
return dst_throw(args, err);
DST_THROW(args, err);
}
}
static int sql_close(DstArgs args) {
sqlite3 **conn;
int status;
dst_fixarity(args, 1);
dst_checkabstract(args, 0, &sql_conn_type);
DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &sql_conn_type);
conn = (sqlite3 **)dst_unwrap_abstract(args.v[0]);
status = sqlite3_close_v2(*conn);
if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_nil());
DST_RETURN_NIL(args);
} 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,
&errmsg);
if (status == SQLITE_OK) {
return dst_return(args, dst_wrap_array(rows));
DST_RETURN_ARRAY(args, rows);
} else {
return dst_throw(args, errmsg);
DST_THROW(args, errmsg);
}
}

View File

@ -148,26 +148,35 @@ static const DstInstructionDef dst_ops[] = {
{"yield", DOP_YIELD}
};
/* Check a dst string against a bunch of test_strings. Return the
* index of the matching test_string, or -1 if not found. */
static int32_t strsearch(const uint8_t *str, const char *const *test_strings) {
int32_t len = dst_string_length(str);
int index;
for (index = 0; ; index++) {
int32_t i;
const char *testword = test_strings[index];
if (NULL == testword)
break;
for (i = 0; i < len; i++) {
if (testword[i] != str[i])
goto nextword;
}
return index;
nextword:
continue;
}
return -1;
}
/* Typename aliases for tchck instruction */
typedef struct TypeAlias {
const char *name;
int32_t mask;
} TypeAlias;
static const TypeAlias type_aliases[] = {
{":abstract", DST_TFLAG_ABSTRACT},
{":array", DST_TFLAG_ARRAY},
{":boolean", DST_TFLAG_BOOLEAN},
{":buffer", DST_TFLAG_BUFFER},
{":callable", DST_TFLAG_CALLABLE},
{":cfunction", DST_TFLAG_CFUNCTION},
{":dictionary", DST_TFLAG_DICTIONARY},
{":false", DST_TFLAG_FALSE},
{":fiber", DST_TFLAG_FIBER},
{":function", DST_TFLAG_FUNCTION},
{":indexed", DST_TFLAG_INDEXED},
{":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. */
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));
}
} else if (argtype == DST_OAT_TYPE || argtype == DST_OAT_SIMPLETYPE) {
int32_t index = strsearch(dst_unwrap_symbol(x), dst_type_names);
if (index != -1) {
ret = index;
const TypeAlias *alias = dst_strbinsearch(
&type_aliases,
sizeof(type_aliases)/sizeof(TypeAlias),
sizeof(TypeAlias),
dst_unwrap_symbol(x));
if (alias) {
ret = alias->mask;
} else {
dst_asm_errorv(a, dst_formatc("unknown type %q", x));
}
@ -890,21 +903,20 @@ Dst dst_disasm(DstFuncDef *def) {
/* C Function for assembly */
int dst_asm_cfun(DstArgs args) {
DstAssembleResult res;
if (args.n < 1) return dst_throw(args, "expected assembly source");
DST_FIXARITY(args, 1);
res = dst_asm(args.v[0], 0);
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 {
return dst_throwv(args, dst_wrap_string(res.error));
DST_THROWV(args, dst_wrap_string(res.error));
}
}
int dst_disasm_cfun(DstArgs args) {
DstFunction *f;
if (args.n < 1 || !dst_checktype(args.v[0], DST_FUNCTION))
return dst_throw(args, "expected function");
f = dst_unwrap_function(args.v[0]);
return dst_return(args, dst_disasm(f->def));
DST_FIXARITY(args, 1);
DST_ARG_FUNCTION(f, args, 0);
DST_RETURN(args, dst_disasm(f->def));
}
static const DstReg cfuns[] = {

View File

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

View File

@ -996,20 +996,17 @@ int dst_compile_cfun(DstArgs args) {
DstCompileResult res;
DstTable *t;
DstTable *env;
if (args.n < 2)
return dst_throw(args, "expected at least 2 arguments");
if (!dst_checktype(args.v[1], DST_TABLE)) return dst_throw(args, "expected table as environment");
env = dst_unwrap_table(args.v[1]);
DST_FIXARITY(args, 2);
DST_ARG_TABLE(env, args, 1);
res = dst_compile(args.v[0], env, 0);
if (res.status == DST_COMPILE_OK) {
DstFunction *fun = dst_thunk(res.funcdef);
return dst_return(args, dst_wrap_function(fun));
DST_RETURN_FUNCTION(args, dst_thunk(res.funcdef));
} else {
t = dst_table(2);
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-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) {
int32_t cap;
DstArray *array;
dst_fixarity(args, 1);
dst_arg_integer(cap, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_INTEGER(cap, args, 0);
array = dst_array(cap);
return dst_return(args, dst_wrap_array(array));
DST_RETURN_ARRAY(args, array);
}
static int cfun_pop(DstArgs args) {
dst_fixarity(args, 1);
dst_check(args, 0, DST_ARRAY);
return dst_return(args, dst_array_pop(dst_unwrap_array(args.v[0])));
DstArray *array;
DST_FIXARITY(args, 1);
DST_ARG_ARRAY(array, args, 0);
DST_RETURN(args, dst_array_pop(array));
}
static int cfun_peek(DstArgs args) {
dst_fixarity(args, 1);
dst_check(args, 0, DST_ARRAY);
return dst_return(args, dst_array_peek(dst_unwrap_array(args.v[0])));
DstArray *array;
DST_FIXARITY(args, 1);
DST_ARG_ARRAY(array, args, 0);
DST_RETURN(args, dst_array_peek(array));
}
static int cfun_push(DstArgs args) {
DstArray *array;
int32_t newcount;
dst_minarity(args, 1);
dst_check(args, 0, DST_ARRAY);
array = dst_unwrap_array(args.v[0]);
DST_MINARITY(args, 1);
DST_ARG_ARRAY(array, args, 0);
newcount = array->count - 1 + args.n;
dst_array_ensure(array, newcount);
if (args.n > 1) memcpy(array->data + array->count, args.v + 1, (args.n - 1) * sizeof(Dst));
array->count = newcount;
return dst_return(args, args.v[0]);
DST_RETURN(args, args.v[0]);
}
static int cfun_setcount(DstArgs args) {
DstArray *array;
int32_t newcount;
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);
return dst_return(args, args.v[0]);
DST_FIXARITY(args, 2);
DST_ARG_ARRAY(array, args, 0);
DST_ARG_INTEGER(newcount, args, 1);
if (newcount < 0) DST_THROW(args, "expected positive integer");
dst_array_setcount(array, newcount);
DST_RETURN(args, args.v[0]);
}
static int cfun_ensure(DstArgs args) {
DstArray *array;
int32_t newcount;
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);
return dst_return(args, args.v[0]);
DST_FIXARITY(args, 2);
DST_ARG_ARRAY(array, args, 0);
DST_ARG_INTEGER(newcount, args, 1);
if (newcount < 0) DST_THROW(args, "expected positive integer");
dst_array_ensure(array, newcount);
DST_RETURN(args, args.v[0]);
}
static int cfun_slice(DstArgs args) {
@ -166,17 +167,17 @@ static int cfun_slice(DstArgs args) {
int32_t len;
DstArray *ret;
int32_t start, end;
dst_minarity(args, 1);
dst_maxarity(args, 3);
DST_MINARITY(args, 1);
DST_MAXARITY(args, 3);
if (!dst_seq_view(args.v[0], &vals, &len))
return dst_throw(args, "expected array|tuple");
DST_THROW(args, "expected array|tuple");
/* Get start */
if (args.n < 2) {
start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
/* Get end */
if (args.n < 3) {
@ -184,7 +185,7 @@ static int cfun_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
@ -198,15 +199,14 @@ static int cfun_slice(DstArgs args) {
} else {
ret = dst_array(0);
}
return dst_return(args, dst_wrap_array(ret));
DST_RETURN_ARRAY(args, ret);
}
static int cfun_concat(DstArgs args) {
int32_t i;
DstArray *array;
dst_minarity(args, 1);
dst_check(args, 0, DST_ARRAY);
array = dst_unwrap_array(args.v[0]);
DST_MINARITY(args, 1);
DST_ARG_ARRAY(array, args, 0);
for (i = 1; i < args.n; i++) {
switch (dst_type(args.v[i])) {
default:
@ -224,7 +224,7 @@ static int cfun_concat(DstArgs args) {
break;
}
}
return dst_return(args, args.v[0]);
DST_RETURN_ARRAY(args, array);
}
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) {
int32_t cap;
DstBuffer *buffer;
dst_fixarity(args, 1);
dst_arg_integer(cap, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_INTEGER(cap, args, 0);
buffer = dst_buffer(cap);
return dst_return(args, dst_wrap_buffer(buffer));
DST_RETURN_BUFFER(args, buffer);
}
static int cfun_u8(DstArgs args) {
int32_t i;
DstBuffer *buffer;
dst_minarity(args, 1);
dst_arg_buffer(buffer, args, 0);
DST_MINARITY(args, 1);
DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
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)))
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) {
int32_t i;
DstBuffer *buffer;
dst_minarity(args, 1);
dst_arg_buffer(buffer, args, 0);
DST_MINARITY(args, 1);
DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
int32_t integer;
dst_arg_integer(integer, args, i);
DST_ARG_INTEGER(integer, args, i);
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) {
int32_t i;
DstBuffer *buffer;
dst_minarity(args, 1);
dst_arg_buffer(buffer, args, 0);
DST_MINARITY(args, 1);
DST_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
int32_t len;
const uint8_t *str;
if (!dst_chararray_view(args.v[i], &str, &len))
return dst_throw(args, "expected string|symbol|buffer");
DST_ARG_BYTES(str, len, args, i);
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) {
DstBuffer *buffer;
dst_fixarity(args, 1);
dst_arg_buffer(buffer, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_BUFFER(buffer, args, 0);
buffer->count = 0;
return dst_return(args, args.v[0]);
DST_RETURN(args, args.v[0]);
}
static int cfun_popn(DstArgs args) {
DstBuffer *buffer;
int32_t n;
dst_fixarity(args, 2);
dst_arg_buffer(buffer, args, 0);
dst_arg_integer(n, args, 1);
DST_FIXARITY(args, 2);
DST_ARG_BUFFER(buffer, args, 0);
DST_ARG_INTEGER(n, args, 1);
if (buffer->count < n) {
buffer->count = 0;
} else {
buffer->count -= n;
}
return dst_return(args, args.v[0]);
DST_RETURN(args, args.v[0]);
}
static int cfun_slice(DstArgs args) {
const uint8_t *data;
int32_t len, start, end;
DstBuffer *ret;
if (args.n < 1 || !dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected buffer/string");
DST_ARG_BYTES(data, len, args, 0);
/* Get start */
if (args.n < 2) {
start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
/* Get end */
if (args.n < 3) {
@ -253,7 +251,7 @@ static int cfun_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
@ -264,7 +262,7 @@ static int cfun_slice(DstArgs args) {
} else {
ret = dst_buffer(0);
}
return dst_return(args, dst_wrap_buffer(ret));
DST_RETURN_BUFFER(args, ret);
}
static const DstReg cfuns[] = {

View File

@ -35,7 +35,7 @@ int dst_core_print(DstArgs args) {
}
}
putc('\n', stdout);
return 0;
DST_RETURN_NIL();
}
int dst_core_describe(DstArgs args) {
@ -92,15 +92,15 @@ int dst_core_buffer(DstArgs args) {
len = dst_string_length(str);
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) {
const uint8_t *format;
int32_t i, len, n;
DstBuffer buf;
dst_minarity(args, 1);
dst_arg_bytes(format, len, args, 0);
DST_MINARITY(args, 1);
DST_ARG_BYTES(format, len, args, 0);
n = 1;
dst_buffer_init(&buf, len);
for (i = 0; i < len; i++) {
@ -128,33 +128,33 @@ int dst_core_format(DstArgs args) {
return 0;
noarg:
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) {
const uint8_t *data;
Dst x;
int32_t len;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_BYTES(data, len, args, 0);
x = dst_scan_number(data, len);
if (!dst_checktype(x, DST_INTEGER) && !dst_checktype(x, DST_REAL)) {
return dst_throw(args, "error parsing number");
if (dst_checktype(x, DST_NIL)) {
DST_THROW(args, "error parsing number");
}
return dst_return(args, x);
DST_RETURN(args, x);
}
int dst_core_scaninteger(DstArgs args) {
const uint8_t *data;
int32_t len, ret;
int err = 0;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_BYTES(data, len, args, 0);
ret = dst_scan_integer(data, len, &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) {
@ -162,78 +162,82 @@ int dst_core_scanreal(DstArgs args) {
int32_t len;
double ret;
int err = 0;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
DST_FIXARITY(args, 1);
DST_ARG_BYTES(data, len, args, 0);
ret = dst_scan_real(data, len, &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) {
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) {
DstArray *array = dst_array(args.n);
array->count = args.n;
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) {
int32_t i;
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) {
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) {
int32_t i;
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) {
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) {
dst_maxarity(args, 1);
DST_MAXARITY(args, 1);
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 {
const uint8_t *s = dst_to_string(args.v[0]);
return dst_return(args, dst_wrap_symbol(dst_symbol_gen(s, dst_string_length(s))));
const uint8_t *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) {
dst_fixarity(args, 1);
return dst_return(args, dst_wrap_integer(dst_length(args.v[0])));
DST_FIXARITY(args, 1);
DST_RETURN_INTEGER(args, dst_length(args.v[0]));
}
int dst_core_get(DstArgs args) {
int32_t i;
Dst ds;
dst_minarity(args, 1);
DST_MINARITY(args, 1);
ds = args.v[0];
for (i = 1; i < args.n; i++) {
ds = dst_get(ds, args.v[i]);
if (dst_checktype(ds, DST_NIL))
break;
}
return dst_return(args, ds);
DST_RETURN(args, ds);
}
int dst_core_put(DstArgs args) {
Dst ds, key, value;
DstArgs subargs = args;
dst_minarity(args, 3);
DST_MINARITY(args, 3);
subargs.n -= 2;
if (dst_core_get(subargs)) return 1;
ds = *args.ret;
@ -251,34 +255,33 @@ int dst_core_gccollect(DstArgs args) {
int dst_core_gcsetinterval(DstArgs args) {
int32_t val;
dst_fixarity(args, 1);
dst_check(args, 0, DST_INTEGER);
val = dst_unwrap_integer(args.v[0]);
DST_FIXARITY(args, 1);
DST_ARG_INTEGER(val, args, 0);
if (val < 0)
return dst_throw(args, "expected non-negative integer");
DST_THROW(args, "expected non-negative integer");
dst_vm_gc_interval = val;
return dst_return(args, args.v[0]);
DST_RETURN_NIL(args);
}
int dst_core_gcinterval(DstArgs args) {
dst_fixarity(args, 0);
return dst_return(args, dst_wrap_integer(dst_vm_gc_interval));
DST_FIXARITY(args, 0);
DST_RETURN_INTEGER(args, dst_vm_gc_interval);
}
int dst_core_type(DstArgs args) {
dst_fixarity(args, 1);
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));
DST_RETURN(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name));
} 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) {
Dst ds;
const DstKV *kv;
dst_fixarity(args, 2);
dst_checkmany(args, 0, DST_TFLAG_DICTIONARY);
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);
@ -293,31 +296,30 @@ int dst_core_next(DstArgs args) {
}
kv = dst_next(ds, 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) {
dst_fixarity(args, 1);
return dst_return(args, dst_wrap_integer(dst_hash(args.v[0])));
DST_FIXARITY(args, 1);
DST_RETURN_INTEGER(args, dst_hash(args.v[0]));
}
int dst_core_string_slice(DstArgs args) {
const uint8_t *data;
int32_t len, start, end;
const uint8_t *ret;
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");
DST_MINARITY(args, 1);
DST_MAXARITY(args, 3);
DST_ARG_BYTES(data, len, args, 0);
/* Get start */
if (args.n < 2) {
start = 0;
} else if (dst_checktype(args.v[1], DST_INTEGER)) {
start = dst_unwrap_integer(args.v[1]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
/* Get end */
if (args.n < 3) {
@ -325,7 +327,7 @@ int dst_core_string_slice(DstArgs args) {
} else if (dst_checktype(args.v[2], DST_INTEGER)) {
end = dst_unwrap_integer(args.v[2]);
} else {
return dst_throw(args, "expected integer");
DST_THROW(args, "expected integer");
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
@ -334,5 +336,5 @@ int dst_core_string_slice(DstArgs args) {
} else {
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) {
DstFiber *fiber;
dst_minarity(args, 1);
dst_maxarity(args, 2);
dst_check(args, 0, DST_FUNCTION);
fiber = dst_fiber(dst_unwrap_function(args.v[0]), 64);
DstFunction *func;
DST_MINARITY(args, 1);
DST_MAXARITY(args, 2);
DST_ARG_FUNCTION(func, args, 0);
fiber = dst_fiber(func, 64);
if (args.n == 2) {
const uint8_t *flags;
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;
for (i = 0; i < len; i++) {
switch (flags[i]) {
default:
return dst_throw(args, "invalid flag, expected d, e, or y");
DST_THROW(args, "invalid flag, expected d, e, or y");
case ':':
break;
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) {
DstFiber *fiber;
const char *status = "";
dst_fixarity(args, 1);
dst_check(args, 0, DST_FIBER);
switch(dst_unwrap_fiber(args.v[0])->status) {
DST_FIXARITY(args, 1);
DST_ARG_FIBER(fiber, args, 0);
switch(fiber->status) {
case DST_FIBER_PENDING:
status = ":pending";
break;
@ -314,7 +316,7 @@ static int cfun_status(DstArgs args) {
status = ":debug";
break;
}
return dst_return(args, dst_csymbolv(status));
DST_RETURN_CSYMBOL(args, status);
}
/* Extract info from one stack frame */
@ -354,9 +356,8 @@ static Dst doframe(DstStackFrame *frame) {
static int cfun_stack(DstArgs args) {
DstFiber *fiber;
DstArray *array;
dst_fixarity(args, 1);
dst_check(args, 0, DST_FIBER);
fiber = dst_unwrap_fiber(args.v[0]);
DST_FIXARITY(args, 1);
DST_ARG_FIBER(fiber, args, 0);
array = dst_array(0);
{
int32_t i = fiber->frame;
@ -367,26 +368,25 @@ static int cfun_stack(DstArgs args) {
i = frame->prevframe;
}
}
return dst_return(args, dst_wrap_array(array));
DST_RETURN_ARRAY(args, array);
}
static int cfun_current(DstArgs args) {
dst_fixarity(args, 0);
return dst_return(args, dst_wrap_fiber(dst_vm_fiber));
DST_FIXARITY(args, 0);
DST_RETURN_FIBER(args, dst_vm_fiber);
}
static int cfun_lineage(DstArgs args) {
DstFiber *fiber;
DstArray *array;
dst_fixarity(args, 1);
dst_check(args, 0, DST_FIBER);
fiber = dst_unwrap_fiber(args.v[0]);
DST_FIXARITY(args, 1);
DST_ARG_FIBER(fiber, args, 0);
array = dst_array(0);
while (fiber) {
dst_array_push(array, dst_wrap_fiber(fiber));
fiber = fiber->child;
}
return dst_return(args, dst_wrap_array(array));
DST_RETURN_ARRAY(args, array);
}
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]);
}
/* 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) {
IOFile *iof = (IOFile *) dst_abstract(&dst_io_filetype, sizeof(IOFile));
iof->file = f;
@ -143,14 +130,13 @@ static int dst_io_popen(DstArgs args) {
int32_t modelen;
FILE *f;
int flags;
dst_minarity(args, 1);
dst_maxarity(args, 2);
dst_check(args, 0, DST_STRING);
fname = dst_unwrap_string(args.v[0]);
DST_MINARITY(args, 1);
DST_MAXARITY(args, 2);
DST_ARG_STRING(fname, args, 0);
if (args.n == 2) {
if (!dst_checktype(args.v[1], DST_STRING) &&
!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]);
modelen = dst_string_length(fmode);
} else {
@ -162,7 +148,7 @@ static int dst_io_popen(DstArgs args) {
modelen--;
}
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;
#ifdef DST_WINDOWS
@ -172,11 +158,11 @@ static int dst_io_popen(DstArgs args) {
#endif
if (!f) {
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. */
@ -185,14 +171,13 @@ static int dst_io_fopen(DstArgs args) {
int32_t modelen;
FILE *f;
int flags;
dst_minarity(args, 1);
dst_maxarity(args, 2);
dst_check(args, 0, DST_STRING);
fname = dst_unwrap_string(args.v[0]);
DST_MINARITY(args, 1);
DST_MAXARITY(args, 2);
DST_ARG_STRING(fname, args, 0);
if (args.n == 2) {
if (!dst_checktype(args.v[1], DST_STRING) &&
!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]);
modelen = dst_string_length(fmode);
} else {
@ -203,10 +188,12 @@ static int dst_io_fopen(DstArgs args) {
fmode++;
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);
if (!f) return dst_throw(args, "could not open file");
return dst_return(args, makef(f, flags));
if (!f) DST_THROW(args, "could not open file");
DST_RETURN(args, makef(f, flags));
}
/* Read a certain number of bytes into memory */
@ -217,7 +204,7 @@ static int dst_io_fread(DstArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed");
DST_THROW(args, "file is closed");
b = checkbuffer(args, 2, 1);
if (!b) return 1;
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);
fsize = ftell(iof->file);
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;
/* Fall through to normal code */
} else if (!dst_cstrcmp(sym, ":line")) {
for (;;) {
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;
}
return dst_return(args, dst_wrap_buffer(b));
DST_RETURN(args, dst_wrap_buffer(b));
} 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)) {
return dst_throw(args, "expected positive integer");
DST_THROW(args, "expected positive integer");
} else {
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 */
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;
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;
return dst_return(args, dst_wrap_buffer(b));
DST_RETURN(args, dst_wrap_buffer(b));
}
/* Write bytes to a file */
@ -264,16 +252,19 @@ static int dst_io_fwrite(DstArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
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)))
return dst_throw(args, "file is not writeable");
DST_THROW(args, "file is not writeable");
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 (!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 */
@ -281,11 +272,11 @@ static int dst_io_fflush(DstArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
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)))
return dst_throw(args, "file is not flushable");
if (fflush(iof->file)) return dst_throw(args, "could not flush file");
return dst_return(args, dst_wrap_abstract(iof));
DST_THROW(args, "file is not flushable");
if (fflush(iof->file)) DST_THROW(args, "could not flush file");
DST_RETURN(args, dst_wrap_abstract(iof));
}
/* Cleanup a file */
@ -303,20 +294,20 @@ static int dst_io_fclose(DstArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & (IO_CLOSED))
return dst_throw(args, "file already closed");
DST_THROW(args, "file already closed");
if (iof->flags & (IO_NOT_CLOSEABLE))
return dst_throw(args, "file not closable");
DST_THROW(args, "file not closable");
if (iof->flags & IO_PIPED) {
#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
if (pclose(iof->file)) return dst_throw(args, "could not close file");
if (pclose(iof->file)) DST_THROW(args, "could not close file");
#endif
} 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;
return dst_return(args, dst_wrap_abstract(iof));
DST_RETURN(args, dst_wrap_abstract(iof));
}
/* Seek a file */
@ -326,11 +317,11 @@ static int dst_io_fseek(DstArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & IO_CLOSED)
return dst_throw(args, "file is closed");
DST_THROW(args, "file is closed");
if (args.n >= 2) {
const uint8_t *whence_sym;
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]);
if (!dst_cstrcmp(whence_sym, ":cur")) {
whence = SEEK_CUR;
@ -339,17 +330,17 @@ static int dst_io_fseek(DstArgs args) {
} else if (!dst_cstrcmp(whence_sym, ":end")) {
whence = SEEK_END;
} 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 (!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]);
}
}
if (fseek(iof->file, offset, whence))
return dst_throw(args, "error seeking file");
return dst_return(args, args.v[0]);
DST_THROW(args, "error seeking file");
DST_RETURN(args, args.v[0]);
}
static const DstReg cfuns[] = {

View File

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

View File

@ -64,19 +64,12 @@ DstCFunction dst_native(const char *name, const uint8_t **error) {
int dst_core_native(DstArgs args) {
DstCFunction init;
const uint8_t *error = NULL;
if (args.n < 1) {
*args.ret = dst_cstringv("expected at least one argument");
return 1;
}
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);
const uint8_t *path = NULL;
DST_FIXARITY(args, 1);
DST_ARG_STRING(path, args, 0);
init = dst_native((const char *)path, &error);
if (!init) {
*args.ret = dst_wrap_string(error);
return 1;
DST_THROWV(args, dst_wrap_string(error));
}
*args.ret = dst_wrap_cfunction(init);
return 0;
DST_RETURN_CFUNCTION(args, init);
}

View File

@ -23,6 +23,13 @@
#include <dst/dst.h>
#include <stdlib.h>
#include <time.h>
#ifdef DST_WINDOWS
#include <Windows.h>
#else
#include <unistd.h>
#endif
static int os_execute(DstArgs args) {
int nofirstarg = (args.n < 1 || !dst_checktype(args.v[0], DST_STRING));
@ -30,28 +37,28 @@ static int os_execute(DstArgs args) {
? NULL
: (const char *) dst_unwrap_string(args.v[0]);
int stat = system(cmd);
return dst_return(args, cmd
DST_RETURN(args, cmd
? dst_wrap_integer(stat)
: dst_wrap_boolean(stat));
}
static int os_getenv(DstArgs args) {
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 *res = getenv(cstr);
return dst_return(args, cstr
DST_RETURN(args, cstr
? dst_cstringv(res)
: dst_wrap_nil());
}
static int os_setenv(DstArgs args) {
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]);
if (!dst_checktype(args.v[0], DST_STRING)
|| (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]);
#ifdef DST_WINDOWS
if (t2 == DST_NIL) {
@ -73,16 +80,39 @@ static int os_setenv(DstArgs args) {
}
static int os_exit(DstArgs args) {
if (args.n == 0) {
exit(EXIT_SUCCESS);
} else if (dst_checktype(args.v[0], DST_TRUE)
|| dst_checktype(args.v[0], DST_FALSE)) {
exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE);
return 0;
} else {
exit(dst_hash(args.v[0]));
}
return 0;
DST_MAXARITY(args, 1);
if (args.n == 0) {
exit(EXIT_SUCCESS);
} else if (dst_checktype(args.v[0], DST_TRUE)
|| dst_checktype(args.v[0], DST_FALSE)) {
exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE);
return 0;
} else {
exit(dst_hash(args.v[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[] = {
@ -90,6 +120,8 @@ static const DstReg cfuns[] = {
{"os.exit", os_exit},
{"os.getenv", os_getenv},
{"os.setenv", os_setenv},
{"os.clock", os_clock},
{"os.sleep", os_sleep},
{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':
{
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;
}
case 'V':

View File

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

View File

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

View File

@ -35,8 +35,8 @@ const char dst_base64[65] =
* mnemonics instead of a bit pattern for type checking */
const char *const dst_type_names[16] = {
":nil",
":false",
":true",
":boolean",
":boolean",
":fiber",
":integer",
":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 */
static const char *typestr(DstArgs args, int32_t n) {
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_type_names[actual];
: dst_type_names[actual]) + 1;
}
int dst_type_err(DstArgs args, int32_t n, DstType expected) {
const uint8_t *message = dst_formatc(
"bad argument #%d, expected %t, got %s",
"bad slot #%d, expected %t, got %s",
n,
expected,
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) {
@ -229,7 +229,7 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) {
const uint8_t *message;
DstBuffer buf;
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;
while (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));
message = dst_string(buf.data, buf.count);
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) {
return dst_throwv(args,
DST_THROWV(args,
dst_wrap_string(dst_formatc(
"expected %s%d argument%s, got %d",
prefix, n, n == 1 ? "" : "s", args.n)));
}
int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at) {
return dst_throwv(args,
DST_THROWV(args,
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))));
}

View File

@ -224,7 +224,13 @@ static void *op_lookup[255] = {
goto vm_error;
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++;
vm_next();
@ -922,7 +928,7 @@ Dst dst_resume(DstFiber *fiber, int32_t argn, const Dst *argv) {
return dst_run(fiber);
}
/* Setup functions */
/* Setup VM */
int dst_init() {
/* Garbage collection */
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_typemany_err(DstArgs args, int32_t n, int expected);
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)
#define dst_return(a, v) (*((a).ret) = (v), 0)
/* Macros */
#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 */
#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)
#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)
#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)
#define dst_check(A, N, T) do {\
#define DST_CHECK(A, N, T) do {\
if ((A).n > (N)) {\
if (!dst_checktype((A).v[(N)], (T))) return dst_type_err(A, N, T);\
} else {\
if ((T) != DST_NIL) return dst_type_err(A, N, T);\
}\
} while (0)
#define dst_checkmany(A, N, TS) do {\
#define DST_CHECKMANY(A, N, TS) do {\
if ((A).n > (N)) {\
DstType t = dst_type((A).v[(N)]);\
if (!((1 << t) & (TS))) return dst_typemany_err(A, N, TS);\
} 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)
#define dst_checkabstract(A, N, AT) do {\
#define DST_CHECKABSTRACT(A, N, AT) do {\
if ((A).n > (N)) {\
Dst x = (A).v[(N)];\
if (!dst_checktype(x, DST_ABSTRACT) ||\
@ -240,42 +242,69 @@ int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at);
}\
} while (0)
#define dst_arg_number(DEST, A, N) do { \
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\
#define DST_ARG_NUMBER(DEST, A, N) do { \
if ((A).n <= (N)) \
return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\
Dst val = (A).v[(N)];\
if (dst_checktype(val, DST_REAL)) { DEST = dst_unwrap_real(val); }\
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)
if (dst_checktype(val, DST_REAL)) { \
DEST = dst_unwrap_real(val); \
} 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 { \
dst_checkmany(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\
DEST = dst_unwrap_boolean((A).v[(N)]); } while (0)
#define DST_ARG_BOOLEAN(DEST, A, N) do { \
DST_CHECKMANY(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\
DEST = dst_unwrap_boolean((A).v[(N)]); \
} while (0)
#define _dst_arg(TYPE, NAME, DEST, 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 {\
#define DST_ARG_BYTES(DESTBYTES, DESTLEN, A, N) do {\
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
if (!dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
}\
} while (0)
#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(TYPE, NAME, DEST, A, N) do { \
DST_CHECK(A, N, TYPE);\
DEST = dst_unwrap_##NAME((A).v[(N)]); \
} while (0)
#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
}

View File

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

View File

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

View File

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