Skip to content

Commit dfacf3a

Browse files
committed
Added basic casting for usize/isize types
1 parent 6ee5b61 commit dfacf3a

File tree

6 files changed

+132
-4
lines changed

6 files changed

+132
-4
lines changed

src/asg/datatype/kind/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,10 @@ impl TypeKind {
442442
pub fn is_integer_like(&self) -> bool {
443443
matches!(
444444
self,
445-
Self::Integer(..) | Self::IntegerLiteral(..) | Self::CInteger(..)
445+
Self::Integer(..)
446+
| Self::IntegerLiteral(..)
447+
| Self::CInteger(..)
448+
| Self::SizeInteger(..)
446449
)
447450
}
448451

src/lower/cast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub fn integer_like_type_size(target: &Target, ty: &asg::Type) -> Option<ByteUni
1111
asg::TypeKind::Boolean => Some(target.bool_layout().width),
1212
asg::TypeKind::Integer(bits, _) => Some(bits.bytes()),
1313
asg::TypeKind::CInteger(c_integer, _) => Some(c_integer.bytes(target)),
14+
asg::TypeKind::SizeInteger(_) => Some(target.size_layout().width),
1415
_ => None,
1516
}
1617
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use super::{ConformMode, Objective, ObjectiveResult};
2+
use crate::{
3+
asg::{
4+
Cast, CastFrom, Expr, ExprKind, IntegerBits, Type, TypeKind, TypedExpr, UnaryMathOperation,
5+
UnaryMathOperator,
6+
},
7+
ast::{CInteger, ConformBehavior},
8+
ir::IntegerSign,
9+
source_files::Source,
10+
};
11+
12+
pub fn from_size_integer<O: Objective>(
13+
expr: &Expr,
14+
from_type: &Type,
15+
mode: ConformMode,
16+
behavior: ConformBehavior,
17+
from_sign: IntegerSign,
18+
to_type: &Type,
19+
source: Source,
20+
) -> ObjectiveResult<O> {
21+
match &to_type.kind {
22+
TypeKind::Boolean => {
23+
from_size_integer_to_bool::<O>(expr, from_type, mode, behavior, source)
24+
}
25+
TypeKind::Integer(to_bits, to_sign) => {
26+
from_size_integer_to_integer::<O>(expr, mode, from_sign, *to_bits, *to_sign, source)
27+
}
28+
TypeKind::CInteger(to_c_integer, to_sign) => from_size_integer_to_c_integer::<O>(
29+
expr,
30+
mode,
31+
from_sign,
32+
*to_c_integer,
33+
*to_sign,
34+
source,
35+
),
36+
_ => O::fail(),
37+
}
38+
}
39+
40+
fn from_size_integer_to_bool<O: Objective>(
41+
expr: &Expr,
42+
from_type: &Type,
43+
mode: ConformMode,
44+
behavior: ConformBehavior,
45+
source: Source,
46+
) -> ObjectiveResult<O> {
47+
if !behavior.auto_c_integer_to_bool_conversion() && !mode.allow_lossy_integer() {
48+
return O::fail();
49+
}
50+
51+
O::success(|| {
52+
TypedExpr::new(
53+
TypeKind::Boolean.at(source),
54+
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
55+
operator: UnaryMathOperator::IsNonZero,
56+
inner: TypedExpr::new(from_type.clone(), expr.clone()),
57+
}))
58+
.at(source),
59+
)
60+
})
61+
}
62+
63+
pub fn from_size_integer_to_c_integer<O: Objective>(
64+
expr: &Expr,
65+
mode: ConformMode,
66+
from_sign: IntegerSign,
67+
to_c_integer: CInteger,
68+
to_sign: Option<IntegerSign>,
69+
source: Source,
70+
) -> ObjectiveResult<O> {
71+
if !(mode.allow_lossless_integer() && mode.allow_lossy_integer()) {
72+
return O::fail();
73+
}
74+
75+
let target_type = TypeKind::CInteger(to_c_integer, to_sign).at(source);
76+
77+
return O::success(|| {
78+
TypedExpr::new(
79+
target_type.clone(),
80+
ExprKind::IntegerCast(Box::new(CastFrom {
81+
cast: Cast::new(target_type, expr.clone()),
82+
from_type: TypeKind::SizeInteger(from_sign).at(source),
83+
}))
84+
.at(source),
85+
)
86+
});
87+
}
88+
89+
fn from_size_integer_to_integer<O: Objective>(
90+
expr: &Expr,
91+
mode: ConformMode,
92+
from_sign: IntegerSign,
93+
to_bits: IntegerBits,
94+
to_sign: IntegerSign,
95+
source: Source,
96+
) -> ObjectiveResult<O> {
97+
if !mode.allow_lossy_integer() {
98+
return O::fail();
99+
}
100+
101+
let target_type = TypeKind::Integer(to_bits, to_sign).at(source);
102+
103+
O::success(|| {
104+
TypedExpr::new(
105+
target_type.clone(),
106+
ExprKind::IntegerCast(Box::new(CastFrom {
107+
cast: Cast::new(target_type, expr.clone()),
108+
from_type: TypeKind::SizeInteger(from_sign).at(source),
109+
}))
110+
.at(source),
111+
)
112+
})
113+
}

src/resolve/conform/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ mod from_float_literal;
55
mod from_integer;
66
mod from_integer_literal;
77
mod from_pointer;
8+
mod from_size_integer;
89
mod mode;
910
pub mod to_default;
1011

1112
use self::{
1213
from_anonymous_enum::from_anonymous_enum, from_c_integer::from_c_integer,
1314
from_float::from_float, from_float_literal::from_float_literal, from_integer::from_integer,
1415
from_integer_literal::from_integer_literal, from_pointer::from_pointer,
16+
from_size_integer::from_size_integer,
1517
};
1618
use super::{
1719
error::{ResolveError, ResolveErrorKind},
@@ -117,6 +119,15 @@ pub fn conform_expr<O: Objective>(
117119
&to_type,
118120
conform_source,
119121
),
122+
TypeKind::SizeInteger(from_sign) => from_size_integer::<O>(
123+
&expr.expr,
124+
&from_type,
125+
mode,
126+
behavior,
127+
*from_sign,
128+
&to_type,
129+
conform_source,
130+
),
120131
TypeKind::AnonymousEnum(enumeration) => from_anonymous_enum::<O>(
121132
&expr.expr,
122133
&from_type,

src/resolve/expr/call/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use itertools::Itertools;
1414
use num::BigInt;
1515
use ordered_float::NotNan;
1616

17-
pub fn cast(
17+
pub fn find_builtin_cast_func(
1818
ctx: &mut ResolveExprCtx,
1919
call: &ast::Call,
2020
args: Vec<TypedExpr>,

src/resolve/expr/call/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
},
1616
source_files::Source,
1717
};
18-
use cast::cast;
18+
use cast::find_builtin_cast_func;
1919
use infer_impl::infer_callee_missing_impl_args;
2020
use itertools::Itertools;
2121
use specified_impl::resolve_impl_arg;
@@ -39,7 +39,7 @@ pub fn resolve_call_expr(
3939

4040
let generics = resolve_type_args_to_poly_args(ctx, &call.generics)?;
4141

42-
let args = match cast(ctx, call, args, source)? {
42+
let args = match find_builtin_cast_func(ctx, call, args, source)? {
4343
Ok(cast) => return Ok(cast),
4444
Err(args) => args,
4545
};

0 commit comments

Comments
 (0)