@@ -4,18 +4,20 @@ use crate::{
4
4
ir:: IntegerSign ,
5
5
resolve:: {
6
6
conform:: { conform_expr, ConformMode , Perform } ,
7
+ destination:: resolve_expr_to_destination,
7
8
error:: { ResolveError , ResolveErrorKind } ,
8
9
expr:: ResolveExprCtx ,
9
10
} ,
10
11
source_files:: Source ,
11
12
} ;
13
+ use itertools:: Itertools ;
12
14
use num:: BigInt ;
13
15
use ordered_float:: NotNan ;
14
16
15
17
pub fn cast (
16
18
ctx : & mut ResolveExprCtx ,
17
19
call : & ast:: Call ,
18
- arguments : Vec < TypedExpr > ,
20
+ args : Vec < TypedExpr > ,
19
21
source : Source ,
20
22
) -> Result < Result < TypedExpr , Vec < TypedExpr > > , ResolveError > {
21
23
if !call. generics . is_empty ( ) {
@@ -25,13 +27,44 @@ pub fn cast(
25
27
) ) ;
26
28
}
27
29
28
- if !call. name . namespace . is_empty ( ) || arguments . len ( ) != 1 {
29
- return Ok ( Err ( arguments ) ) ;
30
+ if !call. name . namespace . is_empty ( ) || args . len ( ) != 1 {
31
+ return Ok ( Err ( args ) ) ;
30
32
}
31
33
32
34
let name = & call. name . basename ;
33
35
34
36
let target_type_kind = match name. as_ref ( ) {
37
+ "deref" => match args. into_iter ( ) . exactly_one ( ) {
38
+ Ok ( arg) => {
39
+ if let asg:: TypeKind :: Ptr ( inner) = & arg. ty . kind {
40
+ return Ok ( Ok ( TypedExpr {
41
+ ty : inner. as_ref ( ) . clone ( ) ,
42
+ is_initialized : arg. is_initialized ,
43
+ expr : asg:: ExprKind :: Dereference ( Box :: new ( arg) ) . at ( source) ,
44
+ } ) ) ;
45
+ }
46
+
47
+ return Ok ( Err ( vec ! [ arg] ) ) ;
48
+ }
49
+ Err ( args) => {
50
+ return Ok ( Err ( args. collect ( ) ) ) ;
51
+ }
52
+ } ,
53
+ "ptr" => match args. into_iter ( ) . exactly_one ( ) {
54
+ Ok ( arg) => {
55
+ let is_initialized = arg. is_initialized ;
56
+ let destination = resolve_expr_to_destination ( arg) ?;
57
+
58
+ return Ok ( Ok ( TypedExpr {
59
+ ty : destination. ty . clone ( ) . pointer ( source) ,
60
+ is_initialized,
61
+ expr : asg:: ExprKind :: AddressOf ( Box :: new ( destination) ) . at ( source) ,
62
+ } ) ) ;
63
+ }
64
+ Err ( args) => {
65
+ return Ok ( Err ( args. collect ( ) ) ) ;
66
+ }
67
+ } ,
35
68
"bool" => Some ( asg:: TypeKind :: Boolean ) ,
36
69
"u8" => Some ( asg:: TypeKind :: u8 ( ) ) ,
37
70
"u16" => Some ( asg:: TypeKind :: u16 ( ) ) ,
@@ -85,13 +118,13 @@ pub fn cast(
85
118
_ => None ,
86
119
} ;
87
120
88
- let argument_type_kind = & arguments [ 0 ] . ty . kind ;
121
+ let argument_type_kind = & args [ 0 ] . ty . kind ;
89
122
90
123
if let Some ( target_type_kind) = target_type_kind {
91
124
if argument_type_kind. is_integer_literal ( ) || argument_type_kind. is_float_literal ( ) {
92
125
return conform_expr :: < Perform > (
93
126
ctx,
94
- & arguments [ 0 ] ,
127
+ & args [ 0 ] ,
95
128
& target_type_kind. at ( source) ,
96
129
ConformMode :: Explicit ,
97
130
ctx. adept_conform_behavior ( ) ,
@@ -102,7 +135,7 @@ pub fn cast(
102
135
}
103
136
104
137
if target_type_kind. is_boolean ( ) && argument_type_kind. is_integer_literal ( ) {
105
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
138
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
106
139
let is_initialized = argument. is_initialized ;
107
140
108
141
let asg:: ExprKind :: IntegerLiteral ( value) = & argument. expr . kind else {
@@ -120,7 +153,7 @@ pub fn cast(
120
153
&& ( argument_type_kind. is_integer_like ( ) || argument_type_kind. is_float_like ( ) )
121
154
{
122
155
let target_type = target_type_kind. at ( source) ;
123
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
156
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
124
157
let is_initialized = argument. is_initialized ;
125
158
126
159
let expr = asg:: ExprKind :: UnaryMathOperation ( Box :: new ( asg:: UnaryMathOperation {
@@ -138,7 +171,7 @@ pub fn cast(
138
171
139
172
if argument_type_kind. is_floating ( ) {
140
173
let target_type = target_type_kind. at ( source) ;
141
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
174
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
142
175
143
176
let expr = asg:: ExprKind :: FloatToInteger ( Box :: new ( Cast {
144
177
target_type : target_type. clone ( ) ,
@@ -155,7 +188,7 @@ pub fn cast(
155
188
156
189
if argument_type_kind. is_integer_like ( ) || argument_type_kind. is_boolean ( ) {
157
190
let target_type = target_type_kind. at ( source) ;
158
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
191
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
159
192
160
193
let expr = asg:: ExprKind :: IntegerCast ( Box :: new ( CastFrom {
161
194
cast : Cast {
@@ -182,7 +215,7 @@ pub fn cast(
182
215
183
216
if let Some ( ( target_type_kind, float_size) ) = to_float {
184
217
if argument_type_kind. is_integer_literal ( ) {
185
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
218
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
186
219
let is_initialized = argument. is_initialized ;
187
220
188
221
let asg:: ExprKind :: IntegerLiteral ( value) = & argument. expr . kind else {
@@ -207,7 +240,7 @@ pub fn cast(
207
240
}
208
241
209
242
if argument_type_kind. is_float_literal ( ) {
210
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
243
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
211
244
let is_initialized = argument. is_initialized ;
212
245
213
246
let asg:: ExprKind :: FloatingLiteral ( _size, value) = & argument. expr . kind else {
@@ -223,7 +256,7 @@ pub fn cast(
223
256
224
257
if argument_type_kind. is_integer_like ( ) || argument_type_kind. is_boolean ( ) {
225
258
let target_type = target_type_kind. at ( source) ;
226
- let argument = arguments . into_iter ( ) . next ( ) . unwrap ( ) ;
259
+ let argument = args . into_iter ( ) . next ( ) . unwrap ( ) ;
227
260
228
261
let expr = asg:: ExprKind :: IntegerToFloat ( Box :: new ( CastFrom {
229
262
cast : Cast {
@@ -242,5 +275,5 @@ pub fn cast(
242
275
}
243
276
}
244
277
245
- Ok ( Err ( arguments ) )
278
+ Ok ( Err ( args ) )
246
279
}
0 commit comments