Skip to content

Commit f369606

Browse files
committed
Added experimental function syntax for address-of and dereference operators
1 parent 8b20cb2 commit f369606

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

Diff for: src/resolve/expr/call/cast.rs

+46-13
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@ use crate::{
44
ir::IntegerSign,
55
resolve::{
66
conform::{conform_expr, ConformMode, Perform},
7+
destination::resolve_expr_to_destination,
78
error::{ResolveError, ResolveErrorKind},
89
expr::ResolveExprCtx,
910
},
1011
source_files::Source,
1112
};
13+
use itertools::Itertools;
1214
use num::BigInt;
1315
use ordered_float::NotNan;
1416

1517
pub fn cast(
1618
ctx: &mut ResolveExprCtx,
1719
call: &ast::Call,
18-
arguments: Vec<TypedExpr>,
20+
args: Vec<TypedExpr>,
1921
source: Source,
2022
) -> Result<Result<TypedExpr, Vec<TypedExpr>>, ResolveError> {
2123
if !call.generics.is_empty() {
@@ -25,13 +27,44 @@ pub fn cast(
2527
));
2628
}
2729

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));
3032
}
3133

3234
let name = &call.name.basename;
3335

3436
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+
},
3568
"bool" => Some(asg::TypeKind::Boolean),
3669
"u8" => Some(asg::TypeKind::u8()),
3770
"u16" => Some(asg::TypeKind::u16()),
@@ -85,13 +118,13 @@ pub fn cast(
85118
_ => None,
86119
};
87120

88-
let argument_type_kind = &arguments[0].ty.kind;
121+
let argument_type_kind = &args[0].ty.kind;
89122

90123
if let Some(target_type_kind) = target_type_kind {
91124
if argument_type_kind.is_integer_literal() || argument_type_kind.is_float_literal() {
92125
return conform_expr::<Perform>(
93126
ctx,
94-
&arguments[0],
127+
&args[0],
95128
&target_type_kind.at(source),
96129
ConformMode::Explicit,
97130
ctx.adept_conform_behavior(),
@@ -102,7 +135,7 @@ pub fn cast(
102135
}
103136

104137
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();
106139
let is_initialized = argument.is_initialized;
107140

108141
let asg::ExprKind::IntegerLiteral(value) = &argument.expr.kind else {
@@ -120,7 +153,7 @@ pub fn cast(
120153
&& (argument_type_kind.is_integer_like() || argument_type_kind.is_float_like())
121154
{
122155
let target_type = target_type_kind.at(source);
123-
let argument = arguments.into_iter().next().unwrap();
156+
let argument = args.into_iter().next().unwrap();
124157
let is_initialized = argument.is_initialized;
125158

126159
let expr = asg::ExprKind::UnaryMathOperation(Box::new(asg::UnaryMathOperation {
@@ -138,7 +171,7 @@ pub fn cast(
138171

139172
if argument_type_kind.is_floating() {
140173
let target_type = target_type_kind.at(source);
141-
let argument = arguments.into_iter().next().unwrap();
174+
let argument = args.into_iter().next().unwrap();
142175

143176
let expr = asg::ExprKind::FloatToInteger(Box::new(Cast {
144177
target_type: target_type.clone(),
@@ -155,7 +188,7 @@ pub fn cast(
155188

156189
if argument_type_kind.is_integer_like() || argument_type_kind.is_boolean() {
157190
let target_type = target_type_kind.at(source);
158-
let argument = arguments.into_iter().next().unwrap();
191+
let argument = args.into_iter().next().unwrap();
159192

160193
let expr = asg::ExprKind::IntegerCast(Box::new(CastFrom {
161194
cast: Cast {
@@ -182,7 +215,7 @@ pub fn cast(
182215

183216
if let Some((target_type_kind, float_size)) = to_float {
184217
if argument_type_kind.is_integer_literal() {
185-
let argument = arguments.into_iter().next().unwrap();
218+
let argument = args.into_iter().next().unwrap();
186219
let is_initialized = argument.is_initialized;
187220

188221
let asg::ExprKind::IntegerLiteral(value) = &argument.expr.kind else {
@@ -207,7 +240,7 @@ pub fn cast(
207240
}
208241

209242
if argument_type_kind.is_float_literal() {
210-
let argument = arguments.into_iter().next().unwrap();
243+
let argument = args.into_iter().next().unwrap();
211244
let is_initialized = argument.is_initialized;
212245

213246
let asg::ExprKind::FloatingLiteral(_size, value) = &argument.expr.kind else {
@@ -223,7 +256,7 @@ pub fn cast(
223256

224257
if argument_type_kind.is_integer_like() || argument_type_kind.is_boolean() {
225258
let target_type = target_type_kind.at(source);
226-
let argument = arguments.into_iter().next().unwrap();
259+
let argument = args.into_iter().next().unwrap();
227260

228261
let expr = asg::ExprKind::IntegerToFloat(Box::new(CastFrom {
229262
cast: Cast {
@@ -242,5 +275,5 @@ pub fn cast(
242275
}
243276
}
244277

245-
Ok(Err(arguments))
278+
Ok(Err(args))
246279
}

0 commit comments

Comments
 (0)