mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Make native functions const aware
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
@@ -86,7 +87,7 @@ impl StackFrameTrait for ArrayMappingFrame {
|
||||
array_i,
|
||||
el,
|
||||
native_fn(
|
||||
&mut self.this_arg.clone(),
|
||||
ThisWrapper::new(false, &mut self.this_arg.clone()),
|
||||
vec![
|
||||
el.clone(),
|
||||
Val::Number(array_i as f64),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, FrameStepResult, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
@@ -67,7 +68,7 @@ impl StackFrameTrait for ReduceFrame {
|
||||
LoadFunctionResult::NotAFunction => return type_error!("reduce fn is not a function"),
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
self.value = Some(native_fn(
|
||||
&mut Val::Undefined,
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
vec![
|
||||
value.clone(),
|
||||
el.clone(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, FrameStepResult, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
@@ -89,7 +90,7 @@ impl StackFrameTrait for ReduceRightFrame {
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
self.value = Some(native_fn(
|
||||
&mut Val::Undefined,
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
vec![
|
||||
value.clone(),
|
||||
el.clone(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
@@ -271,7 +272,11 @@ impl StackFrameTrait for SortFrame {
|
||||
return type_error!("comparator is not a function");
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
let res = native_fn(&mut Val::Undefined, vec![left, right])?.to_number();
|
||||
let res = native_fn(
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
vec![left, right],
|
||||
)?
|
||||
.to_number();
|
||||
|
||||
let should_swap = match res.is_nan() {
|
||||
true => false,
|
||||
|
||||
@@ -4,7 +4,7 @@ use num_bigint::BigInt;
|
||||
|
||||
use crate::{
|
||||
format_err,
|
||||
native_function::NativeFunction,
|
||||
native_function::{NativeFunction, ThisWrapper},
|
||||
todo_fn::TODO,
|
||||
vs_value::{Val, ValTrait},
|
||||
};
|
||||
@@ -19,14 +19,14 @@ pub fn op_sub_bigint(_bigint: &BigInt, subscript: &Val) -> Val {
|
||||
}
|
||||
|
||||
static TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::BigInt(_) => match params.get(0) {
|
||||
Some(_) => {
|
||||
return format_err!("TODO: toString with radix");
|
||||
}
|
||||
|
||||
None => Val::String(Rc::new(this.val_to_string())),
|
||||
None => Val::String(Rc::new(this.get().val_to_string())),
|
||||
},
|
||||
_ => return format_err!("TODO: bigint indirection"),
|
||||
})
|
||||
@@ -34,8 +34,8 @@ static TO_STRING: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static VALUE_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::BigInt(bigint) => Val::BigInt(bigint.clone()),
|
||||
_ => return format_err!("TODO: bigint indirection"),
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
builtins::range_error_builtin::to_range_error,
|
||||
builtins::type_error_builtin::to_type_error,
|
||||
format_err,
|
||||
native_function::NativeFunction,
|
||||
native_function::{NativeFunction, ThisWrapper},
|
||||
operations::op_sub,
|
||||
range_error, type_error,
|
||||
vs_array::VsArray,
|
||||
@@ -88,7 +88,7 @@ impl ValTrait for ArrayBuiltin {
|
||||
}
|
||||
|
||||
static IS_ARRAY: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match params.get(0) {
|
||||
None => Val::Bool(false),
|
||||
Some(p) => match p.as_array_data() {
|
||||
@@ -100,7 +100,7 @@ static IS_ARRAY: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static FROM: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let first_param = match params.get(0) {
|
||||
None => return type_error!("undefined is not iterable"),
|
||||
Some(p) => p,
|
||||
@@ -157,12 +157,12 @@ static FROM: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static OF: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(Val::Array(Rc::new(VsArray::from(params))))
|
||||
},
|
||||
};
|
||||
|
||||
fn to_array(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
fn to_array(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
if params.len() != 1 {
|
||||
return Ok(Val::Array(Rc::new(VsArray::from(params))));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use num_bigint::BigInt;
|
||||
|
||||
use crate::{
|
||||
builtins::type_error_builtin::to_type_error,
|
||||
native_function::ThisWrapper,
|
||||
type_error,
|
||||
vs_array::VsArray,
|
||||
vs_class::VsClass,
|
||||
@@ -78,7 +79,7 @@ impl ValTrait for BooleanBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_boolean(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
fn to_boolean(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
Val::Bool(value.is_truthy())
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::NativeFunction;
|
||||
use crate::native_function::{NativeFunction, ThisWrapper};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_class::VsClass;
|
||||
use crate::vs_object::VsObject;
|
||||
@@ -82,7 +82,7 @@ impl ValTrait for DebugBuiltin {
|
||||
}
|
||||
|
||||
static LOG: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
for p in params {
|
||||
println!("Debug.log: {}", p);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::{collections::BTreeMap, rc::Rc};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::{builtins::type_error_builtin::to_type_error, type_error};
|
||||
use crate::{
|
||||
format_val,
|
||||
@@ -83,7 +84,7 @@ impl ValTrait for ErrorBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_error(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
fn to_error(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(Val::Object(Rc::new(VsObject {
|
||||
string_map: BTreeMap::from([(
|
||||
"message".to_string(),
|
||||
@@ -111,21 +112,25 @@ fn make_error_prototype() -> Val {
|
||||
}
|
||||
|
||||
static SET_MESSAGE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = match params.get(0) {
|
||||
Some(param) => param.val_to_string(),
|
||||
None => "".to_string(),
|
||||
};
|
||||
|
||||
op_submov(this, format_val!("message"), format_val!("{}", message))?;
|
||||
op_submov(
|
||||
this.get_mut()?,
|
||||
format_val!("message"),
|
||||
format_val!("{}", message),
|
||||
)?;
|
||||
|
||||
Ok(Val::Undefined)
|
||||
},
|
||||
};
|
||||
|
||||
static ERROR_TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.clone(), format_val!("message"))?;
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.get().clone(), format_val!("message"))?;
|
||||
Ok(format_val!("Error({})", message)) // TODO: Fixes needed here (and other errors)
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::NativeFunction;
|
||||
use crate::native_function::{NativeFunction, ThisWrapper};
|
||||
use crate::operations::to_u32;
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_class::VsClass;
|
||||
@@ -134,49 +134,49 @@ fn param_to_number(param: Option<&Val>) -> f64 {
|
||||
}
|
||||
|
||||
static ABS: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.abs()))
|
||||
},
|
||||
};
|
||||
|
||||
static ACOS: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.acos()))
|
||||
},
|
||||
};
|
||||
|
||||
static ACOSH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.acosh()))
|
||||
},
|
||||
};
|
||||
|
||||
static ASIN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.asin()))
|
||||
},
|
||||
};
|
||||
|
||||
static ASINH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.sinh()))
|
||||
},
|
||||
};
|
||||
|
||||
static ATAN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.atan()))
|
||||
},
|
||||
};
|
||||
|
||||
static ATAN2: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
|
||||
@@ -185,77 +185,77 @@ static ATAN2: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static ATANH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.atanh()))
|
||||
},
|
||||
};
|
||||
|
||||
static CBRT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.cbrt()))
|
||||
},
|
||||
};
|
||||
|
||||
static CEIL: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.ceil()))
|
||||
},
|
||||
};
|
||||
|
||||
static CLZ32: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(to_u32(x).leading_zeros() as f64))
|
||||
},
|
||||
};
|
||||
|
||||
static COS: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.cos()))
|
||||
},
|
||||
};
|
||||
|
||||
static COSH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.cosh()))
|
||||
},
|
||||
};
|
||||
|
||||
static EXP: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.exp()))
|
||||
},
|
||||
};
|
||||
|
||||
static EXPM1: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.exp_m1()))
|
||||
},
|
||||
};
|
||||
|
||||
static FLOOR: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.floor()))
|
||||
},
|
||||
};
|
||||
|
||||
static FROUND: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x as f32 as f64))
|
||||
},
|
||||
};
|
||||
|
||||
static HYPOT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
Ok(Val::Number(x.hypot(y)))
|
||||
@@ -263,7 +263,7 @@ static HYPOT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static IMUL: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
Ok(Val::Number((to_u32(x) * to_u32(y)) as i32 as f64))
|
||||
@@ -271,35 +271,35 @@ static IMUL: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static LOG: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.ln()))
|
||||
},
|
||||
};
|
||||
|
||||
static LOG10: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.log10()))
|
||||
},
|
||||
};
|
||||
|
||||
static LOG1P: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.ln_1p()))
|
||||
},
|
||||
};
|
||||
|
||||
static LOG2: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.log2()))
|
||||
},
|
||||
};
|
||||
|
||||
static MAX: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
Ok(Val::Number(x.max(y)))
|
||||
@@ -307,7 +307,7 @@ static MAX: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static MIN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
Ok(Val::Number(x.min(y)))
|
||||
@@ -315,7 +315,7 @@ static MIN: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static POW: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
let y = param_to_number(params.get(1));
|
||||
Ok(Val::Number(x.powf(y)))
|
||||
@@ -323,56 +323,56 @@ static POW: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static ROUND: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.round()))
|
||||
},
|
||||
};
|
||||
|
||||
static SIGN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.signum()))
|
||||
},
|
||||
};
|
||||
|
||||
static SIN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.sin()))
|
||||
},
|
||||
};
|
||||
|
||||
static SINH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.sinh()))
|
||||
},
|
||||
};
|
||||
|
||||
static SQRT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.sqrt()))
|
||||
},
|
||||
};
|
||||
|
||||
static TAN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.tan()))
|
||||
},
|
||||
};
|
||||
|
||||
static TANH: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.tanh()))
|
||||
},
|
||||
};
|
||||
|
||||
static TRUNC: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let x = param_to_number(params.get(0));
|
||||
Ok(Val::Number(x.trunc()))
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::{builtins::type_error_builtin::to_type_error, type_error};
|
||||
use crate::{
|
||||
native_function::NativeFunction,
|
||||
@@ -95,7 +96,7 @@ impl ValTrait for NumberBuiltin {
|
||||
}
|
||||
|
||||
pub static IS_FINITE: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
let number = value.to_number();
|
||||
Val::Bool(number.is_finite())
|
||||
@@ -106,7 +107,7 @@ pub static IS_FINITE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static IS_INTEGER: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let num = match params.get(0) {
|
||||
Some(n) => n.to_number(),
|
||||
None => return Ok(Val::Bool(false)),
|
||||
@@ -120,7 +121,7 @@ static IS_INTEGER: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
pub static IS_NAN: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
let number = value.to_number();
|
||||
Val::Bool(number.is_nan())
|
||||
@@ -131,7 +132,7 @@ pub static IS_NAN: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static IS_SAFE_INTEGER: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let num = match params.get(0) {
|
||||
Some(n) => n.to_number(),
|
||||
None => return Ok(Val::Bool(false)),
|
||||
@@ -148,7 +149,7 @@ static IS_SAFE_INTEGER: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
pub static PARSE_FLOAT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
let string_value = value.val_to_string().trim().to_string();
|
||||
|
||||
@@ -163,7 +164,7 @@ pub static PARSE_FLOAT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
pub static PARSE_INT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
let string_value = value.val_to_string().trim_start().to_string();
|
||||
let radix = params.get(1).and_then(|v| v.to_index()).unwrap_or(10);
|
||||
@@ -196,7 +197,7 @@ pub static PARSE_INT: NativeFunction = NativeFunction {
|
||||
},
|
||||
};
|
||||
|
||||
fn to_number(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
fn to_number(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
Val::Number(value.to_number())
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::{collections::BTreeMap, rc::Rc};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::{builtins::type_error_builtin::to_type_error, type_error};
|
||||
use crate::{
|
||||
format_val,
|
||||
@@ -85,7 +86,7 @@ impl ValTrait for RangeErrorBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_range_error(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
pub fn to_range_error(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(Val::Object(Rc::new(VsObject {
|
||||
string_map: BTreeMap::from([(
|
||||
"message".to_string(),
|
||||
@@ -113,21 +114,25 @@ fn make_range_error_prototype() -> Val {
|
||||
}
|
||||
|
||||
static SET_MESSAGE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = match params.get(0) {
|
||||
Some(param) => param.val_to_string(),
|
||||
None => "".to_string(),
|
||||
};
|
||||
|
||||
op_submov(this, format_val!("message"), format_val!("{}", message))?;
|
||||
op_submov(
|
||||
this.get_mut()?,
|
||||
format_val!("message"),
|
||||
format_val!("{}", message),
|
||||
)?;
|
||||
|
||||
Ok(Val::Undefined)
|
||||
},
|
||||
};
|
||||
|
||||
static RANGE_ERROR_TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.clone(), format_val!("message"))?;
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.get().clone(), format_val!("message"))?;
|
||||
Ok(format_val!("RangeError({})", message))
|
||||
},
|
||||
};
|
||||
@@ -135,10 +140,10 @@ static RANGE_ERROR_TO_STRING: NativeFunction = NativeFunction {
|
||||
#[macro_export]
|
||||
macro_rules! range_error {
|
||||
($fmt:expr $(, $($arg:expr),*)?) => {{
|
||||
let mut this = Val::Undefined;
|
||||
let formatted_string = format!($fmt $(, $($arg),*)?);
|
||||
Err(to_range_error(
|
||||
&mut this, vec![Val::String(Rc::new(formatted_string))]
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
vec![Val::String(Rc::new(formatted_string))],
|
||||
).unwrap())
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::{builtins::range_error_builtin::to_range_error, range_error};
|
||||
use crate::{builtins::type_error_builtin::to_type_error, type_error};
|
||||
use crate::{
|
||||
@@ -88,7 +89,7 @@ impl ValTrait for StringBuiltin {
|
||||
}
|
||||
|
||||
static FROM_CODE_POINT: NativeFunction = NativeFunction {
|
||||
fn_: |_this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |_this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let mut result = String::new();
|
||||
|
||||
for param in params {
|
||||
@@ -106,7 +107,7 @@ static FROM_CODE_POINT: NativeFunction = NativeFunction {
|
||||
},
|
||||
};
|
||||
|
||||
fn to_string(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
fn to_string(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(if let Some(value) = params.get(0) {
|
||||
Val::String(Rc::new(value.val_to_string()))
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::{collections::BTreeMap, rc::Rc};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::type_error;
|
||||
use crate::{
|
||||
format_val,
|
||||
@@ -85,7 +86,7 @@ impl ValTrait for TypeErrorBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_type_error(_: &mut Val, params: Vec<Val>) -> Result<Val, Val> {
|
||||
pub fn to_type_error(_: ThisWrapper, params: Vec<Val>) -> Result<Val, Val> {
|
||||
Ok(Val::Object(Rc::new(VsObject {
|
||||
string_map: BTreeMap::from([(
|
||||
"message".to_string(),
|
||||
@@ -113,21 +114,25 @@ fn make_type_error_prototype() -> Val {
|
||||
}
|
||||
|
||||
static SET_MESSAGE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = match params.get(0) {
|
||||
Some(param) => param.val_to_string(),
|
||||
None => "".to_string(),
|
||||
};
|
||||
|
||||
op_submov(this, format_val!("message"), format_val!("{}", message))?;
|
||||
op_submov(
|
||||
this.get_mut()?,
|
||||
format_val!("message"),
|
||||
format_val!("{}", message),
|
||||
)?;
|
||||
|
||||
Ok(Val::Undefined)
|
||||
},
|
||||
};
|
||||
|
||||
static TYPE_ERROR_TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.clone(), format_val!("message"))?;
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let message = op_sub(this.get().clone(), format_val!("message"))?;
|
||||
Ok(format_val!("TypeError({})", message))
|
||||
},
|
||||
};
|
||||
@@ -135,10 +140,10 @@ static TYPE_ERROR_TO_STRING: NativeFunction = NativeFunction {
|
||||
#[macro_export]
|
||||
macro_rules! type_error {
|
||||
($fmt:expr $(, $($arg:expr),*)?) => {{
|
||||
let mut this = Val::Undefined;
|
||||
let formatted_string = format!($fmt $(, $($arg),*)?);
|
||||
Err(to_type_error(
|
||||
&mut this, vec![Val::String(Rc::new(formatted_string))]
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
vec![Val::String(Rc::new(formatted_string))],
|
||||
).unwrap())
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use valuescript_common::InstructionByte;
|
||||
use crate::builtins::type_error_builtin::to_type_error;
|
||||
use crate::bytecode_decoder::BytecodeDecoder;
|
||||
use crate::bytecode_decoder::BytecodeType;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::operations;
|
||||
use crate::stack_frame::FrameStepOk;
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
@@ -187,7 +188,10 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
let res = native_fn(&mut Val::Undefined, self.decode_parameters())?;
|
||||
let res = native_fn(
|
||||
ThisWrapper::new(true, &mut Val::Undefined),
|
||||
self.decode_parameters(),
|
||||
)?;
|
||||
|
||||
match self.decoder.decode_register_index() {
|
||||
Some(return_target) => {
|
||||
@@ -316,10 +320,11 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
let params = self.decode_parameters();
|
||||
|
||||
let res = match &mut obj {
|
||||
ThisArg::Register(reg_i) => {
|
||||
native_fn(self.registers.get_mut(reg_i.clone()).unwrap(), params)?
|
||||
}
|
||||
ThisArg::Val(val) => native_fn(val, params)?,
|
||||
ThisArg::Register(reg_i) => native_fn(
|
||||
ThisWrapper::new(false, self.registers.get_mut(reg_i.clone()).unwrap()),
|
||||
params,
|
||||
)?,
|
||||
ThisArg::Val(val) => native_fn(ThisWrapper::new(true, val), params)?,
|
||||
};
|
||||
|
||||
match self.decoder.decode_register_index() {
|
||||
@@ -389,7 +394,10 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
native_fn(&mut instance, self.decode_parameters())?;
|
||||
native_fn(
|
||||
ThisWrapper::new(false, &mut instance),
|
||||
self.decode_parameters(),
|
||||
)?;
|
||||
|
||||
match self.decoder.decode_register_index() {
|
||||
Some(target) => {
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::rc::Rc;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::format_err;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::stack_frame::StackFrame;
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_class::VsClass;
|
||||
|
||||
@@ -9,8 +9,31 @@ use crate::vs_object::VsObject;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait, VsType};
|
||||
use crate::{builtins::type_error_builtin::to_type_error, type_error};
|
||||
|
||||
pub struct ThisWrapper<'a> {
|
||||
const_: bool,
|
||||
this: &'a mut Val,
|
||||
}
|
||||
|
||||
impl<'a> ThisWrapper<'a> {
|
||||
pub fn new(const_: bool, this: &'a mut Val) -> ThisWrapper<'a> {
|
||||
ThisWrapper { const_, this }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &Val {
|
||||
self.this
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self) -> Result<&mut Val, Val> {
|
||||
if self.const_ {
|
||||
return type_error!("Cannot mutate this because it is const");
|
||||
}
|
||||
|
||||
Ok(self.this)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NativeFunction {
|
||||
pub fn_: fn(this: &mut Val, params: Vec<Val>) -> Result<Val, Val>,
|
||||
pub fn_: fn(this: ThisWrapper, params: Vec<Val>) -> Result<Val, Val>,
|
||||
}
|
||||
|
||||
impl ValTrait for NativeFunction {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::{builtins::range_error_builtin::to_range_error, range_error};
|
||||
use crate::{
|
||||
format_err, format_val,
|
||||
@@ -21,8 +22,8 @@ pub fn op_sub_number(_number: f64, subscript: &Val) -> Val {
|
||||
}
|
||||
|
||||
static TO_FIXED: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Number(number) => {
|
||||
if number.is_infinite() {
|
||||
return Ok(if number.is_sign_positive() {
|
||||
@@ -34,7 +35,7 @@ static TO_FIXED: NativeFunction = NativeFunction {
|
||||
|
||||
let mut precision = match params.get(0) {
|
||||
Some(p) => p.to_number(),
|
||||
_ => return Ok(Val::String(Rc::new(this.val_to_string()))),
|
||||
_ => return Ok(Val::String(Rc::new(this.get().val_to_string()))),
|
||||
};
|
||||
|
||||
precision = f64::floor(precision);
|
||||
@@ -51,8 +52,8 @@ static TO_FIXED: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_EXPONENTIAL: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Number(number) => match params.get(0) {
|
||||
Some(p) => {
|
||||
let mut precision = p.to_number();
|
||||
@@ -72,8 +73,8 @@ static TO_EXPONENTIAL: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TODO_LOCALE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this.get() {
|
||||
Val::Number(_number) => return format_err!("TODO: locale"),
|
||||
_ => return format_err!("number indirection"),
|
||||
}
|
||||
@@ -81,14 +82,14 @@ static TODO_LOCALE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Number(_) => match params.get(0) {
|
||||
Some(_) => {
|
||||
return format_err!("TODO: toString with radix");
|
||||
}
|
||||
|
||||
None => Val::String(Rc::new(this.val_to_string())),
|
||||
None => Val::String(Rc::new(this.get().val_to_string())),
|
||||
},
|
||||
_ => return format_err!("number indirection"),
|
||||
})
|
||||
@@ -96,8 +97,8 @@ static TO_STRING: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static VALUE_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Number(number) => Val::Number(*number),
|
||||
_ => return format_err!("number indirection"),
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::bigint_methods::op_sub_bigint;
|
||||
use crate::format_err;
|
||||
use crate::format_val;
|
||||
use crate::native_function::NativeFunction;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::number_methods::op_sub_number;
|
||||
use crate::string_methods::op_sub_string;
|
||||
use crate::vs_value::Val;
|
||||
@@ -480,8 +481,8 @@ pub fn op_submov(target: &mut Val, subscript: Val, value: Val) -> Result<(), Val
|
||||
}
|
||||
|
||||
static BOOL_TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match &this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Bool(b) => Val::String(Rc::new(b.to_string())),
|
||||
_ => return format_err!("bool indirection"),
|
||||
})
|
||||
@@ -489,8 +490,8 @@ static BOOL_TO_STRING: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static BOOL_VALUE_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match &this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Bool(b) => Val::Bool(*b),
|
||||
_ => return format_err!("bool indirection"),
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{rc::Rc, str::Chars};
|
||||
use crate::{
|
||||
format_err,
|
||||
helpers::{to_wrapping_index, to_wrapping_index_clamped},
|
||||
native_function::NativeFunction,
|
||||
native_function::{NativeFunction, ThisWrapper},
|
||||
vs_array::VsArray,
|
||||
vs_value::Val,
|
||||
ValTrait,
|
||||
@@ -85,8 +85,8 @@ pub fn get_string_method(method: &str) -> Val {
|
||||
}
|
||||
|
||||
static AT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -106,8 +106,8 @@ static AT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static CODE_POINT_AT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -130,8 +130,8 @@ static CODE_POINT_AT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static CONCAT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let mut result = string_data.as_str().to_string();
|
||||
|
||||
@@ -147,8 +147,8 @@ static CONCAT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static ENDS_WITH: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -190,8 +190,8 @@ static ENDS_WITH: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static INCLUDES: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -222,8 +222,8 @@ static INCLUDES: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static INDEX_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -254,8 +254,8 @@ static INDEX_OF: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static LAST_INDEX_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -286,9 +286,9 @@ static LAST_INDEX_OF: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TODO_LOCALE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::String(_string_data) => {
|
||||
return format_err!("TODO: locale");
|
||||
}
|
||||
@@ -298,9 +298,9 @@ static TODO_LOCALE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TODO_REGEXES: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::String(_string_data) => {
|
||||
return format_err!("TODO: regexes");
|
||||
}
|
||||
@@ -310,9 +310,9 @@ static TODO_REGEXES: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static NORMALIZE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::String(_string_data) => {
|
||||
// Consider https://docs.rs/unicode-normalization/latest/unicode_normalization/
|
||||
return format_err!("TODO: normalize");
|
||||
@@ -324,8 +324,8 @@ static NORMALIZE: NativeFunction = NativeFunction {
|
||||
|
||||
// TODO: JS has some locale-specific behavior, not sure yet how we should deal with that
|
||||
static PAD_END: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let target_length = match params.get(0) {
|
||||
Some(p) => match p.to_index() {
|
||||
@@ -378,8 +378,8 @@ static PAD_END: NativeFunction = NativeFunction {
|
||||
|
||||
// TODO: JS has some locale-specific behavior, not sure yet how we should deal with that
|
||||
static PAD_START: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let target_length = match params.get(0) {
|
||||
Some(p) => match p.to_index() {
|
||||
@@ -433,8 +433,8 @@ static PAD_START: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static REPEAT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let count = match params.get(0) {
|
||||
Some(p) => match p.to_index() {
|
||||
@@ -458,8 +458,8 @@ static REPEAT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SLICE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -492,8 +492,8 @@ static SLICE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SPLIT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let separator = match params.get(0) {
|
||||
Some(s) => s.val_to_string(), // TODO: Regexes
|
||||
@@ -558,8 +558,8 @@ static SPLIT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static STARTS_WITH: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -599,8 +599,8 @@ static STARTS_WITH: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SUBSTRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let string_bytes = string_data.as_bytes();
|
||||
|
||||
@@ -642,8 +642,8 @@ static SUBSTRING: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_LOWER_CASE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let lowercased_string = string_data.to_lowercase();
|
||||
Val::String(Rc::new(lowercased_string))
|
||||
@@ -654,8 +654,8 @@ static TO_LOWER_CASE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => Val::String(string_data.clone()),
|
||||
_ => return format_err!("string indirection"),
|
||||
})
|
||||
@@ -663,8 +663,8 @@ static TO_STRING: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_UPPER_CASE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let uppercased_string = string_data.to_uppercase();
|
||||
Val::String(Rc::new(uppercased_string))
|
||||
@@ -675,8 +675,8 @@ static TO_UPPER_CASE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TRIM: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let trimmed_string = string_data.trim();
|
||||
Val::String(Rc::new(trimmed_string.to_owned()))
|
||||
@@ -687,8 +687,8 @@ static TRIM: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TRIM_END: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let trimmed_string = string_data.trim_end();
|
||||
Val::String(Rc::new(trimmed_string.to_owned()))
|
||||
@@ -699,8 +699,8 @@ static TRIM_END: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TRIM_START: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => {
|
||||
let trimmed_string = string_data.trim_start();
|
||||
Val::String(Rc::new(trimmed_string.to_owned()))
|
||||
@@ -711,8 +711,8 @@ static TRIM_START: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static VALUE_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => Val::String(string_data.clone()),
|
||||
_ => return format_err!("string indirection"),
|
||||
})
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{format_err, native_function::NativeFunction, vs_value::Val};
|
||||
use crate::{
|
||||
format_err,
|
||||
native_function::{NativeFunction, ThisWrapper},
|
||||
vs_value::Val,
|
||||
};
|
||||
|
||||
pub static TODO: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this.get() {
|
||||
Val::Number(_number) => return format_err!("TODO: locale"),
|
||||
_ => return format_err!("number indirection"),
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::array_higher_functions::{
|
||||
};
|
||||
use crate::format_err;
|
||||
use crate::helpers::{to_wrapping_index, to_wrapping_index_clamped};
|
||||
use crate::native_function::NativeFunction;
|
||||
use crate::native_function::{NativeFunction, ThisWrapper};
|
||||
use crate::operations::op_triple_eq_impl;
|
||||
use crate::vs_class::VsClass;
|
||||
use crate::vs_object::VsObject;
|
||||
@@ -149,8 +149,8 @@ impl ValTrait for ArrayPrototype {
|
||||
}
|
||||
|
||||
static AT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => match to_wrapping_index(params.get(0), array_data.elements.len()) {
|
||||
None => Val::Undefined,
|
||||
Some(i) => array_data.elements[i].clone(),
|
||||
@@ -161,8 +161,8 @@ static AT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static CONCAT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
let mut new_array = array_data.as_ref().clone();
|
||||
|
||||
@@ -187,7 +187,9 @@ static CONCAT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static COPY_WITHIN: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
@@ -259,8 +261,8 @@ static COPY_WITHIN: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static ENTRIES: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
match this.get() {
|
||||
Val::Array(_array_data) => return format_err!("TODO: iterators"),
|
||||
_ => return format_err!("array indirection"),
|
||||
};
|
||||
@@ -268,7 +270,9 @@ static ENTRIES: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static FILL: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
@@ -298,8 +302,8 @@ static FILL: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static FLAT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
if params.len() > 0 {
|
||||
return format_err!("TODO: .flat depth parameter");
|
||||
@@ -328,8 +332,8 @@ static FLAT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static INCLUDES: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
let search_param = params.get(0).unwrap_or(&Val::Undefined).clone();
|
||||
|
||||
@@ -351,8 +355,8 @@ static INCLUDES: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static INDEX_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
let search_param = params.get(0).unwrap_or(&Val::Undefined).clone();
|
||||
|
||||
@@ -374,8 +378,8 @@ static INDEX_OF: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static JOIN: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(vals) => {
|
||||
if vals.elements.len() == 0 {
|
||||
return Ok(Val::String(Rc::new("".to_string())));
|
||||
@@ -414,9 +418,9 @@ static JOIN: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static KEYS: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::Array(_array_data) => {
|
||||
return format_err!("TODO: KEYS");
|
||||
}
|
||||
@@ -426,8 +430,8 @@ static KEYS: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static LAST_INDEX_OF: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
let search_param = params.get(0).unwrap_or(&Val::Undefined).clone();
|
||||
|
||||
@@ -449,7 +453,9 @@ static LAST_INDEX_OF: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static POP: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
if array_data.elements.len() == 0 {
|
||||
@@ -473,7 +479,9 @@ static POP: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static PUSH: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
@@ -490,7 +498,9 @@ static PUSH: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static REVERSE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
if array_data.elements.len() == 0 {
|
||||
@@ -517,7 +527,9 @@ static REVERSE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SHIFT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
if array_data.elements.len() == 0 {
|
||||
@@ -534,8 +546,8 @@ static SHIFT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SLICE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this {
|
||||
fn_: |this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => {
|
||||
let mut new_elems = Vec::<Val>::new();
|
||||
|
||||
@@ -561,7 +573,9 @@ static SLICE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static SPLICE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
@@ -638,9 +652,9 @@ static SPLICE: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static TO_LOCALE_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::Array(_array_data) => {
|
||||
return format_err!("TODO: TO_LOCALE_STRING");
|
||||
}
|
||||
@@ -651,13 +665,15 @@ static TO_LOCALE_STRING: NativeFunction = NativeFunction {
|
||||
|
||||
// TODO: Share this? (JS doesn't?)
|
||||
static TO_STRING: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(Val::String(Rc::new(this.val_to_string())))
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
Ok(Val::String(Rc::new(this.get().val_to_string())))
|
||||
},
|
||||
};
|
||||
|
||||
static UNSHIFT: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |mut this: ThisWrapper, params: Vec<Val>| -> Result<Val, Val> {
|
||||
let this = this.get_mut()?;
|
||||
|
||||
Ok(match this {
|
||||
Val::Array(array_data) => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
@@ -677,9 +693,9 @@ static UNSHIFT: NativeFunction = NativeFunction {
|
||||
};
|
||||
|
||||
static VALUES: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
fn_: |this: ThisWrapper, _params: Vec<Val>| -> Result<Val, Val> {
|
||||
// TODO: Ok(...)
|
||||
match this {
|
||||
match this.get() {
|
||||
Val::Array(_array_data) => {
|
||||
return format_err!("TODO: VALUES");
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use num_traits::cast::ToPrimitive;
|
||||
use num_traits::Zero;
|
||||
|
||||
use crate::format_val;
|
||||
use crate::native_function::ThisWrapper;
|
||||
use crate::operations::{op_sub, op_submov};
|
||||
use crate::stack_frame::StackFrame;
|
||||
use crate::vs_array::VsArray;
|
||||
@@ -48,7 +49,7 @@ pub enum VsType {
|
||||
pub enum LoadFunctionResult {
|
||||
NotAFunction,
|
||||
StackFrame(StackFrame),
|
||||
NativeFunction(fn(this: &mut Val, params: Vec<Val>) -> Result<Val, Val>),
|
||||
NativeFunction(fn(this: ThisWrapper, params: Vec<Val>) -> Result<Val, Val>),
|
||||
}
|
||||
|
||||
pub trait ValTrait {
|
||||
|
||||
Reference in New Issue
Block a user