mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-05-10 03:00:06 -04:00
Make unary ops to &Val
This commit is contained in:
@@ -95,60 +95,70 @@ impl BytecodeDecoder {
|
||||
return BytecodeType::from_byte(self.peek_byte());
|
||||
}
|
||||
|
||||
pub fn decode_val(&mut self, registers: &Vec<Val>) -> Val {
|
||||
pub fn decode_vallish<'a>(&mut self, registers: &'a Vec<Val>) -> Vallish<'a> {
|
||||
use Vallish::*;
|
||||
|
||||
return match self.decode_type() {
|
||||
BytecodeType::End => panic!("Cannot decode end"),
|
||||
BytecodeType::Void => Val::Void,
|
||||
BytecodeType::Undefined => Val::Undefined,
|
||||
BytecodeType::Null => Val::Null,
|
||||
BytecodeType::False => Val::Bool(false),
|
||||
BytecodeType::True => Val::Bool(true),
|
||||
BytecodeType::SignedByte => (self.decode_signed_byte() as f64).to_val(),
|
||||
BytecodeType::Number => self.decode_number().to_val(),
|
||||
BytecodeType::String => self.decode_string().to_val(),
|
||||
BytecodeType::Array => self.decode_vec_val(registers).to_val(),
|
||||
BytecodeType::Void => Own(Val::Void),
|
||||
BytecodeType::Undefined => Own(Val::Undefined),
|
||||
BytecodeType::Null => Own(Val::Null),
|
||||
BytecodeType::False => Own(Val::Bool(false)),
|
||||
BytecodeType::True => Own(Val::Bool(true)),
|
||||
BytecodeType::SignedByte => Own((self.decode_signed_byte() as f64).to_val()),
|
||||
BytecodeType::Number => Own(self.decode_number().to_val()),
|
||||
BytecodeType::String => Own(self.decode_string().to_val()),
|
||||
BytecodeType::Array => Own(self.decode_vec_val(registers).to_val()),
|
||||
BytecodeType::Object => {
|
||||
let mut string_map: BTreeMap<String, Val> = BTreeMap::new();
|
||||
let mut symbol_map: BTreeMap<VsSymbol, Val> = BTreeMap::new();
|
||||
|
||||
while self.peek_type() != BytecodeType::End {
|
||||
let key = self.decode_val(registers);
|
||||
let key = self.decode_vallish(registers);
|
||||
let value = self.decode_val(registers);
|
||||
|
||||
match key {
|
||||
match key.get_ref() {
|
||||
Val::String(string) => string_map.insert(string.to_string(), value),
|
||||
Val::Symbol(symbol) => symbol_map.insert(symbol, value),
|
||||
Val::Symbol(symbol) => symbol_map.insert(symbol.clone(), value),
|
||||
key => string_map.insert(key.to_string(), value),
|
||||
};
|
||||
}
|
||||
|
||||
self.decode_type(); // End (TODO: assert)
|
||||
|
||||
VsObject {
|
||||
string_map,
|
||||
symbol_map,
|
||||
prototype: None,
|
||||
}
|
||||
.to_val()
|
||||
Own(
|
||||
VsObject {
|
||||
string_map,
|
||||
symbol_map,
|
||||
prototype: None,
|
||||
}
|
||||
.to_val(),
|
||||
)
|
||||
}
|
||||
BytecodeType::Function => self.decode_function(false),
|
||||
BytecodeType::Pointer => self.decode_pointer(registers),
|
||||
BytecodeType::Register => match registers[self.decode_register_index().unwrap()].clone() {
|
||||
Val::Void => Val::Undefined,
|
||||
val => val,
|
||||
BytecodeType::Function => Own(self.decode_function(false)),
|
||||
BytecodeType::Pointer => Own(self.decode_pointer(registers)),
|
||||
BytecodeType::Register => match registers[self.decode_register_index().unwrap()] {
|
||||
Val::Void => Own(Val::Undefined),
|
||||
ref val => Ref(val),
|
||||
},
|
||||
BytecodeType::Builtin => BUILTIN_VALS[self.decode_varsize_uint()](),
|
||||
BytecodeType::Class => VsClass {
|
||||
constructor: self.decode_val(registers),
|
||||
instance_prototype: self.decode_val(registers),
|
||||
}
|
||||
.to_val(),
|
||||
BytecodeType::BigInt => self.decode_bigint().to_val(),
|
||||
BytecodeType::GeneratorFunction => self.decode_function(true),
|
||||
BytecodeType::Builtin => Own(BUILTIN_VALS[self.decode_varsize_uint()]()),
|
||||
BytecodeType::Class => Own(
|
||||
VsClass {
|
||||
constructor: self.decode_val(registers),
|
||||
instance_prototype: self.decode_val(registers),
|
||||
}
|
||||
.to_val(),
|
||||
),
|
||||
BytecodeType::BigInt => Own(self.decode_bigint().to_val()),
|
||||
BytecodeType::GeneratorFunction => Own(self.decode_function(true)),
|
||||
BytecodeType::Unrecognized => panic!("Unrecognized bytecode type at {}", self.pos - 1),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode_val(&mut self, registers: &Vec<Val>) -> Val {
|
||||
return self.decode_vallish(registers).get_val();
|
||||
}
|
||||
|
||||
pub fn decode_vec_val(&mut self, registers: &Vec<Val>) -> Vec<Val> {
|
||||
let mut vals: Vec<Val> = Vec::new();
|
||||
|
||||
@@ -298,3 +308,24 @@ impl BytecodeDecoder {
|
||||
return InstructionByte::from_byte(self.decode_byte());
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Vallish<'a> {
|
||||
Own(Val),
|
||||
Ref(&'a Val),
|
||||
}
|
||||
|
||||
impl<'a> Vallish<'a> {
|
||||
pub fn get_val(self) -> Val {
|
||||
match self {
|
||||
Vallish::Own(val) => val,
|
||||
Vallish::Ref(val) => val.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ref(&self) -> &Val {
|
||||
match self {
|
||||
Vallish::Own(val) => val,
|
||||
Vallish::Ref(val) => val,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,13 @@ pub struct CatchSetting {
|
||||
}
|
||||
|
||||
impl BytecodeStackFrame {
|
||||
pub fn apply_unary_op(&mut self, op: fn(input: Val) -> Val) {
|
||||
let input = self.decoder.decode_val(&self.registers);
|
||||
pub fn apply_unary_op(&mut self, op: fn(input: &Val) -> Val) {
|
||||
let input = self.decoder.decode_vallish(&self.registers);
|
||||
|
||||
let register_index = self.decoder.decode_register_index();
|
||||
|
||||
if register_index.is_some() {
|
||||
self.registers[register_index.unwrap()] = op(input);
|
||||
self.registers[register_index.unwrap()] = op(input.get_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn op_plus(left: Val, right: Val) -> Result<Val, Val> {
|
||||
return Ok(Val::Number(left_prim.to_number() + right_prim.to_number()));
|
||||
}
|
||||
|
||||
pub fn op_unary_plus(input: Val) -> Val {
|
||||
pub fn op_unary_plus(input: &Val) -> Val {
|
||||
match input.as_bigint_data() {
|
||||
Some(bigint) => Val::BigInt(bigint),
|
||||
_ => Val::Number(input.to_number()),
|
||||
@@ -60,7 +60,7 @@ pub fn op_minus(left: Val, right: Val) -> Result<Val, Val> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn op_unary_minus(input: Val) -> Val {
|
||||
pub fn op_unary_minus(input: &Val) -> Val {
|
||||
match input.as_bigint_data() {
|
||||
Some(bigint) => Val::BigInt(-bigint),
|
||||
_ => Val::Number(-input.to_number()),
|
||||
@@ -170,7 +170,7 @@ pub fn op_or(left: Val, right: Val) -> Result<Val, Val> {
|
||||
Ok(if left.is_truthy() { left } else { right })
|
||||
}
|
||||
|
||||
pub fn op_not(input: Val) -> Val {
|
||||
pub fn op_not(input: &Val) -> Val {
|
||||
return Val::Bool(!input.is_truthy());
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ pub fn op_bit_or(left: Val, right: Val) -> Result<Val, Val> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn op_bit_not(input: Val) -> Val {
|
||||
pub fn op_bit_not(input: &Val) -> Val {
|
||||
match input.as_bigint_data() {
|
||||
Some(bigint) => Val::BigInt(!bigint),
|
||||
None => {
|
||||
@@ -341,7 +341,7 @@ pub fn op_right_shift_unsigned(left: Val, right: Val) -> Result<Val, Val> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn op_typeof(input: Val) -> Val {
|
||||
pub fn op_typeof(input: &Val) -> Val {
|
||||
use VsType::*;
|
||||
|
||||
match input.typeof_() {
|
||||
|
||||
Reference in New Issue
Block a user