mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
chore: add Float
This commit is contained in:
parent
4bc596af00
commit
de92e295dc
6 changed files with 159 additions and 153 deletions
|
@ -91,7 +91,7 @@ impl Context {
|
|||
EPSILON,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
None,
|
||||
ValueObj::Float(2.220446049250313e-16),
|
||||
ValueObj::from(2.220446049250313e-16),
|
||||
);
|
||||
complex.register_builtin_py_impl(
|
||||
REAL,
|
||||
|
|
|
@ -639,7 +639,7 @@ fn _list_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
|
|||
sum += *n as f64;
|
||||
}
|
||||
ValueObj::Float(n) => {
|
||||
sum += *n;
|
||||
sum += **n;
|
||||
}
|
||||
ValueObj::Inf => {
|
||||
return Ok(ValueObj::Inf);
|
||||
|
@ -657,7 +657,7 @@ fn _list_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
|
|||
} else if sum.round() == sum {
|
||||
Ok(ValueObj::Int(sum as i32))
|
||||
} else {
|
||||
Ok(ValueObj::Float(sum))
|
||||
Ok(ValueObj::from(sum))
|
||||
}
|
||||
}
|
||||
_ => Err(format!("Cannot sum {arr}")),
|
||||
|
@ -689,7 +689,7 @@ fn _list_prod(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
|
|||
prod *= *n as f64;
|
||||
}
|
||||
ValueObj::Float(n) => {
|
||||
prod *= *n;
|
||||
prod *= **n;
|
||||
}
|
||||
ValueObj::Inf => {
|
||||
return Ok(ValueObj::Inf);
|
||||
|
@ -707,7 +707,7 @@ fn _list_prod(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
|
|||
} else if prod.round() == prod {
|
||||
Ok(ValueObj::Int(prod as i32))
|
||||
} else {
|
||||
Ok(ValueObj::Float(prod))
|
||||
Ok(ValueObj::from(prod))
|
||||
}
|
||||
}
|
||||
_ => Err(format!("Cannot prod {lis}")),
|
||||
|
@ -1144,7 +1144,7 @@ pub(crate) fn abs_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
|
|||
ValueObj::Nat(n) => Ok(ValueObj::Nat(n).into()),
|
||||
ValueObj::Int(n) => Ok(ValueObj::Nat(n.unsigned_abs() as u64).into()),
|
||||
ValueObj::Bool(b) => Ok(ValueObj::Nat(b as u64).into()),
|
||||
ValueObj::Float(n) => Ok(ValueObj::Float(n.abs()).into()),
|
||||
ValueObj::Float(n) => Ok(ValueObj::from(n.abs()).into()),
|
||||
ValueObj::Inf => Ok(ValueObj::Inf.into()),
|
||||
ValueObj::NegInf => Ok(ValueObj::Inf.into()),
|
||||
_ => Err(type_mismatch("Num", num, "num")),
|
||||
|
@ -1490,7 +1490,7 @@ pub(crate) fn succ_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
|
|||
ValueObj::Bool(b) => ValueObj::Nat(*b as u64 + 1),
|
||||
ValueObj::Nat(n) => ValueObj::Nat(n + 1),
|
||||
ValueObj::Int(n) => ValueObj::Int(n + 1),
|
||||
ValueObj::Float(n) => ValueObj::Float(n + f64::EPSILON),
|
||||
ValueObj::Float(n) => ValueObj::from(**n + f64::EPSILON),
|
||||
v @ (ValueObj::Inf | ValueObj::NegInf) => v.clone(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Number", val, "Value"));
|
||||
|
@ -1507,7 +1507,7 @@ pub(crate) fn pred_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
|
|||
ValueObj::Bool(b) => ValueObj::Nat((*b as u64).saturating_sub(1)),
|
||||
ValueObj::Nat(n) => ValueObj::Nat(n.saturating_sub(1)),
|
||||
ValueObj::Int(n) => ValueObj::Int(n - 1),
|
||||
ValueObj::Float(n) => ValueObj::Float(n - f64::EPSILON),
|
||||
ValueObj::Float(n) => ValueObj::from(**n - f64::EPSILON),
|
||||
v @ (ValueObj::Inf | ValueObj::NegInf) => v.clone(),
|
||||
_ => {
|
||||
return Err(type_mismatch("Number", val, "Value"));
|
||||
|
|
|
@ -171,7 +171,7 @@ impl Deserializer {
|
|||
}
|
||||
DataTypePrefix::BinFloat => {
|
||||
let bytes = Self::consume::<8>(v);
|
||||
Ok(ValueObj::Float(f64::from_le_bytes(bytes)))
|
||||
Ok(ValueObj::from(f64::from_le_bytes(bytes)))
|
||||
}
|
||||
DataTypePrefix::ShortAscii | DataTypePrefix::ShortAsciiInterned => {
|
||||
let len = v.remove(0);
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::atomic::AtomicUsize;
|
|||
use erg_common::consts::DEBUG_MODE;
|
||||
use erg_common::shared::Forkable;
|
||||
use erg_common::traits::{LimitedDisplay, StructuralEq};
|
||||
use erg_common::{addr, Str};
|
||||
use erg_common::Str;
|
||||
use erg_common::{addr_eq, log};
|
||||
|
||||
use super::typaram::TyParam;
|
||||
|
@ -579,9 +579,7 @@ impl Hash for Free<TyParam> {
|
|||
if let Some(lev) = self.level() {
|
||||
lev.hash(state);
|
||||
}
|
||||
if self.is_recursive() {
|
||||
addr!(self).hash(state);
|
||||
} else if let Some(t) = self.get_type() {
|
||||
if let Some(t) = self.get_type() {
|
||||
t.hash(state);
|
||||
} else if self.is_linked() {
|
||||
self.crack().hash(state);
|
||||
|
@ -768,6 +766,7 @@ impl Free<Type> {
|
|||
Type::FreeVar(self.clone()).is_recursive()
|
||||
}
|
||||
|
||||
/// interior-mut
|
||||
fn _do_avoiding_recursion<O, F: FnOnce() -> O>(&self, placeholder: Option<&Type>, f: F) -> O {
|
||||
let placeholder = placeholder.unwrap_or(&Type::Failure);
|
||||
let is_recursive = self.is_recursive();
|
||||
|
@ -781,10 +780,12 @@ impl Free<Type> {
|
|||
res
|
||||
}
|
||||
|
||||
/// interior-mut
|
||||
pub fn do_avoiding_recursion<O, F: FnOnce() -> O>(&self, f: F) -> O {
|
||||
self._do_avoiding_recursion(None, f)
|
||||
}
|
||||
|
||||
/// interior-mut
|
||||
pub fn do_avoiding_recursion_with<O, F: FnOnce() -> O>(&self, placeholder: &Type, f: F) -> O {
|
||||
self._do_avoiding_recursion(Some(placeholder), f)
|
||||
}
|
||||
|
|
|
@ -1451,6 +1451,7 @@ impl PartialEq for Type {
|
|||
| (Self::NotImplementedType, Self::NotImplementedType)
|
||||
| (Self::Ellipsis, Self::Ellipsis)
|
||||
| (Self::Never, Self::Never) => true,
|
||||
(Self::Failure, Self::Failure) | (Self::Uninited, Self::Uninited) => true,
|
||||
(Self::Mono(l), Self::Mono(r)) => l == r,
|
||||
(Self::Ref(l), Self::Ref(r)) => l == r,
|
||||
(
|
||||
|
@ -1474,7 +1475,7 @@ impl PartialEq for Type {
|
|||
return_t: rr,
|
||||
},
|
||||
) => {
|
||||
lps.len() != rps.len()
|
||||
lps.len() == rps.len()
|
||||
&& lps.iter().zip(rps.iter()).all(|(l, r)| l == r)
|
||||
&& (lr == rr)
|
||||
}
|
||||
|
@ -1482,10 +1483,8 @@ impl PartialEq for Type {
|
|||
(Self::NamedTuple(lhs), Self::NamedTuple(rhs)) => lhs == rhs,
|
||||
(Self::Refinement(l), Self::Refinement(r)) => l == r,
|
||||
(Self::Quantified(l), Self::Quantified(r)) => l == r,
|
||||
// REVIEW: should use the same way as `structural_eq`?
|
||||
(Self::And(ll, lr), Self::And(rl, rr)) | (Self::Or(ll, lr), Self::Or(rl, rr)) => {
|
||||
(ll == rl && lr == rr) || (ll == rr && lr == rl)
|
||||
}
|
||||
(Self::And(_, _), Self::And(_, _)) => self.ands() == other.ands(),
|
||||
(Self::Or(_, _), Self::Or(_, _)) => self.ors() == other.ors(),
|
||||
(Self::Not(l), Self::Not(r)) => l == r,
|
||||
(
|
||||
Self::Poly {
|
||||
|
@ -1521,7 +1520,6 @@ impl PartialEq for Type {
|
|||
(Self::FreeVar(fv), other) if fv.is_linked() => &*fv.crack() == other,
|
||||
(_self, Self::FreeVar(fv)) if fv.is_linked() => _self == &*fv.crack(),
|
||||
(Self::FreeVar(l), Self::FreeVar(r)) => l == r,
|
||||
(Self::Failure, Self::Failure) | (Self::Uninited, Self::Uninited) => true,
|
||||
// NoneType == {None}
|
||||
(Self::NoneType, Self::Refinement(refine))
|
||||
| (Self::Refinement(refine), Self::NoneType) => {
|
||||
|
@ -2134,10 +2132,11 @@ impl StructuralEq for Type {
|
|||
return_t: return_t2,
|
||||
},
|
||||
) => {
|
||||
param_ts
|
||||
.iter()
|
||||
.zip(param_ts2.iter())
|
||||
.all(|(t, t2)| t.structural_eq(t2))
|
||||
param_ts.len() == param_ts2.len()
|
||||
&& param_ts
|
||||
.iter()
|
||||
.zip(param_ts2.iter())
|
||||
.all(|(t, t2)| t.structural_eq(t2))
|
||||
&& return_t.structural_eq(return_t2)
|
||||
}
|
||||
(Self::Quantified(quant), Self::Quantified(quant2)) => quant.structural_eq(quant2),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Neg;
|
||||
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Sub};
|
||||
use std::sync::Arc;
|
||||
|
||||
use erg_common::consts::DEBUG_MODE;
|
||||
|
@ -571,13 +571,81 @@ impl TypeObj {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
pub struct Float(f64);
|
||||
|
||||
impl fmt::Display for Float {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Float {}
|
||||
#[allow(clippy::derive_ord_xor_partial_ord)]
|
||||
impl Ord for Float {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0.partial_cmp(&other.0).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// HACK:
|
||||
impl Hash for Float {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Float {
|
||||
type Target = f64;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Float {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self {
|
||||
Self(-self.0)
|
||||
}
|
||||
}
|
||||
impl Add for Float {
|
||||
type Output = Self;
|
||||
fn add(self, other: Self) -> Self {
|
||||
Self(self.0 + other.0)
|
||||
}
|
||||
}
|
||||
impl Sub for Float {
|
||||
type Output = Self;
|
||||
fn sub(self, other: Self) -> Self {
|
||||
Self(self.0 - other.0)
|
||||
}
|
||||
}
|
||||
impl Mul for Float {
|
||||
type Output = Self;
|
||||
fn mul(self, other: Self) -> Self {
|
||||
Self(self.0 * other.0)
|
||||
}
|
||||
}
|
||||
impl Div for Float {
|
||||
type Output = Self;
|
||||
fn div(self, other: Self) -> Self {
|
||||
Self(self.0 / other.0)
|
||||
}
|
||||
}
|
||||
impl Rem for Float {
|
||||
type Output = Self;
|
||||
fn rem(self, other: Self) -> Self {
|
||||
Self(self.0 % other.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 値オブジェクト
|
||||
/// コンパイル時評価ができ、シリアライズも可能(Typeなどはシリアライズ不可)
|
||||
#[derive(Clone, PartialEq, Default)]
|
||||
#[derive(Clone, PartialEq, Default, Hash)]
|
||||
pub enum ValueObj {
|
||||
Int(i32),
|
||||
Nat(u64),
|
||||
Float(f64),
|
||||
Float(Float),
|
||||
Str(Str),
|
||||
Bool(bool),
|
||||
List(ArcArray<ValueObj>),
|
||||
|
@ -919,60 +987,6 @@ impl Neg for ValueObj {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
impl Hash for ValueObj {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
Self::Int(i) => i.hash(state),
|
||||
Self::Nat(n) => n.hash(state),
|
||||
// TODO:
|
||||
Self::Float(f) => f.to_bits().hash(state),
|
||||
Self::Str(s) => s.hash(state),
|
||||
Self::Bool(b) => b.hash(state),
|
||||
Self::List(lis) => lis.hash(state),
|
||||
Self::UnsizedList(elem) => {
|
||||
"UnsizedArray".hash(state);
|
||||
elem.hash(state)
|
||||
}
|
||||
Self::Dict(dict) => dict.hash(state),
|
||||
Self::Tuple(tup) => tup.hash(state),
|
||||
Self::Set(st) => st.hash(state),
|
||||
Self::Code(code) => code.hash(state),
|
||||
Self::Record(rec) => rec.hash(state),
|
||||
Self::DataClass { name, fields } => {
|
||||
name.hash(state);
|
||||
fields.hash(state);
|
||||
}
|
||||
Self::Subr(subr) => subr.hash(state),
|
||||
Self::Type(t) => t.hash(state),
|
||||
Self::None => {
|
||||
"literal".hash(state);
|
||||
"None".hash(state)
|
||||
}
|
||||
Self::Ellipsis => {
|
||||
"literal".hash(state);
|
||||
"Ellipsis".hash(state)
|
||||
}
|
||||
Self::NotImplemented => {
|
||||
"literal".hash(state);
|
||||
"NotImplemented".hash(state)
|
||||
}
|
||||
Self::NegInf => {
|
||||
"literal".hash(state);
|
||||
"NegInf".hash(state)
|
||||
}
|
||||
Self::Inf => {
|
||||
"literal".hash(state);
|
||||
"Inf".hash(state)
|
||||
}
|
||||
Self::Failure => {
|
||||
"literal".hash(state);
|
||||
"illegal".hash(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasLevel for ValueObj {
|
||||
fn level(&self) -> Option<usize> {
|
||||
match self {
|
||||
|
@ -1057,7 +1071,7 @@ impl From<usize> for ValueObj {
|
|||
|
||||
impl From<f64> for ValueObj {
|
||||
fn from(item: f64) -> Self {
|
||||
ValueObj::Float(item)
|
||||
ValueObj::Float(Float(item))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1111,7 +1125,7 @@ impl TryFrom<&ValueObj> for f64 {
|
|||
match val {
|
||||
ValueObj::Int(i) => Ok(*i as f64),
|
||||
ValueObj::Nat(n) => Ok(*n as f64),
|
||||
ValueObj::Float(f) => Ok(*f),
|
||||
ValueObj::Float(f) => Ok(**f),
|
||||
ValueObj::Inf => Ok(f64::INFINITY),
|
||||
ValueObj::NegInf => Ok(f64::NEG_INFINITY),
|
||||
ValueObj::Bool(b) => Ok(if *b { 1.0 } else { 0.0 }),
|
||||
|
@ -1126,7 +1140,7 @@ impl TryFrom<&ValueObj> for usize {
|
|||
match val {
|
||||
ValueObj::Int(i) => usize::try_from(*i).map_err(|_| ()),
|
||||
ValueObj::Nat(n) => usize::try_from(*n).map_err(|_| ()),
|
||||
ValueObj::Float(f) => Ok(*f as usize),
|
||||
ValueObj::Float(f) => Ok(**f as usize),
|
||||
ValueObj::Bool(b) => Ok(if *b { 1 } else { 0 }),
|
||||
_ => Err(()),
|
||||
}
|
||||
|
@ -1319,17 +1333,9 @@ impl ValueObj {
|
|||
_ => content.parse::<u64>().ok().map(Self::Nat),
|
||||
}
|
||||
}
|
||||
Type::Float => content
|
||||
.replace('_', "")
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(Self::Float),
|
||||
Type::Float => content.replace('_', "").parse::<f64>().ok().map(Self::from),
|
||||
// TODO:
|
||||
Type::Ratio => content
|
||||
.replace('_', "")
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(Self::Float),
|
||||
Type::Ratio => content.replace('_', "").parse::<f64>().ok().map(Self::from),
|
||||
Type::Str => {
|
||||
if &content[..] == "\"\"" {
|
||||
Some(Self::Str(Str::from("")))
|
||||
|
@ -1463,7 +1469,7 @@ impl ValueObj {
|
|||
Self::Int(i) => Some(*i),
|
||||
Self::Nat(n) => i32::try_from(*n).ok(),
|
||||
Self::Bool(b) => Some(if *b { 1 } else { 0 }),
|
||||
Self::Float(f) if f.round() == *f => Some(*f as i32),
|
||||
Self::Float(f) if f.round() == **f => Some(**f as i32),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1473,7 +1479,7 @@ impl ValueObj {
|
|||
Self::Int(i) => Some(*i as f64),
|
||||
Self::Nat(n) => Some(*n as f64),
|
||||
Self::Bool(b) => Some(if *b { 1.0 } else { 0.0 }),
|
||||
Self::Float(f) => Some(*f),
|
||||
Self::Float(f) => Some(**f),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1543,10 +1549,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l + r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l + r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Int(l as i32 + r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::Float(l - r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::Float(l as f64 - r)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::Float(l as f64 - r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::Float(l - r as f64)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l - r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 - *r)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 - *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l - r as f64)),
|
||||
(Self::Str(l), Self::Str(r)) => Some(Self::Str(Str::from(format!("{l}{r}")))),
|
||||
(Self::List(l), Self::List(r)) => {
|
||||
let lis = Arc::from([l, r].concat());
|
||||
|
@ -1567,10 +1573,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l - r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l - r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as i32 - r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l - r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 - r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l - r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 - r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l - r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 - *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l - r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 - *r)),
|
||||
(inf @ (Self::Inf | Self::NegInf), other)
|
||||
| (other, inf @ (Self::Inf | Self::NegInf))
|
||||
if other != Self::Inf && other != Self::NegInf =>
|
||||
|
@ -1588,10 +1594,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l * r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::Int(l * r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Int(l as i32 * r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l * r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 * r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l * r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 * r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l * r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 * *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l * r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 * *r)),
|
||||
(Self::Str(l), Self::Nat(r)) => Some(Self::Str(Str::from(l.repeat(r as usize)))),
|
||||
(inf @ (Self::Inf | Self::NegInf), _) | (_, inf @ (Self::Inf | Self::NegInf)) => {
|
||||
Some(inf)
|
||||
|
@ -1602,15 +1608,15 @@ impl ValueObj {
|
|||
|
||||
pub fn try_div(self, other: Self) -> Option<Self> {
|
||||
match (self, other) {
|
||||
(Self::Int(l), Self::Int(r)) => Some(Self::Float(l as f64 / r as f64)),
|
||||
(Self::Nat(l), Self::Nat(r)) => Some(Self::Float(l as f64 / r as f64)),
|
||||
(Self::Int(l), Self::Int(r)) => Some(Self::from(l as f64 / r as f64)),
|
||||
(Self::Nat(l), Self::Nat(r)) => Some(Self::from(l as f64 / r as f64)),
|
||||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l / r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::Float(l as f64 / r as f64)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Float(l as f64 / r as f64)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::Float(l / r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 / r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l / r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 / r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l as f64 / r as f64)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as f64 / r as f64)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l / r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 / *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l / r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 / *r)),
|
||||
// TODO: x/±Inf = 0
|
||||
_ => None,
|
||||
}
|
||||
|
@ -1620,13 +1626,13 @@ impl ValueObj {
|
|||
match (self, other) {
|
||||
(Self::Int(l), Self::Int(r)) => Some(Self::Int(l / r)),
|
||||
(Self::Nat(l), Self::Nat(r)) => Some(Self::Nat(l / r)),
|
||||
(Self::Float(l), Self::Float(r)) => Some(Self::Float((l / r).floor())),
|
||||
(Self::Float(l), Self::Float(r)) => Some(Self::from((l / r).floor())),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::Int(l / r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Int(l as i32 / r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::Float((l / r as f64).floor())),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::Float((l as f64 / r).floor())),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::Float((l / r as f64).floor())),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::Float((l as f64 / r).floor())),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from((*l / r as f64).floor())),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64 / *r).floor())),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from((*l / r as f64).floor())),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64 / *r).floor())),
|
||||
// TODO: x//±Inf = 0
|
||||
_ => None,
|
||||
}
|
||||
|
@ -1636,13 +1642,13 @@ impl ValueObj {
|
|||
match (self, other) {
|
||||
(Self::Int(l), Self::Int(r)) => Some(Self::Int(l.pow(r.try_into().ok()?))),
|
||||
(Self::Nat(l), Self::Nat(r)) => Some(Self::Nat(l.pow(r.try_into().ok()?))),
|
||||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l.powf(r))),
|
||||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l.powf(*r))),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::Int(l.pow(r.try_into().ok()?))),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Nat(l.pow(r.try_into().ok()?))),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::Float(l.powf(r as f64))),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::Float((l as f64).powf(r))),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::Float(l.powi(r))),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::Float((l as f64).powf(r))),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l.powf(r as f64))),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64).powf(*r))),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l.powi(r))),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64).powf(*r))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1654,10 +1660,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::Float(l % r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::Int(l % r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::Int(l as i32 % r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::Float(l % r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::Float(l as f64 % r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::Float(l % r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::Float(l as f64 % r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l % r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 % *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l % r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 % *r)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1669,10 +1675,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l > r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l > r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as i32 > r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l > r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 > r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l > r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 > r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l > r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 > *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l > r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 > *r)),
|
||||
(Self::Inf, Self::Inf) | (Self::NegInf, Self::NegInf) => Some(Self::Bool(false)),
|
||||
(Self::Inf, Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_))
|
||||
| (Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_), Self::NegInf) => {
|
||||
|
@ -1693,10 +1699,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l >= r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l >= r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as i32 >= r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l >= r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 >= r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l >= r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 >= r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l >= r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 >= *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l >= r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 >= *r)),
|
||||
(Self::Inf, Self::Inf) | (Self::NegInf, Self::NegInf) => Some(Self::Bool(true)),
|
||||
(Self::Inf, Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_))
|
||||
| (Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_), Self::NegInf) => {
|
||||
|
@ -1717,10 +1723,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l < r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l < r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from((l as i32) < r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l < r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64) < r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l < r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64) < r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l < r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64) < *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l < r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64) < *r)),
|
||||
(Self::Inf, Self::Inf) | (Self::NegInf, Self::NegInf) => Some(Self::Bool(false)),
|
||||
(Self::Inf, Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_))
|
||||
| (Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_), Self::NegInf) => {
|
||||
|
@ -1741,10 +1747,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l <= r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l <= r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from((l as i32) <= r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l <= r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64) <= r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l <= r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64) <= r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l <= r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from((l as f64) <= *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l <= r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from((l as f64) <= *r)),
|
||||
(Self::Inf, Self::Inf) | (Self::NegInf, Self::NegInf) => Some(Self::Bool(true)),
|
||||
(Self::Inf, Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_))
|
||||
| (Self::Nat(_) | Self::Int(_) | Self::Float(_) | Self::Bool(_), Self::NegInf) => {
|
||||
|
@ -1765,10 +1771,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l == r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l == r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as i32 == r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l == r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 == r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l == r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 == r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l == r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 == *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l == r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 == *r)),
|
||||
(Self::Str(l), Self::Str(r)) => Some(Self::from(l == r)),
|
||||
(Self::Bool(l), Self::Bool(r)) => Some(Self::from(l == r)),
|
||||
(Self::Type(l), Self::Type(r)) => Some(Self::from(l == r)),
|
||||
|
@ -1785,10 +1791,10 @@ impl ValueObj {
|
|||
(Self::Float(l), Self::Float(r)) => Some(Self::from(l != r)),
|
||||
(Self::Int(l), Self::Nat(r)) => Some(Self::from(l != r as i32)),
|
||||
(Self::Nat(l), Self::Int(r)) => Some(Self::from(l as i32 != r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(l != r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 != r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(l != r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 != r)),
|
||||
(Self::Float(l), Self::Nat(r)) => Some(Self::from(*l != r as f64)),
|
||||
(Self::Nat(l), Self::Float(r)) => Some(Self::from(l as f64 != *r)),
|
||||
(Self::Float(l), Self::Int(r)) => Some(Self::from(*l != r as f64)),
|
||||
(Self::Int(l), Self::Float(r)) => Some(Self::from(l as f64 != *r)),
|
||||
(Self::Str(l), Self::Str(r)) => Some(Self::from(l != r)),
|
||||
(Self::Bool(l), Self::Bool(r)) => Some(Self::from(l != r)),
|
||||
(Self::Type(l), Self::Type(r)) => Some(Self::from(l != r)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue