mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Add native_function
This commit is contained in:
@@ -7,5 +7,6 @@ mod virtual_machine;
|
||||
mod instruction;
|
||||
mod vs_object;
|
||||
mod vs_array;
|
||||
mod native_function;
|
||||
|
||||
pub use virtual_machine::VirtualMachine;
|
||||
|
||||
44
src/vstc/virtual_machine/native_function.rs
Normal file
44
src/vstc/virtual_machine/native_function.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::vs_value::{
|
||||
Val,
|
||||
VsType,
|
||||
ValTrait,
|
||||
LoadFunctionResult,
|
||||
};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
|
||||
pub struct NativeFunction {
|
||||
fn_: fn(this: &mut Val, params: Vec<Val>) -> Val,
|
||||
}
|
||||
|
||||
impl ValTrait for NativeFunction {
|
||||
fn typeof_(&self) -> VsType { VsType::Function }
|
||||
fn val_to_string(&self) -> String { "function() { [native code] }".to_string() }
|
||||
fn to_number(&self) -> f64 { f64::NAN }
|
||||
fn to_index(&self) -> Option<usize> { None }
|
||||
fn is_primitive(&self) -> bool { false }
|
||||
fn to_primitive(&self) -> Val { Val::String(Rc::new(self.val_to_string())) }
|
||||
fn is_truthy(&self) -> bool { true }
|
||||
fn is_nullish(&self) -> bool { false }
|
||||
|
||||
fn bind(&self, _params: Vec<Val>) -> Option<Val> {
|
||||
std::panic!("Not implemented");
|
||||
}
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NativeFunction(self.fn_)
|
||||
}
|
||||
|
||||
fn sub(&self, _key: Val) -> Val {
|
||||
std::panic!("Not implemented");
|
||||
}
|
||||
|
||||
fn submov(&mut self, _key: Val, _value: Val) {
|
||||
std::panic!("Not implemented: exceptions");
|
||||
}
|
||||
}
|
||||
@@ -279,7 +279,7 @@ pub fn op_sub(left: Val, right: Val) -> Val {
|
||||
},
|
||||
Val::Function(_) => Val::Undefined,
|
||||
Val::Static(s) => s.sub(right),
|
||||
Val::Custom(custom_data) => op_sub(custom_data.resolve(), right),
|
||||
Val::Custom(custom_data) => custom_data.sub(right),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,10 +318,6 @@ pub fn op_submov(target: &mut Val, subscript: Val, value: Val) {
|
||||
},
|
||||
Val::Function(_) => std::panic!("Not implemented: function subscript assignment"),
|
||||
Val::Static(_) => std::panic!("Not implemented: exceptions"),
|
||||
Val::Custom(custom_data) => {
|
||||
let mut resolved_target = custom_data.resolve();
|
||||
op_submov(&mut resolved_target, subscript, value);
|
||||
*target = resolved_target;
|
||||
},
|
||||
Val::Custom(_) => std::panic!("Not implemented"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ use super::vs_value::{
|
||||
Val,
|
||||
VsType,
|
||||
ValTrait,
|
||||
StaticValExtraTrait,
|
||||
StaticValTrait,
|
||||
LoadFunctionResult,
|
||||
};
|
||||
use super::vs_object::VsObject;
|
||||
@@ -42,8 +40,6 @@ impl ValTrait for ArrayPrototype {
|
||||
fn is_truthy(&self) -> bool { true }
|
||||
fn is_nullish(&self) -> bool { false }
|
||||
|
||||
fn resolve(&self) -> Val { Val::Static(&ARRAY_PROTOTYPE) }
|
||||
|
||||
fn bind(&self, _params: Vec<Val>) -> Option<Val> { None }
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
|
||||
@@ -52,14 +48,14 @@ impl ValTrait for ArrayPrototype {
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NotAFunction
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticValExtraTrait for ArrayPrototype {
|
||||
fn sub(&self, key: Val) -> Val {
|
||||
match key.val_to_string().as_str() {
|
||||
_ => Val::Undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticValTrait for ArrayPrototype {}
|
||||
fn submov(&mut self, key: Val, value: Val) {
|
||||
std::panic!("Not implemented: exceptions");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,27 @@ impl VsPointer {
|
||||
resolved: RefCell::new(None),
|
||||
}));
|
||||
}
|
||||
|
||||
fn resolve(&self) -> Val {
|
||||
let mut resolved = self.resolved.borrow_mut();
|
||||
|
||||
if resolved.is_some() {
|
||||
return resolved.clone().unwrap();
|
||||
}
|
||||
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: self.bytecode.clone(),
|
||||
pos: self.pos,
|
||||
};
|
||||
|
||||
let val = bd.decode_val(&Vec::new());
|
||||
|
||||
// TODO: Check that this actually inserts into the cell and not just a copy
|
||||
// somehow
|
||||
*resolved = Some(val.clone());
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
impl ValTrait for VsPointer {
|
||||
@@ -76,27 +97,6 @@ impl ValTrait for VsPointer {
|
||||
return self.resolve().to_primitive();
|
||||
}
|
||||
|
||||
fn resolve(&self) -> Val {
|
||||
let mut resolved = self.resolved.borrow_mut();
|
||||
|
||||
if resolved.is_some() {
|
||||
return resolved.clone().unwrap();
|
||||
}
|
||||
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: self.bytecode.clone(),
|
||||
pos: self.pos,
|
||||
};
|
||||
|
||||
let val = bd.decode_val(&Vec::new());
|
||||
|
||||
// TODO: Check that this actually inserts into the cell and not just a copy
|
||||
// somehow
|
||||
*resolved = Some(val.clone());
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
fn bind(&self, params: Vec<Val>) -> Option<Val> {
|
||||
return self.resolve().bind(params);
|
||||
}
|
||||
@@ -120,4 +120,12 @@ impl ValTrait for VsPointer {
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
return self.resolve().load_function();
|
||||
}
|
||||
|
||||
fn sub(&self, subscript: Val) -> Val {
|
||||
return self.resolve().sub(subscript);
|
||||
}
|
||||
|
||||
fn submov(&mut self, subscript: Val, value: Val) {
|
||||
std::panic!("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use super::vs_function::VsFunction;
|
||||
use super::virtual_machine::StackFrame;
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
use super::operations::{op_sub, op_submov};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Val {
|
||||
@@ -17,7 +18,7 @@ pub enum Val {
|
||||
Array(Rc<VsArray>),
|
||||
Object(Rc<VsObject>),
|
||||
Function(Rc<VsFunction>),
|
||||
Static(&'static dyn StaticValTrait),
|
||||
Static(&'static dyn ValTrait),
|
||||
Custom(Rc<dyn ValTrait>),
|
||||
}
|
||||
|
||||
@@ -49,22 +50,17 @@ pub trait ValTrait {
|
||||
fn is_truthy(&self) -> bool;
|
||||
fn is_nullish(&self) -> bool;
|
||||
|
||||
fn resolve(&self) -> Val;
|
||||
|
||||
fn bind(&self, params: Vec<Val>) -> Option<Val>;
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>>;
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>>;
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult;
|
||||
}
|
||||
|
||||
pub trait StaticValExtraTrait {
|
||||
fn sub(&self, key: Val) -> Val;
|
||||
fn submov(&mut self, key: Val, value: Val);
|
||||
}
|
||||
|
||||
pub trait StaticValTrait: ValTrait + StaticValExtraTrait {}
|
||||
|
||||
impl ValTrait for Val {
|
||||
fn typeof_(&self) -> VsType {
|
||||
use Val::*;
|
||||
@@ -223,10 +219,6 @@ impl ValTrait for Val {
|
||||
};
|
||||
}
|
||||
|
||||
fn resolve(&self) -> Val {
|
||||
std::panic!("Unexpected resolve call on plain Val")
|
||||
}
|
||||
|
||||
fn bind(&self, params: Vec<Val>) -> Option<Val> {
|
||||
use Val::*;
|
||||
|
||||
@@ -270,6 +262,15 @@ impl ValTrait for Val {
|
||||
_ => LoadFunctionResult::NotAFunction,
|
||||
}
|
||||
}
|
||||
|
||||
fn sub(&self, key: Val) -> Val {
|
||||
// TODO: Avoid cloning?
|
||||
return op_sub(self.clone(), key);
|
||||
}
|
||||
|
||||
fn submov(&mut self, key: Val, value: Val) {
|
||||
op_submov(self, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Val {
|
||||
|
||||
Reference in New Issue
Block a user