Skip to content

Commit

Permalink
Started implementing address-of and dereference operators
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Sep 13, 2024
1 parent 4b8fe61 commit f72c90b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 13 deletions.
4 changes: 4 additions & 0 deletions src/ast/expr/unary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub enum UnaryOperator {
BitComplement,
Negate,
IsNonZero,
AddressOf,
Dereference,
}

impl Display for UnaryOperator {
Expand All @@ -22,6 +24,8 @@ impl Display for UnaryOperator {
Self::BitComplement => "~",
Self::Negate => "-",
Self::IsNonZero => "bool()",
Self::AddressOf => "(address of) &",
Self::Dereference => "(dereference) *",
})
}
}
10 changes: 10 additions & 0 deletions src/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,11 +736,21 @@ fn lower_expr(
resolved_ast,
)?;

let inner_type = lower_type(
ir_module.target,
&unary_operation.inner.resolved_type,
resolved_ast,
)?;

Ok(builder.push(match unary_operation.operator {
resolved::UnaryOperator::Not => ir::Instruction::IsZero(inner),
resolved::UnaryOperator::BitComplement => ir::Instruction::BitComplement(inner),
resolved::UnaryOperator::Negate => ir::Instruction::Negate(inner),
resolved::UnaryOperator::IsNonZero => ir::Instruction::IsNonZero(inner),
resolved::UnaryOperator::AddressOf => {
unimplemented!("address of operator");
}
resolved::UnaryOperator::Dereference => ir::Instruction::Load((inner, inner_type)),
}))
}
ExprKind::Conditional(conditional) => {
Expand Down
10 changes: 8 additions & 2 deletions src/parser/parse_expr/primary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,24 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
}
}
}
TokenKind::Not | TokenKind::BitComplement | TokenKind::Subtract => {
TokenKind::Not
| TokenKind::BitComplement
| TokenKind::Subtract
| TokenKind::AddressOf
| TokenKind::Dereference => {
let operator = match kind {
TokenKind::Not => UnaryOperator::Not,
TokenKind::BitComplement => UnaryOperator::BitComplement,
TokenKind::Subtract => UnaryOperator::Negate,
TokenKind::AddressOf => UnaryOperator::AddressOf,
TokenKind::Dereference => UnaryOperator::Dereference,
_ => unreachable!(),
};

// Eat unary operator
self.input.advance();

let inner = self.parse_expr()?;
let inner = self.parse_expr_primary()?;

Ok(Expr::new(
ExprKind::UnaryOperation(Box::new(UnaryOperation { operator, inner })),
Expand Down
26 changes: 15 additions & 11 deletions src/parser/parse_stmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,23 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
return self.parse_declaration();
}

let lhs = self.parse_expr()?;
()
}
TokenKind::ReturnKeyword => return self.parse_return(),
TokenKind::EndOfFile => return Err(self.unexpected_token_is_next()),
_ => (),
}

if self.input.peek().is_assignment_like() {
// Assignment-Like Statement
return self.parse_assignment(lhs);
}
let lhs = self.parse_expr_primary()?;

// Plain Expression Statement
Ok(StmtKind::Expr(lhs).at(source))
}
TokenKind::ReturnKeyword => self.parse_return(),
TokenKind::EndOfFile => Err(self.unexpected_token_is_next()),
_ => Ok(Stmt::new(StmtKind::Expr(self.parse_expr()?), source)),
if self.input.peek().is_assignment_like() {
// Assignment-Like Statement
return self.parse_assignment(lhs);
}

let lhs = self.parse_operator_expr(0, lhs)?;

// Plain Expression Statement
Ok(StmtKind::Expr(lhs).at(source))
}
}
4 changes: 4 additions & 0 deletions src/resolve/expr/unary_operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub fn resolve_unary_operation_expr(
let result_type = match unary_operation.operator {
UnaryOperator::Not | UnaryOperator::IsNonZero => TypeKind::Boolean.at(source),
UnaryOperator::BitComplement | UnaryOperator::Negate => resolved_expr.resolved_type.clone(),
UnaryOperator::AddressOf => {
TypeKind::Pointer(Box::new(resolved_expr.resolved_type.clone())).at(source)
}
UnaryOperator::Dereference => resolved_expr.resolved_type.clone(),
};

let expr = Expr::new(
Expand Down

0 comments on commit f72c90b

Please sign in to comment.