Add VsBool and jump instructions

This commit is contained in:
Andrew Morris
2022-05-02 16:11:25 +10:00
parent b5f1cc7b78
commit 78cacc3372
4 changed files with 76 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
mod vs_value;
mod vs_undefined;
mod vs_bool;
mod vs_number;
mod vs_string;
mod vs_function;

View File

@@ -3,6 +3,7 @@ use super::vs_value::ValTrait;
use super::vs_value::VsType;
use super::vs_string::VsString;
use super::vs_number::VsNumber;
use super::vs_bool::VsBool;
pub fn op_plus(left: &Val, right: &Val) -> Val {
let left_prim = left.to_primitive();
@@ -22,3 +23,11 @@ pub fn op_mul(left: &Val, right: &Val) -> Val {
pub fn op_mod(left: &Val, right: &Val) -> Val {
return VsNumber::from_f64(left.to_number() % right.to_number());
}
pub fn op_less(left: &Val, right: &Val) -> Val {
if left.typeof_() != VsType::Number || right.typeof_() != VsType::Number {
std::panic!("Not implemented");
}
return VsBool::from_bool(left.to_number() < right.to_number());
}

View File

@@ -108,9 +108,30 @@ impl VirtualMachine {
}
},
// 0x11 => OpLess,
// 0x27 => Jmp,
// 0x28 => JmpIf,
OpLess => {
let left = frame.decoder.decode_val(&frame.registers);
let right = frame.decoder.decode_val(&frame.registers);
let register_index = frame.decoder.decode_register_index();
if register_index.is_some() {
frame.registers[register_index.unwrap()] = operations::op_less(&left, &right);
}
}
Jmp => {
let dst = frame.decoder.decode_pos();
frame.decoder.pos = dst;
}
JmpIf => {
let cond = frame.decoder.decode_val(&frame.registers);
let dst = frame.decoder.decode_pos();
if cond.is_truthy() {
frame.decoder.pos = dst;
}
}
_ => std::panic!("Not implemented"),
};

View File

@@ -0,0 +1,42 @@
use std::rc::Rc;
use super::vs_value::Val;
use super::vs_value::VsType;
use super::vs_value::VsValue;
use super::virtual_machine::VirtualMachine;
pub struct VsBool {
value: bool,
}
impl VsBool {
pub fn from_bool(value: bool) -> Val {
return Rc::new(VsBool { value: value });
}
}
impl VsValue for VsBool {
fn typeof_(&self) -> VsType {
return VsType::Bool;
}
fn to_string(&self) -> String {
return self.value.to_string();
}
fn to_number(&self) -> f64 {
return if self.value { 1_f64 } else { 0_f64 };
}
fn is_primitive(&self) -> bool {
return true;
}
fn push_frame(&self, vm: &mut VirtualMachine) -> bool {
return false;
}
fn is_truthy(&self) -> bool {
return self.value;
}
}