]> gitweb.factorcode.org Git - factor.git/blob - core/words/words.factor
56503d36920d180c06f789133a9685cd8b542ae3
[factor.git] / core / words / words.factor
1 ! Copyright (C) 2004, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays definitions kernel kernel.private
4 slots.private math namespaces sequences strings vectors sbufs
5 quotations assocs hashtables sorting vocabs math.order sets
6 words.private ;
7 FROM: assocs => change-at ;
8 IN: words
9
10 : word ( -- word ) \ word get-global ;
11
12 : set-word ( word -- ) \ word set-global ;
13
14 M: word execute (execute) ;
15
16 M: word ?execute execute( -- value ) ; inline
17
18 M: word <=>
19     [ [ name>> ] [ vocabulary>> ] bi 2array ] compare ;
20
21 M: word definer drop \ : \ ; ;
22
23 M: word definition def>> ;
24
25 : word-prop ( word name -- value ) swap props>> at ;
26
27 : remove-word-prop ( word name -- ) swap props>> delete-at ;
28
29 : set-word-prop ( word value name -- )
30     over
31     [ pick props>> ?set-at >>props drop ]
32     [ nip remove-word-prop ] if ;
33
34 : change-word-prop ( ..a word prop quot: ( ..a value -- ..b newvalue ) -- ..b )
35     [ swap props>> ] dip change-at ; inline
36
37 : reset-props ( word seq -- ) [ remove-word-prop ] with each ;
38
39 <PRIVATE
40
41 : caller ( callstack -- word ) callstack>array <reversed> third ;
42
43 PRIVATE>
44
45 TUPLE: undefined word ;
46 : undefined ( -- * ) callstack caller \ undefined boa throw ;
47
48 : undefined-def ( -- quot )
49     #! 'f' inhibits tail call optimization in non-optimizing
50     #! compiler, ensuring that we can pull out the caller word
51     #! above.
52     [ undefined f ] ;
53
54 PREDICATE: deferred < word ( obj -- ? ) def>> undefined-def = ;
55 M: deferred definer drop \ DEFER: f ;
56 M: deferred definition drop f ;
57
58 PREDICATE: primitive < word ( obj -- ? ) "primitive" word-prop ;
59 M: primitive definer drop \ PRIMITIVE: f ;
60 M: primitive definition drop f ;
61
62 : lookup ( name vocab -- word ) vocab-words at ;
63
64 : target-word ( word -- target )
65     [ name>> ] [ vocabulary>> ] bi lookup ;
66
67 SYMBOL: bootstrapping?
68
69 : if-bootstrapping ( true false -- )
70     [ bootstrapping? get ] 2dip if ; inline
71
72 : bootstrap-word ( word -- target )
73     [ target-word ] [ ] if-bootstrapping ;
74
75 GENERIC: crossref? ( word -- ? )
76
77 M: word crossref?
78     dup "forgotten" word-prop [ drop f ] [ vocabulary>> >boolean ] if ;
79
80 GENERIC: subwords ( word -- seq )
81
82 M: word subwords drop f ;
83
84 GENERIC: parent-word ( word -- word/f )
85
86 M: word parent-word drop f ;
87
88 : define ( word def -- )
89     over changed-definition [ ] like >>def drop ;
90
91 : changed-effect ( word -- )
92     [ dup changed-effects get set-in-unit ]
93     [ dup primitive? [ drop ] [ changed-definition ] if ] bi ;
94
95 : set-stack-effect ( effect word -- )
96     2dup "declared-effect" word-prop = [ 2drop ] [
97         [ nip changed-effect ]
98         [ nip subwords [ changed-effect ] each ]
99         [ swap "declared-effect" set-word-prop ]
100         2tri
101     ] if ;
102
103 : define-declared ( word def effect -- )
104     [ nip swap set-stack-effect ] [ drop define ] 3bi ;
105
106 : make-deprecated ( word -- )
107     t "deprecated" set-word-prop ;
108
109 : inline? ( word -- ? ) "inline" word-prop ; inline
110
111 ERROR: cannot-be-inline word ;
112
113 GENERIC: make-inline ( word -- )
114
115 M: word make-inline
116     dup inline? [ drop ] [
117         [ t "inline" set-word-prop ]
118         [ changed-effect ]
119         bi
120     ] if ;
121
122 : define-inline ( word def effect -- )
123     [ define-declared ] [ 2drop make-inline ] 3bi ;
124
125 : make-recursive ( word -- )
126     t "recursive" set-word-prop ;
127
128 GENERIC: flushable? ( word -- ? )
129
130 M: word flushable?
131     [ "flushable" word-prop ]
132     [ parent-word dup [ flushable? ] when ] bi or ;
133
134 : make-flushable ( word -- )
135     t "flushable" set-word-prop ;
136
137 GENERIC: foldable? ( word -- ? )
138
139 M: word foldable?
140     [ "foldable" word-prop ]
141     [ parent-word dup [ foldable? ] when ] bi or ;
142
143 : make-foldable ( word -- )
144     dup make-flushable t "foldable" set-word-prop ;
145
146 GENERIC: reset-word ( word -- )
147
148 M: word reset-word
149     dup flushable? [ dup changed-conditionally ] when
150     {
151         "unannotated-def" "parsing" "inline" "recursive"
152         "foldable" "flushable" "reading" "writing" "reader"
153         "writer" "delimiter" "deprecated"
154     } reset-props ;
155
156 : reset-generic ( word -- )
157     [ subwords forget-all ]
158     [ reset-word ]
159     [
160         f >>pic-def
161         f >>pic-tail-def
162         {
163             "methods"
164             "combination"
165             "default-method"
166             "engines"
167             "decision-tree"
168         } reset-props
169     ] tri ;
170
171 : <word> ( name vocab -- word )
172     2dup 0 hash-combine hash-combine >fixnum (word) dup new-word ;
173
174 : <uninterned-word> ( name -- word )
175     f \ <uninterned-word> counter >fixnum (word)
176     new-words get [ dup new-word ] when ;
177
178 : gensym ( -- word )
179     "( gensym )" <uninterned-word> ;
180
181 : define-temp ( quot effect -- word )
182     [ gensym dup ] 2dip define-declared ;
183
184 : reveal ( word -- )
185     dup [ name>> ] [ vocabulary>> ] bi dup vocab-words
186     [ ] [ no-vocab ] ?if
187     set-at ;
188
189 ERROR: bad-create name vocab ;
190
191 : check-create ( name vocab -- name vocab )
192     2dup [ string? ] [ [ string? ] [ vocab? ] bi or ] bi* and
193     [ bad-create ] unless ;
194
195 : create ( name vocab -- word )
196     check-create 2dup lookup
197     dup [ 2nip ] [
198         drop
199         vocab-name <word>
200         dup reveal
201         dup changed-definition
202     ] if ;
203
204 : constructor-word ( name vocab -- word )
205     [ "<" ">" surround ] dip create ;
206
207 PREDICATE: parsing-word < word "parsing" word-prop ;
208
209 M: parsing-word definer drop \ SYNTAX: \ ; ;
210
211 : define-syntax ( word quot -- )
212     [ drop ] [ define ] 2bi t "parsing" set-word-prop ;
213
214 : delimiter? ( obj -- ? )
215     dup word? [ "delimiter" word-prop ] [ drop f ] if ;
216
217 : deprecated? ( obj -- ? )
218     dup word? [ "deprecated" word-prop ] [ drop f ] if ;
219
220 ! Definition protocol
221 M: word where "loc" word-prop ;
222
223 M: word set-where swap "loc" set-word-prop ;
224
225 M: word forget*
226     dup "forgotten" word-prop [ drop ] [
227         [ subwords forget-all ]
228         [ [ name>> ] [ vocabulary>> vocab-words ] bi delete-at ]
229         [ t "forgotten" set-word-prop ]
230         tri
231     ] if ;
232
233 M: word hashcode*
234     nip 1 slot { fixnum } declare ; inline foldable
235
236 M: word literalize <wrapper> ;
237
238 INSTANCE: word definition