From dafc121f4d588fd5c718a61ebf85a6813d4082ec Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sat, 12 May 2018 20:31:28 -0400 Subject: [PATCH] Change c function macros to be explicitly non functional by capitalizing them. --- natives/sqlite3/main.c | 20 +++---- src/assembler/asm.c | 72 ++++++++++++++----------- src/compiler/boot.dst | 26 +++++++-- src/compiler/compile.c | 11 ++-- src/core/array.c | 74 +++++++++++++------------- src/core/buffer.c | 60 ++++++++++----------- src/core/corelib.c | 114 ++++++++++++++++++++------------------- src/core/fiber.c | 42 +++++++-------- src/core/io.c | 115 ++++++++++++++++++--------------------- src/core/math.c | 87 +++++++++++++++--------------- src/core/native.c | 19 +++---- src/core/os.c | 62 ++++++++++++++++------ src/core/os.h | 33 ------------ src/core/string.c | 2 +- src/core/table.c | 43 ++++++++------- src/core/tuple.c | 21 ++++---- src/core/util.c | 22 ++++---- src/core/vm.c | 10 +++- src/include/dst/dst.h | 101 ++++++++++++++++++++++------------- src/mainclient/line.c | 8 +-- src/parser/ast.c | 2 +- src/parser/parse.c | 118 +++++++++++++++++++---------------------- 22 files changed, 549 insertions(+), 513 deletions(-) delete mode 100644 src/core/os.h diff --git a/natives/sqlite3/main.c b/natives/sqlite3/main.c index d1b6f385..f3e1920f 100644 --- a/natives/sqlite3/main.c +++ b/natives/sqlite3/main.c @@ -45,29 +45,29 @@ static int sql_open(DstArgs args) { sqlite3 **conn; const uint8_t *filename; int status; - dst_fixarity(args, 1); - dst_arg_string(filename, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_STRING(filename, args, 0); conn = (sqlite3 **) dst_abstract(&sql_conn_type, sizeof(sqlite3 *)); status = sqlite3_open((const char *)filename, conn); if (status == SQLITE_OK) { - return dst_return(args, dst_wrap_abstract(conn)); + DST_RETURN_ABSTRACT(args, conn); } else { const char *err = sqlite3_errmsg(*conn); - return dst_throw(args, err); + DST_THROW(args, err); } } static int sql_close(DstArgs args) { sqlite3 **conn; int status; - dst_fixarity(args, 1); - dst_checkabstract(args, 0, &sql_conn_type); + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &sql_conn_type); conn = (sqlite3 **)dst_unwrap_abstract(args.v[0]); status = sqlite3_close_v2(*conn); if (status == SQLITE_OK) { - return dst_return(args, dst_wrap_nil()); + DST_RETURN_NIL(args); } else { - return dst_throw(args, "unable to close the sqlite3 connection"); + DST_THROW(args, "unable to close the sqlite3 connection"); } } @@ -100,9 +100,9 @@ static int sql_sql(DstArgs args) { rows, &errmsg); if (status == SQLITE_OK) { - return dst_return(args, dst_wrap_array(rows)); + DST_RETURN_ARRAY(args, rows); } else { - return dst_throw(args, errmsg); + DST_THROW(args, errmsg); } } diff --git a/src/assembler/asm.c b/src/assembler/asm.c index 9bc54f27..99aef083 100644 --- a/src/assembler/asm.c +++ b/src/assembler/asm.c @@ -148,26 +148,35 @@ static const DstInstructionDef dst_ops[] = { {"yield", DOP_YIELD} }; -/* Check a dst string against a bunch of test_strings. Return the - * index of the matching test_string, or -1 if not found. */ -static int32_t strsearch(const uint8_t *str, const char *const *test_strings) { - int32_t len = dst_string_length(str); - int index; - for (index = 0; ; index++) { - int32_t i; - const char *testword = test_strings[index]; - if (NULL == testword) - break; - for (i = 0; i < len; i++) { - if (testword[i] != str[i]) - goto nextword; - } - return index; - nextword: - continue; - } - return -1; -} +/* Typename aliases for tchck instruction */ +typedef struct TypeAlias { + const char *name; + int32_t mask; +} TypeAlias; + +static const TypeAlias type_aliases[] = { + {":abstract", DST_TFLAG_ABSTRACT}, + {":array", DST_TFLAG_ARRAY}, + {":boolean", DST_TFLAG_BOOLEAN}, + {":buffer", DST_TFLAG_BUFFER}, + {":callable", DST_TFLAG_CALLABLE}, + {":cfunction", DST_TFLAG_CFUNCTION}, + {":dictionary", DST_TFLAG_DICTIONARY}, + {":false", DST_TFLAG_FALSE}, + {":fiber", DST_TFLAG_FIBER}, + {":function", DST_TFLAG_FUNCTION}, + {":indexed", DST_TFLAG_INDEXED}, + {":integer", DST_TFLAG_INTEGER}, + {":nil", DST_TFLAG_NIL}, + {":number", DST_TFLAG_NUMBER}, + {":real", DST_TFLAG_REAL}, + {":string", DST_TFLAG_STRING}, + {":struct", DST_TFLAG_STRUCT}, + {":symbol", DST_TFLAG_SYMBOL}, + {":table", DST_TFLAG_BOOLEAN}, + {":true", DST_TFLAG_TRUE}, + {":tuple", DST_TFLAG_BOOLEAN} +}; /* Deinitialize an Assembler. Does not deinitialize the parents. */ static void dst_asm_deinit(DstAssembler *a) { @@ -295,9 +304,13 @@ static int32_t doarg_1( dst_asm_errorv(a, dst_formatc("unknown name %q", x)); } } else if (argtype == DST_OAT_TYPE || argtype == DST_OAT_SIMPLETYPE) { - int32_t index = strsearch(dst_unwrap_symbol(x), dst_type_names); - if (index != -1) { - ret = index; + const TypeAlias *alias = dst_strbinsearch( + &type_aliases, + sizeof(type_aliases)/sizeof(TypeAlias), + sizeof(TypeAlias), + dst_unwrap_symbol(x)); + if (alias) { + ret = alias->mask; } else { dst_asm_errorv(a, dst_formatc("unknown type %q", x)); } @@ -890,21 +903,20 @@ Dst dst_disasm(DstFuncDef *def) { /* C Function for assembly */ int dst_asm_cfun(DstArgs args) { DstAssembleResult res; - if (args.n < 1) return dst_throw(args, "expected assembly source"); + DST_FIXARITY(args, 1); res = dst_asm(args.v[0], 0); if (res.status == DST_ASSEMBLE_OK) { - return dst_return(args, dst_wrap_function(dst_thunk(res.funcdef))); + DST_RETURN_FUNCTION(args, dst_thunk(res.funcdef)); } else { - return dst_throwv(args, dst_wrap_string(res.error)); + DST_THROWV(args, dst_wrap_string(res.error)); } } int dst_disasm_cfun(DstArgs args) { DstFunction *f; - if (args.n < 1 || !dst_checktype(args.v[0], DST_FUNCTION)) - return dst_throw(args, "expected function"); - f = dst_unwrap_function(args.v[0]); - return dst_return(args, dst_disasm(f->def)); + DST_FIXARITY(args, 1); + DST_ARG_FUNCTION(f, args, 0); + DST_RETURN(args, dst_disasm(f->def)); } static const DstReg cfuns[] = { diff --git a/src/compiler/boot.dst b/src/compiler/boot.dst index 16bc9d17..88198e30 100644 --- a/src/compiler/boot.dst +++ b/src/compiler/boot.dst @@ -74,19 +74,34 @@ (defn pos? [x] (> x 0)) (defn neg? [x] (< x 0)) (defn one? [x] (== x 1)) +(defn integer? [x] (= (type x) :integer)) +(defn real? [x] (= (type x) :real)) +(defn number? [x] + (def t (type x)) + (if (= t :integer) true (= t :real))) +(defn fiber? [x] (= (type x) :fiber)) +(defn function? [x] (= (type x) :function)) +(defn cfunction? [x] (= (type x) :cfunction)) +(defn abstract? [x] (= (type x) :abstract)) (defn table? [x] (= (type x) :table )) (defn struct? [x] (= (type x) :struct)) (defn array? [x] (= (type x) :array)) (defn tuple? [x] (= (type x) :tuple)) (defn boolean? [x] (= (type x) :boolean)) +(defn bytes? [x] + (def t (type x)) + (if (= t :string) true (if (= t :symbol) true (= t :buffer)))) +(defn dictionary? [x] + (def t (type x)) + (if (= t :table) true (= t :struct))) (defn indexed? [x] (def t (type x)) (if (= t :array) true (= t :tuple))) -(defn function? [x] +(defn callable? [x] (def t (type x)) (if (= t :function) true (= t :cfunction))) -(defn true? [x] (= (type x) true)) -(defn false? [x] (= (type x) false)) +(defn true? [x] (= x true)) +(defn false? [x] (= x false)) (defn nil? [x] (= x nil)) (def atomic? (do (def non-atomic-types { @@ -923,7 +938,10 @@ onvalue." (defn default-error-handler [t x f] (file.write stdout (string t " error: ")) - (pp x) + (if (bytes? x) + (do (file.write stdout x) + (file.write stdout "\n")) + (pp x)) (when f (def st (fiber.stack f)) (def len (length st)) diff --git a/src/compiler/compile.c b/src/compiler/compile.c index e135b0f7..bfe29cd6 100644 --- a/src/compiler/compile.c +++ b/src/compiler/compile.c @@ -996,20 +996,17 @@ int dst_compile_cfun(DstArgs args) { DstCompileResult res; DstTable *t; DstTable *env; - if (args.n < 2) - return dst_throw(args, "expected at least 2 arguments"); - if (!dst_checktype(args.v[1], DST_TABLE)) return dst_throw(args, "expected table as environment"); - env = dst_unwrap_table(args.v[1]); + DST_FIXARITY(args, 2); + DST_ARG_TABLE(env, args, 1); res = dst_compile(args.v[0], env, 0); if (res.status == DST_COMPILE_OK) { - DstFunction *fun = dst_thunk(res.funcdef); - return dst_return(args, dst_wrap_function(fun)); + DST_RETURN_FUNCTION(args, dst_thunk(res.funcdef)); } else { t = dst_table(2); dst_table_put(t, dst_csymbolv(":error"), dst_wrap_string(res.error)); dst_table_put(t, dst_csymbolv(":error-start"), dst_wrap_integer(res.error_start)); dst_table_put(t, dst_csymbolv(":error-end"), dst_wrap_integer(res.error_end)); - return dst_return(args, dst_wrap_table(t)); + DST_RETURN_TABLE(args, t); } } diff --git a/src/core/array.c b/src/core/array.c index 7e6d944d..1e810213 100644 --- a/src/core/array.c +++ b/src/core/array.c @@ -108,57 +108,58 @@ Dst dst_array_peek(DstArray *array) { static int cfun_new(DstArgs args) { int32_t cap; DstArray *array; - dst_fixarity(args, 1); - dst_arg_integer(cap, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(cap, args, 0); array = dst_array(cap); - return dst_return(args, dst_wrap_array(array)); + DST_RETURN_ARRAY(args, array); } static int cfun_pop(DstArgs args) { - dst_fixarity(args, 1); - dst_check(args, 0, DST_ARRAY); - return dst_return(args, dst_array_pop(dst_unwrap_array(args.v[0]))); + DstArray *array; + DST_FIXARITY(args, 1); + DST_ARG_ARRAY(array, args, 0); + DST_RETURN(args, dst_array_pop(array)); } static int cfun_peek(DstArgs args) { - dst_fixarity(args, 1); - dst_check(args, 0, DST_ARRAY); - return dst_return(args, dst_array_peek(dst_unwrap_array(args.v[0]))); + DstArray *array; + DST_FIXARITY(args, 1); + DST_ARG_ARRAY(array, args, 0); + DST_RETURN(args, dst_array_peek(array)); } static int cfun_push(DstArgs args) { DstArray *array; int32_t newcount; - dst_minarity(args, 1); - dst_check(args, 0, DST_ARRAY); - array = dst_unwrap_array(args.v[0]); + DST_MINARITY(args, 1); + DST_ARG_ARRAY(array, args, 0); newcount = array->count - 1 + args.n; dst_array_ensure(array, newcount); if (args.n > 1) memcpy(array->data + array->count, args.v + 1, (args.n - 1) * sizeof(Dst)); array->count = newcount; - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_setcount(DstArgs args) { + DstArray *array; int32_t newcount; - dst_fixarity(args, 2); - dst_check(args, 0, DST_ARRAY); - dst_check(args, 1, DST_INTEGER); - newcount = dst_unwrap_integer(args.v[1]); - if (newcount < 0) return dst_throw(args, "expected positive integer"); - dst_array_setcount(dst_unwrap_array(args.v[0]), newcount); - return dst_return(args, args.v[0]); + DST_FIXARITY(args, 2); + DST_ARG_ARRAY(array, args, 0); + DST_ARG_INTEGER(newcount, args, 1); + if (newcount < 0) DST_THROW(args, "expected positive integer"); + dst_array_setcount(array, newcount); + DST_RETURN(args, args.v[0]); } static int cfun_ensure(DstArgs args) { + DstArray *array; int32_t newcount; - dst_fixarity(args, 2); - dst_check(args, 0, DST_ARRAY); - dst_check(args, 1, DST_INTEGER); - newcount = dst_unwrap_integer(args.v[1]); - if (newcount < 0) return dst_throw(args, "expected positive integer"); - dst_array_ensure(dst_unwrap_array(args.v[0]), newcount); - return dst_return(args, args.v[0]); + DST_FIXARITY(args, 2); + DST_ARG_ARRAY(array, args, 0); + DST_ARG_INTEGER(newcount, args, 1); + if (newcount < 0) DST_THROW(args, "expected positive integer"); + dst_array_ensure(array, newcount); + DST_RETURN(args, args.v[0]); } static int cfun_slice(DstArgs args) { @@ -166,17 +167,17 @@ static int cfun_slice(DstArgs args) { int32_t len; DstArray *ret; int32_t start, end; - dst_minarity(args, 1); - dst_maxarity(args, 3); + DST_MINARITY(args, 1); + DST_MAXARITY(args, 3); if (!dst_seq_view(args.v[0], &vals, &len)) - return dst_throw(args, "expected array|tuple"); + DST_THROW(args, "expected array|tuple"); /* Get start */ if (args.n < 2) { start = 0; } else if (dst_checktype(args.v[1], DST_INTEGER)) { start = dst_unwrap_integer(args.v[1]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } /* Get end */ if (args.n < 3) { @@ -184,7 +185,7 @@ static int cfun_slice(DstArgs args) { } else if (dst_checktype(args.v[2], DST_INTEGER)) { end = dst_unwrap_integer(args.v[2]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } if (start < 0) start = len + start; if (end < 0) end = len + end + 1; @@ -198,15 +199,14 @@ static int cfun_slice(DstArgs args) { } else { ret = dst_array(0); } - return dst_return(args, dst_wrap_array(ret)); + DST_RETURN_ARRAY(args, ret); } static int cfun_concat(DstArgs args) { int32_t i; DstArray *array; - dst_minarity(args, 1); - dst_check(args, 0, DST_ARRAY); - array = dst_unwrap_array(args.v[0]); + DST_MINARITY(args, 1); + DST_ARG_ARRAY(array, args, 0); for (i = 1; i < args.n; i++) { switch (dst_type(args.v[i])) { default: @@ -224,7 +224,7 @@ static int cfun_concat(DstArgs args) { break; } } - return dst_return(args, args.v[0]); + DST_RETURN_ARRAY(args, array); } static const DstReg cfuns[] = { diff --git a/src/core/buffer.c b/src/core/buffer.c index cf1afc7c..0204c82d 100644 --- a/src/core/buffer.c +++ b/src/core/buffer.c @@ -161,91 +161,89 @@ int dst_buffer_push_u64(DstBuffer *buffer, uint64_t x) { static int cfun_new(DstArgs args) { int32_t cap; DstBuffer *buffer; - dst_fixarity(args, 1); - dst_arg_integer(cap, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(cap, args, 0); buffer = dst_buffer(cap); - return dst_return(args, dst_wrap_buffer(buffer)); + DST_RETURN_BUFFER(args, buffer); } static int cfun_u8(DstArgs args) { int32_t i; DstBuffer *buffer; - dst_minarity(args, 1); - dst_arg_buffer(buffer, args, 0); + DST_MINARITY(args, 1); + DST_ARG_BUFFER(buffer, args, 0); for (i = 1; i < args.n; i++) { int32_t integer; - dst_arg_integer(integer, args, i); + DST_ARG_INTEGER(integer, args, i); if (dst_buffer_push_u8(buffer, (uint8_t) (integer & 0xFF))) - return dst_throw(args, "buffer overflow"); + DST_THROW(args, "buffer overflow"); } - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_int(DstArgs args) { int32_t i; DstBuffer *buffer; - dst_minarity(args, 1); - dst_arg_buffer(buffer, args, 0); + DST_MINARITY(args, 1); + DST_ARG_BUFFER(buffer, args, 0); for (i = 1; i < args.n; i++) { int32_t integer; - dst_arg_integer(integer, args, i); + DST_ARG_INTEGER(integer, args, i); if (dst_buffer_push_u32(buffer, (uint32_t) integer)) - return dst_throw(args, "buffer overflow"); + DST_THROW(args, "buffer overflow"); } - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_chars(DstArgs args) { int32_t i; DstBuffer *buffer; - dst_minarity(args, 1); - dst_arg_buffer(buffer, args, 0); + DST_MINARITY(args, 1); + DST_ARG_BUFFER(buffer, args, 0); for (i = 1; i < args.n; i++) { int32_t len; const uint8_t *str; - if (!dst_chararray_view(args.v[i], &str, &len)) - return dst_throw(args, "expected string|symbol|buffer"); + DST_ARG_BYTES(str, len, args, i); if (dst_buffer_push_bytes(buffer, str, len)) - return dst_throw(args, "buffer overflow"); + DST_THROW(args, "buffer overflow"); } - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_clear(DstArgs args) { DstBuffer *buffer; - dst_fixarity(args, 1); - dst_arg_buffer(buffer, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_BUFFER(buffer, args, 0); buffer->count = 0; - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_popn(DstArgs args) { DstBuffer *buffer; int32_t n; - dst_fixarity(args, 2); - dst_arg_buffer(buffer, args, 0); - dst_arg_integer(n, args, 1); + DST_FIXARITY(args, 2); + DST_ARG_BUFFER(buffer, args, 0); + DST_ARG_INTEGER(n, args, 1); if (buffer->count < n) { buffer->count = 0; } else { buffer->count -= n; } - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_slice(DstArgs args) { const uint8_t *data; int32_t len, start, end; DstBuffer *ret; - if (args.n < 1 || !dst_chararray_view(args.v[0], &data, &len)) - return dst_throw(args, "expected buffer/string"); + DST_ARG_BYTES(data, len, args, 0); /* Get start */ if (args.n < 2) { start = 0; } else if (dst_checktype(args.v[1], DST_INTEGER)) { start = dst_unwrap_integer(args.v[1]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } /* Get end */ if (args.n < 3) { @@ -253,7 +251,7 @@ static int cfun_slice(DstArgs args) { } else if (dst_checktype(args.v[2], DST_INTEGER)) { end = dst_unwrap_integer(args.v[2]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } if (start < 0) start = len + start; if (end < 0) end = len + end + 1; @@ -264,7 +262,7 @@ static int cfun_slice(DstArgs args) { } else { ret = dst_buffer(0); } - return dst_return(args, dst_wrap_buffer(ret)); + DST_RETURN_BUFFER(args, ret); } static const DstReg cfuns[] = { diff --git a/src/core/corelib.c b/src/core/corelib.c index 8398eaf7..f103e167 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -35,7 +35,7 @@ int dst_core_print(DstArgs args) { } } putc('\n', stdout); - return 0; + DST_RETURN_NIL(); } int dst_core_describe(DstArgs args) { @@ -92,15 +92,15 @@ int dst_core_buffer(DstArgs args) { len = dst_string_length(str); dst_buffer_push_bytes(b, str, len); } - return dst_return(args, dst_wrap_buffer(b)); + DST_RETURN_BUFFER(args, b); } int dst_core_format(DstArgs args) { const uint8_t *format; int32_t i, len, n; DstBuffer buf; - dst_minarity(args, 1); - dst_arg_bytes(format, len, args, 0); + DST_MINARITY(args, 1); + DST_ARG_BYTES(format, len, args, 0); n = 1; dst_buffer_init(&buf, len); for (i = 0; i < len; i++) { @@ -128,33 +128,33 @@ int dst_core_format(DstArgs args) { return 0; noarg: dst_buffer_deinit(&buf); - return dst_throw(args, "not enough arguments to format"); + DST_THROW(args, "not enough arguments to format"); } int dst_core_scannumber(DstArgs args) { const uint8_t *data; Dst x; int32_t len; - dst_fixarity(args, 1); - dst_arg_bytes(data, len, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_BYTES(data, len, args, 0); x = dst_scan_number(data, len); - if (!dst_checktype(x, DST_INTEGER) && !dst_checktype(x, DST_REAL)) { - return dst_throw(args, "error parsing number"); + if (dst_checktype(x, DST_NIL)) { + DST_THROW(args, "error parsing number"); } - return dst_return(args, x); + DST_RETURN(args, x); } int dst_core_scaninteger(DstArgs args) { const uint8_t *data; int32_t len, ret; int err = 0; - dst_fixarity(args, 1); - dst_arg_bytes(data, len, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_BYTES(data, len, args, 0); ret = dst_scan_integer(data, len, &err); if (err) { - return dst_throw(args, "error parsing integer"); + DST_THROW(args, "error parsing integer"); } - return dst_return(args, dst_wrap_integer(ret)); + DST_RETURN_INTEGER(args, ret); } int dst_core_scanreal(DstArgs args) { @@ -162,78 +162,82 @@ int dst_core_scanreal(DstArgs args) { int32_t len; double ret; int err = 0; - dst_fixarity(args, 1); - dst_arg_bytes(data, len, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_BYTES(data, len, args, 0); ret = dst_scan_real(data, len, &err); if (err) { - return dst_throw(args, "error parsing real"); + DST_THROW(args, "error parsing real"); } - return dst_return(args, dst_wrap_real(ret)); + DST_RETURN_REAL(args, ret); } int dst_core_tuple(DstArgs args) { - return dst_return(args, dst_wrap_tuple(dst_tuple_n(args.v, args.n))); + DST_RETURN_TUPLE(args, dst_tuple_n(args.v, args.n)); } int dst_core_array(DstArgs args) { DstArray *array = dst_array(args.n); array->count = args.n; memcpy(array->data, args.v, args.n * sizeof(Dst)); - return dst_return(args, dst_wrap_array(array)); + DST_RETURN_ARRAY(args, array); } int dst_core_table(DstArgs args) { int32_t i; DstTable *table = dst_table(args.n >> 1); - if (args.n & 1) return dst_throw(args, "expected even number of arguments"); + if (args.n & 1) + DST_THROW(args, "expected even number of arguments"); for (i = 0; i < args.n; i += 2) { dst_table_put(table, args.v[i], args.v[i + 1]); } - return dst_return(args, dst_wrap_table(table)); + DST_RETURN_TABLE(args, table); } int dst_core_struct(DstArgs args) { int32_t i; DstKV *st = dst_struct_begin(args.n >> 1); - if (args.n & 1) return dst_throw(args, "expected even number of arguments"); + if (args.n & 1) + DST_THROW(args, "expected even number of arguments"); for (i = 0; i < args.n; i += 2) { dst_struct_put(st, args.v[i], args.v[i + 1]); } - return dst_return(args, dst_wrap_struct(dst_struct_end(st))); + DST_RETURN_STRUCT(args, dst_struct_end(st)); } int dst_core_gensym(DstArgs args) { - dst_maxarity(args, 1); + DST_MAXARITY(args, 1); if (args.n == 0) { - return dst_return(args, dst_wrap_symbol(dst_symbol_gen(NULL, 0))); + DST_RETURN_SYMBOL(args, dst_symbol_gen(NULL, 0)); } else { - const uint8_t *s = dst_to_string(args.v[0]); - return dst_return(args, dst_wrap_symbol(dst_symbol_gen(s, dst_string_length(s)))); + const uint8_t *s; + int32_t len; + DST_ARG_BYTES(s, len, args, 0); + DST_RETURN_SYMBOL(args, dst_symbol_gen(s, len)); } } int dst_core_length(DstArgs args) { - dst_fixarity(args, 1); - return dst_return(args, dst_wrap_integer(dst_length(args.v[0]))); + DST_FIXARITY(args, 1); + DST_RETURN_INTEGER(args, dst_length(args.v[0])); } int dst_core_get(DstArgs args) { int32_t i; Dst ds; - dst_minarity(args, 1); + DST_MINARITY(args, 1); ds = args.v[0]; for (i = 1; i < args.n; i++) { ds = dst_get(ds, args.v[i]); if (dst_checktype(ds, DST_NIL)) break; } - return dst_return(args, ds); + DST_RETURN(args, ds); } int dst_core_put(DstArgs args) { Dst ds, key, value; DstArgs subargs = args; - dst_minarity(args, 3); + DST_MINARITY(args, 3); subargs.n -= 2; if (dst_core_get(subargs)) return 1; ds = *args.ret; @@ -251,34 +255,33 @@ int dst_core_gccollect(DstArgs args) { int dst_core_gcsetinterval(DstArgs args) { int32_t val; - dst_fixarity(args, 1); - dst_check(args, 0, DST_INTEGER); - val = dst_unwrap_integer(args.v[0]); + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(val, args, 0); if (val < 0) - return dst_throw(args, "expected non-negative integer"); + DST_THROW(args, "expected non-negative integer"); dst_vm_gc_interval = val; - return dst_return(args, args.v[0]); + DST_RETURN_NIL(args); } int dst_core_gcinterval(DstArgs args) { - dst_fixarity(args, 0); - return dst_return(args, dst_wrap_integer(dst_vm_gc_interval)); + DST_FIXARITY(args, 0); + DST_RETURN_INTEGER(args, dst_vm_gc_interval); } int dst_core_type(DstArgs args) { - dst_fixarity(args, 1); + DST_FIXARITY(args, 1); if (dst_checktype(args.v[0], DST_ABSTRACT)) { - return dst_return(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name)); + DST_RETURN(args, dst_csymbolv(dst_abstract_type(dst_unwrap_abstract(args.v[0]))->name)); } else { - return dst_return(args, dst_csymbolv(dst_type_names[dst_type(args.v[0])])); + DST_RETURN(args, dst_csymbolv(dst_type_names[dst_type(args.v[0])])); } } int dst_core_next(DstArgs args) { Dst ds; const DstKV *kv; - dst_fixarity(args, 2); - dst_checkmany(args, 0, DST_TFLAG_DICTIONARY); + DST_FIXARITY(args, 2); + DST_CHECKMANY(args, 0, DST_TFLAG_DICTIONARY); ds = args.v[0]; if (dst_checktype(ds, DST_TABLE)) { DstTable *t = dst_unwrap_table(ds); @@ -293,31 +296,30 @@ int dst_core_next(DstArgs args) { } kv = dst_next(ds, kv); if (kv) { - return dst_return(args, kv->key); + DST_RETURN(args, kv->key); } - return dst_return(args, dst_wrap_nil()); + DST_RETURN_NIL(args); } int dst_core_hash(DstArgs args) { - dst_fixarity(args, 1); - return dst_return(args, dst_wrap_integer(dst_hash(args.v[0]))); + DST_FIXARITY(args, 1); + DST_RETURN_INTEGER(args, dst_hash(args.v[0])); } int dst_core_string_slice(DstArgs args) { const uint8_t *data; int32_t len, start, end; const uint8_t *ret; - dst_minarity(args, 1); - dst_maxarity(args, 3); - if (!dst_chararray_view(args.v[0], &data, &len)) - return dst_throw(args, "expected buffer|string|symbol"); + DST_MINARITY(args, 1); + DST_MAXARITY(args, 3); + DST_ARG_BYTES(data, len, args, 0); /* Get start */ if (args.n < 2) { start = 0; } else if (dst_checktype(args.v[1], DST_INTEGER)) { start = dst_unwrap_integer(args.v[1]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } /* Get end */ if (args.n < 3) { @@ -325,7 +327,7 @@ int dst_core_string_slice(DstArgs args) { } else if (dst_checktype(args.v[2], DST_INTEGER)) { end = dst_unwrap_integer(args.v[2]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } if (start < 0) start = len + start; if (end < 0) end = len + end + 1; @@ -334,5 +336,5 @@ int dst_core_string_slice(DstArgs args) { } else { ret = dst_cstring(""); } - return dst_return(args, dst_wrap_string(ret)); + DST_RETURN_STRING(args, ret); } diff --git a/src/core/fiber.c b/src/core/fiber.c index 32b6ed80..fb10044c 100644 --- a/src/core/fiber.c +++ b/src/core/fiber.c @@ -260,19 +260,20 @@ void dst_fiber_popframe(DstFiber *fiber) { static int cfun_new(DstArgs args) { DstFiber *fiber; - dst_minarity(args, 1); - dst_maxarity(args, 2); - dst_check(args, 0, DST_FUNCTION); - fiber = dst_fiber(dst_unwrap_function(args.v[0]), 64); + DstFunction *func; + DST_MINARITY(args, 1); + DST_MAXARITY(args, 2); + DST_ARG_FUNCTION(func, args, 0); + fiber = dst_fiber(func, 64); if (args.n == 2) { const uint8_t *flags; int32_t len, i; - dst_arg_bytes(flags, len, args, 1); + DST_ARG_BYTES(flags, len, args, 1); fiber->flags |= DST_FIBER_MASK_ERROR | DST_FIBER_MASK_YIELD; for (i = 0; i < len; i++) { switch (flags[i]) { default: - return dst_throw(args, "invalid flag, expected d, e, or y"); + DST_THROW(args, "invalid flag, expected d, e, or y"); case ':': break; case 'd': @@ -287,14 +288,15 @@ static int cfun_new(DstArgs args) { } } } - return dst_return(args, dst_wrap_fiber(fiber)); + DST_RETURN_FIBER(args, fiber); } static int cfun_status(DstArgs args) { + DstFiber *fiber; const char *status = ""; - dst_fixarity(args, 1); - dst_check(args, 0, DST_FIBER); - switch(dst_unwrap_fiber(args.v[0])->status) { + DST_FIXARITY(args, 1); + DST_ARG_FIBER(fiber, args, 0); + switch(fiber->status) { case DST_FIBER_PENDING: status = ":pending"; break; @@ -314,7 +316,7 @@ static int cfun_status(DstArgs args) { status = ":debug"; break; } - return dst_return(args, dst_csymbolv(status)); + DST_RETURN_CSYMBOL(args, status); } /* Extract info from one stack frame */ @@ -354,9 +356,8 @@ static Dst doframe(DstStackFrame *frame) { static int cfun_stack(DstArgs args) { DstFiber *fiber; DstArray *array; - dst_fixarity(args, 1); - dst_check(args, 0, DST_FIBER); - fiber = dst_unwrap_fiber(args.v[0]); + DST_FIXARITY(args, 1); + DST_ARG_FIBER(fiber, args, 0); array = dst_array(0); { int32_t i = fiber->frame; @@ -367,26 +368,25 @@ static int cfun_stack(DstArgs args) { i = frame->prevframe; } } - return dst_return(args, dst_wrap_array(array)); + DST_RETURN_ARRAY(args, array); } static int cfun_current(DstArgs args) { - dst_fixarity(args, 0); - return dst_return(args, dst_wrap_fiber(dst_vm_fiber)); + DST_FIXARITY(args, 0); + DST_RETURN_FIBER(args, dst_vm_fiber); } static int cfun_lineage(DstArgs args) { DstFiber *fiber; DstArray *array; - dst_fixarity(args, 1); - dst_check(args, 0, DST_FIBER); - fiber = dst_unwrap_fiber(args.v[0]); + DST_FIXARITY(args, 1); + DST_ARG_FIBER(fiber, args, 0); array = dst_array(0); while (fiber) { dst_array_push(array, dst_wrap_fiber(fiber)); fiber = fiber->child; } - return dst_return(args, dst_wrap_array(array)); + DST_RETURN_ARRAY(args, array); } static const DstReg cfuns[] = { diff --git a/src/core/io.c b/src/core/io.c index b601c13b..cc559be8 100644 --- a/src/core/io.c +++ b/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]); } -/* Check char array argument */ -static int checkchars(DstArgs args, int32_t n, const uint8_t **str, int32_t *len) { - if (n >= args.n) { - *args.ret = dst_cstringv("expected string/buffer"); - return 0; - } - if (!dst_chararray_view(args.v[n], str, len)) { - *args.ret = dst_cstringv("expected string/buffer"); - return 0; - } - return 1; -} - static Dst makef(FILE *f, int flags) { IOFile *iof = (IOFile *) dst_abstract(&dst_io_filetype, sizeof(IOFile)); iof->file = f; @@ -143,14 +130,13 @@ static int dst_io_popen(DstArgs args) { int32_t modelen; FILE *f; int flags; - dst_minarity(args, 1); - dst_maxarity(args, 2); - dst_check(args, 0, DST_STRING); - fname = dst_unwrap_string(args.v[0]); + DST_MINARITY(args, 1); + DST_MAXARITY(args, 2); + DST_ARG_STRING(fname, args, 0); if (args.n == 2) { if (!dst_checktype(args.v[1], DST_STRING) && !dst_checktype(args.v[1], DST_SYMBOL)) - return dst_throw(args, "expected string mode"); + DST_THROW(args, "expected string mode"); fmode = dst_unwrap_string(args.v[1]); modelen = dst_string_length(fmode); } else { @@ -162,7 +148,7 @@ static int dst_io_popen(DstArgs args) { modelen--; } if (modelen != 1 || !(fmode[0] == 'r' || fmode[0] == 'w')) { - return dst_throw(args, "invalid file mode"); + DST_THROW(args, "invalid file mode"); } flags = (fmode[0] == 'r') ? IO_PIPED | IO_READ : IO_PIPED | IO_WRITE; #ifdef DST_WINDOWS @@ -172,11 +158,11 @@ static int dst_io_popen(DstArgs args) { #endif if (!f) { if (errno == EMFILE) { - return dst_throw(args, "too many streams are open"); + DST_THROW(args, "too many streams are open"); } - return dst_throw(args, "could not open file"); + DST_THROW(args, "could not open file"); } - return dst_return(args, makef(f, flags)); + DST_RETURN(args, makef(f, flags)); } /* Open a a file and return a userdata wrapper around the C file API. */ @@ -185,14 +171,13 @@ static int dst_io_fopen(DstArgs args) { int32_t modelen; FILE *f; int flags; - dst_minarity(args, 1); - dst_maxarity(args, 2); - dst_check(args, 0, DST_STRING); - fname = dst_unwrap_string(args.v[0]); + DST_MINARITY(args, 1); + DST_MAXARITY(args, 2); + DST_ARG_STRING(fname, args, 0); if (args.n == 2) { if (!dst_checktype(args.v[1], DST_STRING) && !dst_checktype(args.v[1], DST_SYMBOL)) - return dst_throw(args, "expected string mode"); + DST_THROW(args, "expected string mode"); fmode = dst_unwrap_string(args.v[1]); modelen = dst_string_length(fmode); } else { @@ -203,10 +188,12 @@ static int dst_io_fopen(DstArgs args) { fmode++; modelen--; } - if ((flags = checkflags(fmode, modelen)) < 0) return dst_throw(args, "invalid file mode"); + if ((flags = checkflags(fmode, modelen)) < 0) { + DST_THROW(args, "invalid file mode"); + } f = fopen((const char *)fname, (const char *)fmode); - if (!f) return dst_throw(args, "could not open file"); - return dst_return(args, makef(f, flags)); + if (!f) DST_THROW(args, "could not open file"); + DST_RETURN(args, makef(f, flags)); } /* Read a certain number of bytes into memory */ @@ -217,7 +204,7 @@ static int dst_io_fread(DstArgs args) { IOFile *iof = checkfile(args, 0); if (!iof) return 1; if (iof->flags & IO_CLOSED) - return dst_throw(args, "file is closed"); + DST_THROW(args, "file is closed"); b = checkbuffer(args, 2, 1); if (!b) return 1; if (dst_checktype(args.v[1], DST_SYMBOL)) { @@ -228,33 +215,34 @@ static int dst_io_fread(DstArgs args) { fseek(iof->file, 0, SEEK_END); fsize = ftell(iof->file); fseek(iof->file, 0, SEEK_SET); - if (fsize > INT32_MAX) return dst_throw(args, "buffer overflow"); + if (fsize > INT32_MAX) DST_THROW(args, "buffer overflow"); len = fsize; /* Fall through to normal code */ } else if (!dst_cstrcmp(sym, ":line")) { for (;;) { int x = fgetc(iof->file); - if (x != EOF && dst_buffer_push_u8(b, (uint8_t)x)) return dst_throw(args, "buffer overflow"); + if (x != EOF && dst_buffer_push_u8(b, (uint8_t)x)) + DST_THROW(args, "buffer overflow"); if (x == EOF || x == '\n') break; } - return dst_return(args, dst_wrap_buffer(b)); + DST_RETURN(args, dst_wrap_buffer(b)); } else { - return dst_throw(args, "expected one of :all, :line"); + DST_THROW(args, "expected one of :all, :line"); } } else if (!dst_checktype(args.v[1], DST_INTEGER)) { - return dst_throw(args, "expected positive integer"); + DST_THROW(args, "expected positive integer"); } else { len = dst_unwrap_integer(args.v[1]); - if (len < 0) return dst_throw(args, "expected positive integer"); + if (len < 0) DST_THROW(args, "expected positive integer"); } - if (!(iof->flags & (IO_READ | IO_UPDATE))) return dst_throw(args, "file is not readable"); + if (!(iof->flags & (IO_READ | IO_UPDATE))) DST_THROW(args, "file is not readable"); /* Ensure buffer size */ - if (dst_buffer_extra(b, len)) return dst_throw(args, "buffer overflow"); + if (dst_buffer_extra(b, len)) DST_THROW(args, "buffer overflow"); ntoread = len; nread = fread((char *)(b->data + b->count), 1, ntoread, iof->file); - if (nread != ntoread && ferror(iof->file)) return dst_throw(args, "could not read file"); + if (nread != ntoread && ferror(iof->file)) DST_THROW(args, "could not read file"); b->count += nread; - return dst_return(args, dst_wrap_buffer(b)); + DST_RETURN(args, dst_wrap_buffer(b)); } /* Write bytes to a file */ @@ -264,16 +252,19 @@ static int dst_io_fwrite(DstArgs args) { IOFile *iof = checkfile(args, 0); if (!iof) return 1; if (iof->flags & IO_CLOSED) - return dst_throw(args, "file is closed"); + DST_THROW(args, "file is closed"); if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE))) - return dst_throw(args, "file is not writeable"); + DST_THROW(args, "file is not writeable"); for (i = 1; i < args.n; i++) { - if (!checkchars(args, i, &str, &len)) return 1; + DST_CHECKMANY(args, i, DST_TFLAG_BYTES); + } + for (i = 1; i < args.n; i++) { + DST_ARG_BYTES(str, len, args, i); if (len) { - if (!fwrite(str, len, 1, iof->file)) return dst_throw(args, "error writing to file"); + if (!fwrite(str, len, 1, iof->file)) DST_THROW(args, "error writing to file"); } } - return dst_return(args, dst_wrap_abstract(iof)); + DST_RETURN(args, dst_wrap_abstract(iof)); } /* Flush the bytes in the file */ @@ -281,11 +272,11 @@ static int dst_io_fflush(DstArgs args) { IOFile *iof = checkfile(args, 0); if (!iof) return 1; if (iof->flags & IO_CLOSED) - return dst_throw(args, "file is closed"); + DST_THROW(args, "file is closed"); if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE))) - return dst_throw(args, "file is not flushable"); - if (fflush(iof->file)) return dst_throw(args, "could not flush file"); - return dst_return(args, dst_wrap_abstract(iof)); + DST_THROW(args, "file is not flushable"); + if (fflush(iof->file)) DST_THROW(args, "could not flush file"); + DST_RETURN(args, dst_wrap_abstract(iof)); } /* Cleanup a file */ @@ -303,20 +294,20 @@ static int dst_io_fclose(DstArgs args) { IOFile *iof = checkfile(args, 0); if (!iof) return 1; if (iof->flags & (IO_CLOSED)) - return dst_throw(args, "file already closed"); + DST_THROW(args, "file already closed"); if (iof->flags & (IO_NOT_CLOSEABLE)) - return dst_throw(args, "file not closable"); + DST_THROW(args, "file not closable"); if (iof->flags & IO_PIPED) { #ifdef DST_WINDOWS - if (_pclose(iof->file)) return dst_throw(args, "could not close file"); + if (_pclose(iof->file)) DST_THROW(args, "could not close file"); #else - if (pclose(iof->file)) return dst_throw(args, "could not close file"); + if (pclose(iof->file)) DST_THROW(args, "could not close file"); #endif } else { - if (fclose(iof->file)) return dst_throw(args, "could not close file"); + if (fclose(iof->file)) DST_THROW(args, "could not close file"); } iof->flags |= IO_CLOSED; - return dst_return(args, dst_wrap_abstract(iof)); + DST_RETURN(args, dst_wrap_abstract(iof)); } /* Seek a file */ @@ -326,11 +317,11 @@ static int dst_io_fseek(DstArgs args) { IOFile *iof = checkfile(args, 0); if (!iof) return 1; if (iof->flags & IO_CLOSED) - return dst_throw(args, "file is closed"); + DST_THROW(args, "file is closed"); if (args.n >= 2) { const uint8_t *whence_sym; if (!dst_checktype(args.v[1], DST_SYMBOL)) - return dst_throw(args, "expected symbol"); + DST_THROW(args, "expected symbol"); whence_sym = dst_unwrap_symbol(args.v[1]); if (!dst_cstrcmp(whence_sym, ":cur")) { whence = SEEK_CUR; @@ -339,17 +330,17 @@ static int dst_io_fseek(DstArgs args) { } else if (!dst_cstrcmp(whence_sym, ":end")) { whence = SEEK_END; } else { - return dst_throw(args, "expected one of :cur, :set, :end"); + DST_THROW(args, "expected one of :cur, :set, :end"); } if (args.n >= 3) { if (!dst_checktype(args.v[2], DST_INTEGER)) - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); offset = dst_unwrap_integer(args.v[2]); } } if (fseek(iof->file, offset, whence)) - return dst_throw(args, "error seeking file"); - return dst_return(args, args.v[0]); + DST_THROW(args, "error seeking file"); + DST_RETURN(args, args.v[0]); } static const DstReg cfuns[] = { diff --git a/src/core/math.c b/src/core/math.c index d3a20262..bb1de96d 100644 --- a/src/core/math.c +++ b/src/core/math.c @@ -25,26 +25,26 @@ /* Get a random number */ int dst_rand(DstArgs args) { - dst_fixarity(args, 0); + DST_FIXARITY(args, 0); double r = (rand() % RAND_MAX) / ((double) RAND_MAX); - return dst_return(args, dst_wrap_real(r)); + DST_RETURN_REAL(args, r); } /* Seed the random number generator */ int dst_srand(DstArgs args) { int32_t x = 0; - dst_fixarity(args, 0); - dst_arg_integer(x, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(x, args, 0); srand((unsigned) x); return 0; } /* Convert a number to an integer */ int dst_int(DstArgs args) { - dst_fixarity(args, 1); + DST_FIXARITY(args, 1); switch (dst_type(args.v[0])) { default: - return dst_throw(args, "could not convert to integer"); + DST_THROW(args, "could not convert to integer"); case DST_REAL: *args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0])); break; @@ -57,10 +57,10 @@ int dst_int(DstArgs args) { /* Convert a number to a real number */ int dst_real(DstArgs args) { - dst_fixarity(args, 1); + DST_FIXARITY(args, 1); switch (dst_type(args.v[0])) { default: - return dst_throw(args, "could not convert to real"); + DST_THROW(args, "could not convert to real"); case DST_REAL: *args.ret = args.v[0]; break; @@ -200,34 +200,34 @@ DST_DEFINE_BITOP(bxor, ^=, 0) int dst_lshift(DstArgs args) { int32_t lhs, rhs; - dst_fixarity(args, 2); - dst_arg_integer(lhs, args, 0); - dst_arg_integer(rhs, args, 1); - return dst_return(args, dst_wrap_integer(lhs >> rhs)); + DST_FIXARITY(args, 2); + DST_ARG_INTEGER(lhs, args, 0); + DST_ARG_INTEGER(rhs, args, 1); + DST_RETURN_INTEGER(args, lhs >> rhs); } int dst_rshift(DstArgs args) { int32_t lhs, rhs; - dst_fixarity(args, 2); - dst_arg_integer(lhs, args, 0); - dst_arg_integer(rhs, args, 1); - return dst_return(args, dst_wrap_integer(lhs << rhs)); + DST_FIXARITY(args, 2); + DST_ARG_INTEGER(lhs, args, 0); + DST_ARG_INTEGER(rhs, args, 1); + DST_RETURN_INTEGER(args, lhs << rhs); } int dst_lshiftu(DstArgs args) { int32_t lhs, rhs; - dst_fixarity(args, 2); - dst_arg_integer(lhs, args, 0); - dst_arg_integer(rhs, args, 1); - return dst_return(args, dst_wrap_integer((int32_t)((uint32_t)lhs << rhs))); + DST_FIXARITY(args, 2); + DST_ARG_INTEGER(lhs, args, 0); + DST_ARG_INTEGER(rhs, args, 1); + DST_RETURN_INTEGER(args, (int32_t)((uint32_t)lhs << rhs)); } #define DST_DEFINE_MATHOP(name, fop)\ int dst_##name(DstArgs args) {\ double x;\ - dst_fixarity(args, 1);\ - dst_arg_number(x, args, 0);\ - return dst_return(args, dst_wrap_real(fop(x)));\ + DST_FIXARITY(args, 1);\ + DST_ARG_NUMBER(x, args, 0);\ + DST_RETURN_REAL(args, fop(x));\ } DST_DEFINE_MATHOP(acos, acos) @@ -250,10 +250,10 @@ DST_DEFINE_MATHOP(floor, floor) #define DST_DEFINE_MATH2OP(name, fop)\ int dst_##name(DstArgs args) {\ double lhs, rhs;\ - dst_fixarity(args, 2);\ - dst_arg_number(lhs, args, 0);\ - dst_arg_number(rhs, args, 1);\ - return dst_return(args, dst_wrap_real(fop(lhs, rhs)));\ + DST_FIXARITY(args, 2);\ + DST_ARG_NUMBER(lhs, args, 0);\ + DST_ARG_NUMBER(rhs, args, 1);\ + DST_RETURN_REAL(args, fop(lhs, rhs));\ }\ DST_DEFINE_MATH2OP(atan2, atan2) @@ -263,13 +263,12 @@ DST_DEFINE_MATH2OP(fmod, fmod) int dst_modf(DstArgs args) { double x, intpart; Dst *tup; - dst_fixarity(args, 1); - dst_arg_number(x, args, 0); + DST_FIXARITY(args, 2); + DST_ARG_NUMBER(x, args, 0); tup = dst_tuple_begin(2); tup[0] = dst_wrap_real(modf(x, &intpart)); tup[1] = dst_wrap_real(intpart); - *args.ret = dst_wrap_tuple(dst_tuple_end(tup)); - return 0; + DST_RETURN_TUPLE(args, dst_tuple_end(tup)); } /* Comparison */ @@ -278,12 +277,10 @@ static int dst_##name(DstArgs args) {\ int32_t i;\ for (i = 0; i < args.n - 1; i++) {\ if (dst_compare(args.v[i], args.v[i+1]) pred) {\ - *args.ret = dst_wrap_false();\ - return 0;\ + DST_RETURN_FALSE(args);\ }\ }\ - *args.ret = dst_wrap_true();\ - return 0;\ + DST_RETURN_TRUE(args);\ } DST_DEFINE_COMPARATOR(ascending, >= 0) @@ -296,25 +293,25 @@ static int dst_strict_equal(DstArgs args) { int32_t i; for (i = 0; i < args.n - 1; i++) { if (!dst_equals(args.v[i], args.v[i+1])) { - return dst_return(args, dst_wrap_false()); + DST_RETURN(args, dst_wrap_false()); } } - return dst_return(args, dst_wrap_true()); + DST_RETURN(args, dst_wrap_true()); } static int dst_strict_notequal(DstArgs args) { int32_t i; for (i = 0; i < args.n - 1; i++) { if (dst_equals(args.v[i], args.v[i+1])) { - return dst_return(args, dst_wrap_false()); + DST_RETURN(args, dst_wrap_false()); } } - return dst_return(args, dst_wrap_true()); + DST_RETURN(args, dst_wrap_true()); } static int dst_not(DstArgs args) { - dst_fixarity(args, 1); - return dst_return(args, dst_wrap_boolean(!dst_truthy(args.v[0]))); + DST_FIXARITY(args, 1); + DST_RETURN_BOOLEAN(args, !dst_truthy(args.v[0])); } #define DEF_NUMERIC_COMP(name, op) \ @@ -322,13 +319,13 @@ int dst_numeric_##name(DstArgs args) { \ int32_t i; \ for (i = 1; i < args.n; i++) { \ double x = 0, y = 0; \ - dst_arg_number(x, args, i-1);\ - dst_arg_number(y, args, i);\ + DST_ARG_NUMBER(x, args, i-1);\ + DST_ARG_NUMBER(y, args, i);\ if (!(x op y)) { \ - return dst_return(args, dst_wrap_false()); \ + DST_RETURN(args, dst_wrap_false()); \ } \ } \ - return dst_return(args, dst_wrap_true()); \ + DST_RETURN(args, dst_wrap_true()); \ } DEF_NUMERIC_COMP(gt, >) diff --git a/src/core/native.c b/src/core/native.c index 95b6196b..e39557c8 100644 --- a/src/core/native.c +++ b/src/core/native.c @@ -64,19 +64,12 @@ DstCFunction dst_native(const char *name, const uint8_t **error) { int dst_core_native(DstArgs args) { DstCFunction init; const uint8_t *error = NULL; - if (args.n < 1) { - *args.ret = dst_cstringv("expected at least one argument"); - return 1; - } - if (!dst_checktype(args.v[0], DST_STRING)) { - *args.ret = dst_cstringv("expected string"); - return 1; - } - init = dst_native((const char *)dst_unwrap_string(args.v[0]), &error); + const uint8_t *path = NULL; + DST_FIXARITY(args, 1); + DST_ARG_STRING(path, args, 0); + init = dst_native((const char *)path, &error); if (!init) { - *args.ret = dst_wrap_string(error); - return 1; + DST_THROWV(args, dst_wrap_string(error)); } - *args.ret = dst_wrap_cfunction(init); - return 0; + DST_RETURN_CFUNCTION(args, init); } diff --git a/src/core/os.c b/src/core/os.c index 6f40e312..772def65 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -23,6 +23,13 @@ #include #include +#include + +#ifdef DST_WINDOWS +#include +#else +#include +#endif static int os_execute(DstArgs args) { int nofirstarg = (args.n < 1 || !dst_checktype(args.v[0], DST_STRING)); @@ -30,28 +37,28 @@ static int os_execute(DstArgs args) { ? NULL : (const char *) dst_unwrap_string(args.v[0]); int stat = system(cmd); - return dst_return(args, cmd + DST_RETURN(args, cmd ? dst_wrap_integer(stat) : dst_wrap_boolean(stat)); } static int os_getenv(DstArgs args) { if (args.n != 1 || !dst_checktype(args.v[0], DST_STRING)) - return dst_throw(args, "expected string"); + DST_THROW(args, "expected string"); const char *cstr = (const char *) dst_unwrap_string(args.v[0]); const char *res = getenv(cstr); - return dst_return(args, cstr + DST_RETURN(args, cstr ? dst_cstringv(res) : dst_wrap_nil()); } static int os_setenv(DstArgs args) { int t2; - if (args.n < 2) return dst_throw(args, "expected 2 arguments"); + if (args.n < 2) DST_THROW(args, "expected 2 arguments"); t2 = dst_type(args.v[1]); if (!dst_checktype(args.v[0], DST_STRING) || (t2 != DST_STRING && t2 != DST_NIL)) - return dst_throw(args, "expected string"); + DST_THROW(args, "expected string"); const char *k = (const char *) dst_unwrap_string(args.v[0]); #ifdef DST_WINDOWS if (t2 == DST_NIL) { @@ -73,16 +80,39 @@ static int os_setenv(DstArgs args) { } static int os_exit(DstArgs args) { - if (args.n == 0) { - exit(EXIT_SUCCESS); - } else if (dst_checktype(args.v[0], DST_TRUE) - || dst_checktype(args.v[0], DST_FALSE)) { - exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE); - return 0; - } else { - exit(dst_hash(args.v[0])); - } - return 0; + DST_MAXARITY(args, 1); + if (args.n == 0) { + exit(EXIT_SUCCESS); + } else if (dst_checktype(args.v[0], DST_TRUE) + || dst_checktype(args.v[0], DST_FALSE)) { + exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE); + return 0; + } else { + exit(dst_hash(args.v[0])); + } + return 0; +} + +static int os_clock(DstArgs args) { + DST_FIXARITY(args, 0); + clock_t time = clock(); + double dtime = time / (double) (CLOCKS_PER_SEC); + DST_RETURN_REAL(args, dtime); +} + +static int os_sleep(DstArgs args) { + int32_t delay; + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(delay, args, 0); + if (delay < 0) { + DST_THROW(args, "invalid argument to sleep"); + } +#ifdef DST_WINDOWS + Sleep(delay); +#else + sleep((unsigned int) delay); +#endif + return 0; } static const DstReg cfuns[] = { @@ -90,6 +120,8 @@ static const DstReg cfuns[] = { {"os.exit", os_exit}, {"os.getenv", os_getenv}, {"os.setenv", os_setenv}, + {"os.clock", os_clock}, + {"os.sleep", os_sleep}, {NULL, NULL} }; diff --git a/src/core/os.h b/src/core/os.h deleted file mode 100644 index 1e290767..00000000 --- a/src/core/os.h +++ /dev/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 - -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 diff --git a/src/core/string.c b/src/core/string.c index d8dfcadf..da89457a 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -468,7 +468,7 @@ const uint8_t *dst_formatc(const char *format, ...) { } case 't': { - dst_buffer_push_cstring(bufp, dst_type_names[va_arg(args, DstType)]); + dst_buffer_push_cstring(bufp, dst_type_names[va_arg(args, DstType)] + 1); break; } case 'V': diff --git a/src/core/table.c b/src/core/table.c index 5115bbaa..a3e168e9 100644 --- a/src/core/table.c +++ b/src/core/table.c @@ -240,43 +240,46 @@ void dst_table_merge_struct(DstTable *table, const DstKV *other) { static int cfun_new(DstArgs args) { DstTable *t; int32_t cap; - dst_fixarity(args, 1); - dst_arg_integer(cap, args, 0); + DST_FIXARITY(args, 1); + DST_ARG_INTEGER(cap, args, 0); t = dst_table(cap); - return dst_return(args, dst_wrap_table(t)); + DST_RETURN_TABLE(args, t); } static int cfun_getproto(DstArgs args) { DstTable *t; - dst_fixarity(args, 1); - dst_check(args, 0, DST_TABLE); - t = dst_unwrap_table(args.v[0]); - return dst_return(args, t->proto + DST_FIXARITY(args, 1); + DST_ARG_TABLE(t, args, 0); + DST_RETURN(args, t->proto ? dst_wrap_table(t->proto) : dst_wrap_nil()); } static int cfun_setproto(DstArgs args) { - dst_fixarity(args, 2); - dst_check(args, 0, DST_TABLE); - dst_checkmany(args, 1, DST_TFLAG_TABLE | DST_TFLAG_NIL); - dst_unwrap_table(args.v[0])->proto = dst_checktype(args.v[1], DST_TABLE) - ? dst_unwrap_table(args.v[1]) - : NULL; - return dst_return(args, args.v[0]); + DstTable *table, *proto; + DST_FIXARITY(args, 2); + DST_ARG_TABLE(table, args, 0); + if (dst_checktype(args.v[1], DST_NIL)) { + proto = NULL; + } else { + DST_ARG_TABLE(proto, args, 1); + } + table->proto = proto; + DST_RETURN_TABLE(args, table); } static int cfun_tostruct(DstArgs args) { DstTable *t; - dst_fixarity(args, 1); - dst_arg_table(t, args, 0); - return dst_return(args, dst_wrap_struct(dst_table_to_struct(t))); + DST_FIXARITY(args, 1); + DST_ARG_TABLE(t, args, 0); + DST_RETURN_STRUCT(args, dst_table_to_struct(t)); } static int cfun_rawget(DstArgs args) { - dst_fixarity(args, 2); - dst_check(args, 0, DST_TABLE); - return dst_return(args, dst_table_rawget(dst_unwrap_table(args.v[0]), args.v[1])); + DstTable *table; + DST_FIXARITY(args, 2); + DST_ARG_TABLE(table, args, 0); + DST_RETURN(args, dst_table_rawget(table, args.v[1])); } static const DstReg cfuns[] = { diff --git a/src/core/tuple.c b/src/core/tuple.c index 04d6c950..c651c183 100644 --- a/src/core/tuple.c +++ b/src/core/tuple.c @@ -94,14 +94,15 @@ static int cfun_slice(DstArgs args) { int32_t len; Dst *ret; int32_t start, end; - if (args.n < 1 || !dst_seq_view(args.v[0], &vals, &len)) return dst_throw(args, "expected array/tuple"); + DST_MINARITY(args, 1); + if (!dst_seq_view(args.v[0], &vals, &len)) DST_THROW(args, "expected array/tuple"); /* Get start */ if (args.n < 2) { start = 0; } else if (dst_checktype(args.v[1], DST_INTEGER)) { start = dst_unwrap_integer(args.v[1]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } /* Get end */ if (args.n < 3) { @@ -109,7 +110,7 @@ static int cfun_slice(DstArgs args) { } else if (dst_checktype(args.v[2], DST_INTEGER)) { end = dst_unwrap_integer(args.v[2]); } else { - return dst_throw(args, "expected integer"); + DST_THROW(args, "expected integer"); } if (start < 0) start = len + start; if (end < 0) end = len + end + 1; @@ -122,31 +123,31 @@ static int cfun_slice(DstArgs args) { } else { ret = dst_tuple_begin(0); } - return dst_return(args, dst_wrap_tuple(dst_tuple_end(ret))); + DST_RETURN_TUPLE(args, dst_tuple_end(ret)); } static int cfun_prepend(DstArgs args) { const Dst *t; int32_t len; Dst *n; - if (args.n != 2) return dst_throw(args, "expected 2 arguments"); - if (!dst_seq_view(args.v[0], &t, &len)) return dst_throw(args, "expected tuple/array"); + DST_FIXARITY(args, 2); + if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array"); n = dst_tuple_begin(len + 1); memcpy(n + 1, t, sizeof(Dst) * len); n[0] = args.v[1]; - return dst_return(args, dst_wrap_tuple(dst_tuple_end(n))); + DST_RETURN_TUPLE(args, dst_tuple_end(n)); } static int cfun_append(DstArgs args) { const Dst *t; int32_t len; Dst *n; - if (args.n != 2) return dst_throw(args, "expected 2 arguments"); - if (!dst_seq_view(args.v[0], &t, &len)) return dst_throw(args, "expected tuple/array"); + DST_FIXARITY(args, 2); + if (!dst_seq_view(args.v[0], &t, &len)) DST_THROW(args, "expected tuple/array"); n = dst_tuple_begin(len + 1); memcpy(n, t, sizeof(Dst) * len); n[len] = args.v[1]; - return dst_return(args, dst_wrap_tuple(dst_tuple_end(n))); + DST_RETURN_TUPLE(args, dst_tuple_end(n)); } /* Load the tuple module */ diff --git a/src/core/util.c b/src/core/util.c index 1df1857a..37ad6e8f 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -35,8 +35,8 @@ const char dst_base64[65] = * mnemonics instead of a bit pattern for type checking */ const char *const dst_type_names[16] = { ":nil", - ":false", - ":true", + ":boolean", + ":boolean", ":fiber", ":integer", ":real", @@ -209,18 +209,18 @@ int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap) /* Get actual type name of a value for debugging purposes */ static const char *typestr(DstArgs args, int32_t n) { DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL; - return (actual == DST_ABSTRACT) + return ((actual == DST_ABSTRACT) ? dst_abstract_type(dst_unwrap_abstract(args.v[n]))->name - : dst_type_names[actual]; + : dst_type_names[actual]) + 1; } int dst_type_err(DstArgs args, int32_t n, DstType expected) { const uint8_t *message = dst_formatc( - "bad argument #%d, expected %t, got %s", + "bad slot #%d, expected %t, got %s", n, expected, typestr(args, n)); - return dst_throwv(args, dst_wrap_string(message)); + DST_THROWV(args, dst_wrap_string(message)); } int dst_typemany_err(DstArgs args, int32_t n, int expected) { @@ -229,7 +229,7 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) { const uint8_t *message; DstBuffer buf; dst_buffer_init(&buf, 20); - dst_buffer_push_string(&buf, dst_formatc("bad argument #%d, expected ", n)); + dst_buffer_push_string(&buf, dst_formatc("bad slot #%d, expected ", n)); i = 0; while (expected) { if (1 & expected) { @@ -247,19 +247,19 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) { dst_buffer_push_cstring(&buf, typestr(args, n)); message = dst_string(buf.data, buf.count); dst_buffer_deinit(&buf); - return dst_throwv(args, dst_wrap_string(message)); + DST_THROWV(args, dst_wrap_string(message)); } int dst_arity_err(DstArgs args, int32_t n, const char *prefix) { - return dst_throwv(args, + DST_THROWV(args, dst_wrap_string(dst_formatc( "expected %s%d argument%s, got %d", prefix, n, n == 1 ? "" : "s", args.n))); } int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at) { - return dst_throwv(args, + DST_THROWV(args, dst_wrap_string(dst_formatc( - "bad argument #%d, expected %s, got %s", + "bad slot #%d, expected %s, got %s", n, at->name, typestr(args, n)))); } diff --git a/src/core/vm.c b/src/core/vm.c index 9f0cbdaf..39356e2a 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -224,7 +224,13 @@ static void *op_lookup[255] = { goto vm_error; VM_OP(DOP_TYPECHECK) - vm_assert((1 << dst_type(stack[oparg(1, 0xFF)])) & oparg(2, 0xFFFF), "typecheck failed"); + if (!((1 << dst_type(stack[oparg(1, 0xFF)])) & oparg(2, 0xFFFF))) { + DstArgs tempargs; + tempargs.n = oparg(1, 0xFF) + 1; + tempargs.v = stack; + dst_typemany_err(tempargs, oparg(1, 0xFF), oparg(2, 0xFFFF)); + goto vm_error; + } pc++; vm_next(); @@ -922,7 +928,7 @@ Dst dst_resume(DstFiber *fiber, int32_t argn, const Dst *argv) { return dst_run(fiber); } -/* Setup functions */ +/* Setup VM */ int dst_init() { /* Garbage collection */ dst_vm_blocks = NULL; diff --git a/src/include/dst/dst.h b/src/include/dst/dst.h index 8c2482fe..f8934966 100644 --- a/src/include/dst/dst.h +++ b/src/include/dst/dst.h @@ -202,34 +202,36 @@ int dst_arity_err(DstArgs args, int32_t n, const char *prefix); int dst_type_err(DstArgs args, int32_t n, DstType expected); int dst_typemany_err(DstArgs args, int32_t n, int expected); int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at); -#define dst_throw(a, e) (*((a).ret) = dst_cstringv(e), 1) -#define dst_throwv(a, v) (*((a).ret) = (v), 1) -#define dst_return(a, v) (*((a).ret) = (v), 0) + +/* Macros */ +#define DST_THROW(a, e) return (*((a).ret) = dst_cstringv(e), 1) +#define DST_THROWV(a, v) return (*((a).ret) = (v), 1) +#define DST_RETURN(a, v) return (*((a).ret) = (v), 0) /* Early exit macros */ -#define dst_maxarity(A, N) do { if ((A).n > (N))\ +#define DST_MAXARITY(A, N) do { if ((A).n > (N))\ return dst_arity_err(A, N, "at most "); } while (0) -#define dst_minarity(A, N) do { if ((A).n < (N))\ +#define DST_MINARITY(A, N) do { if ((A).n < (N))\ return dst_arity_err(A, N, "at least "); } while (0) -#define dst_fixarity(A, N) do { if ((A).n != (N))\ +#define DST_FIXARITY(A, N) do { if ((A).n != (N))\ return dst_arity_err(A, N, ""); } while (0) -#define dst_check(A, N, T) do {\ +#define DST_CHECK(A, N, T) do {\ if ((A).n > (N)) {\ if (!dst_checktype((A).v[(N)], (T))) return dst_type_err(A, N, T);\ } else {\ if ((T) != DST_NIL) return dst_type_err(A, N, T);\ }\ } while (0) -#define dst_checkmany(A, N, TS) do {\ +#define DST_CHECKMANY(A, N, TS) do {\ if ((A).n > (N)) {\ DstType t = dst_type((A).v[(N)]);\ if (!((1 << t) & (TS))) return dst_typemany_err(A, N, TS);\ } else {\ - if (!((TS) & DST_NIL)) return dst_type_err(A, N, TS);\ + if (!((TS) & DST_NIL)) return dst_typemany_err(A, N, TS);\ }\ } while (0) -#define dst_checkabstract(A, N, AT) do {\ +#define DST_CHECKABSTRACT(A, N, AT) do {\ if ((A).n > (N)) {\ Dst x = (A).v[(N)];\ if (!dst_checktype(x, DST_ABSTRACT) ||\ @@ -240,42 +242,69 @@ int dst_typeabstract_err(DstArgs args, int32_t n, const DstAbstractType *at); }\ } while (0) -#define dst_arg_number(DEST, A, N) do { \ - if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\ +#define DST_ARG_NUMBER(DEST, A, N) do { \ + if ((A).n <= (N)) \ + return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\ Dst val = (A).v[(N)];\ - if (dst_checktype(val, DST_REAL)) { DEST = dst_unwrap_real(val); }\ - else if (dst_checktype(val, DST_INTEGER)) { DEST = (double) dst_unwrap_integer(val); }\ - else return dst_typemany_err(A, N, DST_TFLAG_NUMBER); } while (0) + if (dst_checktype(val, DST_REAL)) { \ + DEST = dst_unwrap_real(val); \ + } else if (dst_checktype(val, DST_INTEGER)) {\ + DEST = (double) dst_unwrap_integer(val);\ + }\ + else return dst_typemany_err(A, N, DST_TFLAG_NUMBER); \ +} while (0) -#define dst_arg_boolean(DEST, A, N) do { \ - dst_checkmany(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\ - DEST = dst_unwrap_boolean((A).v[(N)]); } while (0) +#define DST_ARG_BOOLEAN(DEST, A, N) do { \ + DST_CHECKMANY(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\ + DEST = dst_unwrap_boolean((A).v[(N)]); \ +} while (0) -#define _dst_arg(TYPE, NAME, DEST, A, N) do { \ - dst_check(A, N, TYPE);\ - DEST = dst_unwrap_##NAME((A).v[(N)]); } while (0) - -#define dst_arg_bytes(DESTBYTES, DESTLEN, A, N) do {\ +#define DST_ARG_BYTES(DESTBYTES, DESTLEN, A, N) do {\ if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\ if (!dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\ return dst_typemany_err(A, N, DST_TFLAG_BYTES);\ }\ } while (0) -#define dst_arg_fiber(DEST, A, N) _dst_arg(DST_FIBER, fiber, DEST, A, N) -#define dst_arg_integer(DEST, A, N) _dst_arg(DST_INTEGER, integer, DEST, A, N) -#define dst_arg_real(DEST, A, N) _dst_arg(DST_REAL, real, DEST, A, N) -#define dst_arg_string(DEST, A, N) _dst_arg(DST_STRING, string, DEST, A, N) -#define dst_arg_symbol(DEST, A, N) _dst_arg(DST_SYMBOL, symbol, DEST, A, N) -#define dst_arg_array(DEST, A, N) _dst_arg(DST_ARRAY, array, DEST, A, N) -#define dst_arg_tuple(DEST, A, N) _dst_arg(DST_TUPLE, tuple, DEST, A, N) -#define dst_arg_table(DEST, A, N) _dst_arg(DST_TABLE, table, DEST, A, N) -#define dst_arg_struct(DEST, A, N) _dst_arg(DST_STRUCT, st, DEST, A, N) -#define dst_arg_buffer(DEST, A, N) _dst_arg(DST_BUFFER, buffer, DEST, A, N) -#define dst_arg_function(DEST, A, N) _dst_arg(DST_FUNCTION, function, DEST, A, N) -#define dst_arg_cfunction(DEST, A, N) _dst_arg(DST_CFUNCTION, cfunction, DEST, A, N) +#define _DST_ARG(TYPE, NAME, DEST, A, N) do { \ + DST_CHECK(A, N, TYPE);\ + DEST = dst_unwrap_##NAME((A).v[(N)]); \ +} while (0) -#define dst_arg_abstract(DEST, A, N) _dst_arg(DST_ABSTRACT, abstract, DEST, A, N) +#define DST_ARG_FIBER(DEST, A, N) _DST_ARG(DST_FIBER, fiber, DEST, A, N) +#define DST_ARG_INTEGER(DEST, A, N) _DST_ARG(DST_INTEGER, integer, DEST, A, N) +#define DST_ARG_REAL(DEST, A, N) _DST_ARG(DST_REAL, real, DEST, A, N) +#define DST_ARG_STRING(DEST, A, N) _DST_ARG(DST_STRING, string, DEST, A, N) +#define DST_ARG_SYMBOL(DEST, A, N) _DST_ARG(DST_SYMBOL, symbol, DEST, A, N) +#define DST_ARG_ARRAY(DEST, A, N) _DST_ARG(DST_ARRAY, array, DEST, A, N) +#define DST_ARG_TUPLE(DEST, A, N) _DST_ARG(DST_TUPLE, tuple, DEST, A, N) +#define DST_ARG_TABLE(DEST, A, N) _DST_ARG(DST_TABLE, table, DEST, A, N) +#define DST_ARG_STRUCT(DEST, A, N) _DST_ARG(DST_STRUCT, st, DEST, A, N) +#define DST_ARG_BUFFER(DEST, A, N) _DST_ARG(DST_BUFFER, buffer, DEST, A, N) +#define DST_ARG_FUNCTION(DEST, A, N) _DST_ARG(DST_FUNCTION, function, DEST, A, N) +#define DST_ARG_CFUNCTION(DEST, A, N) _DST_ARG(DST_CFUNCTION, cfunction, DEST, A, N) +#define DST_ARG_ABSTRACT(DEST, A, N) _DST_ARG(DST_ABSTRACT, abstract, DEST, A, N) + +#define DST_RETURN_NIL(A) return 0 +#define DST_RETURN_FALSE(A) DST_RETURN(A, dst_wrap_false()) +#define DST_RETURN_TRUE(A) DST_RETURN(A, dst_wrap_true()) +#define DST_RETURN_BOOLEAN(A, X) DST_RETURN(A, dst_wrap_boolean(X)) +#define DST_RETURN_FIBER(A, X) DST_RETURN(A, dst_wrap_fiber(X)) +#define DST_RETURN_INTEGER(A, X) DST_RETURN(A, dst_wrap_integer(X)) +#define DST_RETURN_REAL(A, X) DST_RETURN(A, dst_wrap_real(X)) +#define DST_RETURN_STRING(A, X) DST_RETURN(A, dst_wrap_string(X)) +#define DST_RETURN_SYMBOL(A, X) DST_RETURN(A, dst_wrap_symbol(X)) +#define DST_RETURN_ARRAY(A, X) DST_RETURN(A, dst_wrap_array(X)) +#define DST_RETURN_TUPLE(A, X) DST_RETURN(A, dst_wrap_tuple(X)) +#define DST_RETURN_TABLE(A, X) DST_RETURN(A, dst_wrap_table(X)) +#define DST_RETURN_STRUCT(A, X) DST_RETURN(A, dst_wrap_struct(X)) +#define DST_RETURN_BUFFER(A, X) DST_RETURN(A, dst_wrap_buffer(X)) +#define DST_RETURN_FUNCTION(A, X) DST_RETURN(A, dst_wrap_function(X)) +#define DST_RETURN_CFUNCTION(A, X) DST_RETURN(A, dst_wrap_cfunction(X)) +#define DST_RETURN_ABSTRACT(A, X) DST_RETURN(A, dst_wrap_abstract(X)) + +#define DST_RETURN_CSTRING(A, X) DST_RETURN(A, dst_cstringv(X)) +#define DST_RETURN_CSYMBOL(A, X) DST_RETURN(A, dst_csymbolv(X)) #ifdef __cplusplus } diff --git a/src/mainclient/line.c b/src/mainclient/line.c index 9ee7ea61..67b40bcb 100644 --- a/src/mainclient/line.c +++ b/src/mainclient/line.c @@ -24,13 +24,13 @@ /* Common */ int dst_line_getter(DstArgs args) { - dst_fixarity(args, 2); - dst_check(args, 0, DST_STRING); - dst_check(args, 1, DST_BUFFER); + DST_FIXARITY(args, 2); + DST_CHECK(args, 0, DST_STRING); + DST_CHECK(args, 1, DST_BUFFER); dst_line_get( dst_unwrap_string(args.v[0]), dst_unwrap_buffer(args.v[1])); - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static void simpleline(DstBuffer *buffer) { diff --git a/src/parser/ast.c b/src/parser/ast.c index 664ebcbb..38055daf 100644 --- a/src/parser/ast.c +++ b/src/parser/ast.c @@ -32,7 +32,7 @@ static int dst_ast_gcmark(void *p, size_t size) { /* AST type */ static DstAbstractType dst_ast_type = { - ":parse.ast", + ":parser.ast", NULL, dst_ast_gcmark }; diff --git a/src/parser/parse.c b/src/parser/parse.c index 753aa048..2706e9b2 100644 --- a/src/parser/parse.c +++ b/src/parser/parse.c @@ -447,6 +447,7 @@ static int ampersand(DstParser *p, DstParseState *state, uint8_t c) { return 0; } +/* The root state of the parser */ static int root(DstParser *p, DstParseState *state, uint8_t c) { switch (c) { default: @@ -575,43 +576,21 @@ static int parsergc(void *p, size_t size) { } DstAbstractType dst_parse_parsertype = { - ":parse.parser", + ":parser.parser", parsergc, parsermark }; /* C Function parser */ static int cfun_parser(DstArgs args) { - int flags; - if (args.n > 1) return dst_throw(args, "expected 1 argument"); - if (args.n) { - if (!dst_checktype(args.v[0], DST_INTEGER)) return dst_throw(args, "expected integer"); - flags = dst_unwrap_integer(args.v[0]); - } else { - flags = 0; + int flags = 0; + DST_MAXARITY(args, 1); + if (args.n == 1) { + DST_ARG_INTEGER(flags, args, 0); } DstParser *p = dst_abstract(&dst_parse_parsertype, sizeof(DstParser)); dst_parser_init(p, flags); - return dst_return(args, dst_wrap_abstract(p)); -} - -/* Check file argument */ -static DstParser *checkparser(DstArgs args) { - DstParser *p; - if (args.n == 0) { - *args.ret = dst_cstringv("expected parse.parser"); - return NULL; - } - if (!dst_checktype(args.v[0], DST_ABSTRACT)) { - *args.ret = dst_cstringv("expected parse.parser"); - return NULL; - } - p = (DstParser *) dst_unwrap_abstract(args.v[0]); - if (dst_abstract_type(p) != &dst_parse_parsertype) { - *args.ret = dst_cstringv("expected parse.parser"); - return NULL; - } - return p; + DST_RETURN_ABSTRACT(args, p); } static int cfun_consume(DstArgs args) { @@ -619,10 +598,10 @@ static int cfun_consume(DstArgs args) { int32_t len; DstParser *p; int32_t i; - if (args.n != 2) return dst_throw(args, "expected 2 arguments"); - p = checkparser(args); - if (!p) return 1; - if (!dst_chararray_view(args.v[1], &bytes, &len)) return dst_throw(args, "expected string/buffer"); + DST_FIXARITY(args, 2); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); + DST_ARG_BYTES(bytes, len, args, 1); for (i = 0; i < len; i++) { dst_parser_consume(p, bytes[i]); switch (dst_parser_status(p)) { @@ -633,27 +612,30 @@ static int cfun_consume(DstArgs args) { { DstBuffer *b = dst_buffer(len - i); dst_buffer_push_bytes(b, bytes + i + 1, len - i - 1); - return dst_return(args, dst_wrap_buffer(b)); + DST_RETURN_BUFFER(args, b); } } } - return dst_return(args, dst_wrap_nil()); + DST_RETURN(args, dst_wrap_nil()); } static int cfun_byte(DstArgs args) { + int32_t i; DstParser *p; - if (args.n != 2) return dst_throw(args, "expected 2 arguments"); - p = checkparser(args); - if (!p) return 1; - if (!dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected integer"); - dst_parser_consume(p, 0xFF & dst_unwrap_integer(args.v[1])); - return dst_return(args, args.v[0]); + DST_FIXARITY(args, 2); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); + DST_ARG_INTEGER(i, args, 1); + dst_parser_consume(p, 0xFF & i); + DST_RETURN(args, args.v[0]); } static int cfun_status(DstArgs args) { const char *stat = NULL; - DstParser *p = checkparser(args); - if (!p) return 1; + DstParser *p; + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); switch (dst_parser_status(p)) { case DST_PARSE_FULL: stat = ":full"; @@ -668,42 +650,50 @@ static int cfun_status(DstArgs args) { stat = ":root"; break; } - return dst_return(args, dst_csymbolv(stat)); + DST_RETURN_CSYMBOL(args, stat); } static int cfun_error(DstArgs args) { const char *err; - DstParser *p = checkparser(args); - if (!p) return 1; + DstParser *p; + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); err = dst_parser_error(p); if (err) { - return dst_return(args, dst_cstringv(err)); + DST_RETURN_CSYMBOL(args, err); } else { - return dst_return(args, dst_wrap_nil()); + DST_RETURN_NIL(args); } } static int cfun_produce(DstArgs args) { Dst val; - DstParser *p = checkparser(args); - if (!p) return 1; + DstParser *p; + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); val = dst_parser_produce(p); - return dst_return(args, val); + DST_RETURN(args, val); } static int cfun_flush(DstArgs args) { - DstParser *p = checkparser(args); - if (!p) return 1; + DstParser *p; + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); dst_parser_flush(p); - return dst_return(args, args.v[0]); + DST_RETURN(args, args.v[0]); } static int cfun_state(DstArgs args) { int32_t i; uint8_t *buf = NULL; const uint8_t *str; - DstParser *p = checkparser(args); - if (!p) return 1; + DstParser *p; + DST_FIXARITY(args, 1); + DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype); + p = (DstParser *) dst_unwrap_abstract(args.v[0]); for (i = 0; i < dst_v_count(p->states); i++) { DstParseState *s = p->states + i; if (s->flags & PFLAG_PARENS) { @@ -723,30 +713,30 @@ static int cfun_state(DstArgs args) { } str = dst_string(buf, dst_v_count(buf)); dst_v_free(buf); - return dst_return(args, dst_wrap_string(str)); + DST_RETURN_STRING(args, str); } /* AST */ static int cfun_unwrap1(DstArgs args) { - if (args.n != 1) return dst_throw(args, "expected 1 argument"); - return dst_return(args, dst_ast_unwrap1(args.v[0])); + DST_FIXARITY(args, 1); + DST_RETURN(args, dst_ast_unwrap1(args.v[0])); } static int cfun_unwrap(DstArgs args) { - if (args.n != 1) return dst_throw(args, "expected 1 argument"); - return dst_return(args, dst_ast_unwrap(args.v[0])); + DST_FIXARITY(args, 1); + DST_RETURN(args, dst_ast_unwrap(args.v[0])); } static int cfun_wrap(DstArgs args) { - if (args.n != 1) return dst_throw(args, "expected 1 argument"); - return dst_return(args, dst_ast_wrap(args.v[0], -1, -1)); + DST_FIXARITY(args, 1); + DST_RETURN(args, dst_ast_wrap(args.v[0], -1, -1)); } static int cfun_node(DstArgs args) { DstAst *ast; Dst *tup; int32_t start, end; - if (args.n != 1) return dst_throw(args, "expected 1 argument"); + DST_FIXARITY(args, 1); ast = dst_ast_node(args.v[0]); if (ast) { start = ast->source_start; @@ -758,7 +748,7 @@ static int cfun_node(DstArgs args) { tup = dst_tuple_begin(2); tup[0] = dst_wrap_integer(start); tup[1] = dst_wrap_integer(end); - return dst_return(args, dst_wrap_tuple(dst_tuple_end(tup))); + DST_RETURN_TUPLE(args, dst_tuple_end(tup)); } static const DstReg cfuns[] = {