mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Implement new instruction
This commit is contained in:
@@ -3,6 +3,7 @@ use std::rc::Rc;
|
||||
use super::vs_value::{Val, VsType, ValTrait, LoadFunctionResult};
|
||||
use super::vs_array::VsArray;
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_class::VsClass;
|
||||
use super::native_function::NativeFunction;
|
||||
use super::operations::to_u32;
|
||||
|
||||
@@ -24,6 +25,7 @@ impl ValTrait for Math {
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NotAFunction
|
||||
|
||||
@@ -8,6 +8,7 @@ use super::vs_value::{
|
||||
};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
use super::vs_class::VsClass;
|
||||
|
||||
pub struct NativeFunction {
|
||||
pub fn_: fn(this: &mut Val, params: Vec<Val>) -> Val,
|
||||
@@ -29,6 +30,7 @@ impl ValTrait for NativeFunction {
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NativeFunction(self.fn_)
|
||||
|
||||
@@ -218,9 +218,10 @@ pub fn op_typeof(input: Val) -> Val {
|
||||
Array => "object".to_string(),
|
||||
Object => "object".to_string(),
|
||||
Function => "function".to_string(),
|
||||
Class => "function".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
pub fn op_instance_of(_left: Val, _right: Val) -> Val {
|
||||
std::panic!("Not implemented: op_instance_of");
|
||||
}
|
||||
@@ -286,6 +287,7 @@ pub fn op_sub(left: Val, right: Val) -> Val {
|
||||
return object_data.sub(right);
|
||||
},
|
||||
Val::Function(_) => Val::Undefined,
|
||||
Val::Class(_) => Val::Undefined,
|
||||
Val::Static(s) => s.sub(right),
|
||||
Val::Custom(custom_data) => custom_data.sub(right),
|
||||
}
|
||||
@@ -325,6 +327,7 @@ pub fn op_submov(target: &mut Val, subscript: Val, value: Val) {
|
||||
Rc::make_mut(object_data).string_map.insert(subscript.val_to_string(), value);
|
||||
},
|
||||
Val::Function(_) => std::panic!("Not implemented: function subscript assignment"),
|
||||
Val::Class(_) => std::panic!("Not implemented: class subscript assignment"),
|
||||
Val::Static(_) => std::panic!("Not implemented: exceptions"),
|
||||
Val::Custom(_) => std::panic!("Not implemented"),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::vs_object::VsObject;
|
||||
use super::operations;
|
||||
use super::bytecode_decoder::BytecodeDecoder;
|
||||
use super::bytecode_decoder::BytecodeType;
|
||||
@@ -233,7 +234,7 @@ impl VirtualMachine {
|
||||
|
||||
self.push(new_frame);
|
||||
},
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
LoadFunctionResult::NativeFunction(_native_fn) => {
|
||||
std::panic!("Not implemented");
|
||||
},
|
||||
}
|
||||
@@ -366,7 +367,44 @@ impl VirtualMachine {
|
||||
UnaryPlus => self.frame.apply_unary_op(operations::op_unary_plus),
|
||||
UnaryMinus => self.frame.apply_unary_op(operations::op_unary_minus),
|
||||
|
||||
New => std::panic!("Not implemented"),
|
||||
New => {
|
||||
let class = self.frame.decoder.decode_val(&self.frame.registers)
|
||||
.as_class_data()
|
||||
.expect("Not implemented: throw exception (not constructible)");
|
||||
|
||||
let mut instance = Val::Object(Rc::new(VsObject {
|
||||
string_map: Default::default(),
|
||||
prototype: Some(class.instance_prototype.clone()),
|
||||
}));
|
||||
|
||||
match class.constructor.load_function() {
|
||||
LoadFunctionResult::NotAFunction =>
|
||||
std::panic!("Not implemented: throw exception (class.constructor is not a function)")
|
||||
,
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
transfer_parameters(&mut self.frame, &mut new_frame);
|
||||
new_frame.registers[1] = instance;
|
||||
|
||||
self.frame.return_target = None;
|
||||
self.frame.this_target = self.frame.decoder.decode_register_index();
|
||||
|
||||
self.push(new_frame);
|
||||
},
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
native_fn(
|
||||
&mut instance,
|
||||
get_parameters(&mut self.frame),
|
||||
);
|
||||
|
||||
match self.frame.decoder.decode_register_index() {
|
||||
Some(target) => {
|
||||
self.frame.registers[target] = instance;
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use super::vs_value::{
|
||||
LoadFunctionResult,
|
||||
};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_class::VsClass;
|
||||
use super::native_function::NativeFunction;
|
||||
use super::operations::op_triple_eq_impl;
|
||||
|
||||
@@ -47,6 +48,7 @@ impl ValTrait for ArrayPrototype {
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NotAFunction
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::vs_value::Val;
|
||||
use super::vs_function::VsFunction;
|
||||
|
||||
pub struct VsClass {
|
||||
pub constructor: Rc<VsFunction>,
|
||||
pub constructor: Val,
|
||||
pub instance_prototype: Val,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ use super::vs_value::{Val, ValTrait, VsType, LoadFunctionResult};
|
||||
use super::bytecode_decoder::{BytecodeDecoder, BytecodeType};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
use super::vs_class::VsClass;
|
||||
|
||||
pub struct VsPointer {
|
||||
bytecode: Rc<Vec<u8>>,
|
||||
@@ -118,6 +119,10 @@ impl ValTrait for VsPointer {
|
||||
return self.resolve().as_object_data();
|
||||
}
|
||||
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> {
|
||||
return self.resolve().as_class_data();
|
||||
}
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
return self.resolve().load_function();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use super::vs_function::VsFunction;
|
||||
use super::virtual_machine::StackFrame;
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
// use super::vs_class::VsClass;
|
||||
use super::vs_class::VsClass;
|
||||
use super::operations::{op_sub, op_submov};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -19,7 +19,7 @@ pub enum Val {
|
||||
Array(Rc<VsArray>),
|
||||
Object(Rc<VsObject>),
|
||||
Function(Rc<VsFunction>),
|
||||
// Class(Rc<VsClass>),
|
||||
Class(Rc<VsClass>),
|
||||
Static(&'static dyn ValTrait),
|
||||
Custom(Rc<dyn ValTrait>),
|
||||
}
|
||||
@@ -34,6 +34,7 @@ pub enum VsType {
|
||||
Array,
|
||||
Object,
|
||||
Function,
|
||||
Class,
|
||||
}
|
||||
|
||||
pub enum LoadFunctionResult {
|
||||
@@ -56,6 +57,7 @@ pub trait ValTrait {
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>>;
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>>;
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>>;
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult;
|
||||
|
||||
@@ -79,6 +81,7 @@ impl ValTrait for Val {
|
||||
Array(_) => VsType::Array,
|
||||
Object(_) => VsType::Object,
|
||||
Function(_) => VsType::Function,
|
||||
Class(_) => VsType::Class,
|
||||
Static(val) => val.typeof_(),
|
||||
Custom(val) => val.typeof_(),
|
||||
};
|
||||
@@ -117,6 +120,7 @@ impl ValTrait for Val {
|
||||
},
|
||||
Object(_) => "[object Object]".to_string(),
|
||||
Function(_) => "[function]".to_string(),
|
||||
Class(_) => "[class]".to_string(),
|
||||
Static(val) => val.val_to_string(),
|
||||
Custom(val) => val.val_to_string(),
|
||||
};
|
||||
@@ -139,6 +143,7 @@ impl ValTrait for Val {
|
||||
},
|
||||
Object(_) => f64::NAN,
|
||||
Function(_) => f64::NAN,
|
||||
Class(_) => f64::NAN,
|
||||
Static(val) => val.to_number(),
|
||||
Custom(val) => val.to_number(),
|
||||
};
|
||||
@@ -160,6 +165,7 @@ impl ValTrait for Val {
|
||||
Array(_) => None,
|
||||
Object(_) => None,
|
||||
Function(_) => None,
|
||||
Class(_) => None,
|
||||
Static(val) => val.to_index(),
|
||||
Custom(val) => val.to_index(),
|
||||
};
|
||||
@@ -178,6 +184,7 @@ impl ValTrait for Val {
|
||||
Array(_) => false,
|
||||
Object(_) => false,
|
||||
Function(_) => false,
|
||||
Class(_) => false,
|
||||
Static(val) => val.is_primitive(), // TODO: false?
|
||||
Custom(val) => val.is_primitive(),
|
||||
}
|
||||
@@ -204,6 +211,7 @@ impl ValTrait for Val {
|
||||
Array(_) => true,
|
||||
Object(_) => true,
|
||||
Function(_) => true,
|
||||
Class(_) => true,
|
||||
Static(val) => val.is_truthy(), // TODO: true?
|
||||
Custom(val) => val.is_truthy(),
|
||||
};
|
||||
@@ -222,6 +230,7 @@ impl ValTrait for Val {
|
||||
Array(_) => false,
|
||||
Object(_) => false,
|
||||
Function(_) => false,
|
||||
Class(_) => false,
|
||||
Static(_) => false,
|
||||
Custom(val) => val.is_nullish(),
|
||||
};
|
||||
@@ -235,7 +244,7 @@ impl ValTrait for Val {
|
||||
Custom(val) => val.bind(params),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> {
|
||||
@@ -246,7 +255,7 @@ impl ValTrait for Val {
|
||||
Custom(val) => val.as_array_data(),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> {
|
||||
@@ -257,7 +266,18 @@ impl ValTrait for Val {
|
||||
Custom(val) => val.as_object_data(),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> {
|
||||
use Val::*;
|
||||
|
||||
return match self {
|
||||
Class(class) => Some(class.clone()),
|
||||
Custom(val) => val.as_class_data(),
|
||||
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
@@ -269,7 +289,7 @@ impl ValTrait for Val {
|
||||
Custom(val) => val.load_function(),
|
||||
|
||||
_ => LoadFunctionResult::NotAFunction,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn sub(&self, key: Val) -> Val {
|
||||
@@ -341,6 +361,7 @@ impl std::fmt::Display for Val {
|
||||
f.write_str(" }")
|
||||
},
|
||||
Val::Function(_) => write!(f, "\x1b[36m[Function]\x1b[39m"),
|
||||
Val::Class(_) => write!(f, "\x1b[36m[Class]\x1b[39m"),
|
||||
|
||||
// TODO: Improve printing these
|
||||
Val::Static(s) => s.fmt(f),
|
||||
|
||||
Reference in New Issue
Block a user