From b446677edaf0e74843edde6741e8962bc1b0a703 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 9 Jul 2024 06:13:55 -0500 Subject: [PATCH] cl-interpret: Enforce wrapping behavior --- compiler/cl-interpret/src/builtin.rs | 4 ++-- compiler/cl-interpret/src/lib.rs | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/compiler/cl-interpret/src/builtin.rs b/compiler/cl-interpret/src/builtin.rs index 702dd40..114142a 100644 --- a/compiler/cl-interpret/src/builtin.rs +++ b/compiler/cl-interpret/src/builtin.rs @@ -1,9 +1,9 @@ //! Implementations of built-in functions use super::{ + convalue::ConValue, env::Environment, error::{Error, IResult}, - convalue::ConValue, BuiltIn, Callable, }; use cl_ast::Sym; @@ -183,7 +183,7 @@ builtins! { pub fn neg(tail) -> IResult { Ok(match tail { ConValue::Empty => ConValue::Empty, - ConValue::Int(v) => ConValue::Int(-v), + ConValue::Int(v) => ConValue::Int(v.wrapping_neg()), _ => Err(Error::TypeError)?, }) } diff --git a/compiler/cl-interpret/src/lib.rs b/compiler/cl-interpret/src/lib.rs index 2e254e4..508b188 100644 --- a/compiler/cl-interpret/src/lib.rs +++ b/compiler/cl-interpret/src/lib.rs @@ -207,7 +207,7 @@ pub mod convalue { ops! { Add: add = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a + b), + (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(), _ => Err(Error::TypeError)? ] @@ -231,32 +231,36 @@ pub mod convalue { ] Div: div = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a / b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.checked_div(b).unwrap_or_else(|| { + eprintln!("Warning: Divide by zero in {a} / {b}"); a + })), _ => Err(Error::TypeError)? ] Mul: mul = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a * b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_mul(b)), _ => Err(Error::TypeError)? ] Rem: rem = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a % b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.checked_rem(b).unwrap_or_else(|| { + eprintln!("Warning: Divide by zero in {a} % {b}"); a + })), _ => Err(Error::TypeError)? ] Shl: shl = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a << b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_shl(b as _)), _ => Err(Error::TypeError)? ] Shr: shr = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a >> b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_shr(b as _)), _ => Err(Error::TypeError)? ] Sub: sub = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, - (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a - b), + (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a.wrapping_sub(b)), _ => Err(Error::TypeError)? ] }