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