From 664b1754d05eded21bdd92e12038b819617791bd Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Fri, 17 May 2024 22:56:17 +1000 Subject: [PATCH] Print special float values as Num.nanF64, etc --- crates/repl_eval/src/eval.rs | 64 ++++++++++++++++++++++++++++++----- crates/repl_test/src/tests.rs | 9 +++-- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/crates/repl_eval/src/eval.rs b/crates/repl_eval/src/eval.rs index 79964cc538..b51f1a0918 100644 --- a/crates/repl_eval/src/eval.rs +++ b/crates/repl_eval/src/eval.rs @@ -367,6 +367,22 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( }; } + macro_rules! f64_helper { + ($ty:ty) => { + app.call_function(main_fn_name, |_, num: $ty| { + f64_literal_to_ast(env.arena, num) + }) + }; + } + + macro_rules! f32_helper { + ($ty:ty) => { + app.call_function(main_fn_name, |_, num: $ty| { + f32_literal_to_ast(env.arena, num) + }) + }; + } + let expr = match env.layout_cache.get_repr(layout) { LayoutRepr::Builtin(Builtin::Bool) => { app.call_function(main_fn_name, |_mem: &A::Memory, num: bool| { @@ -404,8 +420,8 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( use FloatWidth::*; match float_width { - F32 => num_helper!(f32), - F64 => num_helper!(f64), + F32 => f32_helper!(f32), + F64 => f64_helper!(f64), } } LayoutRepr::Builtin(Builtin::Decimal) => num_helper!(RocDec), @@ -1481,17 +1497,47 @@ fn byte_to_ast<'a>(env: &mut Env<'a, '_>, value: u8, content: &Content) -> Expr< /// This is centralized in case we want to format it differently later, /// e.g. adding underscores for large numbers +fn f64_literal_to_ast(arena: &Bump, num: f64) -> Expr<'_> { + use std::fmt::Write; + + if num.is_nan() { + Expr::Num("Num.nanF64") + } else if num.is_infinite() { + if num.is_sign_positive() { + Expr::Num("Num.infinityF64") + } else { + Expr::Num("-Num.infinityF64") + } + } else { + let mut string = bumpalo::collections::String::with_capacity_in(64, arena); + write!(string, "{num}").unwrap(); + Expr::Num(string.into_bump_str()) + } +} + +fn f32_literal_to_ast(arena: &Bump, num: f32) -> Expr<'_> { + use std::fmt::Write; + + if num.is_nan() { + Expr::Num("Num.nanF32") + } else if num.is_infinite() { + if num.is_sign_positive() { + Expr::Num("Num.infinityF32") + } else { + Expr::Num("-Num.infinityF32") + } + } else { + let mut string = bumpalo::collections::String::with_capacity_in(64, arena); + write!(string, "{num}").unwrap(); + Expr::Num(string.into_bump_str()) + } +} + fn number_literal_to_ast(arena: &Bump, num: T) -> Expr<'_> { use std::fmt::Write; let mut string = bumpalo::collections::String::with_capacity_in(64, arena); write!(string, "{num}").unwrap(); - if string == "inf" { - Expr::Num("∞") - } else if string == "-inf" { - Expr::Num("-∞") - } else { - Expr::Num(string.into_bump_str()) - } + Expr::Num(string.into_bump_str()) } diff --git a/crates/repl_test/src/tests.rs b/crates/repl_test/src/tests.rs index 7099e22f19..5aae4e2e1d 100644 --- a/crates/repl_test/src/tests.rs +++ b/crates/repl_test/src/tests.rs @@ -102,8 +102,13 @@ fn num_ceil_checked_division_success() { #[test] fn float_division_by_zero() { - expect_success("1f64 / 0", "∞ : F64"); - expect_success("-1f64 / 0", "-∞ : F64"); + expect_success("1f64 / 0", "Num.infinityF64 : F64"); + expect_success("-1f64 / 0", "-Num.infinityF64 : F64"); + expect_success("0f64 / 0", "Num.nanF64 : F64"); + + expect_success("1f32 / 0", "Num.infinityF32 : F32"); + expect_success("-1f32 / 0", "-Num.infinityF32 : F32"); + expect_success("0f32 / 0", "Num.nanF32 : F32"); } #[test]