Skip to content

Commit d3cc768

Browse files
committed
Continued working on support for size_t/ssize_t/usize/isize types
1 parent 090919c commit d3cc768

File tree

9 files changed

+70
-10
lines changed

9 files changed

+70
-10
lines changed

src/ast/expr/integer.rs

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ impl IntegerKnown {
2323
match self.rigidity {
2424
IntegerRigidity::Fixed(bits, sign) => TypeKind::Integer(bits, sign),
2525
IntegerRigidity::Loose(c_integer, sign) => TypeKind::CInteger(c_integer, sign),
26+
IntegerRigidity::Size(sign) => TypeKind::SizeInteger(sign),
2627
}
2728
.at(source)
2829
}
@@ -32,6 +33,7 @@ impl IntegerKnown {
3233
pub enum IntegerRigidity {
3334
Fixed(IntegerBits, IntegerSign),
3435
Loose(CInteger, Option<IntegerSign>),
36+
Size(IntegerSign),
3537
}
3638

3739
impl Integer {

src/lower/datatype.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use super::error::LowerError;
22
use crate::{
33
asg::{self, Asg},
44
ast::{CInteger, FloatSize},
5+
data_units::ByteUnits,
56
ir::{self, IntegerSign},
67
lower::{error::LowerErrorKind, structure::monomorphize_structure},
7-
target::{Target, TargetOsExt},
8+
target::{type_layout::TypeLayout, Target, TargetOsExt},
89
};
910
use std::borrow::{Borrow, Cow};
1011

@@ -43,10 +44,15 @@ pub fn lower_type(
4344
(Bits::Bits64, Sign::Unsigned) => ir::Type::U64,
4445
}),
4546
asg::TypeKind::CInteger(integer, sign) => Ok(lower_c_integer(target, *integer, *sign)),
46-
asg::TypeKind::SizeInteger(sign) => Ok(match sign {
47-
Sign::Signed => ir::Type::S64,
48-
Sign::Unsigned => ir::Type::U64,
49-
}),
47+
asg::TypeKind::SizeInteger(sign) => {
48+
let layout = ir_module.target.size_layout();
49+
assert_eq!(layout, TypeLayout::basic(ByteUnits::of(8)));
50+
51+
Ok(match sign {
52+
Sign::Signed => ir::Type::S64,
53+
Sign::Unsigned => ir::Type::U64,
54+
})
55+
}
5056
asg::TypeKind::IntegerLiteral(value) => {
5157
Err(LowerErrorKind::CannotLowerUnspecializedIntegerLiteral {
5258
value: value.to_string(),

src/lower/expr/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ pub fn lower_expr(
4949

5050
(bits, sign)
5151
}
52+
IntegerRigidity::Size(sign) => {
53+
let bits = IntegerBits::try_from(ir_module.target.size_layout().width)
54+
.expect("supported integer size");
55+
(bits, *sign)
56+
}
5257
};
5358

5459
match (bits, sign) {

src/resolve/conform/from_integer_literal.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::{Objective, ObjectiveResult};
22
use crate::{
3+
asg::{Expr, ExprKind, Type, TypeKind, TypedExpr},
34
ast::{CInteger, CIntegerAssumptions, FloatSize, IntegerBits, IntegerKnown, IntegerRigidity},
45
data_units::BitUnits,
56
ir::IntegerSign,
6-
asg::{Expr, ExprKind, Type, TypeKind, TypedExpr},
77
source_files::Source,
88
};
99
use num::{BigInt, Zero};
@@ -28,6 +28,9 @@ pub fn from_integer_literal<O: Objective>(
2828
TypeKind::Integer(to_bits, to_sign) => {
2929
from_integer_literal_to_integer::<O>(value, *to_bits, *to_sign, source)
3030
}
31+
TypeKind::SizeInteger(to_sign) => {
32+
from_integer_literal_to_size_integer::<O>(value, *to_sign, source)
33+
}
3134
_ => O::fail(),
3235
}
3336
}
@@ -91,6 +94,34 @@ fn from_integer_literal_to_c_integer<O: Objective>(
9194
O::fail()
9295
}
9396

97+
fn from_integer_literal_to_size_integer<O: Objective>(
98+
value: &BigInt,
99+
to_sign: IntegerSign,
100+
source: Source,
101+
) -> ObjectiveResult<O> {
102+
// Size types (i.e. size_t, ssize_t, usize, isize) are guananteed to be at least 16 bits
103+
// Anything more than that will require explicit casts
104+
let does_fit = match to_sign {
105+
IntegerSign::Signed => i16::try_from(value).is_ok(),
106+
IntegerSign::Unsigned => u16::try_from(value).is_ok(),
107+
};
108+
109+
if does_fit {
110+
return O::success(|| {
111+
TypedExpr::new(
112+
TypeKind::SizeInteger(to_sign).at(source),
113+
ExprKind::IntegerKnown(Box::new(IntegerKnown {
114+
rigidity: IntegerRigidity::Size(to_sign),
115+
value: value.clone(),
116+
}))
117+
.at(source),
118+
)
119+
});
120+
}
121+
122+
O::fail()
123+
}
124+
94125
fn from_integer_literal_to_float<O: Objective>(
95126
value: &BigInt,
96127
to_size: FloatSize,

src/resolve/expr/call/cast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ pub fn cast(
109109
CInteger::LongLong,
110110
Some(IntegerSign::Unsigned),
111111
)),
112+
"isize" => Some(asg::TypeKind::SizeInteger(IntegerSign::Signed)),
113+
"usize" => Some(asg::TypeKind::SizeInteger(IntegerSign::Unsigned)),
112114
_ => None,
113115
};
114116

src/resolve/expr/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub fn resolve_expr(
378378
.resolve(ast_type, ResolveTypeOptions::Unalias)?;
379379

380380
Ok(TypedExpr::new(
381-
// NOTE: This will used the unsigned size integer type in the future
381+
// NOTE: This will be the unsigned size integer type in the future
382382
// asg::TypeKind::SizeInteger(IntegerSign::Unsigned).at(source),
383383
asg::TypeKind::Integer(asg::IntegerBits::Bits64, IntegerSign::Unsigned).at(source),
384384
asg::ExprKind::SizeOf(Box::new(ty)).at(source),
@@ -395,7 +395,7 @@ pub fn resolve_expr(
395395
.ty;
396396

397397
Ok(TypedExpr::new(
398-
// NOTE: This will used the unsigned size integer type in the future
398+
// NOTE: This will used be unsigned size integer type in the future
399399
// asg::TypeKind::SizeInteger(IntegerSign::Unsigned).at(source),
400400
asg::TypeKind::Integer(asg::IntegerBits::Bits64, IntegerSign::Unsigned).at(source),
401401
asg::ExprKind::SizeOf(Box::new(ty)).at(source),

src/target/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ impl Target {
140140
pub fn double_layout(&self) -> TypeLayout {
141141
TypeLayout::basic(ByteUnits::of(8))
142142
}
143+
144+
pub fn size_layout(&self) -> TypeLayout {
145+
TypeLayout::basic(ByteUnits::of(8))
146+
}
143147
}
144148

145149
impl Display for Target {

src/target/type_layout.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
};
99
use once_map::unsync::OnceMap;
1010

11-
#[derive(Copy, Clone, Debug, Default)]
11+
#[derive(Copy, Clone, Debug, Default, PartialEq)]
1212
pub enum AlignmentRequirement {
1313
#[default]
1414
None,
@@ -27,7 +27,7 @@ pub struct ASTRecordLayout {
2727
pub field_offsets: Vec<BitUnits>,
2828
}
2929

30-
#[derive(Copy, Clone, Debug)]
30+
#[derive(Copy, Clone, Debug, PartialEq)]
3131
pub struct TypeLayout {
3232
pub width: ByteUnits,
3333
pub alignment: ByteUnits,
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
pragma => adept("3.0")
3+
4+
#[foreign]
5+
func printf(format ptr#char, ...) int
6+
7+
func main {
8+
x usize = 1234
9+
printf(c"%zu\n", x)
10+
}

0 commit comments

Comments
 (0)