1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays kernel continuations assocs namespaces
4 sequences words vocabs definitions hashtables init sets math
5 math.order classes classes.private classes.algebra classes.tuple
6 classes.tuple.private generic source-files.errors kernel.private ;
7 FROM: namespaces => set ;
10 SYMBOL: old-definitions
11 SYMBOL: new-definitions
13 TUPLE: redefine-error def ;
15 : redefine-error ( definition -- )
16 \ redefine-error boa throw-continue ;
20 : add-once ( key assoc -- )
21 2dup key? [ over redefine-error ] when conjoin ;
23 : (remember-definition) ( definition loc assoc -- )
24 [ over set-where ] dip add-once ;
28 : remember-definition ( definition loc -- )
29 new-definitions get first (remember-definition) ;
31 : fake-definition ( definition -- )
32 old-definitions get [ delete-at ] with each ;
34 : remember-class ( class loc -- )
35 [ dup new-definitions get first key? [ dup redefine-error ] when ] dip
36 new-definitions get second (remember-definition) ;
38 : forward-reference? ( word -- ? )
39 dup old-definitions get assoc-stack
40 [ new-definitions get assoc-stack not ]
45 HOOK: update-call-sites compiler-impl ( class generic -- words )
47 : changed-call-sites ( class generic -- )
48 update-call-sites [ changed-definition ] each ;
50 M: generic update-generic ( class generic -- )
51 [ changed-call-sites ]
52 [ remake-generic drop ]
53 [ changed-conditionally drop ]
56 M: sequence update-methods ( class seq -- )
57 implementors [ update-generic ] with each ;
59 HOOK: recompile compiler-impl ( words -- alist )
61 HOOK: to-recompile compiler-impl ( -- words )
63 HOOK: process-forgotten-words compiler-impl ( words -- )
65 : compile ( words -- )
66 recompile t f modify-code-heap ;
68 ! Non-optimizing compiler
69 M: f update-call-sites
73 changed-definitions get [ drop word? ] assoc-filter keys ;
76 [ dup def>> ] { } map>assoc ;
78 M: f process-forgotten-words drop ;
80 : without-optimizer ( quot -- )
81 [ f compiler-impl ] dip with-variable ; inline
83 : <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
85 SYMBOL: definition-observers
87 GENERIC: definitions-changed ( assoc obj -- )
89 [ V{ } clone definition-observers set-global ]
90 "compiler.units" add-startup-hook
92 ! This goes here because vocabs cannot depend on init
93 [ V{ } clone vocab-observers set-global ]
94 "vocabs" add-startup-hook
96 : add-definition-observer ( obj -- )
97 definition-observers get push ;
99 : remove-definition-observer ( obj -- )
100 definition-observers get remove-eq! drop ;
102 : notify-definition-observers ( assoc -- )
103 definition-observers get
104 [ definitions-changed ] with each ;
106 ! Incremented each time stack effects potentially changed, used
107 ! by compiler.tree.propagation.call-effect for call( and execute(
109 : effect-counter ( -- n ) 47 special-object ; inline
111 GENERIC: always-bump-effect-counter? ( defspec -- ? )
113 M: object always-bump-effect-counter? drop f ;
117 : changed-vocabs ( assoc -- vocabs )
118 [ drop word? ] assoc-filter
119 [ drop vocabulary>> dup [ vocab ] when dup ] assoc-map ;
121 : updated-definitions ( -- assoc )
123 forgotten-definitions get assoc-union!
124 new-definitions get first assoc-union!
125 new-definitions get second assoc-union!
126 changed-definitions get assoc-union!
127 maybe-changed get assoc-union!
128 dup changed-vocabs assoc-union! ;
130 : process-forgotten-definitions ( -- )
131 forgotten-definitions get keys
132 [ [ word? ] filter process-forgotten-words ]
133 [ [ delete-definition-errors ] each ]
136 : bump-effect-counter? ( -- ? )
139 changed-definitions get [ drop always-bump-effect-counter? ] assoc-filter
140 3array assoc-combine new-words get assoc-diff assoc-empty? not ;
142 : bump-effect-counter ( -- )
143 bump-effect-counter? [
144 47 special-object 0 or
146 47 set-special-object
149 : notify-observers ( -- )
150 updated-definitions dup assoc-empty?
151 [ drop ] [ notify-definition-observers notify-error-observers ] if ;
153 : update-existing? ( defs -- ? )
154 new-words get keys diff empty? not ;
156 : reset-pics? ( -- ? )
157 outdated-generics get assoc-empty? not ;
159 : finish-compilation-unit ( -- )
165 process-forgotten-definitions
166 ] keep update-existing? reset-pics? modify-code-heap
171 TUPLE: nesting-observer new-words ;
173 M: nesting-observer definitions-changed new-words>> swap assoc-diff! drop ;
175 : add-nesting-observer ( -- )
176 new-words get nesting-observer boa
177 [ nesting-observer set ] [ add-definition-observer ] bi ;
179 : remove-nesting-observer ( -- )
180 nesting-observer get remove-definition-observer ;
184 : with-nested-compilation-unit ( quot -- )
186 H{ } clone changed-definitions set
187 H{ } clone maybe-changed set
188 H{ } clone changed-effects set
189 H{ } clone outdated-generics set
190 H{ } clone outdated-tuples set
191 H{ } clone new-words set
194 remove-nesting-observer
195 finish-compilation-unit
197 ] with-scope ; inline
199 : with-compilation-unit ( quot -- )
201 <definitions> new-definitions set
202 <definitions> old-definitions set
203 H{ } clone forgotten-definitions set
204 with-nested-compilation-unit
205 ] with-scope ; inline