mirror of
https://github.com/janet-lang/janet
synced 2024-11-10 10:49:54 +00:00
Change c function macros to be explicitly non functional by
capitalizing them.
This commit is contained in:
parent
70e52d91c4
commit
dafc121f4d
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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))
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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[] = {
|
||||||
|
115
src/core/io.c
115
src/core/io.c
@ -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[] = {
|
||||||
|
@ -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, >)
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
|
@ -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':
|
||||||
|
@ -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[] = {
|
||||||
|
@ -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 */
|
||||||
|
@ -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))));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user