Skip to content

Commit f5bdd3f

Browse files
committed
Continued working on address-of/dereference operators, and fixed a few recently introduced parsing bugs
1 parent f72c90b commit f5bdd3f

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::Expr;
2+
use derive_more::IsVariant;
23
use std::fmt::Display;
34

45
#[derive(Clone, Debug)]
@@ -7,7 +8,7 @@ pub struct UnaryOperation {
78
pub inner: Expr,
89
}
910

10-
#[derive(Clone, Debug)]
11+
#[derive(Clone, Debug, IsVariant)]
1112
pub enum UnaryOperator {
1213
Not,
1314
BitComplement,

Diff for: src/lower/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,15 @@ 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+
}
440449
}
441450
}
442451

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

+7-10
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,23 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
8282
self.parse_enum_member_literal(name, source)
8383
}
8484
TokenKind::OpenCurly => {
85-
let ast_type = self.parse_type_from_parts(name, generics, source)?;
8685
let peek = &self.input.peek_nth(1).kind;
8786

8887
if peek.is_extend() || peek.is_colon() {
88+
let ast_type = self.parse_type_from_parts(name, generics, source)?;
8989
self.parse_structure_literal_with(ast_type)
9090
} else {
9191
let next_three =
92-
array_last::<3, 5, _>(self.input.peek_n()).map(|token| &token.kind);
92+
array_last::<2, 4, _>(self.input.peek_n()).map(|token| &token.kind);
9393

9494
match &next_three[..] {
95-
[TokenKind::Identifier(_), TokenKind::Colon, ..]
96-
| [TokenKind::Newline, TokenKind::Identifier(_), TokenKind::Colon, ..] => {
95+
[TokenKind::Colon, ..]
96+
| [TokenKind::Identifier(_), TokenKind::Colon, ..] => {
97+
let ast_type =
98+
self.parse_type_from_parts(name, generics, source)?;
9799
self.parse_structure_literal_with(ast_type)
98100
}
99-
_ => Ok(Expr::new(
100-
ExprKind::Variable(
101-
self.input.advance().kind.unwrap_identifier(),
102-
),
103-
source,
104-
)),
101+
_ => Ok(Expr::new(ExprKind::Variable(name), source)),
105102
}
106103
}
107104
}

Diff for: src/resolve/destination.rs

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ 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)
28+
if unary_operation.operator.is_dereference() =>
29+
{
30+
DestinationKind::Dereference(unary_operation.inner.expr)
31+
}
2732
_ => {
2833
return Err(ResolveErrorKind::CannotMutate {
2934
bad_type: typed_expr.resolved_type.to_string(),

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

+37
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,43 @@ pub fn resolve_unary_operation_expr(
2323
Initialized::Require,
2424
)?;
2525

26+
let operator = &unary_operation.operator;
27+
28+
if operator.is_address_of() || operator.is_dereference() {
29+
if resolved_expr.resolved_type.kind.is_ambiguous_type() {
30+
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
31+
operator: unary_operation.operator.to_string(),
32+
bad_type: resolved_expr.resolved_type.to_string(),
33+
}
34+
.at(source));
35+
}
36+
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));
47+
}
48+
} else if operator.is_address_of() {
49+
result_type = TypeKind::Pointer(Box::new(result_type)).at(source);
50+
}
51+
52+
let expr = Expr::new(
53+
ExprKind::UnaryOperation(Box::new(UnaryOperation {
54+
operator: unary_operation.operator.clone(),
55+
inner: resolved_expr,
56+
})),
57+
source,
58+
);
59+
60+
return Ok(TypedExpr::new(result_type, expr));
61+
}
62+
2663
let resolved_expr = match &resolved_expr.resolved_type.kind {
2764
TypeKind::Boolean => resolved_expr,
2865
TypeKind::Integer(..) => resolved_expr,

Diff for: src/resolve/stmt.rs

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ pub fn resolve_stmt(
205205
resolved::DestinationKind::GlobalVariable(..) => (),
206206
resolved::DestinationKind::Member { .. } => (),
207207
resolved::DestinationKind::ArrayAccess { .. } => (),
208+
resolved::DestinationKind::Dereference { .. } => (),
208209
}
209210

210211
let operator = assignment

Diff for: src/resolved/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ impl TypeKind {
207207
Self::Integer(..) | Self::IntegerLiteral(..) | Self::CInteger(..)
208208
)
209209
}
210+
211+
pub fn is_ambiguous_type(&self) -> bool {
212+
self.is_integer_literal()
213+
}
210214
}
211215

212216
#[derive(Clone, Debug)]
@@ -543,6 +547,7 @@ pub enum DestinationKind {
543547
field_type: Type,
544548
},
545549
ArrayAccess(Box<ArrayAccess>),
550+
Dereference(Expr),
546551
}
547552

548553
#[derive(Copy, Clone, Debug)]

0 commit comments

Comments
 (0)