aboutsummaryrefslogtreecommitdiffstats
path: root/src/vm.rs
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-01-11 14:51:55 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-01-11 14:51:55 +0100
commitcf9ad28eb0a62c2c89f2f679157a54eded97c1cf (patch)
tree3aec0cbf020c0e6e55f066269326d2613aed58a0 /src/vm.rs
parent6c631112c5dc05f861100471d97023dddaa17283 (diff)
downloadsylt-cf9ad28eb0a62c2c89f2f679157a54eded97c1cf.tar.gz
If-statements
Diffstat (limited to 'src/vm.rs')
-rw-r--r--src/vm.rs35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/vm.rs b/src/vm.rs
index 1d66c12..7f121d4 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -21,6 +21,8 @@ pub enum Value {
#[derive(Debug, Clone, Copy)]
pub enum Op {
+ Illegal,
+
Pop,
Constant(Value),
@@ -34,6 +36,9 @@ pub enum Op {
Or,
Not,
+ Jmp(usize),
+ JmpFalse(usize),
+
Equal, // ==
Less, // <
Greater, // >
@@ -69,7 +74,7 @@ impl Block {
}
pub fn add(&mut self, op: Op, token_position: usize) -> usize {
- let len = self.ops.len();
+ let len = self.curr();
if token_position != self.last_line_offset {
self.line_offsets.insert(len, token_position);
self.last_line_offset = token_position;
@@ -79,12 +84,20 @@ impl Block {
}
pub fn add_from(&mut self, ops: &[Op], token_position: usize) -> usize {
- let len = self.ops.len();
+ let len = self.curr();
for op in ops {
self.add(*op, token_position);
}
len
}
+
+ pub fn curr(&self) -> usize {
+ self.ops.len()
+ }
+
+ pub fn patch(&mut self, op: Op, pos: usize) {
+ self.ops[pos] = op;
+ }
}
#[derive(Debug)]
@@ -135,7 +148,7 @@ impl VM {
}
pub fn run(&mut self) -> Result<(), Error>{
- const PRINT_WHILE_RUNNING: bool = false;
+ const PRINT_WHILE_RUNNING: bool = true;
const PRINT_BLOCK: bool = true;
if PRINT_BLOCK {
@@ -159,6 +172,10 @@ impl VM {
let op = self.block.ops[self.ip];
match op {
+ Op::Illegal => {
+ error!(self, ErrorKind::InvalidProgram);
+ }
+
Op::Pop => {
self.stack.pop();
}
@@ -243,6 +260,18 @@ impl VM {
}
}
+ Op::Jmp(line) => {
+ self.ip = line;
+ continue;
+ }
+
+ Op::JmpFalse(line) => {
+ if Some(Value::Bool(false)) == self.stack.pop() {
+ self.ip = line;
+ continue;
+ }
+ }
+
Op::AssertEqual => {
let (a, b) = self.pop_twice();
if a != b {