aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-06-07 20:05:29 +0200
committerFederico Angelilli <code@fedang.net>2024-06-07 20:05:29 +0200
commit5cb78753fe952534996722e1659318143bcca6ed (patch)
tree03de4607d863bb5fce25035bee6ad27f71cdfb5c
parent33801aad0f98f2fcbb45d552cf2a9c85bd166d7b (diff)
Add sexp copy function
-rw-r--r--any_sexp.h48
1 files changed, 43 insertions, 5 deletions
diff --git a/any_sexp.h b/any_sexp.h
index 3b24ca2..c9a2eb1 100644
--- a/any_sexp.h
+++ b/any_sexp.h
@@ -176,10 +176,14 @@ any_sexp_t any_sexp_cdr(any_sexp_t sexp);
any_sexp_t any_sexp_reverse(any_sexp_t sexp);
-void any_sexp_free_list(any_sexp_t sexp);
+any_sexp_t any_sexp_copy(any_sexp_t sexp);
+
+any_sexp_t any_sexp_copy_list(any_sexp_t sexp);
void any_sexp_free(any_sexp_t sexp);
+void any_sexp_free_list(any_sexp_t sexp);
+
#endif
#ifdef ANY_SEXP_IMPLEMENT
@@ -681,14 +685,38 @@ any_sexp_t any_sexp_reverse(any_sexp_t sexp)
return prev;
}
-void any_sexp_free_list(any_sexp_t sexp)
+any_sexp_t any_sexp_copy(any_sexp_t sexp)
+{
+ switch (ANY_SEXP_GET_TAG(sexp)) {
+ case ANY_SEXP_TAG_ERROR:
+ case ANY_SEXP_TAG_NIL:
+ case ANY_SEXP_TAG_NUMBER:
+ return sexp;
+
+ case ANY_SEXP_TAG_CONS:
+ return any_sexp_cons(any_sexp_car(sexp), any_sexp_cdr(sexp));
+
+ case ANY_SEXP_TAG_SYMBOL: {
+ char *symbol = ANY_SEXP_GET_SYMBOL(sexp);
+ return any_sexp_symbol(symbol, strlen(symbol));
+ }
+
+ case ANY_SEXP_TAG_STRING: {
+ char *string = ANY_SEXP_GET_STRING(sexp);
+ return any_sexp_symbol(string, strlen(string));
+ }
+ }
+}
+
+any_sexp_t any_sexp_copy_list(any_sexp_t sexp)
{
if (ANY_SEXP_IS_CONS(sexp)) {
- any_sexp_free_list(any_sexp_car(sexp));
- any_sexp_free_list(any_sexp_cdr(sexp));
+ any_sexp_t car = any_sexp_copy_list(any_sexp_car(sexp));
+ any_sexp_t cdr = any_sexp_copy_list(any_sexp_cdr(sexp));
+ return any_sexp_cons(car, cdr);
}
- any_sexp_free(sexp);
+ return any_sexp_copy(sexp);
}
void any_sexp_free(any_sexp_t sexp)
@@ -710,6 +738,16 @@ void any_sexp_free(any_sexp_t sexp)
}
}
+void any_sexp_free_list(any_sexp_t sexp)
+{
+ if (ANY_SEXP_IS_CONS(sexp)) {
+ any_sexp_free_list(any_sexp_car(sexp));
+ any_sexp_free_list(any_sexp_cdr(sexp));
+ }
+
+ any_sexp_free(sexp);
+}
+
#endif
// MIT License