]> gitweb.factorcode.org Git - factor.git/commitdiff
Virtual sequence concatenation
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 8 Jun 2008 20:30:58 +0000 (15:30 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 8 Jun 2008 20:30:58 +0000 (15:30 -0500)
extra/cords/authors.txt [new file with mode: 0644]
extra/cords/cords-tests.factor [new file with mode: 0644]
extra/cords/cords.factor [new file with mode: 0644]
extra/cords/summary.txt [new file with mode: 0644]
extra/cords/tags.txt [new file with mode: 0644]

diff --git a/extra/cords/authors.txt b/extra/cords/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/extra/cords/cords-tests.factor b/extra/cords/cords-tests.factor
new file mode 100644 (file)
index 0000000..0058c8f
--- /dev/null
@@ -0,0 +1,5 @@
+IN: cords.tests
+USING: cords strings tools.test kernel sequences ;
+
+[ "hello world" ] [ "hello" " world" cord-append dup like ] unit-test
+[ "hello world" ] [ { "he" "llo" " world" } cord-concat dup like ] unit-test
diff --git a/extra/cords/cords.factor b/extra/cords/cords.factor
new file mode 100644 (file)
index 0000000..f5cc89f
--- /dev/null
@@ -0,0 +1,70 @@
+! Copysecond (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs sequences sorting math math.order
+arrays combinators kernel ;
+IN: cords
+
+<PRIVATE
+
+TUPLE: simple-cord first second ;
+
+M: simple-cord length
+    [ first>> length ] [ second>> length ] bi + ;
+
+M: simple-cord virtual-seq first>> ;
+
+M: simple-cord virtual@
+    2dup first>> length <
+    [ first>> ] [ [ first>> length - ] [ second>> ] bi ] if ;
+
+TUPLE: multi-cord count seqs ;
+
+M: multi-cord length count>> ;
+
+M: multi-cord virtual@
+    dupd
+    seqs>> [ first <=> ] binsearch*
+    [ first - ] [ second ] bi ;
+
+M: multi-cord virtual-seq
+    seqs>> dup empty? [ drop f ] [ first second ] if ;
+
+: <cord> ( seqs -- cord )
+    dup length 2 = [
+        first2 simple-cord boa
+    ] [
+        [ 0 [ length + ] accumulate ] keep zip multi-cord boa
+    ] if ;
+
+PRIVATE>
+
+UNION: cord simple-cord multi-cord ;
+
+INSTANCE: cord virtual-sequence
+
+INSTANCE: multi-cord virtual-sequence
+
+: cord-append ( seq1 seq2 -- cord )
+    {
+        { [ over empty? ] [ nip ] }
+        { [ dup empty? ] [ drop ] }
+        { [ 2dup [ cord? ] both? ] [ [ seqs>> values ] bi@ append <cord> ] }
+        { [ over cord? ] [ [ seqs>> values ] dip suffix <cord> ] }
+        { [ dup cord? ] [ seqs>> values swap prefix <cord> ] }
+        [ 2array <cord> ]
+    } cond ;
+
+: cord-concat ( seqs -- cord )
+    {
+        { [ dup empty? ] [ drop f ] }
+        { [ dup length 1 = ] [ first ] }
+        [
+            [
+                {
+                    { [ dup cord? ] [ seqs>> values ] }
+                    { [ dup empty? ] [ drop { } ] }
+                    [ 1array ]
+                } cond
+            ] map concat <cord>
+        ]
+    } cond ;
diff --git a/extra/cords/summary.txt b/extra/cords/summary.txt
new file mode 100644 (file)
index 0000000..3c69862
--- /dev/null
@@ -0,0 +1 @@
+Virtual sequence concatenation
diff --git a/extra/cords/tags.txt b/extra/cords/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections