summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-12-16 00:09:39 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-12-16 00:12:57 +0100
commita68ffccdccc9023c1beb14cae2a8d2695e517da0 (patch)
tree36bc33fd21484f8e0e6b820df69775cfe2d79e2e
parent8be1e42cfbf9e3bc9d64dc839969d4b4293afb53 (diff)
downloadmew-a68ffccdccc9023c1beb14cae2a8d2695e517da0.tar.gz
mew-a68ffccdccc9023c1beb14cae2a8d2695e517da0.tar.xz
mew-a68ffccdccc9023c1beb14cae2a8d2695e517da0.zip
add dup
-rw-r--r--mew.scm18
-rw-r--r--mew.svnwiki6
-rw-r--r--tests/test.mew10
3 files changed, 33 insertions, 1 deletions
diff --git a/mew.scm b/mew.scm
index 259f51c..8635195 100644
--- a/mew.scm
+++ b/mew.scm
@@ -3,7 +3,7 @@
      act accumulate andloc app at
      boolean
      comp cross-product
-     dec def del-at div
+     dec def del-at div dup
      empty? eof esc
      fail fin final for fun*
      gconcatenate gen generator-xfold generic-for-each genumerate get
@@ -395,6 +395,22 @@
           ((procedure? o) (generator-count (op #t) o))
           (#t (error "no len defined"))))
 
+  (define dup
+    (case-lambda
+      ((o) (dup o #t))
+      ((o depth)
+       (if (or (eq? depth #t) (positive? depth))
+         (let ((sub-depth (or (eq? depth #t) (- depth 1))))
+           (cond ((list? o) (map (lambda (oo) (dup oo sub-depth)) o))
+                 ((vector? o) (vector-map (lambda (oo) (dup oo sub-depth)) o))
+                 ((hash-table? o)
+                  (alist->hash-table (dup (hash-table->alist o) sub-depth)
+                                     (hash-table-equivalence-function o)
+                                     (hash-table-hash-function o)))
+                 ((string? o) (string-copy o))
+                 (else o)))
+         o))))
+
   (define (generic-for-each obj)
     (cond ((list? obj) for-each)
           ((vector? obj) vector-for-each)
diff --git a/mew.svnwiki b/mew.svnwiki
index db141f4..1b8c0ae 100644
--- a/mew.svnwiki
+++ b/mew.svnwiki
@@ -380,6 +380,12 @@ Test if {{<obj>}} is an empty list/string/vector/hash-table.
 
 Return the length of the list/vector/string/hash-table/generator {{<obj>}}.
 
+<procedure>(dup <obj> [<depth>])<procedure>
+
+Return a duplicate of the nested datastructure {{<obj>}}, consisting
+of lists, vectors, hash-tables and strings.  Create copies of values
+up to a level of {{<depth>}}, or infinitely by default.
+
 <syntax>(for (<var> <obj>) <body>...)</syntax>
 <syntax>(for ((<key> . <val>) <tbl>) <body>...)</syntax>
 
diff --git a/tests/test.mew b/tests/test.mew
index a775928..cbcf2ff 100644
--- a/tests/test.mew
+++ b/tests/test.mew
@@ -377,6 +377,16 @@
   (test-error (len #t)))
 
 ; for
+(test-group "dup"
+  (let* ((x (list (list "foo") "bar"))
+         (y1 (dup x))
+         (y2 (dup x 1))
+         (y3 (dup x 2)))
+    (test #f (eq? (car x) (car y1)))
+    (test #t (eq? (car x) (car y2)))
+    (test #f (eq? (car x) (car y3)))
+    (test #t (eq? (caar x) (caar y3)))))
+
 
 (test-group "eof"
   (test-assert (eof-object? (eof))))