1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs classes classes.private
4 classes.tuple classes.tuple.private continuations definitions
5 generic init kernel kernel.private math namespaces sequences
6 sets source-files.errors vocabs words ;
7 FROM: namespaces => set ;
8 FROM: sets => members ;
11 SYMBOL: old-definitions
12 SYMBOL: new-definitions
14 TUPLE: redefine-error def ;
16 : redefine-error ( definition -- )
17 \ redefine-error boa throw-continue ;
21 : add-once ( key assoc -- )
22 2dup key? [ over redefine-error ] when conjoin ;
24 : (remember-definition) ( definition loc assoc -- )
25 [ over set-where ] dip add-once ;
29 : remember-definition ( definition loc -- )
30 new-definitions get first (remember-definition) ;
32 : fake-definition ( definition -- )
33 old-definitions get [ delete-at ] with each ;
35 : remember-class ( class loc -- )
36 [ dup new-definitions get first key? [ dup redefine-error ] when ] dip
37 new-definitions get second (remember-definition) ;
39 : forward-reference? ( word -- ? )
40 dup old-definitions get assoc-stack
41 [ new-definitions get assoc-stack not ]
46 HOOK: update-call-sites compiler-impl ( class generic -- words )
48 : changed-call-sites ( class generic -- )
49 update-call-sites [ changed-definition ] each ;
51 M: generic update-generic ( class generic -- )
52 [ changed-call-sites ]
53 [ remake-generic drop ]
54 [ changed-conditionally drop ]
57 M: sequence update-methods ( class seq -- )
58 implementors [ update-generic ] with each ;
60 HOOK: recompile compiler-impl ( words -- alist )
62 HOOK: to-recompile compiler-impl ( -- words )
64 HOOK: process-forgotten-words compiler-impl ( words -- )
66 : compile ( words -- )
67 recompile t f modify-code-heap ;
69 ! Non-optimizing compiler
70 M: f update-call-sites
74 changed-definitions get [ drop word? ] assoc-filter keys ;
77 [ dup def>> ] { } map>assoc ;
79 M: f process-forgotten-words drop ;
81 : without-optimizer ( quot -- )
82 [ f compiler-impl ] dip with-variable ; inline
84 : <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
86 SYMBOL: definition-observers
88 GENERIC: definitions-changed ( set obj -- )
90 [ V{ } clone definition-observers set-global ]
91 "compiler.units" add-startup-hook
93 ! This goes here because vocabs cannot depend on init
94 [ V{ } clone vocab-observers set-global ]
95 "vocabs" add-startup-hook
97 : add-definition-observer ( obj -- )
98 definition-observers get push ;
100 : remove-definition-observer ( obj -- )
101 definition-observers get remove-eq! drop ;
103 : notify-definition-observers ( set -- )
104 definition-observers get
105 [ definitions-changed ] with each ;
107 ! Incremented each time stack effects potentially changed, used
108 ! by compiler.tree.propagation.call-effect for call( and execute(
110 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
112 GENERIC: always-bump-effect-counter? ( defspec -- ? )
114 M: object always-bump-effect-counter? drop f ;
118 : changed-vocabs ( set -- vocabs )
119 members [ word? ] filter
120 [ vocabulary>> dup [ lookup-vocab ] when ] map ;
122 : updated-definitions ( -- set )
124 forgotten-definitions get keys over adjoin-all
125 new-definitions get first keys over adjoin-all
126 new-definitions get second keys over adjoin-all
127 changed-definitions get keys over adjoin-all
128 maybe-changed get keys over adjoin-all
129 dup changed-vocabs over adjoin-all ;
131 : process-forgotten-definitions ( -- )
132 forgotten-definitions get keys
133 [ [ word? ] filter process-forgotten-words ]
134 [ [ delete-definition-errors ] each ]
137 : bump-effect-counter? ( -- ? )
140 changed-definitions get [ drop always-bump-effect-counter? ] assoc-filter
141 3array assoc-combine new-words get assoc-diff! assoc-empty? not ;
143 : bump-effect-counter ( -- )
144 bump-effect-counter? [
145 REDEFINITION-COUNTER special-object 0 or
146 1 + REDEFINITION-COUNTER set-special-object
149 : notify-observers ( -- )
150 updated-definitions dup null?
151 [ drop ] [ notify-definition-observers notify-error-observers ] if ;
153 : update-existing? ( defs -- ? )
154 new-words get [ key? not ] curry any? ;
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
174 [ members ] dip new-words>> [ delete-at ] curry each ;
176 : add-nesting-observer ( -- )
177 new-words get nesting-observer boa
178 [ nesting-observer set ] [ add-definition-observer ] bi ;
180 : remove-nesting-observer ( -- )
181 nesting-observer get remove-definition-observer ;
185 : with-nested-compilation-unit ( quot -- )
187 H{ } clone changed-definitions set
188 H{ } clone maybe-changed set
189 H{ } clone changed-effects set
190 H{ } clone outdated-generics set
191 H{ } clone outdated-tuples set
192 H{ } clone new-words set
195 remove-nesting-observer
196 finish-compilation-unit
198 ] with-scope ; inline
200 : with-compilation-unit ( quot -- )
202 <definitions> new-definitions set
203 <definitions> old-definitions set
204 H{ } clone forgotten-definitions set
205 with-nested-compilation-unit
206 ] with-scope ; inline