summaryrefslogtreecommitdiffstats
path: root/bytecode/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bytecode/src/main.rs')
-rw-r--r--bytecode/src/main.rs51
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(),