From 9b38907cd5e0dbcfd1708788a724a5377965280b Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 31 Mar 2026 23:09:02 +0200 Subject: [PATCH] Add float division and integer/float coercion This commit introduces support for floating-point division, including cases where an integer is divided by a float or vice versa. This allows for more flexible arithmetic operations within the DSL. Additionally, the `Value::Float` display implementation is adjusted to show `.0` for whole numbers, improving readability and consistency in output. --- src/ast/rtl/core.rs | 32 ++++++++++++++++++++++++++++++++ src/ast/types.rs | 8 +++++++- tests/rtl.rs | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/ast/rtl/core.rs b/src/ast/rtl/core.rs index 2760e18..c666ea4 100644 --- a/src/ast/rtl/core.rs +++ b/src/ast/rtl/core.rs @@ -35,6 +35,14 @@ fn register_arithmetic(env: &Environment) { params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]), ret: StaticType::Float, }, + Signature { + params: StaticType::Tuple(vec![StaticType::Int, StaticType::Float]), + ret: StaticType::Float, + }, + Signature { + params: StaticType::Tuple(vec![StaticType::Float, StaticType::Int]), + ret: StaticType::Float, + }, Signature { params: StaticType::Tuple(vec![StaticType::Text, StaticType::Text]), ret: StaticType::Text, @@ -94,6 +102,14 @@ fn register_arithmetic(env: &Environment) { params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]), ret: StaticType::Float, }, + Signature { + params: StaticType::Tuple(vec![StaticType::Int, StaticType::Float]), + ret: StaticType::Float, + }, + Signature { + params: StaticType::Tuple(vec![StaticType::Float, StaticType::Int]), + ret: StaticType::Float, + }, Signature { params: StaticType::Tuple(vec![StaticType::Int]), ret: StaticType::Int, @@ -169,6 +185,14 @@ fn register_arithmetic(env: &Environment) { params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]), ret: StaticType::Float, }, + Signature { + params: StaticType::Tuple(vec![StaticType::Int, StaticType::Float]), + ret: StaticType::Float, + }, + Signature { + params: StaticType::Tuple(vec![StaticType::Float, StaticType::Int]), + ret: StaticType::Float, + }, // Variadic: any number of numeric args Signature { params: StaticType::Variadic(Box::new(StaticType::Float)), @@ -212,6 +236,14 @@ fn register_arithmetic(env: &Environment) { params: StaticType::Tuple(vec![StaticType::Float, StaticType::Float]), ret: StaticType::Float, }, + Signature { + params: StaticType::Tuple(vec![StaticType::Int, StaticType::Float]), + ret: StaticType::Float, + }, + Signature { + params: StaticType::Tuple(vec![StaticType::Float, StaticType::Int]), + ret: StaticType::Float, + }, ]); env.register_native_fn("/", div_ty, Purity::Pure, |args| { if args.len() != 2 { diff --git a/src/ast/types.rs b/src/ast/types.rs index 1ae4307..fa4f2c2 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -784,7 +784,13 @@ impl fmt::Display for Value { Value::Void => write!(f, "void"), Value::Bool(b) => write!(f, "{}", b), Value::Int(i) => write!(f, "{}", i), - Value::Float(fl) => write!(f, "{}", fl), + Value::Float(fl) => { + if fl.fract() == 0.0 { + write!(f, "{:.1}", fl) + } else { + write!(f, "{}", fl) + } + } Value::DateTime(ts) => match Utc.timestamp_millis_opt(*ts) { chrono::LocalResult::Single(dt) => { write!(f, "#{}#", dt.format("%Y-%m-%d %H:%M:%S")) diff --git a/tests/rtl.rs b/tests/rtl.rs index 9710b19..5b646e9 100644 --- a/tests/rtl.rs +++ b/tests/rtl.rs @@ -9,7 +9,7 @@ fn test_rtl_operators() { assert_eq!(format!("{}", env.run_script("(+ 10 20)").unwrap()), "30"); assert_eq!(format!("{}", env.run_script("(- 20 10)").unwrap()), "10"); assert_eq!(format!("{}", env.run_script("(* 10 20)").unwrap()), "200"); - assert_eq!(format!("{}", env.run_script("(/ 20 10)").unwrap()), "2"); + assert_eq!(format!("{}", env.run_script("(/ 20 10)").unwrap()), "2.0"); assert_eq!(format!("{}", env.run_script("(// 20 3)").unwrap()), "6"); assert_eq!(format!("{}", env.run_script("(% 20 3)").unwrap()), "2");