intuicio_frontend_simpleton/library/
array.rs

1use crate::{library::closure::Closure, Array, Boolean, Function, Integer, Reference};
2use intuicio_core::{context::Context, define_native_struct, registry::Registry, IntuicioStruct};
3use intuicio_derive::{intuicio_function, intuicio_method, intuicio_methods, IntuicioStruct};
4
5#[intuicio_function(module_name = "array", use_registry)]
6pub fn new(registry: &Registry, capacity: Reference) -> Reference {
7    Reference::new_array(
8        Array::with_capacity(capacity.read::<Integer>().map(|v| *v as _).unwrap_or(0)),
9        registry,
10    )
11}
12
13#[intuicio_function(module_name = "array")]
14pub fn reserve(mut array: Reference, additional: Reference) -> Reference {
15    array
16        .write::<Array>()
17        .unwrap()
18        .reserve(*additional.read::<Integer>().unwrap() as usize);
19    Reference::null()
20}
21
22#[intuicio_function(module_name = "array", use_registry)]
23pub fn size(registry: &Registry, array: Reference) -> Reference {
24    Reference::new_integer(array.read::<Array>().unwrap().len() as Integer, registry)
25}
26
27#[intuicio_function(module_name = "array", use_registry)]
28pub fn capacity(registry: &Registry, array: Reference) -> Reference {
29    Reference::new_integer(
30        array.read::<Array>().unwrap().capacity() as Integer,
31        registry,
32    )
33}
34
35#[intuicio_function(module_name = "array")]
36pub fn clear(mut array: Reference) -> Reference {
37    array.write::<Array>().unwrap().clear();
38    Reference::null()
39}
40
41#[intuicio_function(module_name = "array", use_registry)]
42pub fn contains(registry: &Registry, map: Reference, value: Reference) -> Reference {
43    let result = map
44        .read::<Array>()
45        .unwrap()
46        .iter()
47        .any(|item| value.does_share_reference(item, true));
48    Reference::new_boolean(result, registry)
49}
50
51#[intuicio_function(module_name = "array", use_registry)]
52pub fn find(
53    registry: &Registry,
54    array: Reference,
55    value: Reference,
56    reverse: Reference,
57) -> Reference {
58    if *reverse.read::<Boolean>().unwrap() {
59        array
60            .read::<Array>()
61            .unwrap()
62            .iter()
63            .rev()
64            .position(|item| value.does_share_reference(item, true))
65            .map(|index| Reference::new_integer(index as Integer, registry))
66            .unwrap_or_default()
67    } else {
68        array
69            .read::<Array>()
70            .unwrap()
71            .iter()
72            .position(|item| value.does_share_reference(item, true))
73            .map(|index| Reference::new_integer(index as Integer, registry))
74            .unwrap_or_default()
75    }
76}
77
78#[intuicio_function(module_name = "array")]
79pub fn push(mut array: Reference, value: Reference) -> Reference {
80    array.write::<Array>().unwrap().push(value);
81    Reference::null()
82}
83
84#[intuicio_function(module_name = "array")]
85pub fn insert(mut array: Reference, index: Reference, value: Reference) -> Reference {
86    array
87        .write::<Array>()
88        .unwrap()
89        .insert(*index.read::<Integer>().unwrap() as _, value);
90    Reference::null()
91}
92
93#[intuicio_function(module_name = "array")]
94pub fn pop(mut array: Reference) -> Reference {
95    array.write::<Array>().unwrap().pop().unwrap_or_default()
96}
97
98#[intuicio_function(module_name = "array")]
99pub fn remove(mut array: Reference, index: Reference) -> Reference {
100    array
101        .write::<Array>()
102        .unwrap()
103        .remove(*index.read::<Integer>().unwrap() as _)
104}
105
106#[intuicio_function(module_name = "array")]
107pub fn set(mut array: Reference, index: Reference, value: Reference) -> Reference {
108    array
109        .write::<Array>()
110        .unwrap()
111        .get_mut(*index.read::<Integer>().unwrap() as usize)
112        .map(|item| std::mem::replace(item, value))
113        .unwrap_or_default()
114}
115
116#[intuicio_function(module_name = "array")]
117pub fn get(array: Reference, index: Reference) -> Reference {
118    array
119        .read::<Array>()
120        .unwrap()
121        .get(*index.read::<Integer>().unwrap() as usize)
122        .cloned()
123        .unwrap_or_default()
124}
125
126#[intuicio_function(module_name = "array", use_registry)]
127pub fn slice(
128    registry: &Registry,
129    array: Reference,
130    index: Reference,
131    count: Reference,
132) -> Reference {
133    let index = *index.read::<Integer>().unwrap() as usize;
134    let count = *count.read::<Integer>().unwrap() as usize;
135    Reference::new_array(
136        array.read::<Array>().unwrap()[index..(index + count)].to_vec(),
137        registry,
138    )
139}
140
141#[intuicio_function(module_name = "array", use_registry)]
142pub fn join(registry: &Registry, a: Reference, b: Reference) -> Reference {
143    Reference::new_array(
144        a.read::<Array>()
145            .unwrap()
146            .iter()
147            .chain(b.read::<Array>().unwrap().iter())
148            .cloned()
149            .collect::<Array>(),
150        registry,
151    )
152}
153
154#[intuicio_function(module_name = "array", use_registry)]
155pub fn iter(registry: &Registry, array: Reference, reversed: Reference) -> Reference {
156    Reference::new(
157        ArrayIter {
158            array,
159            index: 0,
160            reversed: *reversed.read::<Boolean>().unwrap(),
161            next: Reference::new(
162                Closure {
163                    function: Function::by_name("next", "array_iter", registry).unwrap(),
164                    captured: vec![],
165                },
166                registry,
167            ),
168        },
169        registry,
170    )
171}
172
173#[intuicio_function(module_name = "array", use_context, use_registry)]
174pub fn collect(context: &mut Context, registry: &Registry, iterator: Reference) -> Reference {
175    let mut result = Array::new();
176    loop {
177        let value = crate::library::iter::next(context, registry, iterator.clone());
178        if value.is_null() {
179            break;
180        }
181        result.push(value);
182    }
183    Reference::new_array(result, registry)
184}
185
186#[derive(IntuicioStruct, Default)]
187#[intuicio(name = "ArrayIter", module_name = "array_iter")]
188pub struct ArrayIter {
189    #[intuicio(ignore)]
190    pub array: Reference,
191    #[intuicio(ignore)]
192    pub index: usize,
193    #[intuicio(ignore)]
194    pub reversed: bool,
195    pub next: Reference,
196}
197
198#[intuicio_methods(module_name = "array_iter")]
199impl ArrayIter {
200    #[intuicio_method()]
201    pub fn next(mut iterator: Reference) -> Reference {
202        let mut iterator = iterator.write::<ArrayIter>().unwrap();
203        let array = iterator.array.clone();
204        let array = array.read::<Array>().unwrap();
205        if iterator.index >= array.len() {
206            return Reference::null();
207        }
208        let index = if iterator.reversed {
209            array.len() - iterator.index - 1
210        } else {
211            iterator.index
212        };
213        iterator.index += 1;
214        array.get(index).cloned().unwrap_or_default()
215    }
216}
217
218pub fn install(registry: &mut Registry) {
219    registry.add_type(define_native_struct! {
220        registry => mod array struct Array (Array) {}
221        [override_send = true]
222    });
223    registry.add_function(new::define_function(registry));
224    registry.add_function(reserve::define_function(registry));
225    registry.add_function(size::define_function(registry));
226    registry.add_function(capacity::define_function(registry));
227    registry.add_function(clear::define_function(registry));
228    registry.add_function(contains::define_function(registry));
229    registry.add_function(find::define_function(registry));
230    registry.add_function(push::define_function(registry));
231    registry.add_function(insert::define_function(registry));
232    registry.add_function(pop::define_function(registry));
233    registry.add_function(remove::define_function(registry));
234    registry.add_function(set::define_function(registry));
235    registry.add_function(get::define_function(registry));
236    registry.add_function(slice::define_function(registry));
237    registry.add_function(join::define_function(registry));
238    registry.add_function(iter::define_function(registry));
239    registry.add_function(collect::define_function(registry));
240    registry.add_type(ArrayIter::define_struct(registry));
241    registry.add_function(ArrayIter::next__define_function(registry));
242}