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 hash-sets init kernel kernel.private math namespaces
6 sequences sets source-files.errors vocabs words ;
7 FROM: namespaces => set ;
10 PRIMITIVE: modify-code-heap ( alist update-existing? reset-pics? -- )
12 SYMBOL: old-definitions
13 SYMBOL: new-definitions
15 TUPLE: redefine-error def ;
17 : throw-redefine-error ( definition -- )
18 redefine-error boa throw-continue ;
22 : add-once ( key set -- )
23 dupd ?adjoin [ drop ] [ throw-redefine-error ] if ;
25 : (remember-definition) ( definition loc set -- )
26 [ over set-where ] dip add-once ;
30 : remember-definition ( definition loc -- )
31 new-definitions get first (remember-definition) ;
33 : fake-definition ( definition -- )
34 old-definitions get [ delete ] with each ;
36 : remember-class ( class loc -- )
37 new-definitions get first2
38 [ dupd in? [ dup throw-redefine-error ] when ]
39 [ (remember-definition) ] bi-curry* bi* ;
41 : forward-reference? ( word -- ? )
42 dup old-definitions get [ in? ] with any? [
43 new-definitions get [ in? ] with any? not
48 HOOK: update-call-sites compiler-impl ( class generic -- words )
50 : changed-call-sites ( class generic -- )
51 update-call-sites [ changed-definition ] each ;
53 M: generic update-generic ( class generic -- )
54 [ changed-call-sites ]
55 [ remake-generic drop ]
56 [ changed-conditionally drop ]
59 M: sequence update-methods ( class seq -- )
60 implementors [ update-generic ] with each ;
62 HOOK: recompile compiler-impl ( words -- alist )
64 HOOK: to-recompile compiler-impl ( -- words )
66 HOOK: process-forgotten-words compiler-impl ( words -- )
68 : compile ( words -- )
69 recompile t f modify-code-heap ;
71 ! Non-optimizing compiler
72 M: f update-call-sites
76 changed-definitions get members [ word? ] filter ;
79 [ dup def>> ] { } map>assoc ;
81 M: f process-forgotten-words drop ;
83 : without-optimizer ( quot -- )
84 [ f compiler-impl ] dip with-variable ; inline
86 : <definitions> ( -- pair ) { HS{ } HS{ } } [ clone ] map ;
88 SYMBOL: definition-observers
90 GENERIC: definitions-changed ( set obj -- )
92 [ V{ } clone definition-observers set-global ]
93 "compiler.units" add-startup-hook
95 ! This goes here because vocabs cannot depend on init
96 [ V{ } clone vocab-observers set-global ]
97 "vocabs" add-startup-hook
99 : add-definition-observer ( obj -- )
100 definition-observers get push ;
102 : remove-definition-observer ( obj -- )
103 definition-observers get remove-eq! drop ;
105 : notify-definition-observers ( set -- )
106 definition-observers get
107 [ definitions-changed ] with each ;
109 ! Incremented each time stack effects potentially changed, used
110 ! by compiler.tree.propagation.call-effect for call( and execute(
112 : effect-counter ( -- n ) REDEFINITION-COUNTER special-object ; inline
114 GENERIC: always-bump-effect-counter? ( defspec -- ? )
116 M: object always-bump-effect-counter? drop f ;
120 : changed-vocabs ( set -- vocabs )
121 members [ word? ] filter
122 [ vocabulary>> dup [ lookup-vocab ] when ] map ;
124 : updated-definitions ( -- set )
126 forgotten-definitions get union!
127 new-definitions get first union!
128 new-definitions get second union!
129 changed-definitions get union!
130 maybe-changed get union!
131 dup changed-vocabs over adjoin-all ;
133 : process-forgotten-definitions ( -- )
134 forgotten-definitions get members
135 [ [ word? ] filter process-forgotten-words ]
136 [ [ delete-definition-errors ] each ]
139 : bump-effect-counter? ( -- ? )
140 changed-effects get members
141 maybe-changed get members
142 changed-definitions get members [ always-bump-effect-counter? ] filter
143 3array combine new-words get [ in? not ] curry any? ;
145 : bump-effect-counter ( -- )
146 bump-effect-counter? [
147 REDEFINITION-COUNTER special-object 0 or
148 1 + REDEFINITION-COUNTER set-special-object
151 : notify-observers ( -- )
152 updated-definitions dup null?
153 [ drop ] [ notify-definition-observers notify-error-observers ] if ;
155 : update-existing? ( defs -- ? )
156 new-words get [ in? not ] curry any? ;
158 : reset-pics? ( -- ? )
159 outdated-generics get null? not ;
161 : finish-compilation-unit ( -- )
167 process-forgotten-definitions
168 ] keep update-existing? reset-pics? modify-code-heap
173 TUPLE: nesting-observer { new-words hash-set } ;
175 M: nesting-observer definitions-changed
176 [ members ] dip new-words>> [ delete ] curry each ;
178 : add-nesting-observer ( -- )
179 new-words get nesting-observer boa
180 [ nesting-observer set ] [ add-definition-observer ] bi ;
182 : remove-nesting-observer ( -- )
183 nesting-observer get remove-definition-observer ;
187 : with-nested-compilation-unit ( quot -- )
189 HS{ } clone changed-definitions set
190 HS{ } clone maybe-changed set
191 HS{ } clone changed-effects set
192 HS{ } clone outdated-generics set
193 H{ } clone outdated-tuples set
194 HS{ } clone new-words set
197 remove-nesting-observer
198 finish-compilation-unit
200 ] with-scope ; inline
202 : with-compilation-unit ( quot -- )
204 <definitions> new-definitions set
205 <definitions> old-definitions set
206 HS{ } clone forgotten-definitions set
207 with-nested-compilation-unit
208 ] with-scope ; inline