From 1ed451e696ab68b7f284ccf9f216508a9769ad27 Mon Sep 17 00:00:00 2001 From: Roman Godmaire Date: Mon, 6 May 2024 08:28:46 -0400 Subject: [PATCH] fix: support up to 128-bit integers Floats should be next --- src/env/core.rs | 40 ++++++++++++++++++++++++++++++++++++---- src/node.rs | 2 ++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/env/core.rs b/src/env/core.rs index ecc87bc..3ad505b 100644 --- a/src/env/core.rs +++ b/src/env/core.rs @@ -93,7 +93,15 @@ pub(super) fn core() -> HashMap { let res = args .into_iter() .reduce(|lhs, rhs| match (lhs, rhs) { - (Node::Int(lhs), Node::Int(rhs)) => Node::Int(lhs + rhs), + (Node::Int(lhs), Node::Int(rhs)) => match lhs.checked_add(rhs) { + Some(val) => Node::Int(val), + None => Node::Int128(lhs as i128 + rhs as i128), + }, + (Node::Int128(lhs), Node::Int128(rhs)) => Node::Int128(lhs + rhs), + (Node::Int(lhs), Node::Int128(rhs)) => { + Node::Int128(lhs as i128 + rhs as i128) + } + (Node::Int128(lhs), Node::Int(rhs)) => Node::Int128(lhs + rhs as i128), _ => todo!(), }) .unwrap_or(Node::Int(0)); @@ -107,7 +115,15 @@ pub(super) fn core() -> HashMap { let res = args .into_iter() .reduce(|lhs, rhs| match (lhs, rhs) { - (Node::Int(lhs), Node::Int(rhs)) => Node::Int(lhs - rhs), + (Node::Int(lhs), Node::Int(rhs)) => match lhs.checked_sub(rhs) { + Some(val) => Node::Int(val), + None => Node::Int128(lhs as i128 - rhs as i128), + }, + (Node::Int128(lhs), Node::Int128(rhs)) => Node::Int128(lhs - rhs), + (Node::Int(lhs), Node::Int128(rhs)) => { + Node::Int128(lhs as i128 - rhs as i128) + } + (Node::Int128(lhs), Node::Int(rhs)) => Node::Int128(lhs - rhs as i128), _ => todo!(), }) .unwrap_or(Node::Int(0)); @@ -121,7 +137,15 @@ pub(super) fn core() -> HashMap { let res = args .into_iter() .reduce(|lhs, rhs| match (lhs, rhs) { - (Node::Int(lhs), Node::Int(rhs)) => Node::Int(lhs * rhs), + (Node::Int(lhs), Node::Int(rhs)) => match lhs.checked_mul(rhs) { + Some(val) => Node::Int(val), + None => Node::Int128(lhs as i128 * rhs as i128), + }, + (Node::Int128(lhs), Node::Int128(rhs)) => Node::Int128(lhs * rhs), + (Node::Int(lhs), Node::Int128(rhs)) => { + Node::Int128(lhs as i128 * rhs as i128) + } + (Node::Int128(lhs), Node::Int(rhs)) => Node::Int128(lhs * rhs as i128), _ => todo!(), }) .unwrap_or(Node::Int(0)); @@ -135,7 +159,15 @@ pub(super) fn core() -> HashMap { let res = args .into_iter() .reduce(|lhs, rhs| match (lhs, rhs) { - (Node::Int(lhs), Node::Int(rhs)) => Node::Int(lhs / rhs), + (Node::Int(lhs), Node::Int(rhs)) => match lhs.checked_div(rhs) { + Some(val) => Node::Int(val), + None => Node::Int128(lhs as i128 / rhs as i128), + }, + (Node::Int128(lhs), Node::Int128(rhs)) => Node::Int128(lhs / rhs), + (Node::Int(lhs), Node::Int128(rhs)) => { + Node::Int128(lhs as i128 / rhs as i128) + } + (Node::Int128(lhs), Node::Int(rhs)) => Node::Int128(lhs / rhs as i128), _ => todo!(), }) .unwrap_or(Node::Int(0)); diff --git a/src/node.rs b/src/node.rs index 8c3bfb3..c8865ef 100644 --- a/src/node.rs +++ b/src/node.rs @@ -11,6 +11,7 @@ pub enum Node { Symbol(String), Keyword(String), Int(i64), + Int128(i128), String(String), Boolean(bool), Nil, @@ -42,6 +43,7 @@ impl std::fmt::Display for Node { } Node::Int(val) => write!(f, "{}", val), + Node::Int128(val) => write!(f, "{}", val), Node::Boolean(true) => write!(f, "true"), Node::Boolean(false) => write!(f, "false"), Node::Symbol(val) => write!(f, "{}", val),