From faba0abf74dcdab3a4957bd8f13afa3c4dd19950 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Sat, 17 Aug 2024 21:29:40 +0100 Subject: add delete! and objarr_delete --- lib.c | 10 ++++++++++ tests/delete.bth | 16 ++++++++++++++++ tests/delete.out | 4 ++++ val.c | 10 ++++++++++ val.h | 1 + 5 files changed, 41 insertions(+) create mode 100644 tests/delete.bth create mode 100644 tests/delete.out diff --git a/lib.c b/lib.c index b4f5015..f4e9758 100644 --- a/lib.c +++ b/lib.c @@ -68,6 +68,15 @@ static Val fn_append(State *S, int nargs, Val *args) { objarr_append(S, a, args[1]); return args[0]; } +static Val fn_delete(State *S, int nargs, Val *args) { + CHECK(nargs == 2, "need 2 args to delete!"); + CHECK(IS_ARR(args[0]), "can only delete from arr"); + CHECK(IS_NUM(args[1]), "can only delete using num index"); + ObjArr *a = AS_ARR(args[0]); + size_t ix = (size_t)AS_NUM(args[1]); + objarr_delete(S, a, ix); + return args[0]; +} static Val fn_len(State *S, int nargs, Val *args) { CHECK(nargs == 1, "need 1 arg to len"); CHECK(IS_ARR(args[0]), "can only take length of arr"); @@ -174,6 +183,7 @@ static BuiltinFunc builtin_funcs[] = { { "arr", fn_arr }, { "append!", fn_append }, + { "delete!", fn_delete }, { "#", fn_len }, { ",", fn_pend }, { "s,", fn_spend }, diff --git a/tests/delete.bth b/tests/delete.bth new file mode 100644 index 0000000..58063a3 --- /dev/null +++ b/tests/delete.bth @@ -0,0 +1,16 @@ +(let (a [10 20 30 40 50]) + (delete! a 0) + (say a)) + +(let (a [10 20 30 40 50]) + (delete! a 3) + (say a)) + +(let (a [10 20 30 40 50]) + (delete! a 4) + (say a)) + +(let (a [10 20 30 40 50]) + (delete! a 5) + (say a)) + diff --git a/tests/delete.out b/tests/delete.out new file mode 100644 index 0000000..d5ec9d6 --- /dev/null +++ b/tests/delete.out @@ -0,0 +1,4 @@ +[20 30 40 50] +[10 20 30 50] +[10 20 30 40] +array index out of bounds diff --git a/val.c b/val.c index ed375ac..3e8558f 100644 --- a/val.c +++ b/val.c @@ -98,6 +98,16 @@ void objarr_insert(State *S, ObjArr *arr, size_t ix, Val v) { arr->d[ix] = v; } } +void objarr_delete(State *S, ObjArr *arr, size_t ix) { + CHECK(ix < arr->len, "array index out of bounds"); + if (ix < arr->len - 1) { + size_t nix = ix+1; + size_t n = arr->len - nix; + memmove(&arr->d[ix], &arr->d[ix+1], n*sizeof(Val)); + } + arr->len --; +} + static void print_val_h(Val v, int depth); void print_val(Val v) { diff --git a/val.h b/val.h index 097c06a..7f8fd81 100644 --- a/val.h +++ b/val.h @@ -86,6 +86,7 @@ Val objarr_get(State *S, ObjArr *arr, size_t ix); void objarr_append(State *S, ObjArr *arr, Val v); void objarr_put(State *S, ObjArr *arr, size_t ix, Val v); void objarr_insert(State *S, ObjArr *arr, size_t ix, Val v); +void objarr_delete(State *S, ObjArr *arr, size_t ix); #define IS_NIL(x) (x.ty == TY_NIL) #define IS_NUM(x) (x.ty == TY_NUM) -- cgit v1.2.3