diff options
Diffstat (limited to 'bytecode/src/encoding.rs')
| -rw-r--r-- | bytecode/src/encoding.rs | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/bytecode/src/encoding.rs b/bytecode/src/encoding.rs index 81cb29f..80fcc58 100644 --- a/bytecode/src/encoding.rs +++ b/bytecode/src/encoding.rs @@ -1,5 +1,6 @@ use crate::heap; use crate::value::Value; +use std::error::Error; #[derive(Debug, Clone, Copy)] pub enum Arg { @@ -114,30 +115,30 @@ impl Reader<'_> { self.n += size; } - fn parse_byte(&mut self) -> Result<u8, String> { + fn parse_byte(&mut self) -> Result<u8, Box<dyn Error>> { if self.data.is_empty() { - return Err(String::from("read byte: no data")); + return Err(Box::from("read byte: no data")); } let res = self.data[0]; self.advance(1); Ok(res) } - fn parse_local(&mut self) -> Result<u8, String> { + fn parse_local(&mut self) -> Result<u8, Box<dyn Error>> { if self.data.is_empty() { - return Err(String::from("local: no data")); + return Err(Box::from("local: no data")); } let res = self.data[0]; if usize::from(res) >= heap::NUM_LOCALS { - return Err(format!("invalid local (out of range): {}", res)); + return Err(Box::from(format!("invalid local (out of range): {}", res))); } self.advance(1); Ok(res) } - fn parse_value(&mut self) -> Result<Value, String> { + fn parse_value(&mut self) -> Result<Value, Box<dyn Error>> { if self.data.len() < 8 { - return Err(String::from("value: no data")); + return Err(Box::from("value: no data")); } let mut res = [0; 8]; res.copy_from_slice(&self.data[..8]); @@ -145,17 +146,7 @@ impl Reader<'_> { Ok(Value(u64::from_le_bytes(res))) } - fn parse_offset(&mut self) -> Result<usize, String> { - let Some(ioffset) = self.parse_value()?.to_int() else { - return Err(String::from("invalid offset")); - }; - let Ok(offset) = usize::try_from(ioffset) else { - return Err(String::from("invalid offset")); - }; - Ok(offset) - } - - fn parse_arg(&mut self, is_const: bool) -> Result<Arg, String> { + fn parse_arg(&mut self, is_const: bool) -> Result<Arg, Box<dyn Error>> { if is_const { Ok(Arg::Const(self.parse_value()?)) } else { @@ -165,7 +156,7 @@ impl Reader<'_> { } impl Op { - pub fn parse(data: &[u8]) -> Result<(usize, Op), String> { + pub fn parse(data: &[u8]) -> Result<(usize, Op), Box<dyn Error>> { let mut r = Reader { data, n: 0 }; let code_byte = r.parse_byte()?; let code = code_byte >> 2; @@ -180,14 +171,20 @@ impl Op { } 2 => Op::Call, 3 => { - let offset = r.parse_offset()?; + let Some(ioffset) = r.parse_value()?.to_int() else { + return Err(Box::from("invalid offset")); + }; + let offset = usize::try_from(ioffset)?; let ptr = r.parse_local()?; let val = r.parse_arg(arg1_const)?; Op::Poke(Poke { offset, ptr, val }) } 4 => { let out = r.parse_local()?; - let offset = r.parse_offset()?; + let Some(ioffset) = r.parse_value()?.to_int() else { + return Err(Box::from("invalid offset")); + }; + let offset = usize::try_from(ioffset)?; let val = r.parse_arg(arg1_const)?; Op::Peek(Peek { out, offset, val }) } @@ -238,11 +235,14 @@ impl Op { } 13 => { let test = r.parse_arg(arg1_const)?; - let target = r.parse_offset()?; + let Some(itarget) = r.parse_value()?.to_int() else { + return Err(Box::from("invalid target")); + }; + let target = usize::try_from(itarget)?; Op::If(If { test, target }) } _ => { - return Err(format!("invalid code {}", code)); + return Err(Box::from(format!("invalid code {}", code))); } }; |
