Skip to content

Commit 566640d

Browse files
committed
Started working on C integer promotions
1 parent e70c1b5 commit 566640d

File tree

9 files changed

+66
-18
lines changed

9 files changed

+66
-18
lines changed

src/asg/datatype/kind/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::Type;
66
use crate::{
77
asg::{human_name::HumanName, Asg, EnumRef, StructRef, TraitRef, TypeAliasRef},
88
ast::{fmt_c_integer, CInteger, FloatSize, IntegerBits, IntegerSign},
9+
c::implicit_conversions::IntegerRank,
910
source_files::Source,
1011
target::Target,
1112
};
@@ -77,6 +78,17 @@ impl TypeKind {
7778
}
7879
}
7980

81+
pub fn integer_rank(&self) -> Option<IntegerRank> {
82+
match self {
83+
TypeKind::Boolean => Some(IntegerRank::Bool),
84+
TypeKind::Integer(integer_bits, _) => Some(IntegerRank::Fixed(integer_bits.bits())),
85+
TypeKind::CInteger(c_integer, _) => Some(IntegerRank::Flexible(*c_integer)),
86+
TypeKind::SizeInteger(_) => Some(IntegerRank::Size),
87+
TypeKind::IntegerLiteral(_) => Some(IntegerRank::Flexible(CInteger::Int)),
88+
_ => None,
89+
}
90+
}
91+
8092
pub fn sign(&self, target: Option<&Target>) -> Option<IntegerSign> {
8193
match self {
8294
TypeKind::Boolean => Some(IntegerSign::Unsigned),

src/asg/datatype/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub mod kind;
22

3-
use crate::source_files::Source;
3+
use crate::{c::implicit_conversions::IntegerRank, source_files::Source};
44
use core::hash::Hash;
55
pub use kind::*;
66
use std::fmt::Display;
@@ -28,6 +28,10 @@ impl Type {
2828
pub fn is_ambiguous(&self) -> bool {
2929
self.kind.is_ambiguous()
3030
}
31+
32+
pub fn integer_rank(self: &Type) -> Option<IntegerRank> {
33+
self.kind.integer_rank()
34+
}
3135
}
3236

3337
impl PartialEq for Type {

src/ast/expr/kind.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub enum ExprKind {
3838
InterpreterSyscall(Box<InterpreterSyscall>),
3939
Break,
4040
Continue,
41+
IntegerPromote(Box<Expr>),
4142
}
4243

4344
impl ExprKind {

src/c/ast/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub enum ExprKind {
4646
Call(Box<Expr>, Vec<Expr>),
4747
SizeOf(ast::Type),
4848
SizeOfValue(Box<Expr>),
49+
IntegerPromote(Box<Expr>),
4950
}
5051

5152
impl ExprKind {

src/c/implicit_conversions/mod.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
use crate::{data_units::BitUnits, target::Target};
1+
use crate::{ast::CInteger, data_units::BitUnits, target::Target};
22
use derive_more::IsVariant;
33
use std::cmp::Ordering;
44

55
#[derive(Copy, Clone, Debug)]
66
pub enum IntegerRank {
77
Bool,
8-
Char,
9-
Short,
10-
Int,
11-
Long,
12-
LongLong,
8+
Flexible(CInteger),
139
Size,
14-
FixedInt(BitUnits),
10+
Fixed(BitUnits),
1511
}
1612

1713
impl IntegerRank {
@@ -22,19 +18,27 @@ impl IntegerRank {
2218
pub fn precision(&self, target: &Target) -> IntegerPrecision {
2319
match self {
2420
IntegerRank::Bool => IntegerPrecision::boolean(),
25-
IntegerRank::Char => IntegerPrecision::flexible(target.char_layout().width.to_bits()),
26-
IntegerRank::Short => IntegerPrecision::flexible(target.short_layout().width.to_bits()),
27-
IntegerRank::Int => IntegerPrecision::flexible(target.int_layout().width.to_bits()),
28-
IntegerRank::Long => IntegerPrecision::flexible(target.long_layout().width.to_bits()),
29-
IntegerRank::LongLong => {
21+
IntegerRank::Flexible(CInteger::Char) => {
22+
IntegerPrecision::flexible(target.char_layout().width.to_bits())
23+
}
24+
IntegerRank::Flexible(CInteger::Short) => {
25+
IntegerPrecision::flexible(target.short_layout().width.to_bits())
26+
}
27+
IntegerRank::Flexible(CInteger::Int) => {
28+
IntegerPrecision::flexible(target.int_layout().width.to_bits())
29+
}
30+
IntegerRank::Flexible(CInteger::Long) => {
31+
IntegerPrecision::flexible(target.long_layout().width.to_bits())
32+
}
33+
IntegerRank::Flexible(CInteger::LongLong) => {
3034
IntegerPrecision::flexible(target.longlong_layout().width.to_bits())
3135
}
3236
IntegerRank::Size => {
3337
// This means that size types have the same effective rank as the type they would
3438
// be in C for this target.
3539
IntegerPrecision::flexible(target.size_layout().width.to_bits())
3640
}
37-
IntegerRank::FixedInt(bits) => IntegerPrecision::fixed(*bits),
41+
IntegerRank::Fixed(bits) => IntegerPrecision::fixed(*bits),
3842
}
3943
}
4044
}

src/c/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
250250
CTokenKind::Punctuator(Punctuator::Add) => {
251251
self.input.advance();
252252
let inner = self.parse_expr_primary()?;
253-
return Ok(inner);
253+
return Ok(ExprKind::IntegerPromote(Box::new(inner)).at(source));
254254
}
255255
CTokenKind::Punctuator(Punctuator::Subtract) => {
256256
self.input.advance();

src/c/translate/eval.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ pub fn evaluate_to_const_integer(expr: &Expr) -> Result<BigInt, ParseError> {
5050
| ExprKind::Not(_)
5151
| ExprKind::Call(_, _)
5252
| ExprKind::SizeOf(_)
53-
| ExprKind::SizeOfValue(_) => (),
53+
| ExprKind::SizeOfValue(_)
54+
| ExprKind::IntegerPromote(_) => (),
5455
}
5556

5657
Err(ParseErrorKind::MustBeConstantInteger.at(expr.source))

src/c/translate/expr/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ pub fn translate_expr(ctx: &mut TranslateCtx, expr: &Expr) -> Result<ast::Expr,
163163
}
164164
ExprKind::SizeOf(ty) => ast::ExprKind::SizeOf(Box::new(ty.clone())).at(expr.source),
165165
ExprKind::SizeOfValue(value) => {
166-
let inner = translate_expr(ctx, value)?;
167-
ast::ExprKind::SizeOfValue(Box::new(inner)).at(expr.source)
166+
ast::ExprKind::SizeOfValue(Box::new(translate_expr(ctx, value)?)).at(expr.source)
167+
}
168+
ExprKind::IntegerPromote(value) => {
169+
ast::ExprKind::IntegerPromote(Box::new(translate_expr(ctx, value)?)).at(expr.source)
168170
}
169171
})
170172
}

src/resolve/expr/mod.rs

+23
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,29 @@ pub fn resolve_expr(
446446
asg::TypeKind::Never.at(source),
447447
asg::ExprKind::Continue.at(source),
448448
)),
449+
ast::ExprKind::IntegerPromote(value) => {
450+
let inner = resolve_expr(
451+
ctx,
452+
value,
453+
None,
454+
Initialized::AllowUninitialized,
455+
ResolveExprMode::RequireValue,
456+
)?;
457+
458+
let rank = inner.ty.integer_rank();
459+
460+
// After promotion, types will either be int, unsigned int, or the same
461+
// Maybe we express this type as promoted<T>
462+
// And then for combined
463+
// a + b
464+
// and other arithmetic expressions, the
465+
// result could be a separate type like usual_arithmetic<promoted<ushort>,
466+
// promoted<char>>
467+
// I think we just need to be careful of the sign from promoted unsigned shorts.
468+
469+
Ok(todo!("integer promote expression - {:?}", rank))
470+
// Ok(TypedExpr::new())
471+
}
449472
}?;
450473

451474
match initialized {

0 commit comments

Comments
 (0)