]> gitweb.factorcode.org Git - factor.git/blob - core/words/words.factor
7111c2789b9d0e7a84f4439a8baa682b8e23c04f
[factor.git] / core / words / words.factor
1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays definitions graphs assocs kernel kernel.private
4 slots.private math namespaces sequences strings vectors sbufs
5 quotations assocs hashtables sorting words.private vocabs
6 math.order sets ;
7 IN: words
8
9 : word ( -- word ) \ word get-global ;
10
11 : set-word ( word -- ) \ word set-global ;
12
13 GENERIC: execute ( word -- )
14
15 M: word execute (execute) ;
16
17 M: word <=>
18     [ dup word-name swap word-vocabulary 2array ] compare ;
19
20 M: word definer drop \ : \ ; ;
21
22 M: word definition word-def ;
23
24 ERROR: undefined ;
25
26 PREDICATE: deferred < word ( obj -- ? )
27     word-def [ undefined ] = ;
28 M: deferred definer drop \ DEFER: f ;
29 M: deferred definition drop f ;
30
31 PREDICATE: symbol < word ( obj -- ? )
32     dup <wrapper> 1array swap word-def sequence= ;
33 M: symbol definer drop \ SYMBOL: f ;
34 M: symbol definition drop f ;
35
36 PREDICATE: primitive < word ( obj -- ? )
37     word-def [ do-primitive ] tail? ;
38 M: primitive definer drop \ PRIMITIVE: f ;
39 M: primitive definition drop f ;
40
41 : word-prop ( word name -- value ) swap word-props at ;
42
43 : remove-word-prop ( word name -- )
44     swap word-props delete-at ;
45
46 : set-word-prop ( word value name -- )
47     over
48     [ pick word-props ?set-at swap set-word-props ]
49     [ nip remove-word-prop ] if ;
50
51 : reset-props ( word seq -- ) [ remove-word-prop ] with each ;
52
53 : lookup ( name vocab -- word ) vocab-words at ;
54
55 : target-word ( word -- target )
56     dup word-name swap word-vocabulary lookup ;
57
58 SYMBOL: bootstrapping?
59
60 : if-bootstrapping ( true false -- )
61     bootstrapping? get -rot if ; inline
62
63 : bootstrap-word ( word -- target )
64     [ target-word ] [ ] if-bootstrapping ;
65
66 GENERIC: crossref? ( word -- ? )
67
68 M: word crossref?
69     dup "forgotten" word-prop [
70         drop f
71     ] [
72         word-vocabulary >boolean
73     ] if ;
74
75 GENERIC: compiled-crossref? ( word -- ? )
76
77 M: word compiled-crossref? crossref? ;
78
79 GENERIC# (quot-uses) 1 ( obj assoc -- )
80
81 M: object (quot-uses) 2drop ;
82
83 M: word (quot-uses)
84     >r dup crossref? [ dup r> set-at ] [ r> 2drop ] if ;
85
86 : seq-uses ( seq assoc -- ) [ (quot-uses) ] curry each ;
87
88 M: array (quot-uses) seq-uses ;
89
90 M: callable (quot-uses) seq-uses ;
91
92 M: wrapper (quot-uses) >r wrapped r> (quot-uses) ;
93
94 : quot-uses ( quot -- assoc )
95     global [ H{ } clone [ (quot-uses) ] keep ] bind ;
96
97 M: word uses ( word -- seq )
98     word-def quot-uses keys ;
99
100 SYMBOL: compiled-crossref
101
102 compiled-crossref global [ H{ } assoc-like ] change-at
103
104 : compiled-xref ( word dependencies -- )
105     [ drop crossref? ] assoc-filter
106     2dup "compiled-uses" set-word-prop
107     compiled-crossref get add-vertex* ;
108
109 : compiled-unxref ( word -- )
110     dup "compiled-uses" word-prop
111     compiled-crossref get remove-vertex* ;
112
113 : delete-compiled-xref ( word -- )
114     dup compiled-unxref
115     compiled-crossref get delete-at ;
116
117 SYMBOL: +inlined+
118 SYMBOL: +called+
119
120 : compiled-usage ( word -- assoc )
121     compiled-crossref get at ;
122
123 : compiled-usages ( words -- seq )
124     [ unique dup ] keep [
125         compiled-usage [ nip +inlined+ eq? ] assoc-filter update
126     ] with each keys ;
127
128 GENERIC: redefined ( word -- )
129
130 M: object redefined drop ;
131
132 : define ( word def -- )
133     [ ] like
134     over unxref
135     over redefined
136     over set-word-def
137     dup changed-definition
138     dup crossref? [ dup xref ] when drop ;
139
140 : define-declared ( word def effect -- )
141     pick swap "declared-effect" set-word-prop
142     define ;
143
144 : make-inline ( word -- )
145     t "inline" set-word-prop ;
146
147 : make-flushable ( word -- )
148     t "flushable" set-word-prop ;
149
150 : make-foldable ( word -- )
151     dup make-flushable t "foldable" set-word-prop ;
152
153 : define-inline ( word quot -- )
154     dupd define make-inline ;
155
156 : define-symbol ( word -- )
157     dup [ ] curry define-inline ;
158
159 GENERIC: reset-word ( word -- )
160
161 M: word reset-word
162     {
163         "unannotated-def"
164         "parsing" "inline" "foldable" "flushable"
165         "predicating"
166         "reading" "writing"
167         "constructing"
168         "declared-effect" "constructor-quot" "delimiter"
169     } reset-props ;
170
171 GENERIC: subwords ( word -- seq )
172
173 M: word subwords drop f ;
174
175 : reset-generic ( word -- )
176     dup subwords forget-all
177     dup reset-word
178     { "methods" "combination" "default-method" } reset-props ;
179
180 : gensym ( -- word )
181     "( gensym )" f <word> ;
182
183 : define-temp ( quot -- word )
184     gensym dup rot define ;
185
186 : reveal ( word -- )
187     dup word-name over word-vocabulary dup vocab-words
188     [ ] [ no-vocab ] ?if
189     set-at ;
190
191 ERROR: bad-create name vocab ;
192
193 : check-create ( name vocab -- name vocab )
194     2dup [ string? ] both?
195     [ bad-create ] unless ;
196
197 : create ( name vocab -- word )
198     check-create 2dup lookup
199     dup [ 2nip ] [ drop <word> dup reveal ] if ;
200
201 : constructor-word ( name vocab -- word )
202     >r "<" swap ">" 3append r> create ;
203
204 PREDICATE: parsing-word < word "parsing" word-prop ;
205
206 : delimiter? ( obj -- ? )
207     dup word? [ "delimiter" word-prop ] [ drop f ] if ;
208
209 ! Definition protocol
210 M: word where "loc" word-prop ;
211
212 M: word set-where swap "loc" set-word-prop ;
213
214 M: word forget*
215     dup "forgotten" word-prop [
216         dup delete-xref
217         dup delete-compiled-xref
218         dup word-name over word-vocabulary vocab-words delete-at
219         dup t "forgotten" set-word-prop
220     ] unless drop ;
221
222 M: word hashcode*
223     nip 1 slot { fixnum } declare ;
224
225 M: word literalize <wrapper> ;
226
227 : ?word-name ( word -- name ) dup word? [ word-name ] when ;
228
229 : xref-words ( -- ) all-words [ xref ] each ;