diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-12 08:21:14 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-12 08:21:14 -0700 |
| commit | 8ec4edc977e0ed87f86c7e74c13d3633cb788069 (patch) | |
| tree | 0a2ef1c6c89e5187e4082adf22d4ab87925cd7dd /bytecode/src/main.rs | |
| parent | 7b87d7185fc93b92606fcacbc1ea3d7a8e02cb20 (diff) | |
| download | sml-8ec4edc977e0ed87f86c7e74c13d3633cb788069.tar.zst | |
Revert "Use strings for errors."
This reverts commit 7b87d7185fc93b92606fcacbc1ea3d7a8e02cb20.
It was an interesting experiment, but String seems to be worse than
Box<dyn Error> in every way.
Diffstat (limited to 'bytecode/src/main.rs')
| -rw-r--r-- | bytecode/src/main.rs | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/bytecode/src/main.rs b/bytecode/src/main.rs index 4981734..4cba4ef 100644 --- a/bytecode/src/main.rs +++ b/bytecode/src/main.rs @@ -4,6 +4,7 @@ mod value; use encoding::{Arg, Op}; use heap::Heap; +use std::error::Error; use std::ffi::OsString; use std::io::{stderr, Write}; use value::Value; @@ -21,32 +22,29 @@ impl State { } } - fn op(&mut self, op: Op) -> Result<(), String> { + fn op(&mut self, op: Op) -> Result<(), Box<dyn Error>> { match op { Op::Alloc(op) => { let Some(i) = self.read_arg(op.size).to_int() else { - return Err(String::from("alloc needs an int")); + return Err(Box::from("alloc needs an int")); }; self.heap.locals[usize::from(op.out)] = Value::from_pointer(self.heap.alloc(i)?); } Op::Call => { let Some(i) = self.heap.locals[0].to_int() else { - return Err(String::from("call needs an int")); + return Err(Box::from("call needs an int")); }; - let Ok(u) = usize::try_from(i) else { - return Err(String::from("call needs a positive int")); - }; - self.i = u; + self.i = usize::try_from(i)?; } Op::Poke(op) => { let Some(p) = self.heap.locals[usize::from(op.ptr)].to_pointer() else { - return Err(String::from("poke needs a pointer")); + return Err(Box::from("poke needs a pointer")); }; self.heap.poke(p + op.offset, self.read_arg(op.val))?; } Op::Peek(op) => { let Some(p) = self.read_arg(op.val).to_pointer() else { - return Err(String::from("peek needs a pointer")); + return Err(Box::from("peek needs a pointer")); }; self.heap.locals[usize::from(op.out)] = self.heap.peek(p + op.offset)?; } @@ -61,66 +59,66 @@ impl State { } Op::Add(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("add needs an int")); + return Err(Box::from("add needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("add needs an int")); + return Err(Box::from("add needs an int")); }; self.heap.locals[usize::from(op.out)] = Value::from_int(v1.wrapping_add(v2)); } Op::Sub(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("sub needs an int")); + return Err(Box::from("sub needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("sub needs an int")); + return Err(Box::from("sub needs an int")); }; self.heap.locals[usize::from(op.out)] = Value::from_int(v1.wrapping_sub(v2)); } Op::Mul(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("mul needs an int")); + return Err(Box::from("mul needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("mul needs an int")); + return Err(Box::from("mul needs an int")); }; self.heap.locals[usize::from(op.out)] = Value::from_int(v1.wrapping_mul(v2)); } Op::Div(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("div needs an int")); + return Err(Box::from("div needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("div needs an int")); + return Err(Box::from("div needs an int")); }; let Some(res) = v1.checked_div(v2) else { - return Err(String::from("division by zero")); + return Err(Box::from("division by zero")); }; self.heap.locals[usize::from(op.out)] = Value::from_int(res); } Op::Less(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("less needs an int")); + return Err(Box::from("less needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("less needs an int")); + return Err(Box::from("less needs an int")); }; let res = if v1 < v2 { 1 } else { 0 }; self.heap.locals[usize::from(op.out)] = Value::from_int(res); } Op::Eq(op) => { let Some(v1) = self.read_arg(op.val1).to_int() else { - return Err(String::from("eq needs an int")); + return Err(Box::from("eq needs an int")); }; let Some(v2) = self.read_arg(op.val2).to_int() else { - return Err(String::from("eq needs an int")); + return Err(Box::from("eq needs an int")); }; let res = if v1 == v2 { 1 } else { 0 }; self.heap.locals[usize::from(op.out)] = Value::from_int(res); } Op::If(op) => { let Some(t) = self.read_arg(op.test).to_int() else { - return Err(String::from("if needs an int")); + return Err(Box::from("if needs an int")); }; if t != 0 { self.i = op.target; @@ -131,13 +129,12 @@ impl State { } } -fn run() -> Result<(), String> { +fn run() -> Result<(), Box<dyn Error>> { let args: Vec<OsString> = std::env::args_os().collect(); if args.len() != 2 { - return Err(String::from("usage: bytecode <file>")); + return Err(Box::from("usage: bytecode <file>")); } - let prog = std::fs::read(&args[1]) - .map_err(|err| format!("read program from {:?}: {}", args[1], err))?; + let prog = std::fs::read(&args[1])?; let mut st = State { i: 0, heap: Heap::new(), |
