Merge branch 'master' of git://factorcode.org/git/factor
[factor/jcg.git] / core / vocabs / loader / loader.factor
blob48e8737fd25f0edbddfbec2e051d86c3347da400
1 ! Copyright (C) 2007, 2008 Eduardo Cavazos, Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: namespaces make sequences io io.files io.pathnames kernel
4 assocs words vocabs definitions parser continuations hashtables
5 sorting source-files arrays combinators strings system
6 math.parser compiler.errors splitting init accessors sets ;
7 IN: vocabs.loader
9 SYMBOL: vocab-roots
12     "resource:core"
13     "resource:basis"
14     "resource:extra"
15     "resource:work"
16 } clone vocab-roots set-global
18 : add-vocab-root ( root -- )
19     vocab-roots get adjoin ;
21 : vocab-dir ( vocab -- dir )
22     vocab-name { { CHAR: . CHAR: / } } substitute ;
24 : vocab-dir+ ( vocab str/f -- path )
25     [ vocab-name "." split ] dip
26     [ [ dup peek ] dip append suffix ] when*
27     "/" join ;
29 : vocab-dir? ( root name -- ? )
30     over
31     [ ".factor" vocab-dir+ append-path exists? ]
32     [ 2drop f ]
33     if ;
35 SYMBOL: root-cache
37 H{ } clone root-cache set-global
39 <PRIVATE
41 : (find-vocab-root) ( name -- path/f )
42     vocab-roots get swap [ vocab-dir? ] curry find nip ;
44 PRIVATE>
46 : find-vocab-root ( vocab -- path/f )
47     vocab-name dup root-cache get at [ ] [ (find-vocab-root) ] ?if ;
49 : vocab-append-path ( vocab path -- newpath )
50     swap find-vocab-root dup [ prepend-path ] [ 2drop f ] if ;
52 : vocab-source-path ( vocab -- path/f )
53     dup ".factor" vocab-dir+ vocab-append-path ;
55 : vocab-docs-path ( vocab -- path/f )
56     dup "-docs.factor" vocab-dir+ vocab-append-path ;
58 SYMBOL: load-help?
60 <PRIVATE
62 : load-source ( vocab -- )
63     [
64         +parsing+ >>source-loaded?
65         dup vocab-source-path [ parse-file ] [ [ ] ] if*
66         [ +parsing+ >>source-loaded? ] dip
67         [ % ] [ assert-depth ] if-bootstrapping
68         +done+ >>source-loaded? drop
69     ] [ ] [ f >>source-loaded? ] cleanup ;
71 : load-docs ( vocab -- )
72     load-help? get [
73         [
74             +parsing+ >>docs-loaded?
75             [ vocab-docs-path [ ?run-file ] when* ] keep
76             +done+ >>docs-loaded?
77         ] [ ] [ f >>docs-loaded? ] cleanup
78     ] when drop ;
80 PRIVATE>
82 : require ( vocab -- )
83     [ load-vocab drop ] with-compiler-errors ;
85 : reload ( name -- )
86     dup vocab
87     [ [ [ load-source ] [ load-docs ] bi ] with-compiler-errors ]
88     [ require ]
89     ?if ;
91 : run ( vocab -- )
92     dup load-vocab vocab-main [
93         execute
94     ] [
95         "The " write vocab-name write
96         " vocabulary does not define an entry point." print
97         "To define one, refer to \\ MAIN: help" print
98     ] ?if ;
100 SYMBOL: blacklist
102 <PRIVATE
104 : add-to-blacklist ( error vocab -- )
105     vocab-name blacklist get dup [ set-at ] [ 3drop ] if ;
107 GENERIC: (load-vocab) ( name -- )
109 M: vocab (load-vocab)
110     [
111         dup source-loaded?>> +parsing+ eq? [
112             dup source-loaded?>> [ dup load-source ] unless
113             dup docs-loaded?>> [ dup load-docs ] unless
114         ] unless drop
115     ] [ [ swap add-to-blacklist ] keep rethrow ] recover ;
117 M: vocab-link (load-vocab)
118     vocab-name create-vocab (load-vocab) ;
120 M: string (load-vocab)
121     create-vocab (load-vocab) ;
124     [
125         dup vocab-name blacklist get at* [ rethrow ] [
126             drop dup find-vocab-root
127             [ [ (load-vocab) ] with-compiler-errors ]
128             [ dup vocab [ drop ] [ no-vocab ] if ]
129             if
130         ] if
131     ] with-compiler-errors
132 ] load-vocab-hook set-global
134 PRIVATE>
136 : vocab-where ( vocab -- loc )
137     vocab-source-path dup [ 1 2array ] when ;
139 M: vocab where vocab-where ;
141 M: vocab-link where vocab-where ;