From 99a6bfb9e9b8478360edba9e96cf3546343ce515 Mon Sep 17 00:00:00 2001 From: IsaacShelton Date: Sat, 19 Oct 2024 23:26:55 -0500 Subject: [PATCH] Added support for type-casting floating types to non-fixed-sized integers and added ability to cast from all integer types to floating point types --- src/lower/mod.rs | 11 ++++-- src/resolve/expr/call.rs | 74 ++++++++++++++++++++++++++++++++++++++-- src/resolved/mod.rs | 2 +- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/lower/mod.rs b/src/lower/mod.rs index c77a168..6b7fe3a 100644 --- a/src/lower/mod.rs +++ b/src/lower/mod.rs @@ -731,10 +731,17 @@ fn lower_expr( Ok(builder.push(ir::Instruction::FloatToInteger(value, ir_type, sign))) } - ExprKind::IntegerToFloat(cast, from_sign) => { + ExprKind::IntegerToFloat(cast_from) => { + let cast = &cast_from.cast; + let from_sign = cast_from + .from_type + .kind + .sign(Some(ir_module.target)) + .expect("integer to float must know sign"); + let value = lower_expr(builder, ir_module, &cast.value, function, resolved_ast)?; let ir_type = lower_type(&ir_module.target, &cast.target_type, resolved_ast)?; - Ok(builder.push(ir::Instruction::IntegerToFloat(value, ir_type, *from_sign))) + Ok(builder.push(ir::Instruction::IntegerToFloat(value, ir_type, from_sign))) } ExprKind::Member(member) => { let Member { diff --git a/src/resolve/expr/call.rs b/src/resolve/expr/call.rs index 8636ed5..4c1d9e7 100644 --- a/src/resolve/expr/call.rs +++ b/src/resolve/expr/call.rs @@ -1,12 +1,13 @@ use super::{resolve_expr, PreferredType, ResolveExprCtx}; use crate::{ - ast, + ast::{self, CInteger}, + ir::IntegerSign, resolve::{ conform::{conform_expr, to_default::conform_expr_to_default, ConformMode, Perform}, error::{ResolveError, ResolveErrorKind}, Initialized, }, - resolved::{self, Cast, TypedExpr}, + resolved::{self, Cast, CastFrom, TypedExpr}, source_files::Source, }; use itertools::Itertools; @@ -42,6 +43,47 @@ pub fn resolve_call_expr( "i16" => Some(resolved::TypeKind::i16()), "i32" => Some(resolved::TypeKind::i32()), "i64" => Some(resolved::TypeKind::i64()), + "char" => Some(resolved::TypeKind::CInteger(CInteger::Char, None)), + "schar" => Some(resolved::TypeKind::CInteger( + CInteger::Char, + Some(IntegerSign::Signed), + )), + "uchar" => Some(resolved::TypeKind::CInteger( + CInteger::Char, + Some(IntegerSign::Unsigned), + )), + "short" => Some(resolved::TypeKind::CInteger( + CInteger::Char, + Some(IntegerSign::Signed), + )), + "ushort" => Some(resolved::TypeKind::CInteger( + CInteger::Char, + Some(IntegerSign::Unsigned), + )), + "int" => Some(resolved::TypeKind::CInteger( + CInteger::Int, + Some(IntegerSign::Signed), + )), + "uint" => Some(resolved::TypeKind::CInteger( + CInteger::Int, + Some(IntegerSign::Unsigned), + )), + "long" => Some(resolved::TypeKind::CInteger( + CInteger::Long, + Some(IntegerSign::Signed), + )), + "ulong" => Some(resolved::TypeKind::CInteger( + CInteger::Long, + Some(IntegerSign::Unsigned), + )), + "longlong" => Some(resolved::TypeKind::CInteger( + CInteger::LongLong, + Some(IntegerSign::Signed), + )), + "ulonglong" => Some(resolved::TypeKind::CInteger( + CInteger::LongLong, + Some(IntegerSign::Unsigned), + )), _ => None, }; @@ -63,6 +105,34 @@ pub fn resolve_call_expr( }); } } + + let target_type_kind = match name.as_ref() { + "f32" => Some(resolved::TypeKind::f32()), + "f64" => Some(resolved::TypeKind::f64()), + _ => None, + }; + + if let Some(target_type_kind) = target_type_kind { + if arguments[0].resolved_type.kind.is_integer_like() { + let target_type = target_type_kind.at(source); + let argument = arguments.into_iter().next().unwrap(); + + let expr = resolved::ExprKind::IntegerToFloat(Box::new(CastFrom { + cast: Cast { + target_type: target_type.clone(), + value: argument.expr, + }, + from_type: argument.resolved_type, + })) + .at(source); + + return Ok(TypedExpr { + resolved_type: target_type, + expr, + is_initialized: argument.is_initialized, + }); + } + } } let function_ref = match ctx.function_search_ctx.find_function( diff --git a/src/resolved/mod.rs b/src/resolved/mod.rs index 73a600c..bfe84b9 100644 --- a/src/resolved/mod.rs +++ b/src/resolved/mod.rs @@ -522,7 +522,7 @@ pub enum ExprKind { IntegerTruncate(Box), FloatExtend(Box), FloatToInteger(Box), - IntegerToFloat(Box, IntegerSign), + IntegerToFloat(Box), Member(Box), StructLiteral(Box), UnaryMathOperation(Box),