]> gitweb.factorcode.org Git - factor.git/blob - core/compiler/units/units.factor
Merge branch 'master' into startup
[factor.git] / core / compiler / units / units.factor
1 ! Copyright (C) 2008, 2009 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
5 math math.order classes classes.algebra classes.tuple
6 classes.tuple.private generic source-files.errors
7 kernel.private ;
8 IN: compiler.units
9
10 SYMBOL: old-definitions
11 SYMBOL: new-definitions
12
13 TUPLE: redefine-error def ;
14
15 : redefine-error ( definition -- )
16     \ redefine-error boa
17     { { "Continue" t } } throw-restarts drop ;
18
19 <PRIVATE
20
21 : add-once ( key assoc -- )
22     2dup key? [ over redefine-error ] when conjoin ;
23
24 : (remember-definition) ( definition loc assoc -- )
25     [ over set-where ] dip add-once ;
26
27 PRIVATE>
28
29 : remember-definition ( definition loc -- )
30     new-definitions get first (remember-definition) ;
31
32 : fake-definition ( definition -- )
33     old-definitions get [ delete-at ] with each ;
34
35 : remember-class ( class loc -- )
36     [ dup new-definitions get first key? [ dup redefine-error ] when ] dip
37     new-definitions get second (remember-definition) ;
38
39 : forward-reference? ( word -- ? )
40     dup old-definitions get assoc-stack
41     [ new-definitions get assoc-stack not ]
42     [ drop f ] if ;
43
44 SYMBOL: compiler-impl
45
46 HOOK: recompile compiler-impl ( words -- alist )
47
48 HOOK: to-recompile compiler-impl ( -- words )
49
50 HOOK: process-forgotten-words compiler-impl ( words -- )
51
52 : compile ( words -- ) recompile modify-code-heap ;
53
54 ! Non-optimizing compiler
55 M: f recompile
56     [ dup def>> ] { } map>assoc ;
57
58 M: f to-recompile
59     changed-definitions get [ drop word? ] assoc-filter
60     changed-generics get assoc-union keys ;
61
62 M: f process-forgotten-words drop ;
63
64 : without-optimizer ( quot -- )
65     [ f compiler-impl ] dip with-variable ; inline
66
67 ! Trivial compiler. We don't want to touch the code heap
68 ! during stage1 bootstrap, it would just waste time.
69 SINGLETON: dummy-compiler
70
71 M: dummy-compiler to-recompile f ;
72
73 M: dummy-compiler recompile drop { } ;
74
75 M: dummy-compiler process-forgotten-words drop ;
76
77 : <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
78
79 SYMBOL: definition-observers
80
81 GENERIC: definitions-changed ( assoc obj -- )
82
83 [ V{ } clone definition-observers set-global ]
84 "compiler.units" add-startup-hook
85
86 ! This goes here because vocabs cannot depend on init
87 [ V{ } clone vocab-observers set-global ]
88 "vocabs" add-startup-hook
89
90 : add-definition-observer ( obj -- )
91     definition-observers get push ;
92
93 : remove-definition-observer ( obj -- )
94     definition-observers get remove-eq! drop ;
95
96 : notify-definition-observers ( assoc -- )
97     definition-observers get
98     [ definitions-changed ] with each ;
99
100 ! Incremented each time stack effects potentially changed, used
101 ! by compiler.tree.propagation.call-effect for call( and execute(
102 ! inline caching
103 : effect-counter ( -- n ) 46 getenv ; inline
104
105 GENERIC: bump-effect-counter* ( defspec -- ? )
106
107 M: object bump-effect-counter* drop f ;
108
109 <PRIVATE
110
111 : changed-vocabs ( assoc -- vocabs )
112     [ drop word? ] assoc-filter
113     [ drop vocabulary>> dup [ vocab ] when dup ] assoc-map ;
114
115 : updated-definitions ( -- assoc )
116     H{ } clone
117     dup forgotten-definitions get update
118     dup new-definitions get first update
119     dup new-definitions get second update
120     dup changed-definitions get update
121     dup dup changed-vocabs update ;
122
123 : process-forgotten-definitions ( -- )
124     forgotten-definitions get keys
125     [ [ word? ] filter process-forgotten-words ]
126     [ [ delete-definition-errors ] each ]
127     bi ;
128
129 : bump-effect-counter? ( -- ? )
130     changed-effects get new-words get assoc-diff assoc-empty? not
131     changed-definitions get [ drop bump-effect-counter* ] assoc-any?
132     or ;
133
134 : bump-effect-counter ( -- )
135     bump-effect-counter? [ 46 getenv 0 or 1 + 46 setenv ] when ;
136
137 : notify-observers ( -- )
138     updated-definitions dup assoc-empty?
139     [ drop ] [ notify-definition-observers notify-error-observers ] if ;
140
141 : finish-compilation-unit ( -- )
142     remake-generics
143     to-recompile recompile
144     update-tuples
145     process-forgotten-definitions
146     modify-code-heap
147     bump-effect-counter
148     notify-observers ;
149
150 PRIVATE>
151
152 : with-nested-compilation-unit ( quot -- )
153     [
154         H{ } clone changed-definitions set
155         H{ } clone changed-generics set
156         H{ } clone changed-effects set
157         H{ } clone outdated-generics set
158         H{ } clone outdated-tuples set
159         H{ } clone new-words set
160         H{ } clone new-classes set
161         [ finish-compilation-unit ] [ ] cleanup
162     ] with-scope ; inline
163
164 : with-compilation-unit ( quot -- )
165     [
166         H{ } clone changed-definitions set
167         H{ } clone changed-generics set
168         H{ } clone changed-effects set
169         H{ } clone outdated-generics set
170         H{ } clone forgotten-definitions set
171         H{ } clone outdated-tuples set
172         H{ } clone new-words set
173         H{ } clone new-classes set
174         <definitions> new-definitions set
175         <definitions> old-definitions set
176         [ finish-compilation-unit ] [ ] cleanup
177     ] with-scope ; inline