@@ -15,24 +15,31 @@ use crate::sema::{
15
15
self , AliasDefinitionId , ClassDefinition , Element , EnumDefinition , FctDefinitionId , FctParent ,
16
16
ModuleDefinitionId , PackageDefinitionId , PackageName , StructDefinition , TypeParamDefinition ,
17
17
} ;
18
- use crate :: sema:: { ExtensionDefinitionId , GlobalDefinition , GlobalDefinitionId } ;
19
-
20
- use super :: sema:: { ImplDefinitionId , TraitDefinitionId } ;
21
-
22
- struct Emitter {
23
- global_initializer : HashMap < GlobalDefinitionId , FunctionId > ,
24
- }
18
+ use crate :: sema:: {
19
+ ExtensionDefinitionId , GlobalDefinition , GlobalDefinitionId , ImplDefinitionId ,
20
+ TraitDefinitionId ,
21
+ } ;
25
22
26
23
pub fn emit_program ( sa : Sema ) -> Program {
27
24
let mut emitter = Emitter {
28
25
global_initializer : HashMap :: new ( ) ,
26
+ map_functions : HashMap :: new ( ) ,
27
+ functions : Vec :: new ( ) ,
28
+ globals : Vec :: new ( ) ,
29
+ packages : Vec :: new ( ) ,
30
+ modules : Vec :: new ( ) ,
29
31
} ;
30
32
33
+ emitter. create_packages ( & sa) ;
34
+ emitter. create_modules ( & sa) ;
35
+ emitter. create_functions ( & sa) ;
36
+ emitter. create_globals ( & sa) ;
37
+
31
38
Program {
32
- packages : create_packages ( & sa ) ,
33
- modules : create_modules ( & sa ) ,
34
- functions : create_functions ( & sa , & mut emitter) ,
35
- globals : create_globals ( & sa , & emitter) ,
39
+ packages : emitter . packages ,
40
+ modules : emitter . modules ,
41
+ functions : emitter. functions ,
42
+ globals : emitter. globals ,
36
43
classes : create_classes ( & sa) ,
37
44
structs : create_structs ( & sa) ,
38
45
enums : create_enums ( & sa) ,
@@ -48,43 +55,142 @@ pub fn emit_program(sa: Sema) -> Program {
48
55
}
49
56
}
50
57
51
- fn create_packages ( sa : & Sema ) -> Vec < PackageData > {
52
- let mut result = Vec :: new ( ) ;
53
-
54
- for ( _id, pkg) in sa. packages . iter ( ) {
55
- let name = match pkg. name {
56
- PackageName :: Boots => "boots" . into ( ) ,
57
- PackageName :: Std => "std" . into ( ) ,
58
- PackageName :: Program => "program" . into ( ) ,
59
- PackageName :: External ( ref name) => name. clone ( ) ,
60
- } ;
58
+ struct Emitter {
59
+ global_initializer : HashMap < GlobalDefinitionId , FunctionId > ,
60
+ map_functions : HashMap < FctDefinitionId , FunctionId > ,
61
+ functions : Vec < FunctionData > ,
62
+ globals : Vec < GlobalData > ,
63
+ packages : Vec < PackageData > ,
64
+ modules : Vec < ModuleData > ,
65
+ }
61
66
62
- result. push ( PackageData {
63
- name,
64
- root_module_id : convert_module_id ( pkg. top_level_module_id ( ) ) ,
65
- } )
67
+ impl Emitter {
68
+ fn create_packages ( & mut self , sa : & Sema ) {
69
+ for ( _id, pkg) in sa. packages . iter ( ) {
70
+ let name = match pkg. name {
71
+ PackageName :: Boots => "boots" . into ( ) ,
72
+ PackageName :: Std => "std" . into ( ) ,
73
+ PackageName :: Program => "program" . into ( ) ,
74
+ PackageName :: External ( ref name) => name. clone ( ) ,
75
+ } ;
76
+
77
+ self . packages . push ( PackageData {
78
+ name,
79
+ root_module_id : convert_module_id ( pkg. top_level_module_id ( ) ) ,
80
+ } ) ;
81
+ }
66
82
}
67
83
68
- result
69
- }
84
+ fn create_modules ( & mut self , sa : & Sema ) {
85
+ for ( _id, module) in sa. modules . iter ( ) {
86
+ let name = if let Some ( name) = module. name {
87
+ sa. interner . str ( name) . to_string ( )
88
+ } else {
89
+ "<root>" . into ( )
90
+ } ;
91
+
92
+ self . modules . push ( ModuleData {
93
+ name,
94
+ parent_id : module. parent_module_id . map ( |id| convert_module_id ( id) ) ,
95
+ } )
96
+ }
97
+ }
70
98
71
- fn create_modules ( sa : & Sema ) -> Vec < ModuleData > {
72
- let mut result = Vec :: new ( ) ;
99
+ fn create_functions ( & mut self , sa : & Sema ) {
100
+ for ( id, fct) in sa. fcts . iter ( ) {
101
+ let name = sa. interner . str ( fct. name ) . to_string ( ) ;
102
+
103
+ let kind = match fct. parent {
104
+ FctParent :: Extension ( extension_id) => {
105
+ FunctionKind :: Extension ( convert_extension_id ( extension_id) )
106
+ }
107
+ FctParent :: Function => FunctionKind :: Lambda ,
108
+ FctParent :: Impl ( impl_id) => FunctionKind :: Impl ( convert_impl_id ( impl_id) ) ,
109
+ FctParent :: Trait ( trait_id) => FunctionKind :: Trait ( convert_trait_id ( trait_id) ) ,
110
+ FctParent :: None => FunctionKind :: Function ,
111
+ } ;
112
+
113
+ let function_id = FunctionId ( self . functions . len ( ) . try_into ( ) . expect ( "overflow" ) ) ;
114
+ self . functions . push ( FunctionData {
115
+ name,
116
+ loc : sa. compute_loc ( fct. file_id , fct. span ) ,
117
+ kind,
118
+ file_id : convert_source_file_id ( fct. file_id ) ,
119
+ package_id : convert_package_id ( fct. package_id ) ,
120
+ module_id : convert_module_id ( fct. module_id ) ,
121
+ type_params : create_type_params ( sa, fct. type_param_definition ( ) ) ,
122
+ source_file_id : Some ( convert_source_file_id ( fct. file_id ) ) ,
123
+ params : fct
124
+ . params_with_self ( )
125
+ . iter ( )
126
+ . map ( |p| bty_from_ty ( p. ty ( ) ) )
127
+ . collect ( ) ,
128
+ return_type : fct. return_type_bty ( ) ,
129
+ is_internal : fct. is_internal ,
130
+ is_test : fct. is_test ,
131
+ is_optimize_immediately : fct. is_optimize_immediately ,
132
+ is_variadic : fct. params . is_variadic ( ) ,
133
+ is_force_inline : fct. is_force_inline ,
134
+ is_never_inline : fct. is_never_inline ,
135
+ is_trait_object_ignore : fct. is_trait_object_ignore ,
136
+ bytecode : fct. bytecode . get ( ) . cloned ( ) ,
137
+ trait_method_impl : fct
138
+ . trait_method_impl
139
+ . get ( )
140
+ . cloned ( )
141
+ . map ( |id| convert_function_id ( id) ) ,
142
+ } ) ;
143
+
144
+ self . map_functions . insert ( id, function_id) ;
145
+ }
73
146
74
- for ( _id, module) in sa. modules . iter ( ) {
75
- let name = if let Some ( name) = module. name {
76
- sa. interner . str ( name) . to_string ( )
77
- } else {
78
- "<root>" . into ( )
79
- } ;
147
+ for ( _id, global) in sa. globals . iter ( ) {
148
+ if !global. has_initial_value ( ) {
149
+ continue ;
150
+ }
80
151
81
- result. push ( ModuleData {
82
- name,
83
- parent_id : module. parent_module_id . map ( |id| convert_module_id ( id) ) ,
84
- } )
152
+ let fct_id = FunctionId ( self . functions . len ( ) . try_into ( ) . expect ( "overflow" ) ) ;
153
+ let name = sa. interner . str ( global. name ) . to_string ( ) ;
154
+
155
+ self . functions . push ( FunctionData {
156
+ name,
157
+ loc : sa. compute_loc ( global. file_id , global. span ) ,
158
+ kind : FunctionKind :: Function ,
159
+ file_id : convert_source_file_id ( global. file_id ) ,
160
+ package_id : convert_package_id ( global. package_id ) ,
161
+ module_id : convert_module_id ( global. module_id ) ,
162
+ type_params : create_type_params ( sa, & TypeParamDefinition :: empty ( ) ) ,
163
+ source_file_id : Some ( convert_source_file_id ( global. file_id ) ) ,
164
+ params : Vec :: new ( ) ,
165
+ return_type : bty_from_ty ( global. ty ( ) ) ,
166
+ is_internal : false ,
167
+ is_test : false ,
168
+ is_optimize_immediately : false ,
169
+ is_variadic : false ,
170
+ is_force_inline : false ,
171
+ is_never_inline : false ,
172
+ is_trait_object_ignore : false ,
173
+ bytecode : Some ( global. bytecode ( ) . clone ( ) ) ,
174
+ trait_method_impl : None ,
175
+ } ) ;
176
+
177
+ self . global_initializer . insert ( global. id ( ) , fct_id) ;
178
+ }
85
179
}
86
180
87
- result
181
+ fn create_globals ( & mut self , sa : & Sema ) {
182
+ for ( _id, global) in sa. globals . iter ( ) {
183
+ let name = sa. interner . str ( global. name ) . to_string ( ) ;
184
+
185
+ self . globals . push ( GlobalData {
186
+ module_id : convert_module_id ( global. module_id ) ,
187
+ ty : bty_from_ty ( global. ty ( ) ) ,
188
+ mutable : global. mutable ,
189
+ name,
190
+ initial_value : global_initializer_function_id ( sa, & * global, self ) ,
191
+ } )
192
+ }
193
+ }
88
194
}
89
195
90
196
fn create_extensions ( sa : & Sema ) -> Vec < ExtensionData > {
@@ -174,107 +280,6 @@ fn create_aliases(sa: &Sema) -> Vec<AliasData> {
174
280
result
175
281
}
176
282
177
- fn create_functions ( sa : & Sema , e : & mut Emitter ) -> Vec < FunctionData > {
178
- let mut result = Vec :: new ( ) ;
179
-
180
- for ( _id, fct) in sa. fcts . iter ( ) {
181
- let name = sa. interner . str ( fct. name ) . to_string ( ) ;
182
-
183
- let kind = match fct. parent {
184
- FctParent :: Extension ( extension_id) => {
185
- FunctionKind :: Extension ( convert_extension_id ( extension_id) )
186
- }
187
- FctParent :: Function => FunctionKind :: Lambda ,
188
- FctParent :: Impl ( impl_id) => FunctionKind :: Impl ( convert_impl_id ( impl_id) ) ,
189
- FctParent :: Trait ( trait_id) => FunctionKind :: Trait ( convert_trait_id ( trait_id) ) ,
190
- FctParent :: None => FunctionKind :: Function ,
191
- } ;
192
-
193
- result. push ( FunctionData {
194
- name,
195
- loc : sa. compute_loc ( fct. file_id , fct. span ) ,
196
- kind,
197
- file_id : convert_source_file_id ( fct. file_id ) ,
198
- package_id : convert_package_id ( fct. package_id ) ,
199
- module_id : convert_module_id ( fct. module_id ) ,
200
- type_params : create_type_params ( sa, fct. type_param_definition ( ) ) ,
201
- source_file_id : Some ( convert_source_file_id ( fct. file_id ) ) ,
202
- params : fct
203
- . params_with_self ( )
204
- . iter ( )
205
- . map ( |p| bty_from_ty ( p. ty ( ) ) )
206
- . collect ( ) ,
207
- return_type : fct. return_type_bty ( ) ,
208
- is_internal : fct. is_internal ,
209
- is_test : fct. is_test ,
210
- is_optimize_immediately : fct. is_optimize_immediately ,
211
- is_variadic : fct. params . is_variadic ( ) ,
212
- is_force_inline : fct. is_force_inline ,
213
- is_never_inline : fct. is_never_inline ,
214
- is_trait_object_ignore : fct. is_trait_object_ignore ,
215
- bytecode : fct. bytecode . get ( ) . cloned ( ) ,
216
- trait_method_impl : fct
217
- . trait_method_impl
218
- . get ( )
219
- . cloned ( )
220
- . map ( |id| convert_function_id ( id) ) ,
221
- } )
222
- }
223
-
224
- for ( _id, global) in sa. globals . iter ( ) {
225
- if !global. has_initial_value ( ) {
226
- continue ;
227
- }
228
-
229
- let fct_id = FunctionId ( result. len ( ) . try_into ( ) . expect ( "overflow" ) ) ;
230
- let name = sa. interner . str ( global. name ) . to_string ( ) ;
231
-
232
- result. push ( FunctionData {
233
- name,
234
- loc : sa. compute_loc ( global. file_id , global. span ) ,
235
- kind : FunctionKind :: Function ,
236
- file_id : convert_source_file_id ( global. file_id ) ,
237
- package_id : convert_package_id ( global. package_id ) ,
238
- module_id : convert_module_id ( global. module_id ) ,
239
- type_params : create_type_params ( sa, & TypeParamDefinition :: empty ( ) ) ,
240
- source_file_id : Some ( convert_source_file_id ( global. file_id ) ) ,
241
- params : Vec :: new ( ) ,
242
- return_type : bty_from_ty ( global. ty ( ) ) ,
243
- is_internal : false ,
244
- is_test : false ,
245
- is_optimize_immediately : false ,
246
- is_variadic : false ,
247
- is_force_inline : false ,
248
- is_never_inline : false ,
249
- is_trait_object_ignore : false ,
250
- bytecode : Some ( global. bytecode ( ) . clone ( ) ) ,
251
- trait_method_impl : None ,
252
- } ) ;
253
-
254
- e. global_initializer . insert ( global. id ( ) , fct_id) ;
255
- }
256
-
257
- result
258
- }
259
-
260
- fn create_globals ( sa : & Sema , e : & Emitter ) -> Vec < GlobalData > {
261
- let mut result = Vec :: new ( ) ;
262
-
263
- for ( _id, global) in sa. globals . iter ( ) {
264
- let name = sa. interner . str ( global. name ) . to_string ( ) ;
265
-
266
- result. push ( GlobalData {
267
- module_id : convert_module_id ( global. module_id ) ,
268
- ty : bty_from_ty ( global. ty ( ) ) ,
269
- mutable : global. mutable ,
270
- name,
271
- initial_value : global_initializer_function_id ( sa, & * global, e) ,
272
- } )
273
- }
274
-
275
- result
276
- }
277
-
278
283
fn global_initializer_function_id (
279
284
_sa : & Sema ,
280
285
global : & GlobalDefinition ,
0 commit comments