reducing repeating patters
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
e65c72e19f
commit
127fdb3cc5
|
@ -3071,11 +3071,10 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
Expr::Return { pos, val } => {
|
||||
let mut value = if let Some(val) = val {
|
||||
self.raw_expr_ctx(val, Ctx { ty: self.ci.ret })?
|
||||
self.ptr_expr_ctx(val, Ctx { ty: self.ci.ret })?
|
||||
} else {
|
||||
Value { ty: ty::Id::VOID, ..Default::default() }
|
||||
};
|
||||
self.strip_var(&mut value);
|
||||
|
||||
let expected = *self.ci.ret.get_or_insert(value.ty);
|
||||
self.assert_ty(pos, &mut value, expected, "return value");
|
||||
|
@ -3190,8 +3189,7 @@ impl<'a> Codegen<'a> {
|
|||
Expr::UnOp { op: TokenKind::Band, val, pos } => {
|
||||
let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) };
|
||||
|
||||
let mut val = self.raw_expr_ctx(val, ctx)?;
|
||||
self.strip_var(&mut val);
|
||||
let mut val = self.ptr_expr_ctx(val, ctx)?;
|
||||
|
||||
if val.ptr {
|
||||
val.ptr = false;
|
||||
|
@ -3316,8 +3314,7 @@ impl<'a> Codegen<'a> {
|
|||
right: Expr::Null { .. },
|
||||
..
|
||||
} => {
|
||||
let mut cmped = self.raw_expr(left)?;
|
||||
self.strip_var(&mut cmped);
|
||||
let cmped = self.ptr_expr(left)?;
|
||||
|
||||
let Some(ty) = self.tys.inner_of(cmped.ty) else {
|
||||
return self.error(
|
||||
|
@ -3331,8 +3328,7 @@ impl<'a> Codegen<'a> {
|
|||
Expr::BinOp { left, pos, op, right }
|
||||
if !matches!(op, TokenKind::Assign | TokenKind::Decl) =>
|
||||
{
|
||||
let mut lhs = self.raw_expr_ctx(left, ctx)?;
|
||||
self.strip_var(&mut lhs);
|
||||
let mut lhs = self.ptr_expr_ctx(left, ctx)?;
|
||||
self.implicit_unwrap(left.pos(), &mut lhs);
|
||||
|
||||
match lhs.ty.expand() {
|
||||
|
@ -3348,7 +3344,6 @@ impl<'a> Codegen<'a> {
|
|||
let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty));
|
||||
self.ci.nodes.unlock(lhs.id);
|
||||
let mut rhs = rhs?;
|
||||
self.strip_var(&mut rhs);
|
||||
self.implicit_unwrap(right.pos(), &mut rhs);
|
||||
let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
||||
if op.is_compatison() {
|
||||
|
@ -3378,10 +3373,9 @@ impl<'a> Codegen<'a> {
|
|||
ty::Kind::Struct(s) if op.is_homogenous() => {
|
||||
debug_assert!(lhs.ptr);
|
||||
self.ci.nodes.lock(lhs.id);
|
||||
let rhs = self.raw_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
|
||||
let rhs = self.ptr_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
|
||||
self.ci.nodes.unlock(lhs.id);
|
||||
let mut rhs = rhs?;
|
||||
self.strip_var(&mut rhs);
|
||||
debug_assert!(rhs.ptr);
|
||||
self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand");
|
||||
let dst = self.new_stack(pos, lhs.ty);
|
||||
|
@ -3395,10 +3389,9 @@ impl<'a> Codegen<'a> {
|
|||
};
|
||||
|
||||
self.ci.nodes.lock(lhs.id);
|
||||
let rhs = self.raw_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
|
||||
let rhs = self.ptr_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
|
||||
self.ci.nodes.unlock(lhs.id);
|
||||
let mut rhs = rhs?;
|
||||
self.strip_var(&mut rhs);
|
||||
self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand");
|
||||
|
||||
self.struct_fold_op(left.pos(), op, binding_op, s, lhs.id, rhs.id)
|
||||
|
@ -3409,8 +3402,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
Expr::Index { base, index } => {
|
||||
let mut bs = self.raw_expr(base)?;
|
||||
self.strip_var(&mut bs);
|
||||
let mut bs = self.ptr_expr(base)?;
|
||||
|
||||
if let Some(base) = self.tys.base_of(bs.ty) {
|
||||
bs.ptr = true;
|
||||
|
@ -3508,8 +3500,7 @@ impl<'a> Codegen<'a> {
|
|||
self.gen_inferred_const(ctx, ty::Id::DINT, len)
|
||||
}
|
||||
Expr::Directive { name: "bitcast", args: [val], pos } => {
|
||||
let mut val = self.raw_expr(val)?;
|
||||
self.strip_var(&mut val);
|
||||
let mut val = self.ptr_expr(val)?;
|
||||
|
||||
inference!(ty, ctx, self, pos, "type", "@as(<ty>, @bitcast(<expr>))");
|
||||
|
||||
|
@ -3541,8 +3532,7 @@ impl<'a> Codegen<'a> {
|
|||
Some(val)
|
||||
}
|
||||
Expr::Directive { name: "unwrap", args: [expr], .. } => {
|
||||
let mut val = self.raw_expr(expr)?;
|
||||
self.strip_var(&mut val);
|
||||
let mut val = self.ptr_expr(expr)?;
|
||||
|
||||
if !val.ty.is_optional() {
|
||||
return self.error(
|
||||
|
@ -3661,7 +3651,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
Expr::Directive { name: "as", args: [ty, expr], pos } => {
|
||||
let ty = self.ty(ty);
|
||||
let mut val = self.raw_expr_ctx(expr, Ctx::default().with_ty(ty))?;
|
||||
let mut val = self.ptr_expr_ctx(expr, Ctx::default().with_ty(ty))?;
|
||||
|
||||
if let Some(ity) = ctx.ty
|
||||
&& ity.try_upcast(ty) == Some(ty)
|
||||
|
@ -3669,7 +3659,6 @@ impl<'a> Codegen<'a> {
|
|||
{
|
||||
self.error(pos, "the type is known at this point, remove the hint");
|
||||
}
|
||||
self.strip_var(&mut val);
|
||||
self.assert_ty(expr.pos(), &mut val, ty, "hinted expr");
|
||||
Some(val)
|
||||
}
|
||||
|
@ -4381,8 +4370,7 @@ impl<'a> Codegen<'a> {
|
|||
expected_ty: ty::Id,
|
||||
hint: impl Display,
|
||||
) -> Option<Value> {
|
||||
let mut value = self.raw_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?;
|
||||
self.strip_var(&mut value);
|
||||
let mut value = self.ptr_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?;
|
||||
self.assert_ty(expr.pos(), &mut value, expected_ty, hint);
|
||||
self.strip_ptr(&mut value);
|
||||
Some(value)
|
||||
|
@ -4395,8 +4383,7 @@ impl<'a> Codegen<'a> {
|
|||
pos: Pos,
|
||||
name: &str,
|
||||
) -> Option<Result<Value, (ty::Id, Value)>> {
|
||||
let mut vtarget = self.raw_expr(target)?;
|
||||
self.strip_var(&mut vtarget);
|
||||
let mut vtarget = self.ptr_expr(target)?;
|
||||
self.implicit_unwrap(pos, &mut vtarget);
|
||||
let tty = vtarget.ty;
|
||||
|
||||
|
@ -4658,8 +4645,7 @@ impl<'a> Codegen<'a> {
|
|||
&mut self.ci.nodes,
|
||||
),
|
||||
Arg::Value(ty) => {
|
||||
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||
self.strip_var(&mut value);
|
||||
let mut value = self.ptr_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||
debug_assert_ne!(value.id, 0);
|
||||
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
||||
|
@ -4761,11 +4747,8 @@ impl<'a> Codegen<'a> {
|
|||
let carg = cargs.next().unwrap();
|
||||
let Arg::Value(ty) = ty else { continue };
|
||||
|
||||
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||
self.strip_var(&mut value);
|
||||
let value = self.checked_expr(arg, ty, fa!("argument {}", carg.name))?;
|
||||
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
||||
self.strip_ptr(&mut value);
|
||||
self.add_clobbers(value, &mut clobbered_aliases);
|
||||
|
||||
self.ci.nodes.lock(value.id);
|
||||
|
@ -4814,13 +4797,12 @@ impl<'a> Codegen<'a> {
|
|||
let f = &self.files[c.file];
|
||||
let Expr::BinOp { left, right, .. } = c.ast.get(f) else { unreachable!() };
|
||||
|
||||
let mut value = left
|
||||
let value = left
|
||||
.find_pattern_path(c.name, right, |expr, is_ct| {
|
||||
debug_assert!(is_ct);
|
||||
self.raw_expr_ctx(expr, ctx)
|
||||
self.ptr_expr_ctx(expr, ctx)
|
||||
})
|
||||
.unwrap_or_else(|_| unreachable!())?;
|
||||
self.strip_var(&mut value);
|
||||
self.ci.file = prev_file;
|
||||
self.ci.parent = prev_parent;
|
||||
Some(value)
|
||||
|
@ -5079,13 +5061,26 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
|
||||
fn ptr_expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
|
||||
let mut n = self.raw_expr_ctx(expr, ctx)?;
|
||||
self.strip_var(&mut n);
|
||||
if mem::take(&mut n.var) {
|
||||
let id = (u16::MAX - n.id) as usize;
|
||||
n.ptr = self.ci.scope.vars[id].ptr;
|
||||
n.id = self.ci.scope.vars[id].value();
|
||||
}
|
||||
Some(n)
|
||||
}
|
||||
|
||||
fn expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
|
||||
let mut n = self.ptr_expr_ctx(expr, ctx)?;
|
||||
self.strip_ptr(&mut n);
|
||||
Some(n)
|
||||
}
|
||||
|
||||
fn ptr_expr(&mut self, expr: &Expr) -> Option<Value> {
|
||||
self.ptr_expr_ctx(expr, Default::default())
|
||||
}
|
||||
|
||||
fn expr(&mut self, expr: &Expr) -> Option<Value> {
|
||||
self.expr_ctx(expr, Default::default())
|
||||
}
|
||||
|
@ -5110,14 +5105,6 @@ impl<'a> Codegen<'a> {
|
|||
seted
|
||||
}
|
||||
|
||||
fn strip_var(&mut self, n: &mut Value) {
|
||||
if mem::take(&mut n.var) {
|
||||
let id = (u16::MAX - n.id) as usize;
|
||||
n.ptr = self.ci.scope.vars[id].ptr;
|
||||
n.id = self.ci.scope.vars[id].value();
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_defers(&mut self, base: usize) -> Option<()> {
|
||||
let defers = mem::take(&mut self.ci.defers);
|
||||
for &(_, defer) in defers.iter().skip(base).rev() {
|
||||
|
@ -5444,7 +5431,6 @@ impl<'a> Codegen<'a> {
|
|||
fn wrap_in_opt(&mut self, pos: Pos, val: &mut Value) {
|
||||
debug_assert!(!val.var);
|
||||
|
||||
let was_ptr = val.ptr;
|
||||
let oty = self.tys.make_opt(val.ty);
|
||||
|
||||
if let Some((uninit, ..)) = self.tys.nieche_of(val.ty) {
|
||||
|
@ -5456,9 +5442,9 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
let OptLayout { flag_ty, flag_offset, payload_offset } = self.tys.opt_layout(val.ty);
|
||||
|
||||
self.strip_ptr(val);
|
||||
match oty.loc(self.tys) {
|
||||
Loc::Reg => {
|
||||
self.strip_ptr(val);
|
||||
// registers have inverted offsets so that accessing the inner type is a noop
|
||||
let flag_offset = self.tys.size_of(oty) * 8 - flag_offset * 8 - 1;
|
||||
let fill = self.ci.nodes.new_const(oty, 1i64 << flag_offset);
|
||||
|
@ -5471,7 +5457,6 @@ impl<'a> Codegen<'a> {
|
|||
val.ty = oty;
|
||||
}
|
||||
Loc::Stack => {
|
||||
self.strip_ptr(val);
|
||||
let stack = self.new_stack(pos, oty);
|
||||
let fill = self.ci.nodes.new_const(flag_ty, 1);
|
||||
self.store_mem(stack, flag_ty, fill);
|
||||
|
@ -5482,10 +5467,6 @@ impl<'a> Codegen<'a> {
|
|||
val.ty = oty;
|
||||
}
|
||||
}
|
||||
|
||||
if !was_ptr {
|
||||
self.strip_ptr(val);
|
||||
}
|
||||
}
|
||||
|
||||
fn implicit_unwrap(&mut self, pos: Pos, opt: &mut Value) {
|
||||
|
|
Loading…
Reference in a new issue