summaryrefslogtreecommitdiff
path: root/matrix-lang/src/binary/serialize.rs
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
commit5d2747e26f51cc2344a6bd95f93457248fdfebd8 (patch)
tree8755b4068166c3854d26817683ce438a771ab319 /matrix-lang/src/binary/serialize.rs
parentmore mat, sys, and os stdlib functions, better matrix printing, other fixes (diff)
downloadmatrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.gz
matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.bz2
matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.zip
fin prob
Diffstat (limited to 'matrix-lang/src/binary/serialize.rs')
-rw-r--r--matrix-lang/src/binary/serialize.rs283
1 files changed, 283 insertions, 0 deletions
diff --git a/matrix-lang/src/binary/serialize.rs b/matrix-lang/src/binary/serialize.rs
new file mode 100644
index 0000000..2f2b199
--- /dev/null
+++ b/matrix-lang/src/binary/serialize.rs
@@ -0,0 +1,283 @@
+use crate::{prelude::*, binary::PROGRAM_HEADER};
+use std::ops::Deref;
+use super::{prim::VarInt, Program, Serializer, Serialize};
+
+macro_rules! error {
+ ($($arg:tt)*) => {
+ exception!(BINARY_EXCEPTION, $($arg)*)
+ };
+}
+
+impl Serialize for Program {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ for b in PROGRAM_HEADER {
+ s.write(b)?;
+ }
+ s.write(self.version)?;
+ s.serialize(self.fun.as_ref())?;
+ Ok(())
+ }
+}
+
+impl Serialize for Instruction {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ use Instruction as I;
+ match self {
+ I::NoOp => {
+ s.write(0u8)?;
+ },
+ I::CreateLocal => {
+ s.write(1u8)?;
+ },
+ I::LoadLocal(idx) => {
+ s.write(2u8)?;
+ s.write(*idx)?;
+ },
+ I::StoreLocal(idx) => {
+ s.write(3u8)?;
+ s.write(*idx)?;
+ },
+ I::DiscardLocals(idx) => {
+ s.write(4u8)?;
+ s.write(*idx)?;
+ },
+ I::LoadGlobal(idx) => {
+ s.write(5u8)?;
+ s.write(*idx)?;
+ }
+ I::StoreGlobal(idx) => {
+ s.write(6u8)?;
+ s.write(*idx)?;
+ },
+ I::Const(idx) => {
+ s.write(7u8)?;
+ s.write(*idx)?;
+ },
+ I::Int(i) => {
+ s.write(8u8)?;
+ s.write(*i)?;
+ },
+ I::True => {
+ s.write(9u8)?;
+ },
+ I::False => {
+ s.write(10u8)?;
+ },
+ I::Nil => {
+ s.write(11u8)?;
+ },
+ I::Dup => {
+ s.write(12u8)?;
+ },
+ I::Discard(idx) => {
+ s.write(13u8)?;
+ s.write(*idx)?;
+ },
+ I::UnaryOp(op) => {
+ s.write(14u8)?;
+ s.write(*op as u8)?;
+ },
+ I::BinaryOp(op) => {
+ s.write(15u8)?;
+ s.write(*op as u8)?;
+ },
+ I::NewList(len) => {
+ s.write(16u8)?;
+ s.write(*len)?;
+ },
+ I::NewTable(len) => {
+ s.write(17u8)?;
+ s.write(*len)?;
+ },
+ I::NewMatrix(d, c) => {
+ s.write(18u8)?;
+ s.write(*d)?;
+ s.write(*c)?;
+ },
+ I::Field(idx) => {
+ s.write(19u8)?;
+ s.write(*idx)?;
+ },
+ I::StoreField(idx) => {
+ s.write(20u8)?;
+ s.write(*idx)?;
+ },
+ I::Index(idx) => {
+ s.write(21u8)?;
+ s.write(*idx)?;
+ },
+ I::StoreIndex(idx) => {
+ s.write(22u8)?;
+ s.write(*idx)?;
+ },
+ I::Jump(ip) => {
+ s.write(23u8)?;
+ s.write(*ip)?;
+ },
+ I::JumpTrue(ip) => {
+ s.write(24u8)?;
+ s.write(*ip)?;
+ },
+ I::JumpFalse(ip) => {
+ s.write(25u8)?;
+ s.write(*ip)?;
+ },
+ I::JumpNil(ip) => {
+ s.write(26u8)?;
+ s.write(*ip)?;
+ },
+ I::IterCreate => {
+ s.write(27u8)?;
+ },
+ I::IterNext => {
+ s.write(28u8)?;
+ },
+ I::Try(ip) => {
+ s.write(29u8)?;
+ s.write(*ip)?;
+ },
+ I::TryEnd => {
+ s.write(30u8)?;
+ },
+ I::Call(arity) => {
+ s.write(31u8)?;
+ s.write(*arity)?;
+ },
+ I::Return => {
+ s.write(32u8)?;
+ },
+ };
+ Ok(())
+ }
+}
+
+impl<T: Serialize> Serialize for Vec<T> {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ s.write(VarInt(self.len()))?;
+ for val in self {
+ val.serialize(s)?;
+ }
+ Ok(())
+ }
+}
+
+impl<T: Serialize + Deref> Serialize for Gc<T> {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ self.deref().serialize(s)
+ }
+}
+
+impl<T: Serialize + Deref> Serialize for Rc<T> {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ self.deref().serialize(s)
+ }
+}
+
+impl Serialize for Position {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ s.write(VarInt(self.row))?;
+ s.write(VarInt(self.col))?;
+ Ok(())
+ }
+}
+
+impl Serialize for Chunk {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ self.constants.serialize(s)?;
+ self.code.serialize(s)?;
+ self.pos.serialize(s)?;
+ Ok(())
+ }
+}
+
+impl Serialize for Value {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ use Value as V;
+ match self {
+ V::Nil => {
+ s.write(0u8)?;
+ },
+ V::Bool(b) => {
+ s.write(1u8)?;
+ s.write(*b)?;
+ },
+ V::Int(i) => {
+ s.write(2u8)?;
+ s.write(*i)?;
+ },
+ V::Float(f) => {
+ s.write(3u8)?;
+ s.write(*f)?;
+ },
+ V::Ratio(r) => {
+ s.write(4u8)?;
+ s.write(*r.numer())?;
+ s.write(*r.denom())?;
+ },
+ V::Complex(c) => {
+ s.write(5u8)?;
+ s.write(c.re)?;
+ s.write(c.im)?;
+ },
+ V::Regex(r) => {
+ s.write(6u8)?;
+ s.write(r.to_string())?;
+ },
+ V::String(str) => {
+ s.write(7u8)?;
+ s.write(str.to_string())?;
+ },
+ V::List(l) => {
+ s.write(8u8)?;
+ l.serialize(s)?;
+ },
+ V::Matrix(m) => {
+ s.write(9u8)?;
+ s.write(m.domain)?;
+ s.write(m.codomain)?;
+ m.values.serialize(s)?;
+ },
+ V::Table(t) => {
+ s.write(10u8)?;
+ s.write(VarInt(t.len()))?;
+ for (key, value) in t.entries() {
+ key.serialize(s)?;
+ value.serialize(s)?;
+ }
+ },
+ V::Function(f) => {
+ s.write(11u8)?;
+ f.serialize(s)?;
+ },
+ V::Range(r) => {
+ s.write(12u8)?;
+ s.write(r.0)?;
+ s.write(r.1)?;
+ s.write(r.2)?;
+ },
+ V::Iter(f) => {
+ s.write(13u8)?;
+ f.serialize(s)?;
+ },
+ V::File(_) => return Err(error!("cannot compile file")),
+ V::Exception(_) => return Err(error!("cannot compile exception")),
+ };
+ Ok(())
+ }
+}
+
+impl Serialize for Function {
+ fn serialize<S: Serializer>(&self, s: &mut S) -> Result<()> {
+ s.write(self.name.to_string())?;
+ s.write(self.arity)?;
+ s.write(self.variadic)?;
+ use InnerFunction as F;
+ match &self.fun {
+ F::Compiled(c) => {
+ c.serialize(s)?;
+ },
+ F::Native(_) => return Err(error!("cannot compile native function")),
+ };
+ Ok(())
+ }
+}