Implement addition for OwnedLiterals.
This commit is contained in:
@@ -18,6 +18,7 @@ use crate::renderer::Walkable;
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParametersContext<'a> {
|
||||
@@ -325,4 +326,93 @@ impl CompareContextElement for OwnedLiteral {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn math_add<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
|
||||
// If its an OwnedLiteral then add them directly, otherwise
|
||||
// defer to the other type's implementation of
|
||||
// CompareContextElement since the end user could add any
|
||||
// type.
|
||||
match other.to_any().downcast_ref::<Self>() {
|
||||
None => other.math_add(self),
|
||||
Some(other_literal) => {
|
||||
match (self, other_literal) {
|
||||
(OwnedLiteral::LString(_), _) | (_, OwnedLiteral::LString(_)) => None,
|
||||
(
|
||||
OwnedLiteral::LPositiveInteger(self_num),
|
||||
OwnedLiteral::LPositiveInteger(other_num),
|
||||
) => math_ints(*self_num, *other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned),
|
||||
(
|
||||
OwnedLiteral::LNegativeInteger(self_num),
|
||||
OwnedLiteral::LNegativeInteger(other_num),
|
||||
) => math_ints(*self_num, *other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned),
|
||||
(
|
||||
OwnedLiteral::LPositiveInteger(self_num),
|
||||
OwnedLiteral::LNegativeInteger(other_num),
|
||||
) => math_ints(*self_num, *other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned),
|
||||
(
|
||||
OwnedLiteral::LNegativeInteger(self_num),
|
||||
OwnedLiteral::LPositiveInteger(other_num),
|
||||
) => math_ints(*self_num, *other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned),
|
||||
(OwnedLiteral::LFloat(self_num), OwnedLiteral::LFloat(other_num)) => Some(
|
||||
IceResult::from_owned(OwnedLiteral::LFloat(self_num + other_num)),
|
||||
),
|
||||
(OwnedLiteral::LFloat(self_num), OwnedLiteral::LPositiveInteger(other_num)) => {
|
||||
Some(IceResult::from_owned(OwnedLiteral::LFloat(
|
||||
self_num + (*other_num as f64),
|
||||
)))
|
||||
}
|
||||
(OwnedLiteral::LPositiveInteger(self_num), OwnedLiteral::LFloat(other_num)) => {
|
||||
Some(IceResult::from_owned(OwnedLiteral::LFloat(
|
||||
(*self_num as f64) + other_num,
|
||||
)))
|
||||
}
|
||||
(OwnedLiteral::LFloat(self_num), OwnedLiteral::LNegativeInteger(other_num)) => {
|
||||
Some(IceResult::from_owned(OwnedLiteral::LFloat(
|
||||
self_num + (*other_num as f64),
|
||||
)))
|
||||
}
|
||||
(OwnedLiteral::LNegativeInteger(self_num), OwnedLiteral::LFloat(other_num)) => {
|
||||
Some(IceResult::from_owned(OwnedLiteral::LFloat(
|
||||
(*self_num as f64) + other_num,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// For math operations that take in integers and return integers
|
||||
/// (add, subtract, multiply)
|
||||
fn math_ints<L, R, F>(left: L, right: R, operation: F) -> Option<OwnedLiteral>
|
||||
where
|
||||
L: Into<i128>,
|
||||
R: Into<i128>,
|
||||
F: Fn(i128, i128) -> i128,
|
||||
{
|
||||
let result = operation(left.into(), right.into());
|
||||
std::convert::TryInto::<u64>::try_into(result)
|
||||
.map(OwnedLiteral::LPositiveInteger)
|
||||
.ok()
|
||||
.or(std::convert::TryInto::<i64>::try_into(result)
|
||||
.map(OwnedLiteral::LNegativeInteger)
|
||||
.ok())
|
||||
}
|
||||
|
||||
// /// For math operations that take in integers and return integers
|
||||
// /// (add, subtract, multiply)
|
||||
// fn math_floats<L, R, F>(left: L, right: R, operation: F) -> Option<OwnedLiteral>
|
||||
// where
|
||||
// L: Into<f64>,
|
||||
// R: Into<f64>,
|
||||
// F: Fn(f64, f64) -> f64,
|
||||
// {
|
||||
// let result = operation(left.into(), right.into());
|
||||
// std::convert::TryInto::<f64>::try_into(result)
|
||||
// .map(OwnedLiteral::LFloat)
|
||||
// .ok()
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user