#vm #value #traits #building-block

vm_value

Core value trait used by fn_vm, this crate is meant to provide the building blocks to creating pass by value VMs in rust

7 unstable releases (3 breaking)

0.4.3 Jul 17, 2024
0.4.2 Jul 16, 2024
0.3.0 Jul 15, 2024
0.2.0 Jul 15, 2024
0.1.0 Jul 15, 2024

#19 in #building-block

Download history 455/week @ 2024-07-13 30/week @ 2024-07-20 2/week @ 2024-07-27

211 downloads per month
Used in fn_vm

MIT license

18KB
432 lines

vm_value

Core value trait used by fn_vm, this crate is meant to provide the building blocks to creating pass by value VMs in rust.

Implementing these traits allow you to easily create a VM with all base binary and unary operations (Add, Sub, Rem, Not, etc).

Values

Currently this trait is implemented for ints (i8 - i128 & isize), VMStr (an opinionated wrapped around String), and VarNum (VarInt, VarUInt, and VarFloat).

Length and VarNum (number implementation of VMValue) provided by small_len and var_num respectively.

pub struct VMStatus<O, V> {
    pub done: bool,
    pub last_command: O,
    pub value: Option<V>,
}

pub trait VM<Op, Val, T: VMValue<Op, Val, T>> {

    type Error;

    fn run(&mut self) -> Result<VMStatus<Op, Val>, Self::Error>;

    fn execute(&mut self) -> Result<(), Self::Error>;

    fn next_len(&mut self) -> Length{
        let u8 = self.next_byte();
        match u8 {
            253 => Length::Word(u16::from_be_bytes(self.next_n_bytes::<2>())),
            254 => Length::Double(u32::from_be_bytes(self.next_n_bytes::<4>())),
            255 => Length::Quad(u64::from_be_bytes(self.next_n_bytes::<8>())),
            _ => {
                u8.into()
            }
        }
    }

    fn next_byte(&mut self) -> u8;

    fn next_str(&mut self) -> String {
        let len = self.next_len();
        let bytes = self.next_n_bytes_vec(len);
        std::str::from_utf8(&bytes).unwrap().to_string()
    }

    fn next_n_bytes<const N: usize>(&mut self) -> [u8; N];

    fn next_n_bytes_vec(&mut self, n: Length) -> Vec<u8>;
}

pub trait Logical: Clone + Sized {
    fn bool_and(&self, b: &Self) -> bool;
    fn bool_or(&self, b: &Self) -> bool;
    fn bool_xor(&self, b: &Self) -> bool;
    fn bool_not(&self) -> bool;

    fn logical_and(&self, b: &Self) -> Self {
        if self.bool_and(b) {
            self.clone()
        } else {
            b.clone()
        }
    }
    fn logical_or(&self, b: &Self) -> Self {
        if self.bool_or(b) {
            self.clone()
        } else {
            b.clone()
        }
    }
    fn logical_xor(&self, b: &Self) -> Self {
        if self.bool_xor(b) {
            self.clone()
        } else {
            b.clone()
        }
    }

    fn bitwise_reverse(&self) -> Self;
}

pub trait VMValue<Op, Val, T: VMValue<Op, Val, T>>: Display + Debug + Clone + PartialEq + Logical + Add<Output=T> + Mul<Output=T> + Div<Output=T> + PartialOrd + Sub<Output=T> + BitAnd<Output=T> + BitOr<Output=T> + BitXor<Output=T> + Rem<Output=T> + Not<Output=T> + Neg<Output=T> + Shr<Output=T> + Shl<Output=T> {
    fn create_from_vm_bytes<V: VM<Op, Val, T>>(vm: &mut V) -> T;

    fn to_vm_bytes(&self) -> Vec<u8>;
}

Dependencies

~1.3–1.9MB
~34K SLoC