]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/vocabs/hierarchy/hierarchy.factor
use reject instead of [ ... not ] filter.
[factor.git] / basis / vocabs / hierarchy / hierarchy.factor
index 046ccb8c2d9f1687205547113f97d6a08908ed33..07c2097e35b1b868c0ba5f5aac18622be4f0c836 100644 (file)
 ! Copyright (C) 2007, 2009 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: arrays assocs combinators.short-circuit fry\r
-io.directories io.files io.files.info io.pathnames kernel make\r
+USING: accessors arrays assocs combinators.short-circuit fry\r
+io.directories io.files io.files.types io.pathnames kernel make\r
 memoize namespaces sequences sorting splitting vocabs sets\r
 vocabs.loader vocabs.metadata vocabs.errors ;\r
+RENAME: child-vocabs vocabs => vocabs:child-vocabs\r
 IN: vocabs.hierarchy\r
 \r
+TUPLE: vocab-prefix name ;\r
+\r
+C: <vocab-prefix> vocab-prefix\r
+\r
+M: vocab-prefix vocab-name name>> ;\r
+\r
 <PRIVATE\r
 \r
-: vocab-subdirs ( dir -- dirs )\r
+: visible-dirs ( seq -- seq' )\r
     [\r
-        [\r
-            { [ link-info directory? ] [ "." head? not ] } 1&&\r
-        ] filter\r
-    ] with-directory-files natural-sort ;\r
+        {\r
+            [ type>> +directory+ = ]\r
+            [ name>> "." head? not ]\r
+        } 1&&\r
+    ] filter ;\r
 \r
