Skip to content

Commit dae296e

Browse files
committed
Refactored and cleaned up code for address-of and dereference operators
1 parent a0aa808 commit dae296e

File tree

8 files changed

+74
-81
lines changed

8 files changed

+74
-81
lines changed

Diff for: src/ast/expr/unary/math.rs

-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub enum UnaryMathOperator {
1414
BitComplement,
1515
Negate,
1616
IsNonZero,
17-
Dereference,
1817
}
1918

2019
impl Display for UnaryMathOperator {
@@ -24,7 +23,6 @@ impl Display for UnaryMathOperator {
2423
Self::BitComplement => "~",
2524
Self::Negate => "-",
2625
Self::IsNonZero => "bool()",
27-
Self::Dereference => "(dereference) *",
2826
})
2927
}
3028
}

Diff for: src/ast/expr/unary/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ mod math;
33
use crate::ast::Expr;
44
pub use math::*;
55

6+
#[derive(Clone, Debug)]
7+
pub enum UnaryOperator {
8+
Math(UnaryMathOperator),
9+
AddressOf,
10+
Dereference,
11+
}
12+
613
#[derive(Clone, Debug)]
714
pub struct UnaryOperation {
815
pub operator: UnaryOperator,
@@ -21,9 +28,3 @@ impl UnaryOperation {
2128
}
2229
}
2330
}
24-
25-
#[derive(Clone, Debug)]
26-
pub enum UnaryOperator {
27-
Math(UnaryMathOperator),
28-
AddressOf,
29-
}

Diff for: src/lower/mod.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -737,25 +737,28 @@ fn lower_expr(
737737
}
738738
ExprKind::UnaryMathOperation(operation) => {
739739
let UnaryMathOperation { operator, inner } = &**operation;
740-
741-
let ir_type = lower_type(ir_module.target, &inner.resolved_type, resolved_ast)?;
742740
let value = lower_expr(builder, ir_module, &inner.expr, function, resolved_ast)?;
743741

744742
let instruction = match operator {
745743
resolved::UnaryMathOperator::Not => ir::Instruction::IsZero(value),
746744
resolved::UnaryMathOperator::BitComplement => ir::Instruction::BitComplement(value),
747745
resolved::UnaryMathOperator::Negate => ir::Instruction::Negate(value),
748746
resolved::UnaryMathOperator::IsNonZero => ir::Instruction::IsNonZero(value),
749-
resolved::UnaryMathOperator::Dereference => ir::Instruction::Load((value, ir_type)),
750747
};
751748

752749
Ok(builder.push(instruction))
753750
}
754-
ExprKind::AddressOf(destination) => {
755-
let subject_pointer =
756-
lower_destination(builder, ir_module, destination, function, resolved_ast)?;
757-
758-
Ok(subject_pointer)
751+
ExprKind::AddressOf(destination) => Ok(lower_destination(
752+
builder,
753+
ir_module,
754+
destination,
755+
function,
756+
resolved_ast,
757+
)?),
758+
ExprKind::Dereference(subject) => {
759+
let ir_type = lower_type(ir_module.target, &subject.resolved_type, resolved_ast)?;
760+
let value = lower_expr(builder, ir_module, &subject.expr, function, resolved_ast)?;
761+
Ok(builder.push(ir::Instruction::Load((value, ir_type))))
759762
}
760763
ExprKind::Conditional(conditional) => {
761764
let resume_basicblock_id = builder.new_block();

Diff for: src/parser/parse_expr/primary/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
161161
TokenKind::Dereference => {
162162
self.input.advance();
163163

164-
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new_math(
165-
UnaryMathOperator::Dereference,
164+
Ok(ExprKind::UnaryOperation(Box::new(UnaryOperation::new(
165+
UnaryOperator::Dereference,
166166
self.parse_expr_primary()?,
167167
)))
168168
.at(source))

Diff for: src/resolve/destination.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -24,11 +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::UnaryMathOperation(unary_operation)
28-
if unary_operation.operator.is_dereference() =>
29-
{
30-
DestinationKind::Dereference(unary_operation.inner.expr)
31-
}
27+
ExprKind::Dereference(subject) => DestinationKind::Dereference(subject.expr),
3228
_ => {
3329
return Err(ResolveErrorKind::CannotMutate {
3430
bad_type: typed_expr.resolved_type.to_string(),

Diff for: src/resolve/expr/mod.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::{
3737
},
3838
resolve_stmts, resolve_type,
3939
},
40-
resolved::{self, Expr, ExprKind, FunctionRef, StructureRef, TypedExpr},
40+
resolved::{self, Expr, ExprKind, FunctionRef, StructureRef, TypeKind, TypedExpr},
4141
};
4242
use ast::FloatSize;
4343
pub use basic_binary_operation::resolve_basic_binary_operator;
@@ -227,6 +227,34 @@ pub fn resolve_expr(
227227
let expr = Expr::new(ExprKind::AddressOf(Box::new(destination)), source);
228228
return Ok(TypedExpr::new(result_type, expr));
229229
}
230+
UnaryOperator::Dereference => {
231+
let resolved_expr = resolve_expr(
232+
ctx,
233+
&unary_operation.inner,
234+
preferred_type,
235+
Initialized::Require,
236+
)?;
237+
238+
let result_type = match &resolved_expr.resolved_type.kind {
239+
TypeKind::Pointer(inner)
240+
if !resolved_expr.resolved_type.kind.is_ambiguous() =>
241+
{
242+
(**inner).clone()
243+
}
244+
_ => {
245+
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
246+
operator: "(dereference) *".into(),
247+
bad_type: resolved_expr.resolved_type.to_string(),
248+
}
249+
.at(source));
250+
}
251+
};
252+
253+
return Ok(TypedExpr::new(
254+
result_type,
255+
Expr::new(ExprKind::Dereference(Box::new(resolved_expr)), source),
256+
));
257+
}
230258
},
231259
ast::ExprKind::Conditional(conditional) => {
232260
resolve_conditional_expr(ctx, conditional, preferred_type, source)

Diff for: src/resolve/expr/unary_operation.rs

+18-56
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{resolve_expr, PreferredType, ResolveExprCtx};
22
use crate::{
33
ast::{self, UnaryMathOperator},
44
resolve::{
5-
conform::to_default::conform_integer_literal_to_default_or_error,
5+
conform::to_default::conform_expr_to_default,
66
error::{ResolveError, ResolveErrorKind},
77
Initialized,
88
},
@@ -17,70 +17,32 @@ pub fn resolve_unary_math_operation_expr(
1717
preferred_type: Option<PreferredType>,
1818
source: Source,
1919
) -> Result<TypedExpr, ResolveError> {
20-
let resolved_expr = resolve_expr(ctx, inner, preferred_type, Initialized::Require)?;
20+
let resolved_expr = resolve_expr(ctx, inner, preferred_type, Initialized::Require)
21+
.and_then(conform_expr_to_default)?;
2122

22-
if operator.is_dereference() {
23-
if resolved_expr.resolved_type.kind.is_ambiguous_type() {
24-
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
25-
operator: operator.to_string(),
26-
bad_type: resolved_expr.resolved_type.to_string(),
27-
}
28-
.at(source));
23+
if resolved_expr.resolved_type.is_ambiguous() {
24+
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
25+
operator: operator.to_string(),
26+
bad_type: resolved_expr.resolved_type.to_string(),
2927
}
30-
31-
let result_type = if let TypeKind::Pointer(inner) = &resolved_expr.resolved_type.kind {
32-
(**inner).clone()
33-
} else {
34-
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
35-
operator: operator.to_string(),
36-
bad_type: resolved_expr.resolved_type.to_string(),
37-
}
38-
.at(source));
39-
};
40-
41-
let expr = Expr::new(
42-
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
43-
operator: operator.clone(),
44-
inner: resolved_expr,
45-
})),
46-
source,
47-
);
48-
49-
return Ok(TypedExpr::new(result_type, expr));
28+
.at(source));
5029
}
5130

