diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-11 14:51:55 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-11 14:51:55 +0100 |
| commit | cf9ad28eb0a62c2c89f2f679157a54eded97c1cf (patch) | |
| tree | 3aec0cbf020c0e6e55f066269326d2613aed58a0 /src/vm.rs | |
| parent | 6c631112c5dc05f861100471d97023dddaa17283 (diff) | |
| download | sylt-cf9ad28eb0a62c2c89f2f679157a54eded97c1cf.tar.gz | |
If-statements
Diffstat (limited to 'src/vm.rs')
| -rw-r--r-- | src/vm.rs | 35 |
1 files changed, 32 insertions, 3 deletions
@@ -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 { |
