summaryrefslogtreecommitdiffstats
path: root/bytecode/src
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-04-28 15:06:43 -0700
committerRose Hogenson <rosehogenson@posteo.net>2024-04-28 15:06:43 -0700
commit5737e8430d43b3b5bd448f761cd2f3c35707a174 (patch)
treeb24f44ea5245a56b2f712c2eef6a3897f53bd098 /bytecode/src
parent9f5889c1263d63b953b3a324da07321deef5ca58 (diff)
downloadsml-5737e8430d43b3b5bd448f761cd2f3c35707a174.tar.zst
Add case over int.
Diffstat (limited to 'bytecode/src')
-rw-r--r--bytecode/src/encoding.rs43
-rw-r--r--bytecode/src/heap.rs4
-rw-r--r--bytecode/src/main.rs28
3 files changed, 73 insertions, 2 deletions
diff --git a/bytecode/src/encoding.rs b/bytecode/src/encoding.rs
index 8bec753..80fcc58 100644
--- a/bytecode/src/encoding.rs
+++ b/bytecode/src/encoding.rs
@@ -68,6 +68,26 @@ pub struct Div {
}
#[derive(Debug, Clone, Copy)]
+pub struct Less {
+ pub out: u8,
+ pub val1: Arg,
+ pub val2: Arg,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct Eq {
+ pub out: u8,
+ pub val1: Arg,
+ pub val2: Arg,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct If {
+ pub test: Arg,
+ pub target: usize,
+}
+
+#[derive(Debug, Clone, Copy)]
pub enum Op {
Alloc(Alloc),
Call,
@@ -79,6 +99,9 @@ pub enum Op {
Sub(Sub),
Mul(Mul),
Div(Div),
+ Less(Less),
+ Eq(Eq),
+ If(If),
}
struct Reader<'a> {
@@ -198,6 +221,26 @@ impl Op {
let val2 = r.parse_arg(arg2_const)?;
Op::Div(Div { out, val1, val2 })
}
+ 11 => {
+ let out = r.parse_local()?;
+ let val1 = r.parse_arg(arg1_const)?;
+ let val2 = r.parse_arg(arg2_const)?;
+ Op::Less(Less { out, val1, val2 })
+ }
+ 12 => {
+ let out = r.parse_local()?;
+ let val1 = r.parse_arg(arg1_const)?;
+ let val2 = r.parse_arg(arg2_const)?;
+ Op::Eq(Eq { out, val1, val2 })
+ }
+ 13 => {
+ let test = r.parse_arg(arg1_const)?;
+ 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(Box::from(format!("invalid code {}", code)));
}
diff --git a/bytecode/src/heap.rs b/bytecode/src/heap.rs
index 45ce283..970db7d 100644
--- a/bytecode/src/heap.rs
+++ b/bytecode/src/heap.rs
@@ -1,7 +1,7 @@
use crate::value::Value;
use std::error::Error;
-pub const NUM_LOCALS: usize = 8;
+pub const NUM_LOCALS: usize = 256;
#[derive(Debug)]
pub struct Heap {
@@ -27,7 +27,7 @@ impl Heap {
let Some(q) = Value(self.buf[p]).to_pointer() else {
return false;
};
- return self.first_active == (q < self.buf.len() / 2);
+ self.first_active == (q < self.buf.len() / 2)
}
fn alloc_size(&self, p: usize) -> usize {
diff --git a/bytecode/src/main.rs b/bytecode/src/main.rs
index bbc0ddd..4cba4ef 100644
--- a/bytecode/src/main.rs
+++ b/bytecode/src/main.rs
@@ -96,6 +96,34 @@ impl State {
};
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(Box::from("less needs an int"));
+ };
+ let Some(v2) = self.read_arg(op.val2).to_int() else {
+ 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(Box::from("eq needs an int"));
+ };
+ let Some(v2) = self.read_arg(op.val2).to_int() else {
+ 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(Box::from("if needs an int"));
+ };
+ if t != 0 {
+ self.i = op.target;
+ }
+ }
}
Ok(())
}