feat: add support for *T pointers
This commit is contained in:
+62
-18
@@ -139,6 +139,7 @@ impl FuncBuilder {
|
||||
ty,
|
||||
mutable: false,
|
||||
name: Some(name.clone()),
|
||||
address_taken: false,
|
||||
});
|
||||
self.scopes.last_mut().unwrap().insert(name, id);
|
||||
id
|
||||
@@ -152,6 +153,7 @@ impl FuncBuilder {
|
||||
ty,
|
||||
mutable: false,
|
||||
name: None,
|
||||
address_taken: false,
|
||||
});
|
||||
id
|
||||
}
|
||||
@@ -364,15 +366,43 @@ impl FuncBuilder {
|
||||
}
|
||||
TypedExprKind::Boolean { value } => Operand::Constant(ConstantValue::Boolean(*value)),
|
||||
TypedExprKind::Unary { op, expr: inner } => {
|
||||
let inner_op = self.lower_expr(inner);
|
||||
let temp = self.new_temp(expr.ty.clone());
|
||||
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(temp, Rvalue::UnaryOp(*op, inner_op)),
|
||||
span: expr.span,
|
||||
});
|
||||
|
||||
Operand::Copy(temp)
|
||||
match op {
|
||||
UnaryOp::AddressOf => match &inner.kind {
|
||||
TypedExprKind::Identifier { name } => {
|
||||
let id = self.lookup(name);
|
||||
self.locals[id.0].address_taken = true;
|
||||
let temp = self.new_temp(expr.ty.clone());
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(temp, Rvalue::AddressOf(id)),
|
||||
span: expr.span,
|
||||
});
|
||||
Operand::Copy(temp)
|
||||
}
|
||||
TypedExprKind::Unary {
|
||||
op: UnaryOp::Deref,
|
||||
expr: ptr_expr,
|
||||
} => self.lower_expr(ptr_expr), // `&*ptr` is optimized right back to `ptr`!
|
||||
_ => unreachable!("invalid lvalue for addressof"),
|
||||
},
|
||||
UnaryOp::Deref => {
|
||||
let inner_op = self.lower_expr(inner);
|
||||
let temp = self.new_temp(expr.ty.clone());
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(temp, Rvalue::ReadPointer(inner_op)),
|
||||
span: expr.span,
|
||||
});
|
||||
Operand::Copy(temp)
|
||||
}
|
||||
_ => {
|
||||
let inner_op = self.lower_expr(inner);
|
||||
let temp = self.new_temp(expr.ty.clone());
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(temp, Rvalue::UnaryOp(*op, inner_op)),
|
||||
span: expr.span,
|
||||
});
|
||||
Operand::Copy(temp)
|
||||
}
|
||||
}
|
||||
}
|
||||
TypedExprKind::Binary { op, lhs, rhs } => {
|
||||
let lhs_op = self.lower_expr(lhs);
|
||||
@@ -389,15 +419,29 @@ impl FuncBuilder {
|
||||
TypedExprKind::Assign { lval, rval } => {
|
||||
let rval_op = self.lower_expr(rval);
|
||||
|
||||
let local_id = match &lval.kind {
|
||||
TypedExprKind::Identifier { name } => self.lookup(name),
|
||||
_ => panic!("invalid lval in MIR lowering"),
|
||||
};
|
||||
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(local_id, Rvalue::Use(rval_op.clone())),
|
||||
span: expr.span,
|
||||
});
|
||||
match &lval.kind {
|
||||
TypedExprKind::Identifier { name } => {
|
||||
let local_id = self.lookup(name);
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Assign(local_id, Rvalue::Use(rval_op.clone())),
|
||||
span: expr.span,
|
||||
});
|
||||
}
|
||||
TypedExprKind::Unary {
|
||||
op: UnaryOp::Deref,
|
||||
expr: ptr_expr,
|
||||
} => {
|
||||
let ptr_op = self.lower_expr(ptr_expr);
|
||||
self.emit_stmt(Statement {
|
||||
kind: StatementKind::Store {
|
||||
ptr: ptr_op,
|
||||
val: Rvalue::Use(rval_op.clone()),
|
||||
},
|
||||
span: expr.span,
|
||||
});
|
||||
}
|
||||
_ => unreachable!("invalid lval in MIR lowering"),
|
||||
}
|
||||
|
||||
rval_op
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user