summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-08-17 21:29:40 +0100
committerubq323 <ubq323@ubq323.website>2024-08-17 21:29:52 +0100
commitfaba0abf74dcdab3a4957bd8f13afa3c4dd19950 (patch)
tree5dc4f0110ffe204e83fc9db94f52d0803416d25a
parentfc5fb73c08d563ae441f785276f1304da7538fea (diff)
add delete! and objarr_delete
-rw-r--r--lib.c10
-rw-r--r--tests/delete.bth16
-rw-r--r--tests/delete.out4
-rw-r--r--val.c10
-rw-r--r--val.h1
5 files changed, 41 insertions, 0 deletions
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)