Skip to content

Commit 2ac7ee9

Browse files
committed
Started working on implicit integer conversions for C code
1 parent 17bfeb3 commit 2ac7ee9

File tree

4 files changed

+97
-6
lines changed

4 files changed

+97
-6
lines changed

src/c/implicit_conversions/mod.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use crate::{data_units::BitUnits, target::Target};
2+
use derive_more::IsVariant;
3+
use std::cmp::Ordering;
4+
5+
#[derive(Copy, Clone, Debug)]
6+
pub enum IntegerRank {
7+
Bool,
8+
Char,
9+
Short,
10+
Int,
11+
Long,
12+
LongLong,
13+
FixedInt(BitUnits),
14+
}
15+
16+
impl IntegerRank {
17+
pub fn compare_for_target(left: Self, right: Self, target: &Target) -> Ordering {
18+
let left_precision = left.precision(target);
19+
let right_precision = right.precision(target);
20+
left_precision.cmp(&right_precision)
21+
}
22+
23+
pub fn precision(&self, target: &Target) -> IntegerPrecision {
24+
match self {
25+
IntegerRank::Bool => IntegerPrecision::boolean(),
26+
IntegerRank::Char => IntegerPrecision::flexible(target.char_layout().width.to_bits()),
27+
IntegerRank::Short => IntegerPrecision::flexible(target.short_layout().width.to_bits()),
28+
IntegerRank::Int => IntegerPrecision::flexible(target.int_layout().width.to_bits()),
29+
IntegerRank::Long => IntegerPrecision::flexible(target.long_layout().width.to_bits()),
30+
IntegerRank::LongLong => {
31+
IntegerPrecision::flexible(target.longlong_layout().width.to_bits())
32+
}
33+
IntegerRank::FixedInt(bits) => IntegerPrecision::fixed(*bits),
34+
}
35+
}
36+
}
37+
38+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, IsVariant)]
39+
pub enum IntegerPrecision {
40+
Boolean,
41+
Normal { bits: BitUnits, flexible: bool },
42+
}
43+
44+
impl IntegerPrecision {
45+
pub fn boolean() -> Self {
46+
Self::Boolean
47+
}
48+
pub fn flexible(bits: BitUnits) -> Self {
49+
Self::Normal {
50+
bits,
51+
flexible: true,
52+
}
53+
}
54+
55+
pub fn fixed(bits: BitUnits) -> Self {
56+
Self::Normal {
57+
bits,
58+
flexible: false,
59+
}
60+
}
61+
}
62+
63+
impl Ord for IntegerPrecision {
64+
fn cmp(&self, other: &Self) -> Ordering {
65+
match self {
66+
IntegerPrecision::Boolean => other
67+
.is_normal()
68+
.then_some(Ordering::Less)
69+
.unwrap_or(Ordering::Equal),
70+
IntegerPrecision::Normal { bits, flexible } => {
71+
let IntegerPrecision::Normal {
72+
bits: other_bits,
73+
flexible: other_flexible,
74+
} = other
75+
else {
76+
return Ordering::Greater;
77+
};
78+
79+
bits.cmp(other_bits)
80+
.then_with(|| flexible.cmp(other_flexible))
81+
}
82+
}
83+
}
84+
}

src/c/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod ast;
22
pub mod encoding;
3+
pub mod implicit_conversions;
34
pub mod lexer;
45
pub mod parser;
56
pub mod preprocessor;

src/c/parser/expr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
248248
return Ok(ExprKind::Dereference(Box::new(inner)).at(source));
249249
}
250250
CTokenKind::Punctuator(Punctuator::Add) => {
251-
// Is this a no-op?
252251
self.input.advance();
253252
let inner = self.parse_expr_primary()?;
254253
return Ok(inner);

src/c/translate/expr/mod.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub fn translate_expr(ctx: &mut TranslateCtx, expr: &Expr) -> Result<ast::Expr,
3333
let left = translate_expr(ctx, &operation.left)?;
3434
let right = translate_expr(ctx, &operation.right)?;
3535

36+
// TODO: Perfrom usual arithmetic conversions or integer promotions depending on
37+
// operator
38+
// TODO: Array-to-Pointer and Function-to-Pointer conversions may also apply
3639
let operator: ast::BinaryOperator = match operation.operator {
3740
BinaryOperator::LogicalOr => ast::ShortCircuitingBinaryOperator::Or.into(),
3841
BinaryOperator::LogicalAnd => ast::ShortCircuitingBinaryOperator::And.into(),
@@ -113,12 +116,16 @@ pub fn translate_expr(ctx: &mut TranslateCtx, expr: &Expr) -> Result<ast::Expr,
113116
}))
114117
.at(expr.source)
115118
}
116-
ExprKind::Negate(inner) => ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
117-
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::Negate),
118-
inner: translate_expr(ctx, inner)?,
119-
}))
120-
.at(expr.source),
119+
ExprKind::Negate(inner) => {
120+
// TODO: Perform integer promotion
121+
ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
122+
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::Negate),
123+
inner: translate_expr(ctx, inner)?,
124+
}))
125+
.at(expr.source)
126+
}
121127
ExprKind::BitComplement(inner) => {
128+
// TODO: Perform integer promotion
122129
ast::ExprKind::UnaryOperation(Box::new(ast::UnaryOperation {
123130
operator: ast::UnaryOperator::Math(ast::UnaryMathOperator::BitComplement),
124131
inner: translate_expr(ctx, inner)?,

0 commit comments

Comments
 (0)