From fad28beb0582753ec9ff9c24d1caab28128c8e00 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 18 Sep 2024 01:02:09 -0500 Subject: [PATCH] interpreter: Add float machinery - operators - type casting --- compiler/cl-interpret/src/builtin.rs | 1 + compiler/cl-interpret/src/convalue.rs | 14 ++++++++++++-- compiler/cl-interpret/src/interpret.rs | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/cl-interpret/src/builtin.rs b/compiler/cl-interpret/src/builtin.rs index 2ac205b..f14cfbe 100644 --- a/compiler/cl-interpret/src/builtin.rs +++ b/compiler/cl-interpret/src/builtin.rs @@ -223,6 +223,7 @@ builtins! { Ok(match tail { ConValue::Empty => ConValue::Empty, ConValue::Int(v) => ConValue::Int(v.wrapping_neg()), + ConValue::Float(v) => ConValue::Float(-v), _ => Err(Error::TypeError)?, }) } diff --git a/compiler/cl-interpret/src/convalue.rs b/compiler/cl-interpret/src/convalue.rs index 999027c..5b9db2a 100644 --- a/compiler/cl-interpret/src/convalue.rs +++ b/compiler/cl-interpret/src/convalue.rs @@ -20,6 +20,8 @@ pub enum ConValue { Empty, /// An integer Int(Integer), + /// A floating point number + Float(f64), /// A boolean Bool(bool), /// A unicode character @@ -124,6 +126,7 @@ macro cmp ($($fn:ident: $empty:literal, $op:tt);*$(;)?) {$( match (self, other) { (Self::Empty, Self::Empty) => Ok(Self::Bool($empty)), (Self::Int(a), Self::Int(b)) => Ok(Self::Bool(a $op b)), + (Self::Float(a), Self::Float(b)) => Ok(Self::Bool(a $op b)), (Self::Bool(a), Self::Bool(b)) => Ok(Self::Bool(a $op b)), (Self::Char(a), Self::Char(b)) => Ok(Self::Bool(a $op b)), (Self::String(a), Self::String(b)) => Ok(Self::Bool(&**a $op &**b)), @@ -150,6 +153,7 @@ impl From<&Sym> for ConValue { } from! { Integer => ConValue::Int, + f64 => ConValue::Float, bool => ConValue::Bool, char => ConValue::Char, Sym => ConValue::String, @@ -189,7 +193,8 @@ ops! { Add: add = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_add(b)), - (ConValue::String(a), ConValue::String(b)) => (a.to_string() + &b.to_string()).into(), + (ConValue::Float(a), ConValue::Float(b)) => ConValue::Float(a + b), + (ConValue::String(a), ConValue::String(b)) => (a.to_string() + &*b).into(), (ConValue::String(s), ConValue::Char(c)) => { let mut s = s.to_string(); s.push(c); s.into() } (ConValue::Char(a), ConValue::Char(b)) => { ConValue::String([a, b].into_iter().collect::().into()) @@ -219,18 +224,21 @@ ops! { (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.checked_div(b).unwrap_or_else(|| { eprintln!("Warning: Divide by zero in {a} / {b}"); a })), + (ConValue::Float(a), ConValue::Float(b)) => ConValue::Float(a / b), _ => Err(Error::TypeError)? ] Mul: mul = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_mul(b)), + (ConValue::Float(a), ConValue::Float(b)) => ConValue::Float(a * b), _ => Err(Error::TypeError)? ] Rem: rem = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.checked_rem(b).unwrap_or_else(|| { - eprintln!("Warning: Divide by zero in {a} % {b}"); a + println!("Warning: Divide by zero in {a} % {b}"); a })), + (ConValue::Float(a), ConValue::Float(b)) => ConValue::Float(a % b), _ => Err(Error::TypeError)? ] Shl: shl = [ @@ -246,6 +254,7 @@ ops! { Sub: sub = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_sub(b)), + (ConValue::Float(a), ConValue::Float(b)) => ConValue::Float(a - b), _ => Err(Error::TypeError)? ] } @@ -254,6 +263,7 @@ impl std::fmt::Display for ConValue { match self { ConValue::Empty => "Empty".fmt(f), ConValue::Int(v) => v.fmt(f), + ConValue::Float(v) => v.fmt(f), ConValue::Bool(v) => v.fmt(f), ConValue::Char(v) => v.fmt(f), ConValue::String(v) => v.fmt(f), diff --git a/compiler/cl-interpret/src/interpret.rs b/compiler/cl-interpret/src/interpret.rs index 69a1819..6cb3c7d 100644 --- a/compiler/cl-interpret/src/interpret.rs +++ b/compiler/cl-interpret/src/interpret.rs @@ -358,6 +358,9 @@ fn cast(value: ConValue, ty: Sym) -> IResult { ConValue::Bool(b) => b as _, ConValue::Char(c) => c as _, ConValue::Ref(v) => return cast((*v).clone(), ty), + // TODO: This, better + ConValue::Float(_) if ty.starts_with('f') => return Ok(value), + ConValue::Float(f) => f as _, _ => Err(Error::TypeError)?, }; Ok(match &*ty { @@ -369,6 +372,8 @@ fn cast(value: ConValue, ty: Sym) -> IResult { "i32" => ConValue::Int(value as i32 as _), "u64" => ConValue::Int(value), "i64" => ConValue::Int(value), + "f32" => ConValue::Float(value as f32 as _), + "f64" => ConValue::Float(value as f64 as _), "char" => ConValue::Char(char::from_u32(value as _).unwrap_or('\u{fffd}')), "bool" => ConValue::Bool(value < 0), _ => Err(Error::NotDefined(ty))?,