stak_device/
primitive_set.rs1mod error;
2mod primitive;
3
4pub use self::{error::PrimitiveError, primitive::Primitive};
5use crate::Device;
6use stak_vm::{Memory, Number, PrimitiveSet};
7use winter_maybe_async::{maybe_async, maybe_await};
8
9pub struct DevicePrimitiveSet<T: Device> {
11 device: T,
12}
13
14impl<T: Device> DevicePrimitiveSet<T> {
15 pub const fn new(device: T) -> Self {
17 Self { device }
18 }
19
20 pub const fn device(&self) -> &T {
22 &self.device
23 }
24
25 pub const fn device_mut(&mut self) -> &mut T {
27 &mut self.device
28 }
29}
30
31impl<T: Device> PrimitiveSet for DevicePrimitiveSet<T> {
32 type Error = PrimitiveError;
33
34 #[maybe_async]
35 fn operate(&mut self, memory: &mut Memory<'_>, primitive: usize) -> Result<(), Self::Error> {
36 match primitive {
37 Primitive::READ => {
38 let byte =
39 maybe_await!(self.device.read()).map_err(|_| PrimitiveError::ReadInput)?;
40
41 memory.push(if let Some(byte) = byte {
42 Number::from_i64(byte as _).into()
43 } else {
44 memory.boolean(false)?.into()
45 })?;
46 }
47 Primitive::WRITE => {
48 let byte = memory.pop()?.assume_number().to_i64() as u8;
49 maybe_await!(self.device.write(byte)).map_err(|_| PrimitiveError::WriteOutput)?;
50 memory.push(memory.boolean(false)?.into())?;
51 }
52 Primitive::WRITE_ERROR => {
53 let byte = memory.pop()?.assume_number().to_i64() as u8;
54 maybe_await!(self.device.write_error(byte))
55 .map_err(|_| PrimitiveError::WriteError)?;
56 memory.push(memory.boolean(false)?.into())?;
57 }
58 _ => return Err(stak_vm::Error::IllegalPrimitive.into()),
59 }
60
61 Ok(())
62 }
63}