Skip to content

Commit

Permalink
Continued working on address-of/dereference operators, and fixed a fe…
Browse files Browse the repository at this point in the history
…w recently introduced parsing bugs
  • Loading branch information
IsaacShelton committed Sep 13, 2024
1 parent f72c90b commit f5bdd3f
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/ast/expr/unary.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::Expr;
use derive_more::IsVariant;
use std::fmt::Display;

#[derive(Clone, Debug)]
Expand All @@ -7,7 +8,7 @@ pub struct UnaryOperation {
pub inner: Expr,
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, IsVariant)]
pub enum UnaryOperator {
Not,
BitComplement,
Expand Down
9 changes: 9 additions & 0 deletions src/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,15 @@ fn lower_destination(
index,
}))
}
DestinationKind::Dereference(pointer_lvalue) => {
let pointer_rvalue =
lower_expr(builder, ir_module, pointer_lvalue, function, resolved_ast)?;

let result_pointer_type =
lower_type(&ir_module.target, &destination.resolved_type, resolved_ast)?;

Ok(builder.push(ir::Instruction::Load((pointer_rvalue, result_pointer_type))))
}
}
}

Expand Down
17 changes: 7 additions & 10 deletions src/parser/parse_expr/primary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,23 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
self.parse_enum_member_literal(name, source)
}
TokenKind::OpenCurly => {
let ast_type = self.parse_type_from_parts(name, generics, source)?;
let peek = &self.input.peek_nth(1).kind;

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

match &next_three[..] {
[TokenKind::Identifier(_), TokenKind::Colon, ..]
| [TokenKind::Newline, TokenKind::Identifier(_), TokenKind::Colon, ..] => {
[TokenKind::Colon, ..]
| [TokenKind::Identifier(_), TokenKind::Colon, ..] => {
let ast_type =
self.parse_type_from_parts(name, generics, source)?;
self.parse_structure_literal_with(ast_type)
}
_ => Ok(Expr::new(
ExprKind::Variable(
self.input.advance().kind.unwrap_identifier(),
),
source,
)),
_ => Ok(Expr::new(ExprKind::Variable(name), source)),
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/resolve/destination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ pub fn resolve_expr_to_destination(typed_expr: TypedExpr) -> Result<Destination,
}
}
ExprKind::ArrayAccess(array_access) => DestinationKind::ArrayAccess(array_access),
ExprKind::UnaryOperation(unary_operation)
if unary_operation.operator.is_dereference() =>
{
DestinationKind::Dereference(unary_operation.inner.expr)
}
_ => {
return Err(ResolveErrorKind::CannotMutate {
bad_type: typed_expr.resolved_type.to_string(),
Expand Down
37 changes: 37 additions & 0 deletions src/resolve/expr/unary_operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ pub fn resolve_unary_operation_expr(
Initialized::Require,
)?;

let operator = &unary_operation.operator;

if operator.is_address_of() || operator.is_dereference() {
if resolved_expr.resolved_type.kind.is_ambiguous_type() {
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
operator: unary_operation.operator.to_string(),
bad_type: resolved_expr.resolved_type.to_string(),
}
.at(source));
}

let mut result_type = resolved_expr.resolved_type.clone();
if operator.is_dereference() {
if let TypeKind::Pointer(inner) = result_type.kind {
result_type = *inner;
} else {
return Err(ResolveErrorKind::CannotPerformUnaryOperationForType {
operator: unary_operation.operator.to_string(),
bad_type: resolved_expr.resolved_type.to_string(),
}
.at(source));
}
} else if operator.is_address_of() {
result_type = TypeKind::Pointer(Box::new(result_type)).at(source);
}

let expr = Expr::new(
ExprKind::UnaryOperation(Box::new(UnaryOperation {
operator: unary_operation.operator.clone(),
inner: resolved_expr,
})),
source,
);

return Ok(TypedExpr::new(result_type, expr));
}

let resolved_expr = match &resolved_expr.resolved_type.kind {
TypeKind::Boolean => resolved_expr,
TypeKind::Integer(..) => resolved_expr,
Expand Down
1 change: 1 addition & 0 deletions src/resolve/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ pub fn resolve_stmt(
resolved::DestinationKind::GlobalVariable(..) => (),
resolved::DestinationKind::Member { .. } => (),
resolved::DestinationKind::ArrayAccess { .. } => (),
resolved::DestinationKind::Dereference { .. } => (),
}

let operator = assignment
Expand Down
5 changes: 5 additions & 0 deletions src/resolved/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ impl TypeKind {
Self::Integer(..) | Self::IntegerLiteral(..) | Self::CInteger(..)
)
}

pub fn is_ambiguous_type(&self) -> bool {
self.is_integer_literal()
}
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -543,6 +547,7 @@ pub enum DestinationKind {
field_type: Type,
},
ArrayAccess(Box<ArrayAccess>),
Dereference(Expr),
}

#[derive(Copy, Clone, Debug)]
Expand Down

0 comments on commit f5bdd3f

Please sign in to comment.