From 9fe8d6bbff0c9a2f9d8989635a9758bf9b2ed566 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Mon, 16 Dec 2024 14:38:41 +0100 Subject: [PATCH] support integer to float coersion in more places Signed-off-by: Jakub Doka --- lang/src/son.rs | 50 +++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lang/src/son.rs b/lang/src/son.rs index 5e7712d55..351dab457 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -2985,17 +2985,9 @@ impl<'a> Codegen<'a> { } } Expr::Bool { value, .. } => Some(self.ci.nodes.new_const_lit(ty::Id::BOOL, value)), - Expr::Number { 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::Number { value, .. } => self.gen_inferred_const(ctx, ty::Id::DINT, 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) => { Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, bt)) @@ -3038,7 +3030,7 @@ impl<'a> Codegen<'a> { data.clear(); 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 { if data.last() != Some(&0) { 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], .. } => { 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], .. } => { let ty = self.ty(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], .. } => { 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 } => { let mut val = self.raw_expr(val)?; @@ -4547,17 +4539,27 @@ impl<'a> Codegen<'a> { ctx: Ctx, fallback: ty::Id, value: impl Into, - filter: impl Fn(ty::Id) -> bool, ) -> Option { - Some( - self.ci.nodes.new_const_lit( - ctx.ty - .map(|ty| self.tys.inner_of(ty).unwrap_or(ty)) - .filter(|&ty| filter(ty)) - .unwrap_or(fallback), - value, - ), - ) + self.gen_inferred_const_low(ctx, fallback, value, false) + } + + fn gen_inferred_const_low( + &mut self, + ctx: Ctx, + fallback: ty::Id, + value: impl Into, + is_float: bool, + ) -> Option { + let ty = ctx + .ty + .map(|ty| self.tys.inner_of(ty).unwrap_or(ty)) + .filter(|&ty| (ty.is_integer() && !is_float) || ty.is_float()) + .unwrap_or(fallback); + 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 {