From 45a09f9327f77c18ff12ae3b6c0de82d2aa6ddf9 Mon Sep 17 00:00:00 2001 From: Warfa Jibril Date: Mon, 16 Oct 2023 16:38:05 -0700 Subject: [PATCH] fixed numeric -> isize bug for range & implemented some froms --- pax-compiler/src/parsing.rs | 8 +- pax-runtime-api/src/numeric.rs | 203 ++++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 4 deletions(-) diff --git a/pax-compiler/src/parsing.rs b/pax-compiler/src/parsing.rs index 513389ee4..83050f41f 100644 --- a/pax-compiler/src/parsing.rs +++ b/pax-compiler/src/parsing.rs @@ -145,8 +145,9 @@ fn recurse_pratt_parse_to_string<'a>( op0.as_str().to_string() }, Rule::xo_symbol => { + symbolic_ids.borrow_mut().push(op0.as_str().to_string()); //for symbolic identifiers, remove any "this" or "self", then return string - convert_symbolic_binding_from_paxel_to_ril(op0) + format!("{}.get_as_int()",convert_symbolic_binding_from_paxel_to_ril(op0)) }, _ => unimplemented!("") }; @@ -161,8 +162,9 @@ fn recurse_pratt_parse_to_string<'a>( op2.as_str().to_string() }, Rule::xo_symbol => { + symbolic_ids.borrow_mut().push(op2.as_str().to_string()); //for symbolic identifiers, remove any "this" or "self", then return string - convert_symbolic_binding_from_paxel_to_ril(op2) + format!("{}.get_as_int()",convert_symbolic_binding_from_paxel_to_ril(op2)) }, _ => unimplemented!("") }; @@ -194,7 +196,7 @@ fn recurse_pratt_parse_to_string<'a>( Rule::literal_number => { let mut inner = literal_kind.into_inner(); let value = inner.next().unwrap().as_str(); - format!("Numeric::from({})", value) + format!("Numeric::from({}).into()", value) }, Rule::string => { //TODO: figure out string concatenation. Might need to introduce another operator? Or perhaps a higher-level string type, which supports addition-as-concatenation — like we do with Numeric diff --git a/pax-runtime-api/src/numeric.rs b/pax-runtime-api/src/numeric.rs index 4914d70e5..c51c57dc4 100644 --- a/pax-runtime-api/src/numeric.rs +++ b/pax-runtime-api/src/numeric.rs @@ -1,6 +1,7 @@ use crate::Interpolatable; use std::cmp::Ordering; use std::ops::{Add, Div, Mul, Neg, Rem, Sub}; +use std::convert::TryFrom; /// Numeric is a module that wraps numeric literals in Pax /// It encapsulates the built-in Rust numeric scalar types and defines behavior across them @@ -171,14 +172,212 @@ impl From<&f64> for Numeric { Numeric::Float(*value as f64) } } + +impl From for u8 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => u8::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to u8 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= u8::MIN as f64) && (f <= u8::MAX as f64) { + f as u8 + } else { + unreachable!("Conversion from Numeric to u8 resulted in overflow.") + } + } + } + } +} + +impl From for u16 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => u16::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to u16 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= u16::MIN as f64) && (f <= u16::MAX as f64) { + f as u16 + } else { + unreachable!("Conversion from Numeric to u16 resulted in overflow.") + } + } + } + } +} + +impl From for u32 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => u32::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to u32 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= u32::MIN as f64) && (f <= u32::MAX as f64) { + f as u32 + } else { + unreachable!("Conversion from Numeric to u32 resulted in overflow.") + } + } + } + } +} + +impl From for u64 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => u64::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to u64 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= u64::MIN as f64) && (f <= u64::MAX as f64) { + f as u64 + } else { + unreachable!("Conversion from Numeric to u64 resulted in overflow.") + } + } + } + } +} + +impl From for u128 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => u128::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to u128 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= u128::MIN as f64) && (f <= u128::MAX as f64) { + f as u128 + } else { + unreachable!("Conversion from Numeric to u128 resulted in overflow.") + } + } + } + } +} + +impl From for usize { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => usize::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to usize resulted in overflow.")), + Numeric::Float(f) => { + if (f >= usize::MIN as f64) && (f <= usize::MAX as f64) { + f as usize + } else { + unreachable!("Conversion from Numeric to usize resulted in overflow.") + } + } + } + } +} + +impl From for i8 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => i8::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to i8 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= i8::MIN as f64) && (f <= i8::MAX as f64) { + f as i8 + } else { + unreachable!("Conversion from Numeric to i8 resulted in overflow.") + } + } + } + } +} + +impl From for i16 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => i16::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to i16 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= i16::MIN as f64) && (f <= i16::MAX as f64) { + f as i16 + } else { + unreachable!("Conversion from Numeric to i16 resulted in overflow.") + } + } + } + } +} + +impl From for i32 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => i32::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to i32 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= i32::MIN as f64) && (f <= i32::MAX as f64) { + f as i32 + } else { + unreachable!("Conversion from Numeric to i32 resulted in overflow.") + } + } + } + } +} + +impl From for i64 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => i64::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to i64 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= i64::MIN as f64) && (f <= i64::MAX as f64) { + f as i64 + } else { + unreachable!("Conversion from Numeric to i64 resulted in overflow.") + } + } + } + } +} + +impl From for i128 { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => i128::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to i128 resulted in overflow.")), + Numeric::Float(f) => { + if (f >= i128::MIN as f64) && (f <= i128::MAX as f64) { + f as i128 + } else { + unreachable!("Conversion from Numeric to i128 resulted in overflow.") + } + } + } + } +} + +impl From for isize { + fn from(value: Numeric) -> Self { + match value { + Numeric::Integer(i) => isize::try_from(i).unwrap_or_else(|_| unreachable!("Conversion from Numeric to isize resulted in overflow.")), + Numeric::Float(f) => { + if (f >= isize::MIN as f64) && (f <= isize::MAX as f64) { + f as isize + } else { + unreachable!("Conversion from Numeric to isize resulted in overflow.") + } + } + } + } +} + +impl From for f32 { + fn from(value: Numeric) -> Self { + let f = match value { + Numeric::Integer(i) => i as f64, + Numeric::Float(f) => f, + }; + if (f >= f32::MIN as f64) && (f <= f32::MAX as f64) { + f as f32 + } else { + unreachable!("Conversion from Numeric to f32 resulted in overflow.") + } + } +} + impl From for f64 { fn from(value: Numeric) -> Self { match value { - Numeric::Integer(i) => i as Self, + Numeric::Integer(i) => i as f64, Numeric::Float(f) => f, } } } + + + impl Numeric { fn widen( f: fn(f64, f64) -> f64, @@ -306,6 +505,8 @@ impl PartialOrd for Numeric { } } + + /// Helper functions to ease working with built-ins impl Mul for f64 {