Skip to content

Commit a0aa808

Browse files
committed
Refactored and cleaned up code for address-of operator
1 parent b69da40 commit a0aa808

File tree

9 files changed

+147
-96
lines changed

9 files changed

+147
-96
lines changed
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,27 @@ use derive_more::IsVariant;
33
use std::fmt::Display;
44

55
#[derive(Clone, Debug)]
6-
pub struct UnaryOperation {
7-
pub operator: UnaryOperator,
6+
pub struct UnaryMathOperation {
7+
pub operator: UnaryMathOperator,
88
pub inner: Expr,
99
}
1010

11-
#[derive(Clone, Debug, IsVariant)]
12-
pub enum UnaryOperator {
11+
#[derive(Copy, Clone, Debug, IsVariant)]
12+
pub enum UnaryMathOperator {
1313
Not,
1414
BitComplement,
1515
Negate,
1616
IsNonZero,
17-
AddressOf,
1817
Dereference,
1918
}
2019

21-
impl Display for UnaryOperator {
20+
impl Display for UnaryMathOperator {
2221
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2322
f.write_str(match self {
2423
Self::Not => "!",
2524
Self::BitComplement => "~",
2625
Self::Negate => "-",
2726
Self::IsNonZero => "bool()",
28-
Self::AddressOf => "(address of) &",
2927
Self::Dereference => "(dereference) *",
3028
})
3129
}

src/ast/expr/unary/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
mod math;
2+
3+
use crate::ast::Expr;
4+
pub use math::*;
5+
6+
#[derive(Clone, Debug)]
7+
pub struct UnaryOperation {
8+
pub operator: UnaryOperator,
9+
pub inner: Expr,
10+
}
11+
12+
impl UnaryOperation {
13+
pub fn new(operator: UnaryOperator, inner: Expr) -> Self {
14+
Self { operator, inner }
15+
}
16+
17+
pub fn new_math(operator: UnaryMathOperator, inner: Expr) -> Self {
18+
Self {
19+
operator: UnaryOperator::Math(operator),
20+
inner,
21+
}
22+
}
23+
}
24+
25+
#[derive(Clone, Debug)]
26+
pub enum UnaryOperator {
27+
Math(UnaryMathOperator),
28+
AddressOf,
29+
}

src/lower/mod.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::{
99
ir::{self, BasicBlocks, Global, Literal, OverflowOperator, Value, ValueReference},
1010
resolved::{
1111
self, Destination, DestinationKind, Expr, ExprKind, FloatOrInteger, FloatSize, Member,
12-
NumericMode, SignOrIndeterminate, StmtKind, StructureLiteral, VariableStorageKey,
12+
NumericMode, SignOrIndeterminate, StmtKind, StructureLiteral, UnaryMathOperation,
13+
VariableStorageKey,
1314
},
1415
tag::Tag,
1516
target::{Target, TargetOsExt},
@@ -734,29 +735,21 @@ fn lower_expr(
734735

735736
Ok(builder.push(ir::Instruction::StructureLiteral(result_ir_type, values)))
736737
}
737-
ExprKind::UnaryOperation(unary_operation) => {
738-
let inner = lower_expr(
739-
builder,
740-
ir_module,
741-
&unary_operation.inner.expr,
742-
function,
743-
resolved_ast,
744-
)?;
745-
746-
let inner_type = lower_type(
747-
ir_module.target,
748-
&unary_operation.inner.resolved_type,
749-
resolved_ast,
750-
)?;
738+
ExprKind::UnaryMathOperation(operation) => {
739+
let UnaryMathOperation { operator, inner } = &**operation;
740+
741+
let ir_type = lower_type(ir_module.target, &inner.resolved_type, resolved_ast)?;
742+
let value = lower_expr(builder, ir_module, &inner.expr, function, resolved_ast)?;
743+
744+
let instruction = match operator {
745+
resolved::UnaryMathOperator::Not => ir::Instruction::IsZero(value),
746+
resolved::UnaryMathOperator::BitComplement => ir::Instruction::BitComplement(value),
747+
resolved::UnaryMathOperator::Negate => ir::Instruction::Negate(value),
748+
resolved::UnaryMathOperator::IsNonZero => ir::Instruction::IsNonZero(value),
749+
resolved::UnaryMathOperator::Dereference => ir::Instruction::Load((value, ir_type)),
750+
};
751751

752-
Ok(builder.push(match unary_operation.operator {
753-
resolved::UnaryOperator::Not => ir::Instruction::IsZero(inner),
754-
resolved::UnaryOperator::BitComplement => ir::Instruction::BitComplement(inner),
755-
resolved::UnaryOperator::Negate => ir::Instruction::Negate(inner),
756-
resolved::UnaryOperator::IsNonZero => ir::Instruction::IsNonZero(inner),
757-
resolved::UnaryOperator::AddressOf => unreachable!(),
758-
resolved::UnaryOperator::Dereference => ir::Instruction::Load((inner, inner_type)),
759-
}))
752+
Ok(builder.push(instruction))
760753
}
761754
ExprKind::AddressOf(destination) => {
762755
let subject_pointer =

src/parser/parse_expr/primary/mod.rs

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ mod structure_literal;
66

77
use super::{super::error::ParseError, is_right_associative, is_terminating_token, Parser};
88
use crate::{
9-
ast::{Block, Conditional, Expr, ExprKind, Integer, UnaryOperation, UnaryOperator, While},
9+
ast::{
10+
Block, Conditional, Expr, ExprKind, Integer, UnaryMathOperator, UnaryOperation,
11+
UnaryOperator, While,
12+
},
1013
inflow::Inflow,
1114
parser::{array_last, error::ParseErrorKind},
1215
token::{StringLiteral, StringModifier, Token, TokenKind},
@@ -119,29 +122,50 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
119122
}
120123
}
121124
}
122-
TokenKind::Not
123-
| TokenKind::BitComplement
124-
| TokenKind::Subtract
125-
| TokenKind::AddressOf
126-
| TokenKind::Dereference => {
127-
let operator = match kind {
128-
TokenKind::Not => UnaryOperator::Not,
129-
TokenKind::BitComplement => UnaryOperator::BitComplement,
130-
TokenKind::Subtract => UnaryOperator::Negate,
131-
TokenKind::AddressOf => UnaryOperator::AddressOf,
132-
TokenKind::Dereference => UnaryOperator::Dereference,
133-
_ => unreachable!(),
134-
};
125+
TokenKind::Not => {
126+
self.input.advance();
135127

136-
// Eat unary operator
128+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new_math(
129+
UnaryMathOperator::Not,
130+
self.parse_expr_primary()?,
131+
)))
132+
.at(source))
133+
}
134+
TokenKind::BitComplement => {
137135
self.input.advance();
138136

139-
let inner = self.parse_expr_primary()?;
137+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new_math(
138+
UnaryMathOperator::BitComplement,
139+
self.parse_expr_primary()?,
140+
)))
141+
.at(source))
142+
}
143+
TokenKind::Subtract => {
144+
self.input.advance();
140145

141-
Ok(Expr::new(
142-
ExprKind::UnaryOperation(Box::new(UnaryOperation { operator, inner })),
143-
source,
144-
))
146+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new_math(
147+
UnaryMathOperator::Negate,
148+
self.parse_expr_primary()?,
149+
)))
150+
.at(source))
151+
}
152+
TokenKind::AddressOf => {
153+
self.input.advance();
154+
155+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new(
156+
UnaryOperator::AddressOf,
157+
self.parse_expr_primary()?,
158+
)))
159+
.at(source))
160+
}
161+
TokenKind::Dereference => {
162+
self.input.advance();
163+
164+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new_math(
165+
UnaryMathOperator::Dereference,
166+
self.parse_expr_primary()?,
167+
)))
168+
.at(source))
145169
}
146170
TokenKind::IfKeyword => {
147171
self.input.advance().kind.unwrap_if_keyword();

src/resolve/conform/from_c_integer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use crate::{
33
ast::{CInteger, IntegerBits, OptionIntegerSignExt},
44
logic::implies,
55
resolved::{
6-
Cast, CastFrom, ExprKind, IntegerSign, Type, TypeKind, TypedExpr, UnaryOperation,
7-
UnaryOperator,
6+
Cast, CastFrom, ExprKind, IntegerSign, Type, TypeKind, TypedExpr, UnaryMathOperation,
7+
UnaryMathOperator,
88
},
99
source_files::Source,
1010
};
@@ -52,8 +52,8 @@ fn from_c_integer_to_bool(
5252

5353
Some(TypedExpr::new(
5454
TypeKind::Boolean.at(source),
55-
ExprKind::UnaryOperation(Box::new(UnaryOperation {
56-
operator: UnaryOperator::IsNonZero,
55+
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
56+
operator: UnaryMathOperator::IsNonZero,
5757
inner: expr.clone(),
5858
}))
5959
.at(source),

src/resolve/destination.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn resolve_expr_to_destination(typed_expr: TypedExpr) -> Result<Destination,
2424
}
2525
}
2626
ExprKind::ArrayAccess(array_access) => DestinationKind::ArrayAccess(array_access),
27-
ExprKind::UnaryOperation(unary_operation)
27+
ExprKind::UnaryMathOperation(unary_operation)
2828
if unary_operation.operator.is_dereference() =>
2929
{
3030
DestinationKind::Dereference(unary_operation.inner.expr)

src/resolve/expr/mod.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use self::{
1616
};
1717
use super::{
1818
conform::{conform_expr_or_error, ConformMode},
19+
destination::resolve_expr_to_destination,
1920
error::ResolveError,
2021
function_search_ctx::FunctionSearchCtx,
2122
global_search_ctx::GlobalSearchCtx,
@@ -24,19 +25,19 @@ use super::{
2425
Initialized,
2526
};
2627
use crate::{
27-
ast::{self, CInteger, ConformBehavior},
28+
ast::{self, CInteger, ConformBehavior, UnaryOperator},
2829
resolve::{
2930
ensure_initialized,
3031
error::ResolveErrorKind,
3132
expr::{
3233
call::resolve_call_expr, conditional::resolve_conditional_expr,
3334
declare_assign::resolve_declare_assign_expr, member_expr::resolve_member_expr,
3435
struct_literal::resolve_struct_literal_expr,
35-
unary_operation::resolve_unary_operation_expr, variable::resolve_variable_expr,
36+
unary_operation::resolve_unary_math_operation_expr, variable::resolve_variable_expr,
3637
},
3738
resolve_stmts, resolve_type,
3839
},
39-
resolved::{self, FunctionRef, StructureRef, TypedExpr},
40+
resolved::{self, Expr, ExprKind, FunctionRef, StructureRef, TypedExpr},
4041
};
4142
use ast::FloatSize;
4243
pub use basic_binary_operation::resolve_basic_binary_operator;
@@ -206,9 +207,27 @@ pub fn resolve_expr(
206207
source,
207208
)
208209
}
209-
ast::ExprKind::UnaryOperation(unary_operation) => {
210-
resolve_unary_operation_expr(ctx, unary_operation, preferred_type, source)
211-
}
210+
ast::ExprKind::UnaryOperation(unary_operation) => match &unary_operation.operator {
211+
UnaryOperator::Math(operator) => resolve_unary_math_operation_expr(
212+
ctx,
213+
operator,
214+
&unary_operation.inner,
215+
preferred_type,
216+
source,
217+
),
218+
UnaryOperator::AddressOf => {
219+
let resolved_expr = resolve_expr(
220+
ctx,
221+
&unary_operation.inner,
222+
preferred_type,
223+
Initialized::Require,
224+
)?;
225+
let result_type = resolved_expr.resolved_type.clone().pointer(source);
226+
let destination = resolve_expr_to_destination(resolved_expr)?;
227+
let expr = Expr::new(ExprKind::AddressOf(Box::new(destination)), source);
228+
return Ok(TypedExpr::new(result_type, expr));
229+
}
230+
},
212231
ast::ExprKind::Conditional(conditional) => {
213232
resolve_conditional_expr(ctx, conditional, preferred_type, source)
214233
}

src/resolve/expr/unary_operation.rs

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
11
use super::{resolve_expr, PreferredType, ResolveExprCtx};
22
use crate::{
3-
ast::{self, UnaryOperator},
3+
ast::{self, UnaryMathOperator},
44
resolve::{
55
conform::to_default::conform_integer_literal_to_default_or_error,
6-
destination::resolve_expr_to_destination,
76
error::{ResolveError, ResolveErrorKind},
87
Initialized,
98
},
10-
resolved::{Expr, ExprKind, TypeKind, TypedExpr, UnaryOperation},
9+
resolved::{Expr, ExprKind, TypeKind, TypedExpr, UnaryMathOperation},
1110
source_files::Source,
1211
};
1312

14-
pub fn resolve_unary_operation_expr(
13+
pub fn resolve_unary_math_operation_expr(
1514
ctx: &mut ResolveExprCtx<'_, '_>,
16-
unary_operation: &ast::UnaryOperation,
15+
operator: &UnaryMathOperator,
16+
inner: &ast::Expr,
1717
preferred_type: Option<PreferredType>,
1818
source: Source,
1919
) -> Result<TypedExpr, ResolveError> {
20-
let resolved_expr = resolve_expr(
21-
ctx,
22-
&unary_operation.inner,
23-
preferred_type,
24-
Initialized::Require,
25-
)?;
26-
27-
let operator = &unary_operation.operator;
28-
29-
if operator.is_address_of() {
30-
let result_type = resolved_expr.resolved_type.clone().pointer(source);
31-
let destination = resolve_expr_to_destination(resolved_expr)?;
32-
let expr = Expr::new(ExprKind::AddressOf(Box::new(destination)), source);
33-
return Ok(TypedExpr::new(result_type, expr));
34-
}
20+
let resolved_expr = resolve_expr(ctx, inner, preferred_type, Initialized::Require)?;
3521

3622
if operator.is_dereference() {
3723
if resolved_expr.resolved_type.kind.is_ambiguous_type() {
3824
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
39-
operator: unary_operation.operator.to_string(),
25+
operator: operator.to_string(),
4026
bad_type: resolved_expr.resolved_type.to_string(),
4127
}
4228
.at(source));
@@ -46,15 +32,15 @@ pub fn resolve_unary_operation_expr(
4632
(**inner).clone()
4733
} else {
4834
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
49-
operator: unary_operation.operator.to_string(),
35+
operator: operator.to_string(),
5036
bad_type: resolved_expr.resolved_type.to_string(),
5137
}
5238
.at(source));
5339
};
5440

5541
let expr = Expr::new(
56-
ExprKind::UnaryOperation(Box::new(UnaryOperation {
57-
operator: unary_operation.operator.clone(),
42+
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
43+
operator: operator.clone(),
5844
inner: resolved_expr,
5945
})),
6046
source,
@@ -71,24 +57,26 @@ pub fn resolve_unary_operation_expr(
7157
}
7258
_ => {
7359
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
74-
operator: unary_operation.operator.to_string(),
60+
operator: operator.to_string(),
7561
bad_type: resolved_expr.resolved_type.to_string(),
7662
}
7763
.at(source));
7864
}
7965
};
8066

81-
let result_type = match unary_operation.operator {
82-
UnaryOperator::Not | UnaryOperator::IsNonZero => TypeKind::Boolean.at(source),
83-
UnaryOperator::BitComplement | UnaryOperator::Negate => resolved_expr.resolved_type.clone(),
84-
UnaryOperator::Dereference | UnaryOperator::AddressOf => {
67+
let result_type = match operator {
68+
UnaryMathOperator::Not | UnaryMathOperator::IsNonZero => TypeKind::Boolean.at(source),
69+
UnaryMathOperator::BitComplement | UnaryMathOperator::Negate => {
70+
resolved_expr.resolved_type.clone()
71+
}
72+
UnaryMathOperator::Dereference => {
8573
unreachable!("should've already handled address-of/dereference operators")
8674
}
8775
};
8876

8977
let expr = Expr::new(
90-
ExprKind::UnaryOperation(Box::new(UnaryOperation {
91-
operator: unary_operation.operator.clone(),
78+
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
79+
operator: operator.clone(),
9280
inner: resolved_expr,
9381
})),
9482
source,

0 commit comments

Comments
 (0)