From 5d2747e26f51cc2344a6bd95f93457248fdfebd8 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 29 Feb 2024 17:04:28 -0500 Subject: fin prob --- matrix-lang/src/binary/deserialize.rs | 160 ++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 matrix-lang/src/binary/deserialize.rs (limited to 'matrix-lang/src/binary/deserialize.rs') diff --git a/matrix-lang/src/binary/deserialize.rs b/matrix-lang/src/binary/deserialize.rs new file mode 100644 index 0000000..679f6e5 --- /dev/null +++ b/matrix-lang/src/binary/deserialize.rs @@ -0,0 +1,160 @@ +use crate::prelude::*; + +use super::{prim::VarInt, Deserialize, Deserializer}; + +macro_rules! error { + ($($arg:tt)*) => { + exception!(BINARY_EXCEPTION, $($arg)*) + }; +} + +impl Deserialize for Program { + fn deserialize(s: &mut S) -> Result { + for _ in 0..5 { s.read::()?; } // skip header + let version: u8 = s.read()?; + if version != 0 { + return Err(error!("invalid program version {version}")) + } + let fun = >::deserialize(s)?; + Ok(Self { version, fun }) + } +} + +impl Deserialize for Instruction { + fn deserialize(s: &mut S) -> Result { + use Instruction as I; + let ins: u8 = s.read()?; + let ins = match ins { + 0 => I::NoOp, + 1 => I::CreateLocal, + 2 => I::LoadLocal(s.read()?), + 3 => I::StoreLocal(s.read()?), + 4 => I::DiscardLocals(s.read()?), + 5 => I::LoadGlobal(s.read()?), + 6 => I::StoreGlobal(s.read()?), + 7 => I::Const(s.read()?), + 8 => I::Int(s.read()?), + 9 => I::True, + 10 => I::False, + 11 => I::Nil, + 12 => I::Dup, + 13 => I::Discard(s.read()?), + 14 => I::UnaryOp(UnaryOp::try_from(s.read::()?)?), + 15 => I::BinaryOp(BinaryOp::try_from(s.read::()?)?), + 16 => I::NewList(s.read()?), + 17 => I::NewTable(s.read()?), + 18 => I::NewMatrix(s.read()?, s.read()?), + 19 => I::Field(s.read()?), + 20 => I::StoreField(s.read()?), + 21 => I::Index(s.read()?), + 22 => I::StoreIndex(s.read()?), + 23 => I::Jump(s.read()?), + 24 => I::JumpTrue(s.read()?), + 25 => I::JumpFalse(s.read()?), + 26 => I::JumpNil(s.read()?), + 27 => I::IterCreate, + 28 => I::IterNext, + 29 => I::Try(s.read()?), + 30 => I::TryEnd, + 31 => I::Call(s.read()?), + 32 => I::Return, + n => return Err(error!("invalid instruction op code {n}")) + }; + Ok(ins) + } +} + +impl Deserialize for Vec { + fn deserialize(s: &mut S) -> Result { + let len = s.read::()?.0; + let mut vec = Vec::with_capacity(len); + for _ in 0..len { + let v = T::deserialize(s)?; + vec.push(v); + } + Ok(vec) + } +} + +impl Deserialize for Gc { + fn deserialize(s: &mut S) -> Result { + Ok(Gc::new(T::deserialize(s)?)) + } +} + +impl Deserialize for Rc { + fn deserialize(s: &mut S) -> Result { + Ok(Rc::new(T::deserialize(s)?)) + } +} + +impl Deserialize for Position { + fn deserialize(s: &mut S) -> Result { + let row = s.read::()?.0; + let col = s.read::()?.0; + Ok(Self { row, col }) + } +} + +impl Deserialize for Chunk { + fn deserialize(s: &mut S) -> Result { + let constants = >::deserialize(s)?; + let code = >::deserialize(s)?; + let pos = >::deserialize(s)?; + Ok(Self { constants, code, pos }) + } +} + +impl Deserialize for Value { + fn deserialize(s: &mut S) -> Result { + use Value as V; + let ty = s.read::()?; + let value = match ty { + 0 => V::Nil, + 1 => V::Bool(s.read()?), + 2 => V::Int(s.read()?), + 3 => V::Float(s.read()?), + 4 => V::Ratio(Rational64::new(s.read()?, s.read()?)), + 5 => V::Complex(Complex64::new(s.read()?, s.read()?)), + 6 => V::to_regex(s.read::()?.as_str())?, + 7 => V::String(s.read::()?.into()), + 8 => V::List(>::deserialize(s)?.into()), + 9 => { + let domain = s.read()?; + let codomain = s.read()?; + let values = >::deserialize(s)?; + V::Matrix(Matrix::new(domain, codomain, values).into()) + }, + 10 => { + let len = s.read::()?.0; + let mut table = ValueMap::new(); + for _ in 0..len { + let key = ::deserialize(s)?; + let value = ::deserialize(s)?; + table.insert(key, value)?; + } + V::Table(table.into()) + }, + 11 => V::Function(>::deserialize(s)?), + 12 => V::Range((s.read()?, s.read()?, s.read()?).into()), + 13 => V::Iter(>::deserialize(s)?), + n => return Err(error!("invalid value code {n}")) + }; + Ok(value) + } +} + +impl Deserialize for Function { + fn deserialize(s: &mut S) -> Result { + let name = s.read::()?; + let arity = s.read()?; + let variadic = s.read()?; + let chunk = ::deserialize(s)?; + Ok(Function { + name: Rc::from(name.as_str()), + arity, + variadic, + fun: InnerFunction::Compiled(chunk.into()) + }) + } +} -- cgit v1.2.3-freya