#include #include typedef struct { double *data; size_t size; } num_array; static num_array *num_array_init(num_array *array, size_t size) { array->data = (double *)janet_calloc(size, sizeof(double)); array->size = size; return array; } static void num_array_deinit(num_array *array) { janet_free(array->data); } static int num_array_gc(void *p, size_t s) { (void) s; num_array *array = (num_array *)p; num_array_deinit(array); return 0; } int num_array_get(void *p, Janet key, Janet *out); void num_array_put(void *p, Janet key, Janet value); static const JanetAbstractType num_array_type = { "numarray", num_array_gc, NULL, num_array_get, num_array_put, JANET_ATEND_PUT }; static Janet num_array_new(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); int32_t size = janet_getinteger(argv, 0); num_array *array = (num_array *)janet_abstract(&num_array_type, sizeof(num_array)); num_array_init(array, size); return janet_wrap_abstract(array); } static Janet num_array_scale(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); num_array *array = (num_array *)janet_getabstract(argv, 0, &num_array_type); double factor = janet_getnumber(argv, 1); size_t i; for (i = 0; i < array->size; i++) { array->data[i] *= factor; } return argv[0]; } static Janet num_array_sum(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); num_array *array = (num_array *)janet_getabstract(argv, 0, &num_array_type); double sum = 0; for (size_t i = 0; i < array->size; i++) sum += array->data[i]; return janet_wrap_number(sum); } void num_array_put(void *p, Janet key, Janet value) { size_t index; num_array *array = (num_array *)p; if (!janet_checkint(key)) janet_panic("expected integer key"); if (!janet_checktype(value, JANET_NUMBER)) janet_panic("expected number value"); index = (size_t)janet_unwrap_integer(key); if (index < array->size) { array->data[index] = janet_unwrap_number(value); } } static Janet num_array_length(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); num_array *array = (num_array *)janet_getabstract(argv, 0, &num_array_type); return janet_wrap_number(array->size); } static const JanetMethod methods[] = { {"scale", num_array_scale}, {"sum", num_array_sum}, {"length", num_array_length}, {NULL, NULL} }; int num_array_get(void *p, Janet key, Janet *out) { size_t index; num_array *array = (num_array *)p; if (janet_checktype(key, JANET_KEYWORD)) return janet_getmethod(janet_unwrap_keyword(key), methods, out); if (!janet_checkint(key)) janet_panic("expected integer key"); index = (size_t)janet_unwrap_integer(key); if (index >= array->size) { return 0; } else { *out = janet_wrap_number(array->data[index]); } return 1; } static const JanetReg cfuns[] = { { "new", num_array_new, "(numarray/new size)\n\n" "Create new numarray" }, { "scale", num_array_scale, "(numarray/scale numarray factor)\n\n" "scale numarray by factor" }, { "sum", num_array_sum, "(numarray/sum numarray)\n\n" "sums numarray" }, {NULL, NULL, NULL} }; JANET_MODULE_ENTRY(JanetTable *env) { janet_cfuns(env, "numarray", cfuns); }