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

Additionally: make release target binaries smaller and faster

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2025-08-26 17:11:37 +00:00
parent 0f85292e6f
commit fea950ea17
4 changed files with 236 additions and 3 deletions

View file

@ -18,6 +18,7 @@
use core::ops::{Index, Deref, DerefMut};
use core::ptr::NonNull;
use alloc::vec;
use alloc::rc::Rc;
use alloc::vec::Vec;
use alloc::boxed::Box;
@ -25,6 +26,14 @@ use alloc::fmt::Debug;
use organelle::Number;
pub const DATUM_BOOL_FALSE_TAG: u8 = 0x07;
pub const DATUM_BOOL_TRUE_TAG: u8 = 0x08;
pub const DATUM_CONS_TAG: u8 = 0x09;
pub const DATUM_CHAR_TAG: u8 = 0x0A;
pub const DATUM_STRING_TAG: u8 = 0x0B;
pub const DATUM_BYTEVEC_TAG: u8 = 0x0C;
pub const DATUM_VECTOR_TAG: u8 = 0x0D;
/* NOTE
* decided not to implement a cache or a singleton heap manager
* because I did not want to involve a datatype that would add
@ -175,6 +184,81 @@ impl Clone for Datum {
}
}
impl Into<Vec<u8>> for Datum {
fn into(self) -> Vec<u8> {
match self {
// 0x00 - 0x06
Datum::Number(n) => n.into(),
Datum::Bool(b) if !b => vec![DATUM_BOOL_FALSE_TAG],
Datum::Bool(b) if b => vec![DATUM_BOOL_TRUE_TAG],
Datum::Bool(_) => panic!("rustc somehow has a third bool!"),
Datum::Cons(c) => {
let mut v = vec![DATUM_CONS_TAG];
for i in Into::<Vec<u8>>::into(c).iter() {
v.push(*i)
}
v
},
Datum::Char(c) => vec![DATUM_CHAR_TAG, c],
Datum::String(c) => {
let mut v = vec![DATUM_STRING_TAG];
for i in c.len().to_be_bytes().iter() {
v.push(*i);
}
for i in c.iter() {
v.push(*i);
}
v
},
Datum::ByteVector(c) => {
let mut v = vec![DATUM_BYTEVEC_TAG];
for i in c.len().to_be_bytes().iter() {
v.push(*i);
}
for i in c.iter() {
v.push(*i);
}
v
},
Datum::Vector(c) => {
let mut v = vec![DATUM_STRING_TAG];
for i in c.len().to_be_bytes().iter() {
v.push(*i);
}
for i in c.iter() {
let b = Into::<Vec<u8>>::into((**i).clone());
for j in b.iter() {
v.push(*j);
}
}
v
},
Datum::None => vec![],
}
}
}
impl TryFrom<&[u8]> for Datum {
type Error = &'static str;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
match value[0] {
0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 =>
Number::try_from(value).and_then(|a| Ok(Datum::Number(a))),
DATUM_BOOL_FALSE_TAG => Ok(Datum::Bool(false)),
DATUM_BOOL_TRUE_TAG => Ok(Datum::Bool(true)),
DATUM_CONS_TAG if value.len() > 2 =>
Cons::try_from(&value[1..])
.and_then(|a| Ok(Datum::Cons(a))),
DATUM_CHAR_TAG if value.len() == 2 =>
Ok(Datum::Char(value[1])),
DATUM_STRING_TAG if value.len() > 2 => unimplemented!(),
DATUM_BYTEVEC_TAG if value.len() > 2 => unimplemented!(),
DATUM_VECTOR_TAG if value.len() > 2 => unimplemented!(),
_ => Err("Could not unmarshal unknown datum tag or bad format")
}
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct Cons(pub Option<Gc<Datum>>, pub Option<Gc<Datum>>);
@ -293,6 +377,18 @@ impl Index<usize> for Cons {
}
}
impl Into<Vec<u8>> for Cons {
fn into(self) -> Vec<u8> {
unimplemented!("")
}
}
impl TryFrom<&[u8]> for Cons {
type Error = &'static str;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
unimplemented!("")
}
}
#[cfg(test)]
mod tests {