factor/basis/vocabs/hierarchy/hierarchy.factor

159 lines
4.4 KiB
Factor
Raw Normal View History

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