mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Array.prototype.map
This commit is contained in:
80
src/vstc/virtual_machine/array_higher_functions/array_map.rs
Normal file
80
src/vstc/virtual_machine/array_higher_functions/array_map.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::super::vs_array::VsArray;
|
||||
use super::super::native_frame_function::NativeFrameFunction;
|
||||
use super::super::stack_frame::{StackFrameTrait, FrameStepResult, CallResult};
|
||||
|
||||
pub static MAP: NativeFrameFunction = NativeFrameFunction {
|
||||
make_frame: || Box::new(MapFrame {
|
||||
this: None,
|
||||
mapper: Val::Void,
|
||||
param_i: 0,
|
||||
map_results: Vec::new(),
|
||||
}),
|
||||
};
|
||||
|
||||
struct MapFrame {
|
||||
this: Option<Rc<VsArray>>,
|
||||
mapper: Val,
|
||||
param_i: usize,
|
||||
map_results: Vec<Val>,
|
||||
}
|
||||
|
||||
impl StackFrameTrait for MapFrame {
|
||||
fn write_this(&mut self, this: Val) {
|
||||
self.this = this.as_array_data();
|
||||
}
|
||||
|
||||
fn write_param(&mut self, param: Val) {
|
||||
if self.param_i == 0 {
|
||||
self.mapper = param;
|
||||
}
|
||||
|
||||
self.param_i += 1;
|
||||
}
|
||||
|
||||
fn step(&mut self) -> FrameStepResult {
|
||||
let array_data = match &self.this {
|
||||
None => std::panic!("Not implemented: exception: map called on non-array"),
|
||||
Some(ad) => ad,
|
||||
};
|
||||
|
||||
match array_data.elements.get(self.map_results.len()) {
|
||||
Some(el) => match self.mapper.load_function() {
|
||||
LoadFunctionResult::NotAFunction =>
|
||||
std::panic!("Not implemented: exception: map fn is not a function")
|
||||
,
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
self.map_results.push(native_fn(
|
||||
&mut Val::Undefined,
|
||||
vec![el.clone()],
|
||||
));
|
||||
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
new_frame.write_param(el.clone());
|
||||
return FrameStepResult::Push(new_frame);
|
||||
},
|
||||
},
|
||||
None => {
|
||||
let mut return_elements = Vec::new();
|
||||
std::mem::swap(&mut return_elements, &mut self.map_results);
|
||||
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return_: Val::Array(Rc::new(VsArray::from(return_elements))),
|
||||
this: Val::Array(array_data.clone()),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn apply_call_result(&mut self, call_result: CallResult) {
|
||||
self.map_results.push(call_result.return_);
|
||||
}
|
||||
|
||||
fn get_call_result(&mut self) -> CallResult {
|
||||
std::panic!("Not appropriate for MapFrame")
|
||||
}
|
||||
}
|
||||
1
src/vstc/virtual_machine/array_higher_functions/mod.rs
Normal file
1
src/vstc/virtual_machine/array_higher_functions/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod array_map;
|
||||
@@ -14,5 +14,7 @@ mod vs_class;
|
||||
mod bytecode_stack_frame;
|
||||
mod stack_frame;
|
||||
mod first_stack_frame;
|
||||
mod array_higher_functions;
|
||||
mod native_frame_function;
|
||||
|
||||
pub use virtual_machine::VirtualMachine;
|
||||
|
||||
51
src/vstc/virtual_machine/native_frame_function.rs
Normal file
51
src/vstc/virtual_machine/native_frame_function.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::vs_value::{
|
||||
Val,
|
||||
VsType,
|
||||
ValTrait,
|
||||
LoadFunctionResult,
|
||||
};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_array::VsArray;
|
||||
use super::vs_class::VsClass;
|
||||
use super::stack_frame::StackFrame;
|
||||
|
||||
pub struct NativeFrameFunction {
|
||||
pub make_frame: fn() -> StackFrame,
|
||||
}
|
||||
|
||||
impl ValTrait for NativeFrameFunction {
|
||||
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 as_class_data(&self) -> Option<Rc<VsClass>> { None }
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::StackFrame((self.make_frame)())
|
||||
}
|
||||
|
||||
fn sub(&self, _key: Val) -> Val {
|
||||
std::panic!("Not implemented");
|
||||
}
|
||||
|
||||
fn submov(&mut self, _key: Val, _value: Val) {
|
||||
std::panic!("Not implemented: exceptions");
|
||||
}
|
||||
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "\x1b[36m[Function]\x1b[39m")
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use super::vs_object::VsObject;
|
||||
use super::vs_class::VsClass;
|
||||
use super::native_function::NativeFunction;
|
||||
use super::operations::op_triple_eq_impl;
|
||||
use super::array_higher_functions::array_map::MAP;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VsArray {
|
||||
@@ -499,17 +500,6 @@ static LAST_INDEX_OF: NativeFunction = NativeFunction {
|
||||
}
|
||||
};
|
||||
|
||||
static MAP: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Val {
|
||||
match this {
|
||||
Val::Array(_array_data) => {
|
||||
std::panic!("Not implemented: MAP");
|
||||
},
|
||||
_ => std::panic!("Not implemented: exceptions/array indirection"),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static POP: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Val {
|
||||
match this {
|
||||
|
||||
Reference in New Issue
Block a user