Skip to main content

nanvm_lib/vm/array/
argument.rs

1use super::Array;
2use crate::{
3    common::sized_index::SizedIndex,
4    vm::{Any, IVm},
5};
6
7impl<A: IVm> Array<A> {
8    /// The `i`-th argument of a call whose arguments this array holds, or
9    /// `undefined` past the end, as JavaScript binds a parameter the call
10    /// left out. What a built-in and a compiled function's body read their
11    /// fixed arguments with: one bounds check and one clone, where
12    /// `Index<u32>` panics past the end.
13    pub fn argument(&self, i: u32) -> Any<A> {
14        self.present(i).unwrap_or_else(Any::undefined)
15    }
16
17    /// The `i`-th argument if the call passed one, `undefined` included,
18    /// and `None` if it did not: for a reader whose answer depends on
19    /// whether an argument is there, not only on its value —
20    /// `lastIndexOf(x)` searches from the end, `lastIndexOf(x, undefined)`
21    /// from `0`, and an effect's optional parameter is absent.
22    pub fn present(&self, i: u32) -> Option<Any<A>> {
23        self.get(i).cloned()
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use crate::{
30        naive::Naive,
31        vm::{Any, ToAny, ToArray},
32    };
33
34    type A = Naive;
35
36    /// An argument the call passed is itself, `undefined` included; one
37    /// past the end is `undefined`.
38    #[test]
39    fn argument() {
40        let args = [1.0.to_any(), Any::<A>::undefined(), "s".into()].to_array();
41        assert_eq!(args.argument(0), 1.0.to_any());
42        assert_eq!(args.argument(1), Any::undefined());
43        assert_eq!(args.argument(2), "s".into());
44        assert_eq!(args.argument(3), Any::undefined());
45        assert_eq!(args.argument(u32::MAX), Any::undefined());
46        assert_eq!([].to_array().argument(0), Any::<A>::undefined());
47    }
48
49    /// An argument the call passed is there, `undefined` included; one
50    /// past the end is not.
51    #[test]
52    fn present() {
53        let args = [1.0.to_any(), Any::<A>::undefined()].to_array();
54        assert_eq!(args.present(0), Some(1.0.to_any()));
55        assert_eq!(args.present(1), Some(Any::undefined()));
56        assert_eq!(args.present(2), None);
57        assert_eq!([].to_array().present(0), None::<Any<A>>);
58    }
59}