@@ -5,19 +5,20 @@ use crate::builder::{
5
5
values:: { InternalValue , InternalValueKind } ,
6
6
} ;
7
7
use ast:: {
8
- LiteralKind ,
8
+ FieldAccess , LiteralKind ,
9
9
operators:: { InfixOperator , PrefixOperator , UnaryOperator } ,
10
10
token:: Location ,
11
11
} ;
12
12
use inkwell:: {
13
13
AddressSpace , FloatPredicate , IntPredicate ,
14
- types:: BasicTypeEnum ,
15
- values:: { BasicMetadataValueEnum , BasicValue , BasicValueEnum } ,
14
+ types:: { BasicType , BasicTypeEnum } ,
15
+ values:: { ArrayValue , BasicMetadataValueEnum , BasicValue , BasicValueEnum } ,
16
16
} ;
17
17
use resolver:: scope:: LocalScopeRef ;
18
18
use typed_ast:: {
19
- SymbolID , TypedExpression , TypedExpressionKind , TypedFuncCall , TypedInfixExpression , TypedLiteral ,
20
- TypedPrefixExpression , TypedUnaryExpression ,
19
+ SymbolID , TypedAddressOf , TypedArray , TypedAssignment , TypedCast , TypedDereference , TypedExpression ,
20
+ TypedExpressionKind , TypedFuncCall , TypedInfixExpression , TypedLiteral , TypedPrefixExpression , TypedStructInit ,
21
+ TypedUnaryExpression , TypedUnnamedStructValue ,
21
22
types:: { BasicConcreteType , ConcreteType } ,
22
23
} ;
23
24
@@ -35,20 +36,230 @@ impl<'a> CodeGenBuilder<'a> {
35
36
}
36
37
TypedExpressionKind :: Infix ( typed_infix_expr) => self . build_infix_expr ( local_scope_opt, typed_infix_expr) ,
37
38
TypedExpressionKind :: Unary ( typed_unary_expr) => self . build_unary_expr ( local_scope_opt, typed_unary_expr) ,
38
- TypedExpressionKind :: Assignment ( typed_assignment ) => todo ! ( ) ,
39
- TypedExpressionKind :: Cast ( typed_cast) => todo ! ( ) ,
40
- TypedExpressionKind :: Array ( typed_array) => todo ! ( ) ,
39
+ TypedExpressionKind :: Assignment ( typed_assign ) => self . build_assign ( local_scope_opt , typed_assign ) ,
40
+ TypedExpressionKind :: Cast ( typed_cast) => self . build_cast_expr ( local_scope_opt , typed_cast ) ,
41
+ TypedExpressionKind :: Array ( typed_array) => self . build_array_expr ( local_scope_opt , typed_array ) ,
41
42
TypedExpressionKind :: ArrayIndex ( typed_array_index) => todo ! ( ) ,
42
- TypedExpressionKind :: AddressOf ( typed_address_of) => todo ! ( ) ,
43
- TypedExpressionKind :: Dereference ( typed_dereference) => todo ! ( ) ,
44
- TypedExpressionKind :: StructInit ( typed_struct_init) => todo ! ( ) ,
43
+ TypedExpressionKind :: AddressOf ( typed_address_of) => {
44
+ self . build_address_of ( local_scope_opt, typed_address_of)
45
+ }
46
+ TypedExpressionKind :: Dereference ( typed_dereference) => {
47
+ self . build_dereference ( local_scope_opt, typed_dereference)
48
+ }
49
+ TypedExpressionKind :: StructInit ( typed_struct_init) => {
50
+ self . build_struct_init ( local_scope_opt, typed_struct_init)
51
+ }
45
52
TypedExpressionKind :: FuncCall ( typed_func_call) => self . build_func_call ( local_scope_opt, typed_func_call) ,
46
53
TypedExpressionKind :: FieldAccess ( typed_field_access) => todo ! ( ) ,
47
54
TypedExpressionKind :: MethodCall ( typed_method_call) => todo ! ( ) ,
48
- TypedExpressionKind :: UnnamedStructValue ( typed_unnamed_struct_value) => todo ! ( ) ,
55
+ TypedExpressionKind :: UnnamedStructValue ( typed_unnamed_struct_value) => {
56
+ self . build_unnamed_struct_value ( local_scope_opt, typed_unnamed_struct_value)
57
+ }
58
+ }
59
+ }
60
+
61
+ fn build_unnamed_struct_value (
62
+ & self ,
63
+ local_scope_opt : Option < LocalScopeRef > ,
64
+ unnamed_struct_value : & TypedUnnamedStructValue ,
65
+ ) -> InternalValue < ' a > {
66
+ let struct_type = self
67
+ . build_unnamed_struct_type (
68
+ local_scope_opt. clone ( ) ,
69
+ & unnamed_struct_value. unnamed_struct_type . clone ( ) . unwrap ( ) ,
70
+ )
71
+ . into_struct_type ( ) ;
72
+
73
+ let mut struct_value = struct_type. get_undef ( ) ;
74
+
75
+ let mut all_const = true ;
76
+ let field_values: Vec < BasicValueEnum < ' a > > = unnamed_struct_value
77
+ . fields
78
+ . iter ( )
79
+ . map ( |unnamed_struct_value_field| {
80
+ let field_lvalue = self . build_expr ( local_scope_opt. clone ( ) , & unnamed_struct_value_field. field_value ) ;
81
+ let field_rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , field_lvalue) ;
82
+ let field_basic_value = field_rvalue. as_basic_value ( ) ;
83
+ if !self . is_basic_value_constant ( field_basic_value) {
84
+ all_const = false ;
85
+ }
86
+ field_basic_value
87
+ } )
88
+ . collect ( ) ;
89
+
90
+ if all_const {
91
+ struct_value = struct_type. const_named_struct ( & field_values) ;
92
+ } else {
93
+ field_values. iter ( ) . enumerate ( ) . for_each ( |( index, field_value) | {
94
+ struct_value = self
95
+ . llvmbuilder
96
+ . build_insert_value ( struct_value, * field_value, index. try_into ( ) . unwrap ( ) , "insert" )
97
+ . unwrap ( )
98
+ . into_struct_value ( ) ;
99
+ } ) ;
100
+ }
101
+
102
+ InternalValue :: new (
103
+ ConcreteType :: UnnamedStruct ( unnamed_struct_value. unnamed_struct_type . clone ( ) . unwrap ( ) ) ,
104
+ InternalValueKind :: RValue ( struct_value. as_basic_value_enum ( ) ) ,
105
+ )
106
+ }
107
+
108
+ fn build_struct_init (
109
+ & self ,
110
+ local_scope_opt : Option < LocalScopeRef > ,
111
+ typed_struct_init : & TypedStructInit ,
112
+ ) -> InternalValue < ' a > {
113
+ let struct_type = self
114
+ . build_concrete_type (
115
+ local_scope_opt. clone ( ) ,
116
+ ConcreteType :: Symbol ( typed_struct_init. symbol_id ) ,
117
+ )
118
+ . into_struct_type ( ) ;
119
+
120
+ let mut struct_value = struct_type. get_undef ( ) ;
121
+
122
+ let mut all_const = true ;
123
+ let field_values: Vec < BasicValueEnum < ' a > > = typed_struct_init
124
+ . fields
125
+ . iter ( )
126
+ . map ( |field_init| {
127
+ let field_lvalue = self . build_expr ( local_scope_opt. clone ( ) , & field_init. value ) ;
128
+ let field_rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , field_lvalue) ;
129
+ let field_basic_value = field_rvalue. as_basic_value ( ) ;
130
+ if !self . is_basic_value_constant ( field_basic_value) {
131
+ all_const = false ;
132
+ }
133
+ field_basic_value
134
+ } )
135
+ . collect ( ) ;
136
+
137
+ if all_const {
138
+ struct_value = struct_type. const_named_struct ( & field_values) ;
139
+ } else {
140
+ field_values. iter ( ) . enumerate ( ) . for_each ( |( index, field_value) | {
141
+ struct_value = self
142
+ . llvmbuilder
143
+ . build_insert_value ( struct_value, * field_value, index. try_into ( ) . unwrap ( ) , "insert" )
144
+ . unwrap ( )
145
+ . into_struct_value ( ) ;
146
+ } ) ;
147
+ }
148
+
149
+ InternalValue :: new (
150
+ ConcreteType :: Symbol ( typed_struct_init. symbol_id ) ,
151
+ InternalValueKind :: RValue ( struct_value. as_basic_value_enum ( ) ) ,
152
+ )
153
+ }
154
+
155
+ fn build_assign ( & self , local_scope_opt : Option < LocalScopeRef > , assign : & TypedAssignment ) -> InternalValue < ' a > {
156
+ let lhs_lvalue = self . build_expr ( local_scope_opt. clone ( ) , & assign. lhs ) ;
157
+ let rhs_lvalue = self . build_expr ( local_scope_opt. clone ( ) , & assign. rhs ) ;
158
+ let rhs_rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , rhs_lvalue) ;
159
+
160
+ assert ! ( lhs_lvalue. as_basic_value( ) . is_pointer_value( ) == true ) ;
161
+ let pointer_value = lhs_lvalue. as_basic_value ( ) . into_pointer_value ( ) ;
162
+
163
+ self . llvmbuilder
164
+ . build_store ( pointer_value, rhs_rvalue. as_basic_value ( ) )
165
+ . unwrap ( ) ;
166
+ rhs_rvalue
167
+ }
168
+
169
+ fn build_dereference ( & self , local_scope_opt : Option < LocalScopeRef > , deref : & TypedDereference ) -> InternalValue < ' a > {
170
+ let operand_type = deref. operand . concrete_type . clone ( ) . unwrap ( ) ;
171
+ let lvalue = self . build_expr ( local_scope_opt. clone ( ) , & deref. operand ) ;
172
+ let rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , lvalue) ;
173
+
174
+ InternalValue :: new ( operand_type, InternalValueKind :: RValue ( rvalue. as_basic_value ( ) ) )
175
+ }
176
+
177
+ fn build_address_of (
178
+ & self ,
179
+ local_scope_opt : Option < LocalScopeRef > ,
180
+ address_of : & TypedAddressOf ,
181
+ ) -> InternalValue < ' a > {
182
+ let operand_type = address_of. operand . concrete_type . clone ( ) . unwrap ( ) ;
183
+ let lvalue = self . build_expr ( local_scope_opt. clone ( ) , & address_of. operand ) ;
184
+
185
+ InternalValue :: new (
186
+ ConcreteType :: Pointer ( Box :: new ( operand_type) ) ,
187
+ InternalValueKind :: RValue ( lvalue. as_basic_value ( ) ) ,
188
+ )
189
+ }
190
+
191
+ fn build_array_expr ( & self , local_scope_opt : Option < LocalScopeRef > , array : & TypedArray ) -> InternalValue < ' a > {
192
+ let array_concrete_type = array. array_type . as_array_type ( ) . unwrap ( ) ;
193
+ let element_type = array_concrete_type. element_type . clone ( ) ;
194
+ let array_type = self
195
+ . build_concrete_type ( local_scope_opt. clone ( ) , array. array_type . clone ( ) )
196
+ . into_array_type ( ) ;
197
+
198
+ let mut all_const = true ;
199
+ let elements: Vec < BasicValueEnum < ' a > > = array
200
+ . elements
201
+ . iter ( )
202
+ . map ( |typed_expr| {
203
+ let lvalue = self . build_expr ( local_scope_opt. clone ( ) , typed_expr) ;
204
+ let rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , lvalue) ;
205
+ let casted_rvalue = self
206
+ . build_implicit_cast ( local_scope_opt. clone ( ) , * element_type. clone ( ) , rvalue)
207
+ . as_basic_value ( ) ;
208
+ if !self . is_basic_value_constant ( casted_rvalue) {
209
+ all_const = false ;
210
+ }
211
+ casted_rvalue
212
+ } )
213
+ . collect ( ) ;
214
+
215
+ if all_const {
216
+ let array_value = unsafe { ArrayValue :: new_const_array ( & array_type, & elements) } ;
217
+
218
+ InternalValue :: new (
219
+ array. array_type . clone ( ) ,
220
+ InternalValueKind :: RValue ( array_value. as_basic_value_enum ( ) ) ,
221
+ )
222
+ } else {
223
+ let mut array_value = array_type. get_undef ( ) ;
224
+
225
+ elements. iter ( ) . enumerate ( ) . for_each ( |( index, element) | {
226
+ array_value = self
227
+ . llvmbuilder
228
+ . build_insert_value ( array_value, * element, index. try_into ( ) . unwrap ( ) , "insert" )
229
+ . unwrap ( )
230
+ . into_array_value ( ) ;
231
+ } ) ;
232
+
233
+ InternalValue :: new (
234
+ array. array_type . clone ( ) ,
235
+ InternalValueKind :: RValue ( array_value. as_basic_value_enum ( ) ) ,
236
+ )
49
237
}
50
238
}
51
239
240
+ fn is_basic_value_constant ( & self , basic_value : BasicValueEnum < ' a > ) -> bool {
241
+ match basic_value {
242
+ BasicValueEnum :: IntValue ( int_value) => int_value. is_const ( ) ,
243
+ BasicValueEnum :: FloatValue ( float_value) => float_value. is_const ( ) ,
244
+ BasicValueEnum :: PointerValue ( ptr_value) => ptr_value. is_const ( ) ,
245
+ BasicValueEnum :: StructValue ( struct_value) => struct_value. is_const ( ) ,
246
+ BasicValueEnum :: ArrayValue ( array_value) => array_value. is_const ( ) ,
247
+ BasicValueEnum :: VectorValue ( vector_value) => vector_value. is_const ( ) ,
248
+ }
249
+ }
250
+
251
+ fn build_cast_expr ( & self , local_scope_opt : Option < LocalScopeRef > , cast : & TypedCast ) -> InternalValue < ' a > {
252
+ let lvalue = self . build_expr ( local_scope_opt. clone ( ) , & cast. operand ) ;
253
+ let rvalue = self . build_load_lvalue_to_rvalue ( local_scope_opt. clone ( ) , lvalue) ;
254
+
255
+ let target_any_type = self . build_concrete_type ( local_scope_opt, cast. target_type . clone ( ) ) ;
256
+ let any_value = self . build_cast ( target_any_type, rvalue) ;
257
+ InternalValue :: new (
258
+ cast. target_type . clone ( ) ,
259
+ InternalValueKind :: RValue ( any_value. try_into ( ) . unwrap ( ) ) ,
260
+ )
261
+ }
262
+
52
263
fn build_func_call ( & self , local_scope_opt : Option < LocalScopeRef > , func_call : & TypedFuncCall ) -> InternalValue < ' a > {
53
264
let module_id = self . resolver . lookup_symbol_id_in_modules ( func_call. symbol_id ) . unwrap ( ) ;
54
265
let symbol_entry = self
0 commit comments