mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Add array.entries()
This commit is contained in:
137
valuescript_vm/src/iteration/array_entries_iterator.rs
Normal file
137
valuescript_vm/src/iteration/array_entries_iterator.rs
Normal file
@@ -0,0 +1,137 @@
|
||||
use std::{fmt, rc::Rc};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::{
|
||||
builtins::{error_builtin::ToError, type_error_builtin::ToTypeError},
|
||||
native_function::{native_fn, NativeFunction},
|
||||
vs_array::VsArray,
|
||||
vs_class::VsClass,
|
||||
vs_value::{dynamic_make_mut, ToDynamicVal, ToVal, Val, VsType},
|
||||
LoadFunctionResult, ValTrait,
|
||||
};
|
||||
|
||||
use super::iteration_result::IterationResult;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ArrayEntriesIterator {
|
||||
pub array: Rc<VsArray>,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
impl ArrayEntriesIterator {
|
||||
pub fn new(array: Rc<VsArray>) -> ArrayEntriesIterator {
|
||||
ArrayEntriesIterator { array, index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl ValTrait for ArrayEntriesIterator {
|
||||
fn typeof_(&self) -> VsType {
|
||||
VsType::Object
|
||||
}
|
||||
|
||||
fn to_number(&self) -> f64 {
|
||||
core::f64::NAN
|
||||
}
|
||||
|
||||
fn to_index(&self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
fn is_primitive(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_truthy(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_nullish(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn bind(&self, _params: Vec<Val>) -> Option<Val> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_bigint_data(&self) -> Option<BigInt> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
LoadFunctionResult::NotAFunction
|
||||
}
|
||||
|
||||
fn sub(&self, key: Val) -> Result<Val, Val> {
|
||||
if key.to_string() == "next" {
|
||||
return Ok(NEXT.to_val());
|
||||
}
|
||||
|
||||
Ok(Val::Undefined)
|
||||
}
|
||||
|
||||
fn submov(&mut self, _key: Val, _value: Val) -> Result<(), Val> {
|
||||
Err("Cannot assign to subscript of array iterator".to_type_error())
|
||||
}
|
||||
|
||||
fn pretty_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "\x1b[36m[ArrayEntriesIterator]\x1b[39m")
|
||||
}
|
||||
|
||||
fn codify(&self) -> String {
|
||||
format!(
|
||||
"ArrayEntriesIterator({{ array: {}, index: {} }})",
|
||||
Val::Array(self.array.clone()).codify(),
|
||||
self.index
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayEntriesIterator {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "[object Array Iterator]")
|
||||
}
|
||||
}
|
||||
|
||||
static NEXT: NativeFunction = native_fn(|mut this, _| {
|
||||
let dynamic = match this.get_mut()? {
|
||||
Val::Dynamic(dynamic) => dynamic,
|
||||
_ => return Err("TODO: indirection".to_error()),
|
||||
};
|
||||
|
||||
let iter = dynamic_make_mut(dynamic)
|
||||
.as_any_mut()
|
||||
.downcast_mut::<ArrayEntriesIterator>()
|
||||
.ok_or_else(|| "ArrayEntriesIterator.next called on different object".to_type_error())?;
|
||||
|
||||
match iter.array.elements.get(iter.index) {
|
||||
Some(item) => {
|
||||
let res = Ok(
|
||||
IterationResult {
|
||||
value: vec![(iter.index as f64).to_val(), item.clone()].to_val(),
|
||||
done: false,
|
||||
}
|
||||
.to_dynamic_val(),
|
||||
);
|
||||
|
||||
iter.index += 1;
|
||||
|
||||
res
|
||||
}
|
||||
None => Ok(
|
||||
IterationResult {
|
||||
value: Val::Undefined,
|
||||
done: true,
|
||||
}
|
||||
.to_dynamic_val(),
|
||||
),
|
||||
}
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod array_entries_iterator;
|
||||
pub mod array_iterator;
|
||||
pub mod iteration_result;
|
||||
pub mod string_iterator;
|
||||
|
||||
@@ -148,10 +148,8 @@ static NEXT: NativeFunction = native_fn(|mut this, _| {
|
||||
.downcast_mut::<StringIterator>()
|
||||
.ok_or_else(|| "StringIterator.next called on different object".to_type_error())?;
|
||||
|
||||
let char = iter.next();
|
||||
|
||||
Ok(
|
||||
match char {
|
||||
match iter.next() {
|
||||
Some(c) => IterationResult {
|
||||
value: c.to_val(),
|
||||
done: false,
|
||||
|
||||
@@ -661,11 +661,9 @@ static VALUE_OF: NativeFunction = native_fn(|this, _params| {
|
||||
})
|
||||
});
|
||||
|
||||
static VALUES: NativeFunction = native_fn(|this, _params| {
|
||||
Ok(match this.get() {
|
||||
Val::String(string_data) => StringIterator::new(string_data.clone()).to_dynamic_val(),
|
||||
_ => return Err("string indirection".to_error()),
|
||||
})
|
||||
static VALUES: NativeFunction = native_fn(|this, _params| match this.get() {
|
||||
Val::String(string_data) => Ok(StringIterator::new(string_data.clone()).to_dynamic_val()),
|
||||
_ => Err("string indirection".to_error()),
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ use crate::array_higher_functions::{
|
||||
use crate::builtins::error_builtin::ToError;
|
||||
use crate::builtins::type_error_builtin::ToTypeError;
|
||||
use crate::helpers::{to_wrapping_index, to_wrapping_index_clamped};
|
||||
use crate::iteration::array_entries_iterator::ArrayEntriesIterator;
|
||||
use crate::iteration::array_iterator::ArrayIterator;
|
||||
use crate::native_function::{native_fn, NativeFunction};
|
||||
use crate::operations::op_triple_eq_impl;
|
||||
@@ -272,11 +273,9 @@ static COPY_WITHIN: NativeFunction = native_fn(|mut this, params| {
|
||||
})
|
||||
});
|
||||
|
||||
static ENTRIES: NativeFunction = native_fn(|this, _params| {
|
||||
match this.get() {
|
||||
Val::Array(_array_data) => return Err("TODO: iterators".to_error()),
|
||||
_ => return Err("array indirection".to_error()),
|
||||
};
|
||||
static ENTRIES: NativeFunction = native_fn(|this, _params| match this.get() {
|
||||
Val::Array(array_data) => Ok(ArrayEntriesIterator::new(array_data.clone()).to_dynamic_val()),
|
||||
_ => Err("array indirection".to_error()),
|
||||
});
|
||||
|
||||
static FILL: NativeFunction = native_fn(|mut this, params| {
|
||||
@@ -646,9 +645,7 @@ static UNSHIFT: NativeFunction = native_fn(|mut this, params| {
|
||||
})
|
||||
});
|
||||
|
||||
static VALUES: NativeFunction = native_fn(|this, _params| {
|
||||
Ok(match this.get() {
|
||||
Val::Array(array_data) => ArrayIterator::new(array_data.clone()).to_dynamic_val(),
|
||||
_ => return Err("array indirection".to_error()),
|
||||
})
|
||||
static VALUES: NativeFunction = native_fn(|this, _params| match this.get() {
|
||||
Val::Array(array_data) => Ok(ArrayIterator::new(array_data.clone()).to_dynamic_val()),
|
||||
_ => Err("array indirection".to_error()),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user