From 56b4676fbd6bc7b0afe1daf078744b413fd33a0a Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 2 May 2022 11:14:23 +1000 Subject: [PATCH] Add VsPointer --- src/vstc/bytecode_decoder.rs | 31 +++++++-- src/vstc/vs_value.rs | 130 ++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 51 deletions(-) diff --git a/src/vstc/bytecode_decoder.rs b/src/vstc/bytecode_decoder.rs index db71955..ebfaddb 100644 --- a/src/vstc/bytecode_decoder.rs +++ b/src/vstc/bytecode_decoder.rs @@ -1,14 +1,15 @@ use std::rc::Rc; use super::vs_value; -struct BytecodeDecoder { - data: Rc>, - pos: usize, +pub struct BytecodeDecoder { + // TODO: Enable borrow usage to avoid the rc overhead + pub data: Rc>, + pub pos: usize, } #[repr(u8)] #[derive(PartialEq)] -enum BytecodeType { +pub enum BytecodeType { Undefined = 0x02, Null = 0x03, False = 0x04, @@ -20,6 +21,8 @@ enum BytecodeType { Object = 0x0a, Function = 0x0b, Instance = 0x0c, + Pointer = 0x0d, + Register = 0x0e, } impl BytecodeDecoder { @@ -44,6 +47,8 @@ impl BytecodeDecoder { 0x0a => Object, 0x0b => Function, 0x0c => Instance, + 0x0d => Pointer, + 0x0e => Register, _ => std::panic!("Unrecognized BytecodeType"), }; @@ -62,7 +67,17 @@ impl BytecodeDecoder { String => vs_value::VsString::from_string( self.decode_string() ), - _ => std::panic!("not imlemented"), + Pointer => { + let from_pos = self.pos; + let pos = self.decode_pos(); + + return vs_value::VsPointer::new( + &self.data, + from_pos, + pos, + ); + }, + _ => std::panic!("Not implemented"), } } @@ -102,4 +117,10 @@ impl BytecodeDecoder { res *= 128; } } + + pub fn decode_pos(&mut self) -> usize { + // TODO: the number of bytes to represent a position should be based on the + // size of the bytecode + return self.decode_byte() as usize; + } } diff --git a/src/vstc/vs_value.rs b/src/vstc/vs_value.rs index f12d25a..aeea35c 100644 --- a/src/vstc/vs_value.rs +++ b/src/vstc/vs_value.rs @@ -1,4 +1,7 @@ use std::rc::Rc; +use std::cell::RefCell; +use super::bytecode_decoder::BytecodeDecoder; +use super::bytecode_decoder::BytecodeType; pub type Val = Rc; @@ -59,28 +62,56 @@ impl VsString { } } -// pub struct VsPointer { -// bytecode: Rc>, -// pos: usize, -// } +pub struct VsPointer { + bytecode: Rc>, + pos: usize, + decoded: RefCell>, +} -// impl VsPointer { -// fn decode(&self) -> Val { -// return match self.bytecode[self.pos] { -// // 0x02 => VsType::Undefined, -// // 0x03 => VsType::Null, -// // 0x04 => VsType::Bool, -// // 0x05 => VsType::Bool, -// 0x06 => VsType::Number, -// 0x07 => VsType::Number, -// 0x08 => VsType::String, -// // 0x09 => VsType::Array, -// // 0x0a => VsType::Object, -// // 0x0b => VsType::Function, -// _ => std::panic!("not imlemented"), -// }; -// } -// } +impl VsPointer { + pub fn new(bytecode: &Rc>, from_pos: usize, pos: usize) -> Val { + if pos < from_pos { + let mut bd = BytecodeDecoder { + data: bytecode.clone(), + pos: pos, + }; + + let byte = bd.decode_byte(); + + if byte != BytecodeType::Function as u8 { + // Prevent circular objects + std::panic!("Invalid: non-function pointer that points backwards"); + } + } + + return Rc::new(VsPointer { + bytecode: bytecode.clone(), + pos: pos, + decoded: RefCell::new(None), + }); + } + + pub fn decode(&self) -> Val { + let mut decoded = self.decoded.borrow_mut(); + + if decoded.is_some() { + return decoded.clone().unwrap(); + } + + let mut bd = BytecodeDecoder { + data: self.bytecode.clone(), + pos: self.pos, + }; + + let val = bd.decode_val(); + + // TODO: Check that this actually inserts into the cell and not just a copy + // somehow + *decoded = Some(val.clone()); + + return val; + } +} impl VsValue for VsNumber { fn typeof_(&self) -> VsType { @@ -110,23 +141,38 @@ impl VsValue for VsString { } } -// impl VsValue for VsPointer { -// fn typeof_(&self) -> VsType { -// return match self.bytecode[self.pos] { -// 0x02 => VsType::Undefined, -// 0x03 => VsType::Null, -// 0x04 => VsType::Bool, -// 0x05 => VsType::Bool, -// 0x06 => VsType::Number, -// 0x07 => VsType::Number, -// 0x08 => VsType::String, -// 0x09 => VsType::Array, -// 0x0a => VsType::Object, -// 0x0b => VsType::Function, -// _ => std::panic!("not imlemented"), -// }; -// } -// } +impl VsValue for VsPointer { + fn typeof_(&self) -> VsType { + let mut bd = BytecodeDecoder { + data: self.bytecode.clone(), + pos: self.pos, + }; + + return match bd.decode_type() { + BytecodeType::Undefined => VsType::Undefined, + BytecodeType::Null => VsType::Null, + BytecodeType::False => VsType::Bool, + BytecodeType::True => VsType::Bool, + BytecodeType::SignedByte => VsType::Number, + BytecodeType::Number => VsType::Number, + BytecodeType::String => VsType::String, + BytecodeType::Array => VsType::Array, + BytecodeType::Object => VsType::Object, + BytecodeType::Function => VsType::Function, + BytecodeType::Instance => std::panic!("Not implemented"), + BytecodeType::Pointer => std::panic!("Invalid: pointer to pointer"), + BytecodeType::Register => std::panic!("Invalid: pointer to register"), + } + } + + fn to_string(&self) -> String { + return self.decode().to_string(); + } + + fn to_number(&self) -> f64 { + return self.decode().to_number(); + } +} impl std::fmt::Display for dyn VsValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -141,11 +187,3 @@ pub fn add(left: &Rc, right: &Rc) -> Rc { return VsNumber::from_f64(left.to_number() + right.to_number()); } - -// pub fn from_bytecode(bytecode: &Rc>) -> Rc { -// return from_bytecode_at(&bytecode, 0); -// } - -// pub fn from_bytecode_at(bytecode: &Rc>, pos: usize) -> Rc { - -// }