WIP: serialization/deserialization of datum in VM
All checks were successful
per-push tests / build (push) Successful in 1m52s
per-push tests / test-utility (push) Successful in 58s
per-push tests / test-frontend (push) Successful in 1m52s
per-push tests / test-backend (push) Successful in 1m0s
per-push tests / timed-decomposer-parse (push) Successful in 1m2s
All checks were successful
per-push tests / build (push) Successful in 1m52s
per-push tests / test-utility (push) Successful in 58s
per-push tests / test-frontend (push) Successful in 1m52s
per-push tests / test-backend (push) Successful in 1m0s
per-push tests / timed-decomposer-parse (push) Successful in 1m2s
Additionally: make release target binaries smaller and faster Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
parent
0f85292e6f
commit
fea950ea17
4 changed files with 236 additions and 3 deletions
|
|
@ -21,6 +21,8 @@ extern crate alloc;
|
|||
use alloc::string::String;
|
||||
use alloc::format;
|
||||
use alloc::fmt::Debug;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::{cmp::Ordering, f64, ops::{Add, Div, Mul, Sub}, str::FromStr};
|
||||
use num::{integer::{gcd}, pow::Pow};
|
||||
|
||||
|
|
@ -250,6 +252,96 @@ impl FromStr for Number {
|
|||
}
|
||||
}
|
||||
|
||||
// this looks rushed and it is
|
||||
// would rather work on organelles replacement than improve this
|
||||
impl Into<Vec<u8>> for Number {
|
||||
fn into(self) -> Vec<u8> {
|
||||
let mut out = vec![];
|
||||
match self {
|
||||
Number::Sci(num) => {
|
||||
out.push(0x00);
|
||||
for ele in num.0.to_be_bytes().iter() {
|
||||
out.push(*ele);
|
||||
}
|
||||
for ele in num.1.to_be_bytes().iter() {
|
||||
out.push(*ele);
|
||||
}
|
||||
out
|
||||
},
|
||||
Number::Flt(num) => {
|
||||
out.push(0x01 as u8);
|
||||
for ele in num.0.to_be_bytes().iter() {
|
||||
out.push(*ele);
|
||||
}
|
||||
out
|
||||
},
|
||||
Number::Fra(num) => {
|
||||
out.push(0x02);
|
||||
for ele in num.0.to_be_bytes().iter() {
|
||||
out.push(*ele);
|
||||
}
|
||||
for ele in num.1.to_be_bytes().iter() {
|
||||
out.push(*ele);
|
||||
}
|
||||
out
|
||||
},
|
||||
Number::Sym(num) => {
|
||||
match num {
|
||||
SymbolicNumber::Inf => out.push(0x03),
|
||||
SymbolicNumber::NaN => out.push(0x04),
|
||||
SymbolicNumber::NegInf => out.push(0x05),
|
||||
SymbolicNumber::NegNan => out.push(0x06),
|
||||
}
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// same as the Into impl
|
||||
impl TryFrom<&[u8]> for Number {
|
||||
type Error = &'static str;
|
||||
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
|
||||
match value[0] {
|
||||
0x03 => Ok(Number::Sym(SymbolicNumber::Inf)),
|
||||
0x04 => Ok(Number::Sym(SymbolicNumber::NaN)),
|
||||
0x05 => Ok(Number::Sym(SymbolicNumber::NegInf)),
|
||||
0x06 => Ok(Number::Sym(SymbolicNumber::NegNan)),
|
||||
0x00 if value.len() >= (1 + 4 + (isize::BITS / 8)) as usize => {
|
||||
let mut i: [u8; 4] = [0, 0, 0, 0];
|
||||
value[1..5].iter().zip(i.iter_mut())
|
||||
.for_each(|(a, b)| { *b = *a });
|
||||
let i = f32::from_be_bytes(i);
|
||||
|
||||
let mut j: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
value[5..13].iter().zip(j.iter_mut())
|
||||
.for_each(|(a, b)| { *b = *a });
|
||||
let j = isize::from_be_bytes(j);
|
||||
Ok(Number::Sci(ScientificNotation(i, j)))
|
||||
},
|
||||
0x01 if value.len() >= 9 as usize => {
|
||||
let mut i: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
value[1..9].iter().zip(i.iter_mut())
|
||||
.for_each(|(a, b)| { *b = *a });
|
||||
let i = f64::from_be_bytes(i);
|
||||
Ok(Number::Flt(Float(i)))
|
||||
},
|
||||
0x02 if value.len() >= 1 + ((isize::BITS / 8) * 2) as usize => {
|
||||
let mut i: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
value[1..9].iter().zip(i.iter_mut())
|
||||
.for_each(|(a, b)| { *b = *a });
|
||||
let i = isize::from_be_bytes(i);
|
||||
let mut j: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
value[9..17].iter().zip(j.iter_mut())
|
||||
.for_each(|(a, b)| { *b = *a });
|
||||
let j = isize::from_be_bytes(j);
|
||||
Ok(Number::Fra(Fraction(i, j)))
|
||||
},
|
||||
_ => Err("attempted to deserialize invalid number format")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Number {
|
||||
type Output = Number;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
|
|
@ -596,6 +688,22 @@ impl Numeric for ScientificNotation {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize_tests() {
|
||||
let cases = vec![
|
||||
"2/3".parse::<Number>().unwrap(),
|
||||
"-4/5".parse::<Number>().unwrap(),
|
||||
"2e45".parse::<Number>().unwrap(),
|
||||
"1.2432566".parse::<Number>().unwrap(),
|
||||
"+inf.0".parse::<Number>().unwrap(),
|
||||
];
|
||||
|
||||
for i in cases.iter() {
|
||||
let j = Into::<Vec<u8>>::into(*i);
|
||||
assert_eq!(*i, Number::try_from(j.as_slice()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_fraction_tests() {
|
||||
assert_eq!("2/3".parse::<Fraction>(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue