support integer to float coersion in more places

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-16 14:38:41 +01:00
parent 04680c8b7c
commit 9fe8d6bbff
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143

View file

@ -2985,17 +2985,9 @@ impl<'a> Codegen<'a> {
} }
} }
Expr::Bool { value, .. } => Some(self.ci.nodes.new_const_lit(ty::Id::BOOL, value)), Expr::Bool { value, .. } => Some(self.ci.nodes.new_const_lit(ty::Id::BOOL, value)),
Expr::Number { value, .. } Expr::Number { value, .. } => self.gen_inferred_const(ctx, ty::Id::DINT, value),
if let Some(ty) = ctx.ty
&& ty.is_float() =>
{
Some(self.ci.nodes.new_const_lit(ty, (value as f64).to_bits() as i64))
}
Expr::Number { value, .. } => {
self.gen_inferred_const(ctx, ty::Id::DINT, value, ty::Id::is_integer)
}
Expr::Float { value, .. } => { Expr::Float { value, .. } => {
self.gen_inferred_const(ctx, ty::Id::F32, value as i64, ty::Id::is_float) self.gen_inferred_const_low(ctx, ty::Id::F32, value as i64, true)
} }
Expr::Ident { id, .. } if let Ok(bt) = ty::Builtin::try_from(id) => { Expr::Ident { id, .. } if let Ok(bt) = ty::Builtin::try_from(id) => {
Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, bt)) Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, bt))
@ -3038,7 +3030,7 @@ impl<'a> Codegen<'a> {
data.clear(); data.clear();
self.pool.lit_buf = data; self.pool.lit_buf = data;
self.gen_inferred_const(ctx, ty::Id::U8, value, ty::Id::is_integer) self.gen_inferred_const(ctx, ty::Id::U8, value)
} else { } else {
if data.last() != Some(&0) { if data.last() != Some(&0) {
self.error(pos, "string literal must end with null byte (for now)"); self.error(pos, "string literal must end with null byte (for now)");
@ -3489,12 +3481,12 @@ impl<'a> Codegen<'a> {
} }
Expr::Directive { name: "sizeof", args: [ty], .. } => { Expr::Directive { name: "sizeof", args: [ty], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
self.gen_inferred_const(ctx, ty::Id::DINT, self.tys.size_of(ty), ty::Id::is_integer) self.gen_inferred_const(ctx, ty::Id::DINT, self.tys.size_of(ty))
} }
Expr::Directive { name: "alignof", args: [ty], .. } => { Expr::Directive { name: "alignof", args: [ty], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
let align = self.tys.align_of(ty); let align = self.tys.align_of(ty);
self.gen_inferred_const(ctx, ty::Id::DINT, align, ty::Id::is_integer) self.gen_inferred_const(ctx, ty::Id::DINT, align)
} }
Expr::Directive { name: "len", args: [ety], .. } => { Expr::Directive { name: "len", args: [ety], .. } => {
let ty = self.ty(ety); let ty = self.ty(ety);
@ -3508,7 +3500,7 @@ impl<'a> Codegen<'a> {
), ),
); );
}; };
self.gen_inferred_const(ctx, ty::Id::DINT, len, ty::Id::is_integer) 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.raw_expr(val)?;
@ -4547,17 +4539,27 @@ impl<'a> Codegen<'a> {
ctx: Ctx, ctx: Ctx,
fallback: ty::Id, fallback: ty::Id,
value: impl Into<i64>, value: impl Into<i64>,
filter: impl Fn(ty::Id) -> bool,
) -> Option<Value> { ) -> Option<Value> {
Some( self.gen_inferred_const_low(ctx, fallback, value, false)
self.ci.nodes.new_const_lit( }
ctx.ty
fn gen_inferred_const_low(
&mut self,
ctx: Ctx,
fallback: ty::Id,
value: impl Into<i64>,
is_float: bool,
) -> Option<Value> {
let ty = ctx
.ty
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty)) .map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
.filter(|&ty| filter(ty)) .filter(|&ty| (ty.is_integer() && !is_float) || ty.is_float())
.unwrap_or(fallback), .unwrap_or(fallback);
value, let value = value.into();
), Some(self.ci.nodes.new_const_lit(
) ty,
if ty.is_float() && !is_float { (value as f64).to_bits() as i64 } else { value },
))
} }
fn gen_call(&mut self, func: &Expr, args: &[Expr], mut inline: bool) -> Option<Value> { fn gen_call(&mut self, func: &Expr, args: &[Expr], mut inline: bool) -> Option<Value> {