-: (all-child-vocabs) ( root name -- vocabs )\r
-    [\r
-        vocab-dir append-path dup exists?\r
-        [ vocab-subdirs ] [ drop { } ] if\r
-    ] keep\r
-    [ '[ [ _ "." ] dip 3append ] map ] unless-empty ;\r
+: vocab-subdirs ( dir -- dirs )\r
+    directory-entries visible-dirs [ name>> ] map! natural-sort ;\r
 \r
 : vocab-dir? ( root name -- ? )\r
     over\r
-    [ ".factor" vocab-dir+ append-path exists? ]\r
+    [ ".factor" append-vocab-dir append-path exists? ]\r
     [ 2drop f ]\r
     if ;\r
 \r
-: vocabs-in-dir ( root name -- )\r
-    dupd (all-child-vocabs) [\r
-        2dup vocab-dir? [ dup >vocab-link , ] when\r
-        vocabs-in-dir\r
-    ] with each ;\r
+ERROR: vocab-root-required root ;\r
 \r
-PRIVATE>\r
+: ensure-vocab-root ( root -- root )\r
+    dup vocab-roots get member? [ vocab-root-required ] unless ;\r
 \r
-: all-vocabs ( -- assoc )\r
-    vocab-roots get [\r
-        dup [ "" vocabs-in-dir ] { } make\r
-    ] { } map>assoc ;\r
+: ensure-vocab-root/prefix ( root prefix -- root prefix )\r
+    [ ensure-vocab-root ] [ check-vocab-name ] bi* ;\r
 \r
-: all-vocabs-under ( prefix -- vocabs )\r
-    [\r
-        [ vocab-roots get ] dip '[ _ vocabs-in-dir ] each\r
-    ] { } make ;\r
+: (child-vocabs) ( root prefix -- vocabs )\r
+    check-vocab-name\r
+    [ vocab-dir append-path dup exists? [ vocab-subdirs ] [ drop { } ] if ]\r
+    [ nip [ "." append '[ _ prepend ] map! ] unless-empty ]\r
+    [ drop '[ _ over vocab-dir? [ >vocab-link ] [ <vocab-prefix> ] if ] map! ]\r
+    2tri ;\r
 \r
-MEMO: all-vocabs-seq ( -- seq )\r
-    "" all-vocabs-under ;\r
+: ((child-vocabs-recursive)) ( root prefix -- )\r
+    dupd vocab-name (child-vocabs) [ % ] keep\r
+    [ ((child-vocabs-recursive)) ] with each ;\r
 \r
-<PRIVATE\r
+: (child-vocabs-recursive) ( root prefix -- seq )\r
+    [ ensure-vocab-root ] dip\r
+    [ ((child-vocabs-recursive)) ] { } make ;\r
+\r
+: no-rooted ( seq -- seq' ) [ find-vocab-root ] reject ;\r
+\r
+: one-level-only? ( name prefix -- ? )\r
+    ?head [ "." split1 nip not ] [ drop f ] if ;\r
 \r
 : unrooted-child-vocabs ( prefix -- seq )\r
+    [ vocabs no-rooted ] dip\r
     dup empty? [ CHAR: . suffix ] unless\r
-    vocabs\r
-    [ find-vocab-root not ] filter\r
-    [\r
-        vocab-name swap ?head CHAR: . rot member? not and\r
-    ] with filter\r
-    [ vocab ] map ;\r
+    '[ vocab-name _ one-level-only? ] filter ;\r
+\r
+: unrooted-child-vocabs-recursive ( prefix -- seq )\r
+    vocabs:child-vocabs no-rooted ;\r
 \r
 PRIVATE>\r
 \r
-: all-child-vocabs ( prefix -- assoc )\r
-    vocab-roots get [\r
-        dup pick (all-child-vocabs) [ >vocab-link ] map\r
-    ] { } map>assoc\r
-    swap unrooted-child-vocabs f swap 2array suffix ;\r
+: no-prefixes ( seq -- seq' ) [ vocab-prefix? ] reject ;\r
+\r
+: convert-prefixes ( seq -- seq' )\r
+    [ dup vocab-prefix? [ name>> <vocab-link> ] when ] map ;\r
 \r
-: all-child-vocabs-seq ( prefix -- assoc )\r
-    vocab-roots get swap '[\r
-        dup _ (all-child-vocabs)\r
-        [ vocab-dir? ] with filter\r
-    ] map concat ;\r
+: remove-redundant-prefixes ( seq -- seq' )\r
+    #! Hack.\r
+    [ vocab-prefix? ] partition\r
+    [\r
+        [ vocab-name ] map fast-set\r
+        '[ name>> _ in? ] reject\r
+        convert-prefixes\r
+    ] keep\r
+    append ;\r
+\r
+: no-roots ( assoc -- seq ) values concat ;\r
+\r
+: filter-vocabs ( assoc -- seq )\r
+    no-roots no-prefixes members ;\r
+\r
+: child-vocabs ( prefix -- assoc )\r
+    [ [ vocab-roots get ] dip '[ dup _ (child-vocabs) ] { } map>assoc ]\r
+    [ unrooted-child-vocabs [ lookup-vocab ] map! f swap 2array ]\r
+    bi suffix ;\r
+\r
+: all-vocabs ( -- assoc )\r
+    "" child-vocabs ;\r
+\r
+: child-vocabs-recursive ( prefix -- assoc )\r
+    [ [ vocab-roots get ] dip '[ dup _ (child-vocabs-recursive) ] { } map>assoc ]\r
+    [ unrooted-child-vocabs-recursive [ lookup-vocab ] map! f swap 2array ]\r
+    bi suffix ;\r
+\r
+MEMO: all-vocabs-recursive ( -- assoc )\r
+    "" child-vocabs-recursive ;\r
+\r
+: all-vocab-names ( -- seq )\r
+    all-vocabs-recursive filter-vocabs [ vocab-name ] map! ;\r
+\r
+: child-vocab-names ( prefix -- seq )\r
+    child-vocabs filter-vocabs [ vocab-name ] map! ;\r
 \r
 <PRIVATE\r
 \r
-: filter-unportable ( seq -- seq' )\r
-    [ vocab-name unportable? not ] filter ;\r
+: collect-vocabs ( quot -- seq )\r
+    [ all-vocabs-recursive filter-vocabs ] dip\r
+    gather natural-sort ; inline\r
+\r
+: maybe-include-root/prefix ( root prefix -- vocab-link/f )\r
+    over [\r
+        [ find-vocab-root = ] keep swap\r
+    ] [\r
+        nip dup find-vocab-root\r
+    ] if [ >vocab-link ] [ drop f ] if ;\r
 \r
 PRIVATE>\r
 \r
-: (load) ( prefix -- failures )\r
-    all-vocabs-under\r
-    filter-unportable\r
+: vocabs-in-root/prefix ( root prefix -- seq )\r
+    [ (child-vocabs-recursive) ]\r
+    [ maybe-include-root/prefix [ prefix ] when* ] 2bi ;\r
+\r
+: vocabs-in-root ( root -- seq )\r
+    "" vocabs-in-root/prefix ;\r
+\r
+: (load-from-root) ( root prefix -- failures )\r
+    vocabs-in-root/prefix\r
+    [ don't-load? ] reject no-prefixes\r
     require-all ;\r
 \r
+: load-from-root ( root prefix -- )\r
+    (load-from-root) load-failures. ;\r
+\r
+: load-root ( root -- )\r
+    "" load-from-root ;\r
+\r
+: (load) ( prefix -- failures )\r
+    [ vocab-roots get ] dip '[ _ (load-from-root) ] map concat ;\r
+\r
 : load ( prefix -- )\r
     (load) load-failures. ;\r
 \r
 : load-all ( -- )\r
     "" load ;\r
 \r
-MEMO: all-tags ( -- seq )\r
-    all-vocabs-seq [ vocab-tags ] gather natural-sort ;\r
+MEMO: all-tags ( -- seq ) [ vocab-tags ] collect-vocabs ;\r
 \r
-MEMO: all-authors ( -- seq )\r
-    all-vocabs-seq [ vocab-authors ] gather natural-sort ;
\ No newline at end of file
+MEMO: all-authors ( -- seq ) [ vocab-authors ] collect-vocabs ;\r