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()) }) } }