diff options
Diffstat (limited to '')
| -rw-r--r-- | src/engine.rs | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/src/engine.rs b/src/engine.rs index 8cf2726..6c69bc1 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -2,11 +2,29 @@ //! //! This predominantly allows implementation of a [`u16`] executor. -use std::io::Read; +use std::io::{Cursor, Read}; +use byteorder::{BigEndian, ReadBytesExt}; use num_traits::{One, Unsigned, WrappingAdd, WrappingSub, Zero}; +use thiserror::Error; -use crate::executor::{self, Error}; +use crate::executor; + +/// Error type for engine errors +#[derive(Debug, Error)] +pub enum Error { + /// Engine ran into an io Error + #[error(transparent)] + Io(#[from] std::io::Error), + + /// Utf16 error from widestring + #[error("could not convert byte to Utf16Str")] + Utf16, + + /// Utf32 error from widestring + #[error("could not convert byte to Utf32Str")] + Utf32, +} /// Generic engine implementation for the Brainfuck interpreter. pub trait Engine { @@ -56,13 +74,39 @@ impl Engine for executor::U16 { std::io::stdin().read_exact(&mut input)?; - let number = ((u16::from(input[0])) << 8i32) | u16::from(input[1]); + let mut reader = Cursor::new(input); - Ok(number) + Ok(reader.read_u16::<BigEndian>()?) } fn write_byte(byte: u16) -> Result<(), Error> { - print!("{}", String::from_utf16_lossy(&[byte])); + print!( + "{}", + widestring::Utf16Str::from_slice(&[byte]).map_err(|_err| Error::Utf16)? + ); + + Ok(()) + } +} + +impl Engine for executor::U32 { + type TapeInner = u32; + + fn read_byte() -> Result<u32, Error> { + let mut input: [u8; 4] = [0; 4]; + + std::io::stdin().read_exact(&mut input)?; + + let mut reader = Cursor::new(input); + + Ok(reader.read_u32::<BigEndian>()?) + } + + fn write_byte(byte: u32) -> Result<(), Error> { + print!( + "{}", + widestring::Utf32Str::from_slice(&[byte]).map_err(|_err| Error::Utf32)? + ); Ok(()) } |