52-
let resolved_expr = match &resolved_expr.resolved_type.kind {
53-
TypeKind::Boolean => resolved_expr,
54-
TypeKind::Integer(..) => resolved_expr,
55-
TypeKind::IntegerLiteral(value) => {
56-
conform_integer_literal_to_default_or_error(value, resolved_expr.expr.source)?
57-
}
58-
_ => {
59-
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
60-
operator: operator.to_string(),
61-
bad_type: resolved_expr.resolved_type.to_string(),
62-
}
63-
.at(source));
64-
}
65-
};
66-
6731
let result_type = match operator {
6832
UnaryMathOperator::Not | UnaryMathOperator::IsNonZero => TypeKind::Boolean.at(source),
6933
UnaryMathOperator::BitComplement | UnaryMathOperator::Negate => {
7034
resolved_expr.resolved_type.clone()
7135
}
72-
UnaryMathOperator::Dereference => {
73-
unreachable!("should've already handled address-of/dereference operators")
74-
}
7536
};
7637

77-
let expr = Expr::new(
78-
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
79-
operator: operator.clone(),
80-
inner: resolved_expr,
81-
})),
82-
source,
83-
);
84-
85-
Ok(TypedExpr::new(result_type, expr))
38+
Ok(TypedExpr::new(
39+
result_type,
40+
Expr::new(
41+
ExprKind::UnaryMathOperation(Box::new(UnaryMathOperation {
42+
operator: operator.clone(),
43+
inner: resolved_expr,
44+
})),
45+
source,
46+
),
47+
))
8648
}

Diff for: src/resolved/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ impl Type {
126126
pub fn pointer(self, source: Source) -> Self {
127127
TypeKind::Pointer(Box::new(self)).at(source)
128128
}
129+
130+
pub fn is_ambiguous(&self) -> bool {
131+
self.kind.is_ambiguous()
132+
}
129133
}
130134

131135
impl Display for Type {
@@ -214,7 +218,7 @@ impl TypeKind {
214218
)
215219
}
216220

217-
pub fn is_ambiguous_type(&self) -> bool {
221+
pub fn is_ambiguous(&self) -> bool {
218222
self.is_integer_literal()
219223
}
220224
}
@@ -424,6 +428,7 @@ pub enum ExprKind {
424428
Member(Box<Member>),
425429
StructureLiteral(Box<StructureLiteral>),
426430
UnaryMathOperation(Box<UnaryMathOperation>),
431+
Dereference(Box<TypedExpr>),
427432
AddressOf(Box<Destination>),
428433
Conditional(Box<Conditional>),
429434
While(Box<While>),

0 commit comments

Comments
 (0)