Skip to content

Commit b69da40

Browse files
committed
Finished initial implementation of address-of and dereference operators
1 parent f5bdd3f commit b69da40

File tree

6 files changed

+62
-31
lines changed

6 files changed

+62
-31
lines changed

Diff for: src/lower/mod.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,13 @@ fn lower_destination(
437437
index,
438438
}))
439439
}
440-
DestinationKind::Dereference(pointer_lvalue) => {
441-
let pointer_rvalue =
442-
lower_expr(builder, ir_module, pointer_lvalue, function, resolved_ast)?;
443-
444-
let result_pointer_type =
445-
lower_type(&ir_module.target, &destination.resolved_type, resolved_ast)?;
446-
447-
Ok(builder.push(ir::Instruction::Load((pointer_rvalue, result_pointer_type))))
448-
}
440+
DestinationKind::Dereference(lvalue) => Ok(lower_expr(
441+
builder,
442+
ir_module,
443+
lvalue,
444+
function,
445+
resolved_ast,
446+
)?),
449447
}
450448
}
451449

@@ -756,12 +754,16 @@ fn lower_expr(
756754
resolved::UnaryOperator::BitComplement => ir::Instruction::BitComplement(inner),
757755
resolved::UnaryOperator::Negate => ir::Instruction::Negate(inner),
758756
resolved::UnaryOperator::IsNonZero => ir::Instruction::IsNonZero(inner),
759-
resolved::UnaryOperator::AddressOf => {
760-
unimplemented!("address of operator");
761-
}
757+
resolved::UnaryOperator::AddressOf => unreachable!(),
762758
resolved::UnaryOperator::Dereference => ir::Instruction::Load((inner, inner_type)),
763759
}))
764760
}
761+
ExprKind::AddressOf(destination) => {
762+
let subject_pointer =
763+
lower_destination(builder, ir_module, destination, function, resolved_ast)?;
764+
765+
Ok(subject_pointer)
766+
}
765767
ExprKind::Conditional(conditional) => {
766768
let resume_basicblock_id = builder.new_block();
767769

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
8888
let ast_type = self.parse_type_from_parts(name, generics, source)?;
8989
self.parse_structure_literal_with(ast_type)
9090
} else {
91-
let next_three =
91+
let last_two =
9292
array_last::<2, 4, _>(self.input.peek_n()).map(|token| &token.kind);
9393

94-
match &next_three[..] {
94+
match &last_two[..] {
9595
[TokenKind::Colon, ..]
9696
| [TokenKind::Identifier(_), TokenKind::Colon, ..] => {
9797
let ast_type =

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

+19-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
ast::{self, UnaryOperator},
44
resolve::{
55
conform::to_default::conform_integer_literal_to_default_or_error,
6+
destination::resolve_expr_to_destination,
67
error::{ResolveError, ResolveErrorKind},
78
Initialized,
89
},
@@ -25,7 +26,14 @@ pub fn resolve_unary_operation_expr(
2526

2627
let operator = &unary_operation.operator;
2728

28-
if operator.is_address_of() || operator.is_dereference() {
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+
}
35+
36+
if operator.is_dereference() {
2937
if resolved_expr.resolved_type.kind.is_ambiguous_type() {
3038
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
3139
operator: unary_operation.operator.to_string(),
@@ -34,20 +42,15 @@ pub fn resolve_unary_operation_expr(
3442
.at(source));
3543
}
3644

37-
let mut result_type = resolved_expr.resolved_type.clone();
38-
if operator.is_dereference() {
39-
if let TypeKind::Pointer(inner) = result_type.kind {
40-
result_type = *inner;
41-
} else {
42-
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
43-
operator: unary_operation.operator.to_string(),
44-
bad_type: resolved_expr.resolved_type.to_string(),
45-
}
46-
.at(source));
45+
let result_type = if let TypeKind::Pointer(inner) = &resolved_expr.resolved_type.kind {
46+
(**inner).clone()
47+
} else {
48+
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
49+
operator: unary_operation.operator.to_string(),
50+
bad_type: resolved_expr.resolved_type.to_string(),
4751
}
48-
} else if operator.is_address_of() {
49-
result_type = TypeKind::Pointer(Box::new(result_type)).at(source);
50-
}
52+
.at(source));
53+
};
5154

5255
let expr = Expr::new(
5356
ExprKind::UnaryOperation(Box::new(UnaryOperation {
@@ -78,10 +81,9 @@ pub fn resolve_unary_operation_expr(
7881
let result_type = match unary_operation.operator {
7982
UnaryOperator::Not | UnaryOperator::IsNonZero => TypeKind::Boolean.at(source),
8083
UnaryOperator::BitComplement | UnaryOperator::Negate => resolved_expr.resolved_type.clone(),
81-
UnaryOperator::AddressOf => {
82-
TypeKind::Pointer(Box::new(resolved_expr.resolved_type.clone())).at(source)
84+
UnaryOperator::Dereference | UnaryOperator::AddressOf => {
85+
unreachable!("should've already handled address-of/dereference operators")
8386
}
84-
UnaryOperator::Dereference => resolved_expr.resolved_type.clone(),
8587
};
8688

8789
let expr = Expr::new(

Diff for: src/resolved/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ pub struct Type {
122122
pub source: Source,
123123
}
124124

125+
impl Type {
126+
pub fn pointer(self, source: Source) -> Self {
127+
TypeKind::Pointer(Box::new(self)).at(source)
128+
}
129+
}
130+
125131
impl Display for Type {
126132
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127133
std::fmt::Display::fmt(&self.kind, f)
@@ -418,6 +424,7 @@ pub enum ExprKind {
418424
Member(Box<Member>),
419425
StructureLiteral(Box<StructureLiteral>),
420426
UnaryOperation(Box<UnaryOperation>),
427+
AddressOf(Box<Destination>),
421428
Conditional(Box<Conditional>),
422429
While(Box<While>),
423430
ArrayAccess(Box<ArrayAccess>),

Diff for: tests/pointers/main.adept

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
#[foreign]
3+
func printf(format ptr<char>, ...) int
4+
5+
func main {
6+
message i32 = 0x41000041
7+
printf(c"&message = %s\n", &message)
8+
9+
stair long = 0
10+
stair_ptr ptr<long> = &stair
11+
*stair_ptr = 1234
12+
printf(c"*stair_ptr = %ld\n", *stair_ptr)
13+
14+
pi := 0.0
15+
pi_ptr ptr<double> = &pi
16+
*pi_ptr = 3.14159
17+
printf(c"PI = %f\n", pi)
18+
}
19+

Diff for: tests/run.sh

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ compile nested_expressions
5151
compile object_mutation
5252
compile op_then_assign
5353
compile_module preprocessor_toggle
54+
compile pointers
5455
compile reference_counted
5556
compile return
5657
compile return_message

0 commit comments

Comments
 (0)