From 3262316e6055deb1e6fbd36f512e286c68d832aa Mon Sep 17 00:00:00 2001 From: bakpakin Date: Sun, 14 Jan 2018 12:10:45 -0500 Subject: [PATCH] Factor CFunction args into struct. --- core/math.c | 158 ++++++++++++------------- core/native.c | 16 +-- core/stl.c | 263 ++++++++++++++++++++--------------------- core/table.c | 21 ++++ core/vm.c | 29 ++--- include/dst/dst.h | 5 +- include/dst/dststl.h | 78 ++++++------ include/dst/dsttypes.h | 10 +- 8 files changed, 304 insertions(+), 276 deletions(-) diff --git a/core/math.c b/core/math.c index 2f8abcf4..72a10c46 100644 --- a/core/math.c +++ b/core/math.c @@ -24,40 +24,40 @@ #include /* Convert a number to an integer */ -int dst_int(int32_t argn, Dst *argv, Dst *ret) { - if (argn != 1) { - *ret = dst_cstringv("expected 1 argument"); +int dst_int(DstArgs args) { + if (args.n != 1) { + *args.ret = dst_cstringv("expected 1 argument"); return 1; } - switch (dst_type(argv[0])) { + switch (dst_type(args.v[0])) { default: - *ret = dst_cstringv("could not convert to integer"); + *args.ret = dst_cstringv("could not convert to integer"); return 1; case DST_REAL: - *ret = dst_wrap_integer((int32_t) dst_unwrap_real(argv[0])); + *args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0])); break; case DST_INTEGER: - *ret = argv[0]; + *args.ret = args.v[0]; break; } return 0; } /* Convert a number to a real number */ -int dst_real(int32_t argn, Dst *argv, Dst *ret) { - if (argn != 1) { - *ret = dst_cstringv("expected 1 argument"); +int dst_real(DstArgs args) { + if (args.n != 1) { + *args.ret = dst_cstringv("expected 1 argument"); return 1; } - switch (dst_type(argv[0])) { + switch (dst_type(args.v[0])) { default: - *ret = dst_cstringv("could not convert to real"); + *args.ret = dst_cstringv("could not convert to real"); return 1; case DST_REAL: - *ret = argv[0]; + *args.ret = args.v[0]; break; case DST_INTEGER: - *ret = dst_wrap_real((double) dst_unwrap_integer(argv[0])); + *args.ret = dst_wrap_real((double) dst_unwrap_integer(args.v[0])); break; } return 0; @@ -105,17 +105,17 @@ DST_DEFINE_DIVIDER_OP(divide, DIV, DIV) DST_DEFINE_DIVIDER_OP(modulo, MOD, fmod) #define DST_DEFINE_REDUCER(name, fop, start)\ -int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ +int dst_##name(DstArgs args) {\ int32_t i;\ Dst accum = dst_wrap_integer(start);\ - for (i = 0; i < argn; i++) {\ - accum = fop(accum, argv[i]);\ + for (i = 0; i < args.n; i++) {\ + accum = fop(accum, args.v[i]);\ }\ if (dst_checktype(accum, DST_NIL)) {\ - *ret = dst_cstringv("expected number");\ + *args.ret = dst_cstringv("expected number");\ return 1;\ }\ - *ret = accum;\ + *args.ret = accum;\ return 0;\ } @@ -123,27 +123,27 @@ DST_DEFINE_REDUCER(add, dst_op_add, 0) DST_DEFINE_REDUCER(multiply, dst_op_multiply, 1) #define DST_DEFINE_DIVIDER(name, unarystart)\ -int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ +int dst_##name(DstArgs args) {\ int32_t i;\ Dst accum;\ - if (argn < 1) {\ - *ret = dst_cstringv("expected at least one argument");\ + if (args.n < 1) {\ + *args.ret = dst_cstringv("expected at least one argument");\ return 1;\ - } else if (argn == 1) {\ + } else if (args.n == 1) {\ accum = unarystart;\ i = 0;\ } else {\ - accum = argv[0];\ + accum = args.v[0];\ i = 1;\ }\ - for (; i < argn; i++) {\ - accum = dst_op_##name(accum, argv[i]);\ + for (; i < args.n; i++) {\ + accum = dst_op_##name(accum, args.v[i]);\ }\ if (dst_checktype(accum, DST_NIL)) {\ - *ret = dst_cstringv("expected number or division error");\ + *args.ret = dst_cstringv("expected number or division error");\ return 1;\ }\ - *ret = accum;\ + *args.ret = accum;\ return 0;\ } @@ -157,32 +157,32 @@ DST_DEFINE_DIVIDER(subtract, dst_wrap_integer(0)) #undef MOD #undef DST_DEFINE_BINOP -int dst_bnot(int32_t argn, Dst *argv, Dst *ret) { - if (argn != 1) { - *ret = dst_cstringv("expected 1 argument"); +int dst_bnot(DstArgs args) { + if (args.n != 1) { + *args.ret = dst_cstringv("expected 1 argument"); return 1; } - if (!dst_checktype(argv[0], DST_INTEGER)) { - *ret = dst_cstringv("expected integer"); + if (!dst_checktype(args.v[0], DST_INTEGER)) { + *args.ret = dst_cstringv("expected integer"); return 1; } - *ret = dst_wrap_integer(~dst_unwrap_integer(argv[0])); + *args.ret = dst_wrap_integer(~dst_unwrap_integer(args.v[0])); return 0; } #define DST_DEFINE_BITOP(name, op, start)\ -int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ +int dst_##name(DstArgs args) {\ int32_t i;\ int32_t accum = start;\ - for (i = 0; i < argn; i++) {\ - Dst arg = argv[i];\ + for (i = 0; i < args.n; i++) {\ + Dst arg = args.v[i];\ if (!dst_checktype(arg, DST_INTEGER)) {\ - *ret = dst_cstringv("expected integer");\ + *args.ret = dst_cstringv("expected integer");\ return -1;\ }\ accum op dst_unwrap_integer(arg);\ }\ - *ret = dst_wrap_integer(accum);\ + *args.ret = dst_wrap_integer(accum);\ return 0;\ } @@ -190,47 +190,47 @@ DST_DEFINE_BITOP(band, &=, -1) DST_DEFINE_BITOP(bor, |=, 0) DST_DEFINE_BITOP(bxor, ^=, 0) -int dst_lshift(int argn, Dst *argv, Dst *ret) { - if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { - *ret = dst_cstringv("expected 2 integers"); +int dst_lshift(DstArgs args) { + if (args.n != 2 || !dst_checktype(args.v[0], DST_INTEGER) || !dst_checktype(args.v[1], DST_INTEGER)) { + *args.ret = dst_cstringv("expected 2 integers"); return 1; } - *ret = dst_wrap_integer(dst_unwrap_integer(argv[0]) >> dst_unwrap_integer(argv[1])); + *args.ret = dst_wrap_integer(dst_unwrap_integer(args.v[0]) >> dst_unwrap_integer(args.v[1])); return 0; } -int dst_rshift(int argn, Dst *argv, Dst *ret) { - if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { - *ret = dst_cstringv("expected 2 integers"); +int dst_rshift(DstArgs args) { + if (args.n != 2 || !dst_checktype(args.v[0], DST_INTEGER) || !dst_checktype(args.v[1], DST_INTEGER)) { + *args.ret = dst_cstringv("expected 2 integers"); return 1; } - *ret = dst_wrap_integer(dst_unwrap_integer(argv[0]) << dst_unwrap_integer(argv[1])); + *args.ret = dst_wrap_integer(dst_unwrap_integer(args.v[0]) << dst_unwrap_integer(args.v[1])); return 0; } -int dst_lshiftu(int argn, Dst *argv, Dst *ret) { - if (argn != 2 || !dst_checktype(argv[0], DST_INTEGER) || !dst_checktype(argv[1], DST_INTEGER)) { - *ret = dst_cstringv("expected 2 integers"); +int dst_lshiftu(DstArgs args) { + if (args.n != 2 || !dst_checktype(args.v[0], DST_INTEGER) || !dst_checktype(args.v[1], DST_INTEGER)) { + *args.ret = dst_cstringv("expected 2 integers"); return 1; } - *ret = dst_wrap_integer((int32_t)((uint32_t)dst_unwrap_integer(argv[0]) >> dst_unwrap_integer(argv[1]))); + *args.ret = dst_wrap_integer((int32_t)((uint32_t)dst_unwrap_integer(args.v[0]) >> dst_unwrap_integer(args.v[1]))); return 0; } #define DST_DEFINE_MATHOP(name, fop)\ -int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ - if (argn != 1) {\ - *ret = dst_cstringv("expected 1 argument");\ +int dst_##name(DstArgs args) {\ + if (args.n != 1) {\ + *args.ret = dst_cstringv("expected 1 argument");\ return 1;\ }\ - if (dst_checktype(argv[0], DST_INTEGER)) {\ - argv[0] = dst_wrap_real(dst_unwrap_integer(argv[0]));\ + if (dst_checktype(args.v[0], DST_INTEGER)) {\ + args.v[0] = dst_wrap_real(dst_unwrap_integer(args.v[0]));\ }\ - if (!dst_checktype(argv[0], DST_REAL)) {\ - *ret = dst_cstringv("expected number");\ + if (!dst_checktype(args.v[0], DST_REAL)) {\ + *args.ret = dst_cstringv("expected number");\ return 1;\ }\ - *ret = dst_wrap_real(fop(dst_unwrap_real(argv[0])));\ + *args.ret = dst_wrap_real(fop(dst_unwrap_real(args.v[0])));\ return 0;\ } @@ -252,21 +252,21 @@ DST_DEFINE_MATHOP(fabs, fabs) DST_DEFINE_MATHOP(floor, floor) #define DST_DEFINE_MATH2OP(name, fop)\ -int dst_##name(int32_t argn, Dst *argv, Dst *ret) {\ - if (argn != 2) {\ - *ret = dst_cstringv("expected 2 arguments");\ +int dst_##name(DstArgs args) {\ + if (args.n != 2) {\ + *args.ret = dst_cstringv("expected 2 arguments");\ return 1;\ }\ - if (dst_checktype(argv[0], DST_INTEGER))\ - argv[0] = dst_wrap_real(dst_unwrap_integer(argv[0]));\ - if (dst_checktype(argv[1], DST_INTEGER))\ - argv[1] = dst_wrap_real(dst_unwrap_integer(argv[1]));\ - if (!dst_checktype(argv[0], DST_REAL) || !dst_checktype(argv[1], DST_REAL)) {\ - *ret = dst_cstringv("expected real");\ + if (dst_checktype(args.v[0], DST_INTEGER))\ + args.v[0] = dst_wrap_real(dst_unwrap_integer(args.v[0]));\ + if (dst_checktype(args.v[1], DST_INTEGER))\ + args.v[1] = dst_wrap_real(dst_unwrap_integer(args.v[1]));\ + if (!dst_checktype(args.v[0], DST_REAL) || !dst_checktype(args.v[1], DST_REAL)) {\ + *args.ret = dst_cstringv("expected real");\ return 1;\ }\ - *ret =\ - dst_wrap_real(fop(dst_unwrap_real(argv[0]), dst_unwrap_real(argv[1])));\ + *args.ret =\ + dst_wrap_real(fop(dst_unwrap_real(args.v[0]), dst_unwrap_real(args.v[1])));\ return 0;\ }\ @@ -274,22 +274,22 @@ DST_DEFINE_MATH2OP(atan2, atan2) DST_DEFINE_MATH2OP(pow, pow) DST_DEFINE_MATH2OP(fmod, fmod) -int dst_modf(int32_t argn, Dst *argv, Dst *ret) { +int dst_modf(DstArgs args) { double intpart; Dst *tup; - if (argn != 1) { - *ret = dst_cstringv("expected 1 argument"); + if (args.n != 1) { + *args.ret = dst_cstringv("expected 1 argument"); return 1; } - if (dst_checktype(argv[0], DST_INTEGER)) - argv[0] = dst_wrap_real(dst_unwrap_integer(argv[0])); - if (!dst_checktype(argv[0], DST_REAL)) { - *ret = dst_cstringv("expected real"); + if (dst_checktype(args.v[0], DST_INTEGER)) + args.v[0] = dst_wrap_real(dst_unwrap_integer(args.v[0])); + if (!dst_checktype(args.v[0], DST_REAL)) { + *args.ret = dst_cstringv("expected real"); return 1; } tup = dst_tuple_begin(2); - tup[0] = dst_wrap_real(modf(dst_unwrap_real(argv[0]), &intpart)); + tup[0] = dst_wrap_real(modf(dst_unwrap_real(args.v[0]), &intpart)); tup[1] = dst_wrap_real(intpart); - *ret = dst_wrap_tuple(dst_tuple_end(tup)); + *args.ret = dst_wrap_tuple(dst_tuple_end(tup)); return 0; } diff --git a/core/native.c b/core/native.c index 20ed0c42..ea63c995 100644 --- a/core/native.c +++ b/core/native.c @@ -53,21 +53,21 @@ DstCFunction dst_native(const char *name, const uint8_t **error) { return init; } -int dst_load_native(int32_t argn, Dst *argv, Dst *ret) { +int dst_load_native(DstArgs args) { DstCFunction init; const uint8_t *error = NULL; - if (argn < 1) { - *ret = dst_cstringv("expected at least one argument"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected at least one argument"); return 1; } - if (!dst_checktype(argv[0], DST_STRING)) { - *ret = dst_cstringv("expected string"); + if (!dst_checktype(args.v[0], DST_STRING)) { + *args.ret = dst_cstringv("expected string"); return 1; } - init = dst_native((const char *)dst_unwrap_string(argv[0]), &error); + init = dst_native((const char *)dst_unwrap_string(args.v[0]), &error); if (!init) { - *ret = dst_wrap_string(error); + *args.ret = dst_wrap_string(error); return 1; } - return init(argn, argv, ret); + return init(args); } diff --git a/core/stl.c b/core/stl.c index e3092f09..ab92eb76 100644 --- a/core/stl.c +++ b/core/stl.c @@ -23,32 +23,32 @@ #include #include -int dst_stl_push(int32_t argn, Dst *argv, Dst *ret) { - if (argn != 2) { - *ret = dst_cstringv("expected 2 arguments"); +int dst_stl_push(DstArgs args) { + if (args.n != 2) { + *args.ret = dst_cstringv("expected 2 arguments"); return 1; } - if (!dst_checktype(argv[0], DST_ARRAY)) { - *ret = dst_cstringv("expected array"); + if (!dst_checktype(args.v[0], DST_ARRAY)) { + *args.ret = dst_cstringv("expected array"); return 1; } - dst_array_push(dst_unwrap_array(argv[0]), argv[1]); - *ret = argv[0]; + dst_array_push(dst_unwrap_array(args.v[0]), args.v[1]); + *args.ret = args.v[0]; return 0; } -int dst_stl_parse(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_parse(DstArgs args) { const uint8_t *src; int32_t len; DstParseResult res; const char *status_string = "ok"; DstTable *t; - if (argn < 1) { - *ret = dst_cstringv("expected at least on argument"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected at least on argument"); return 1; } - if (!dst_chararray_view(argv[0], &src, &len)) { - *ret = dst_cstringv("expected string/buffer"); + if (!dst_chararray_view(args.v[0], &src, &len)) { + *args.ret = dst_cstringv("expected string/buffer"); return 1; } res = dst_parse(src, len); @@ -72,58 +72,55 @@ int dst_stl_parse(int32_t argn, Dst *argv, Dst *ret) { if (res.status == DST_PARSE_OK) dst_table_put(t, dst_cstringv("value"), res.value); if (res.status == DST_PARSE_ERROR) dst_table_put(t, dst_cstringv("error"), dst_wrap_string(res.error)); dst_table_put(t, dst_cstringv("bytes-read"), dst_wrap_integer(res.bytes_read)); - *ret = dst_wrap_table(t); + *args.ret = dst_wrap_table(t); return 0; } -int dst_stl_compile(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_compile(DstArgs args) { DstCompileOptions opts; DstCompileResult res; DstTable *t; - if (argn < 1) { - *ret = dst_cstringv("expected at least on argument"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected at least on argument"); return 1; } - if (argn >= 3 && !dst_checktype(argv[2], DST_TUPLE)) { - *ret = dst_cstringv("expected source map to be tuple"); + if (args.n >= 3 && !dst_checktype(args.v[2], DST_TUPLE)) { + *args.ret = dst_cstringv("expected source map to be tuple"); return 1; } - opts.source = argv[0]; - opts.env = argn >= 2 ? argv[1] : dst_loadstl(0); - opts.sourcemap = argn >= 3 ? dst_unwrap_tuple(argv[2]) : NULL; + opts.source = args.v[0]; + opts.env = args.n >= 2 ? args.v[1] : dst_loadstl(0); + opts.sourcemap = args.n >= 3 ? dst_unwrap_tuple(args.v[2]) : NULL; opts.flags = 0; res = dst_compile(opts); if (res.status == DST_COMPILE_OK) { DstFunction *fun = dst_compile_func(res); - *ret = dst_wrap_function(fun); + *args.ret = dst_wrap_function(fun); } else { t = dst_table(2); dst_table_put(t, dst_cstringv("error"), dst_wrap_string(res.error)); dst_table_put(t, dst_cstringv("error-start"), dst_wrap_integer(res.error_start)); dst_table_put(t, dst_cstringv("error-end"), dst_wrap_integer(res.error_end)); - *ret = dst_wrap_table(t); + *args.ret = dst_wrap_table(t); } return 0; } -int dst_stl_exit(int32_t argn, Dst *argv, Dst *ret) { - (void)ret; +int dst_stl_exit(DstArgs args) { int32_t exitcode = 0; - if (argn > 0) { - exitcode = dst_hash(argv[0]); + if (args.n > 0) { + exitcode = dst_hash(args.v[0]); } exit(exitcode); return 0; } -int dst_stl_print(int32_t argn, Dst *argv, Dst *ret) { - (void)ret; - +int dst_stl_print(DstArgs args) { int32_t i; - for (i = 0; i < argn; ++i) { + for (i = 0; i < args.n; ++i) { int32_t j, len; - const uint8_t *vstr = dst_to_string(argv[i]); + const uint8_t *vstr = dst_to_string(args.v[i]); len = dst_string_length(vstr); for (j = 0; j < len; ++j) { putc(vstr[j], stdout); @@ -133,13 +130,11 @@ int dst_stl_print(int32_t argn, Dst *argv, Dst *ret) { return 0; } -int dst_stl_describe(int32_t argn, Dst *argv, Dst *ret) { - (void)ret; - +int dst_stl_describe(DstArgs args) { int32_t i; - for (i = 0; i < argn; ++i) { + for (i = 0; i < args.n; ++i) { int32_t j, len; - const uint8_t *vstr = dst_description(argv[i]); + const uint8_t *vstr = dst_description(args.v[i]); len = dst_string_length(vstr); for (j = 0; j < len; ++j) { putc(vstr[j], stdout); @@ -149,172 +144,172 @@ int dst_stl_describe(int32_t argn, Dst *argv, Dst *ret) { return 0; } -int dst_stl_string(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_string(DstArgs args) { int32_t i; DstBuffer b; dst_buffer_init(&b, 0); - for (i = 0; i < argn; ++i) { + for (i = 0; i < args.n; ++i) { int32_t len; - const uint8_t *str = dst_to_string(argv[i]); + const uint8_t *str = dst_to_string(args.v[i]); len = dst_string_length(str); dst_buffer_push_bytes(&b, str, len); } - *ret = dst_stringv(b.data, b.count); + *args.ret = dst_stringv(b.data, b.count); dst_buffer_deinit(&b); return 0; } -int dst_stl_asm(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_asm(DstArgs args) { DstAssembleOptions opts; DstAssembleResult res; - if (argn < 1) { - *ret = dst_cstringv("expected assembly source"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected assembly source"); return 1; } - opts.source = argv[0]; + opts.source = args.v[0]; opts.flags = 0; res = dst_asm(opts); if (res.status == DST_ASSEMBLE_OK) { - *ret = dst_wrap_function(dst_asm_func(res)); + *args.ret = dst_wrap_function(dst_asm_func(res)); return 0; } else { - *ret = dst_wrap_string(res.error); + *args.ret = dst_wrap_string(res.error); return 1; } } -int dst_stl_disasm(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_disasm(DstArgs args) { DstFunction *f; - if (argn < 1 || !dst_checktype(argv[0], DST_FUNCTION)) { - *ret = dst_cstringv("expected function"); + if (args.n < 1 || !dst_checktype(args.v[0], DST_FUNCTION)) { + *args.ret = dst_cstringv("expected function"); return 1; } - f = dst_unwrap_function(argv[0]); - *ret = dst_disasm(f->def); + f = dst_unwrap_function(args.v[0]); + *args.ret = dst_disasm(f->def); return 0; } -int dst_stl_tuple(int32_t argn, Dst *argv, Dst *ret) { - *ret = dst_wrap_tuple(dst_tuple_n(argv, argn)); +int dst_stl_tuple(DstArgs args) { + *args.ret = dst_wrap_tuple(dst_tuple_n(args.v, args.n)); return 0; } -int dst_stl_array(int32_t argn, Dst *argv, Dst *ret) { - DstArray *array = dst_array(argn); - array->count = argn; - memcpy(array->data, argv, argn * sizeof(Dst)); - *ret = dst_wrap_array(array); +int dst_stl_array(DstArgs args) { + DstArray *array = dst_array(args.n); + array->count = args.n; + memcpy(array->data, args.v, args.n * sizeof(Dst)); + *args.ret = dst_wrap_array(array); return 0; } -int dst_stl_table(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_table(DstArgs args) { int32_t i; - DstTable *table = dst_table(argn >> 1); - if (argn & 1) { - *ret = dst_cstringv("expected even number of arguments"); + DstTable *table = dst_table(args.n >> 1); + if (args.n & 1) { + *args.ret = dst_cstringv("expected even number of arguments"); return 1; } - for (i = 0; i < argn; i += 2) { - dst_table_put(table, argv[i], argv[i + 1]); + for (i = 0; i < args.n; i += 2) { + dst_table_put(table, args.v[i], args.v[i + 1]); } - *ret = dst_wrap_table(table); + *args.ret = dst_wrap_table(table); return 0; } -int dst_stl_struct(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_struct(DstArgs args) { int32_t i; - DstKV *st = dst_struct_begin(argn >> 1); - if (argn & 1) { - *ret = dst_cstringv("expected even number of arguments"); + DstKV *st = dst_struct_begin(args.n >> 1); + if (args.n & 1) { + *args.ret = dst_cstringv("expected even number of arguments"); return 1; } - for (i = 0; i < argn; i += 2) { - dst_struct_put(st, argv[i], argv[i + 1]); + for (i = 0; i < args.n; i += 2) { + dst_struct_put(st, args.v[i], args.v[i + 1]); } - *ret = dst_wrap_struct(dst_struct_end(st)); + *args.ret = dst_wrap_struct(dst_struct_end(st)); return 0; } -int dst_stl_fiber(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_fiber(DstArgs args) { DstFiber *fiber; - if (argn < 1) { - *ret = dst_cstringv("expected at least one argument"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected at least one argument"); return 1; } - if (!dst_checktype(argv[0], DST_FUNCTION)) { - *ret = dst_cstringv("expected a function"); + if (!dst_checktype(args.v[0], DST_FUNCTION)) { + *args.ret = dst_cstringv("expected a function"); return 1; } fiber = dst_fiber(64); - dst_fiber_funcframe(fiber, dst_unwrap_function(argv[0])); + dst_fiber_funcframe(fiber, dst_unwrap_function(args.v[0])); fiber->parent = dst_vm_fiber; - *ret = dst_wrap_fiber(fiber); + *args.ret = dst_wrap_fiber(fiber); return 0; } -int dst_stl_buffer(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_buffer(DstArgs args) { DstBuffer *buffer = dst_buffer(10); int32_t i; - for (i = 0; i < argn; ++i) { - const uint8_t *bytes = dst_to_string(argv[i]); + for (i = 0; i < args.n; ++i) { + const uint8_t *bytes = dst_to_string(args.v[i]); int32_t len = dst_string_length(bytes); dst_buffer_push_bytes(buffer, bytes, len); } - *ret = dst_wrap_buffer(buffer); + *args.ret = dst_wrap_buffer(buffer); return 0; } -int dst_stl_gensym(int32_t argn, Dst *argv, Dst *ret) { - if (argn > 1) { - *ret = dst_cstringv("expected one argument"); +int dst_stl_gensym(DstArgs args) { + if (args.n > 1) { + *args.ret = dst_cstringv("expected one argument"); return 1; } - if (argn == 0) { - *ret = dst_wrap_symbol(dst_symbol_gen(NULL, 0)); + if (args.n == 0) { + *args.ret = dst_wrap_symbol(dst_symbol_gen(NULL, 0)); } else { - const uint8_t *s = dst_to_string(argv[0]); - *ret = dst_wrap_symbol(dst_symbol_gen(s, dst_string_length(s))); + const uint8_t *s = dst_to_string(args.v[0]); + *args.ret = dst_wrap_symbol(dst_symbol_gen(s, dst_string_length(s))); } return 0; } -int dst_stl_length(int32_t argn, Dst *argv, Dst *ret) { - if (argn != 1) { - *ret = dst_cstringv("expected at least 1 argument"); +int dst_stl_length(DstArgs args) { + if (args.n != 1) { + *args.ret = dst_cstringv("expected at least 1 argument"); return 1; } - *ret = dst_wrap_integer(dst_length(argv[0])); + *args.ret = dst_wrap_integer(dst_length(args.v[0])); return 0; } -int dst_stl_get(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_get(DstArgs args) { int32_t i; Dst ds; - if (argn < 1) { - *ret = dst_cstringv("expected at least 1 argument"); + if (args.n < 1) { + *args.ret = dst_cstringv("expected at least 1 argument"); return 1; } - ds = argv[0]; - for (i = 1; i < argn; i++) { - ds = dst_get(ds, argv[i]); + 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; } - *ret = ds; + *args.ret = ds; return 0; } -int dst_stl_status(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_status(DstArgs args) { const char *status; - if (argn != 1) { - *ret = dst_cstringv("expected 1 argument"); + if (args.n != 1) { + *args.ret = dst_cstringv("expected 1 argument"); return 1; } - if (!dst_checktype(argv[0], DST_FIBER)) { - *ret = dst_cstringv("expected fiber"); + if (!dst_checktype(args.v[0], DST_FIBER)) { + *args.ret = dst_cstringv("expected fiber"); return 1; } - switch(dst_unwrap_fiber(argv[0])->status) { + switch(dst_unwrap_fiber(args.v[0])->status) { case DST_FIBER_PENDING: status = "pending"; break; @@ -331,65 +326,67 @@ int dst_stl_status(int32_t argn, Dst *argv, Dst *ret) { status = "error"; break; } - *ret = dst_cstringv(status); + *args.ret = dst_cstringv(status); return 0; } -int dst_stl_put(int32_t argn, Dst *argv, Dst *ret) { +int dst_stl_put(DstArgs args) { Dst ds, key, value; - if (argn < 3) { - *ret = dst_cstringv("expected at least 3 arguments"); + DstArgs subargs = args; + if (args.n < 3) { + *args.ret = dst_cstringv("expected at least 3 arguments"); return 1; } - if (dst_stl_get(argn - 2, argv, ret)) { + subargs.n -= 2; + if (dst_stl_get(subargs)) { return 1; } - ds = *ret; - key = argv[argn - 2]; - value = argv[argn - 1]; + ds = *args.ret; + key = args.v[args.n - 2]; + value = args.v[args.n - 1]; dst_put(ds, key, value); return 0; } -static int dst_stl_equal(int32_t argn, Dst *argv, Dst *ret) { +static int dst_stl_equal(DstArgs args) { int32_t i; - for (i = 0; i < argn - 1; i++) { - if (!dst_equals(argv[i], argv[i+1])) { - *ret = dst_wrap_false(); + for (i = 0; i < args.n - 1; i++) { + if (!dst_equals(args.v[i], args.v[i+1])) { + *args.ret = dst_wrap_false(); return 0; } } - *ret = dst_wrap_true(); + *args.ret = dst_wrap_true(); return 0; } -static int dst_stl_notequal(int32_t argn, Dst *argv, Dst *ret) { +static int dst_stl_notequal(DstArgs args) { int32_t i; - for (i = 0; i < argn - 1; i++) { - if (dst_equals(argv[i], argv[i+1])) { - *ret = dst_wrap_false(); + for (i = 0; i < args.n - 1; i++) { + if (dst_equals(args.v[i], args.v[i+1])) { + *args.ret = dst_wrap_false(); return 0; } } - *ret = dst_wrap_true(); + *args.ret = dst_wrap_true(); return 0; } -static int dst_stl_not(int32_t argn, Dst *argv, Dst *ret) { - *ret = dst_wrap_boolean(argn == 0 || !dst_truthy(argv[0])); +static int dst_stl_not(DstArgs args) { + *args.ret = dst_wrap_boolean(args.n == 0 || !dst_truthy(args.v[0])); return 0; } #define DST_DEFINE_COMPARATOR(name, pred)\ -static int dst_stl_##name(int32_t argn, Dst *argv, Dst *ret) {\ +static int dst_stl_##name(DstArgs args) {\ int32_t i;\ - for (i = 0; i < argn - 1; i++) {\ - if (dst_compare(argv[i], argv[i+1]) pred) {\ - *ret = dst_wrap_false();\ + 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;\ }\ }\ - *ret = dst_wrap_true();\ + *args.ret = dst_wrap_true();\ return 0;\ } diff --git a/core/table.c b/core/table.c index 76194b99..c8004208 100644 --- a/core/table.c +++ b/core/table.c @@ -196,4 +196,25 @@ const DstKV *dst_table_to_struct(DstTable *t) { return dst_struct_end(st); } +/* Merge a table or struct into a table */ +static void dst_table_mergekv(DstTable *table, const DstKV *kvs, int32_t cap) { + int32_t i; + for (i = 0; i < cap; i++) { + const DstKV *kv = kvs + i; + if (!dst_checktype(kv->key, DST_NIL)) { + dst_table_put(table, kv->key, kv->value); + } + } +} + +/* Merge a table other into another table */ +void dst_table_merge_table(DstTable *table, DstTable *other) { + dst_table_mergekv(table, other->data, other->capacity); +} + +/* Merge a struct into a table */ +void dst_table_merge_struct(DstTable *table, const DstKV *other) { + dst_table_mergekv(table, other, dst_struct_capacity(other)); +} + #undef dst_table_maphash diff --git a/core/vm.c b/core/vm.c index f7ced1a0..83ff7ed6 100644 --- a/core/vm.c +++ b/core/vm.c @@ -492,13 +492,13 @@ static int dst_continue(Dst *returnreg) { pc = func->def->bytecode; vm_checkgc_next(); } else if (dst_checktype(callee, DST_CFUNCTION)) { - int32_t argn = dst_vm_fiber->stacktop - dst_vm_fiber->stackstart; + DstArgs args; + args.n = dst_vm_fiber->stacktop - dst_vm_fiber->stackstart; dst_fiber_cframe(dst_vm_fiber); retreg = dst_wrap_nil(); - if (dst_unwrap_cfunction(callee)( - argn, - dst_vm_fiber->data + dst_vm_fiber->frame, - &retreg)) { + args.v = dst_vm_fiber->data + dst_vm_fiber->frame; + args.ret = &retreg; + if (dst_unwrap_cfunction(callee)(args)) { goto vm_error; } goto vm_return_cfunc; @@ -516,13 +516,13 @@ static int dst_continue(Dst *returnreg) { pc = func->def->bytecode; vm_checkgc_next(); } else if (dst_checktype(callee, DST_CFUNCTION)) { - int32_t argn = dst_vm_fiber->stacktop - dst_vm_fiber->stackstart; + DstArgs args; + args.n = dst_vm_fiber->stacktop - dst_vm_fiber->stackstart; dst_fiber_cframe(dst_vm_fiber); retreg = dst_wrap_nil(); - if (dst_unwrap_cfunction(callee)( - argn, - dst_vm_fiber->data + dst_vm_fiber->frame, - &retreg)) { + args.v = dst_vm_fiber->data + dst_vm_fiber->frame; + args.ret = &retreg; + if (dst_unwrap_cfunction(callee)(args)) { goto vm_error; } goto vm_return_cfunc_tail; @@ -684,12 +684,13 @@ int dst_run(Dst callee, Dst *returnreg) { dst_fiber_reset(dst_vm_fiber); } if (dst_checktype(callee, DST_CFUNCTION)) { + DstArgs args; *returnreg = dst_wrap_nil(); dst_fiber_cframe(dst_vm_fiber); - return dst_unwrap_cfunction(callee)( - 0, - dst_vm_fiber->data + dst_vm_fiber->frame, - returnreg); + args.n = 0; + args.v = dst_vm_fiber->data + dst_vm_fiber->frame; + args.ret = returnreg; + return dst_unwrap_cfunction(callee)(args); } else if (dst_checktype(callee, DST_FUNCTION)) { dst_fiber_funcframe(dst_vm_fiber, dst_unwrap_function(callee)); return dst_continue(returnreg); diff --git a/include/dst/dst.h b/include/dst/dst.h index 053c55f8..b71c67bd 100644 --- a/include/dst/dst.h +++ b/include/dst/dst.h @@ -119,7 +119,8 @@ Dst dst_table_remove(DstTable *t, Dst key); void dst_table_put(DstTable *t, Dst key, Dst value); const DstKV *dst_table_next(DstTable *t, const DstKV *kv); const DstKV *dst_table_to_struct(DstTable *t); -void dst_table_merge(DstTable *t, Dst other); +void dst_table_merge_table(DstTable *table, DstTable *other); +void dst_table_merge_struct(DstTable *table, const DstKV *other); /* Fiber */ DstFiber *dst_fiber(int32_t capacity); @@ -171,7 +172,7 @@ DstParseResult dst_parsec(const char *src); /* Native */ DstCFunction dst_native(const char *name, const uint8_t **error); -int dst_load_native(int32_t argn, Dst *argv, Dst *ret); +int dst_load_native(DstArgs args); /* VM functions */ int dst_init(); diff --git a/include/dst/dststl.h b/include/dst/dststl.h index d7a67cb4..9ac5db5d 100644 --- a/include/dst/dststl.h +++ b/include/dst/dststl.h @@ -28,50 +28,50 @@ /* File type definition */ extern DstAbstractType dst_stl_filetype; -int dst_int(int32_t argn, Dst *argv, Dst *ret); -int dst_real(int32_t argn, Dst *argv, Dst *ret); +int dst_int(DstArgs args); +int dst_real(DstArgs args); -int dst_add(int32_t argn, Dst *argv, Dst *ret); -int dst_subtract(int32_t argn, Dst *argv, Dst *ret); -int dst_multiply(int32_t argn, Dst *argv, Dst *ret); -int dst_divide(int32_t argn, Dst *argv, Dst *ret); -int dst_modulo(int32_t argn, Dst *argv, Dst *ret); +int dst_add(DstArgs args); +int dst_subtract(DstArgs args); +int dst_multiply(DstArgs args); +int dst_divide(DstArgs args); +int dst_modulo(DstArgs args); -int dst_acos(int32_t argn, Dst *argv, Dst *ret); -int dst_asin(int32_t argn, Dst *argv, Dst *ret); -int dst_atan(int32_t argn, Dst *argv, Dst *ret); -int dst_cos(int32_t argn, Dst *argv, Dst *ret); -int dst_cosh(int32_t argn, Dst *argv, Dst *ret); -int dst_sin(int32_t argn, Dst *argv, Dst *ret); -int dst_sinh(int32_t argn, Dst *argv, Dst *ret); -int dst_tan(int32_t argn, Dst *argv, Dst *ret); -int dst_tanh(int32_t argn, Dst *argv, Dst *ret); -int dst_exp(int32_t argn, Dst *argv, Dst *ret); -int dst_log(int32_t argn, Dst *argv, Dst *ret); -int dst_log10(int32_t argn, Dst *argv, Dst *ret); -int dst_sqrt(int32_t argn, Dst *argv, Dst *ret); -int dst_ceil(int32_t argn, Dst *argv, Dst *ret); -int dst_fabs(int32_t argn, Dst *argv, Dst *ret); -int dst_floor(int32_t argn, Dst *argv, Dst *ret); -int dst_pow(int32_t argn, Dst *argv, Dst *ret); +int dst_acos(DstArgs args); +int dst_asin(DstArgs args); +int dst_atan(DstArgs args); +int dst_cos(DstArgs args); +int dst_cosh(DstArgs args); +int dst_sin(DstArgs args); +int dst_sinh(DstArgs args); +int dst_tan(DstArgs args); +int dst_tanh(DstArgs args); +int dst_exp(DstArgs args); +int dst_log(DstArgs args); +int dst_log10(DstArgs args); +int dst_sqrt(DstArgs args); +int dst_ceil(DstArgs args); +int dst_fabs(DstArgs args); +int dst_floor(DstArgs args); +int dst_pow(DstArgs args); -int dst_stl_table(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_array(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_struct(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_tuple(int32_t argn, Dst *argv, Dst *ret); +int dst_stl_table(DstArgs args); +int dst_stl_array(DstArgs args); +int dst_stl_struct(DstArgs args); +int dst_stl_tuple(DstArgs args); -int dst_band(int32_t argn, Dst *argv, Dst *ret); -int dst_bor(int32_t argn, Dst *argv, Dst *ret); -int dst_bxor(int32_t argn, Dst *argv, Dst *ret); +int dst_band(DstArgs args); +int dst_bor(DstArgs args); +int dst_bxor(DstArgs args); -int dst_lshift(int argn, Dst *argv, Dst *ret); -int dst_rshift(int argn, Dst *argv, Dst *ret); -int dst_lshiftu(int argn, Dst *argv, Dst *ret); +int dst_lshift(DstArgs arsg); +int dst_rshift(DstArgs args); +int dst_lshiftu(DstArgs args); -int dst_stl_fileopen(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_slurp(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_fileread(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_filewrite(int32_t argn, Dst *argv, Dst *ret); -int dst_stl_fileclose(int32_t argn, Dst *argv, Dst *ret); +int dst_stl_fileopen(DstArgs args); +int dst_stl_slurp(DstArgs args); +int dst_stl_fileread(DstArgs args); +int dst_stl_filewrite(DstArgs args); +int dst_stl_fileclose(DstArgs args); #endif /* DST_MATH_H_defined */ diff --git a/include/dst/dsttypes.h b/include/dst/dsttypes.h index 038bcc01..f66cf133 100644 --- a/include/dst/dsttypes.h +++ b/include/dst/dsttypes.h @@ -47,7 +47,8 @@ typedef struct DstFuncEnv DstFuncEnv; typedef struct DstKV DstKV; typedef struct DstStackFrame DstStackFrame; typedef struct DstAbstractType DstAbstractType; -typedef int (*DstCFunction)(int32_t argn, Dst *argv, Dst *ret); +typedef struct DstArgs DstArgs; +typedef int (*DstCFunction)(DstArgs args); typedef enum DstAssembleStatus DstAssembleStatus; typedef struct DstAssembleResult DstAssembleResult; @@ -309,6 +310,13 @@ struct DstReg { DstCFunction function; }; +/* Hold components of arguments passed to DstCFunction. */ +struct DstArgs { + int32_t n; + Dst *v; + Dst *ret; +}; + /* A lightweight green thread in dst. Does not correspond to * operating system threads. */ struct DstFiber {