intuicio_frontend_simpleton/library/
array.rs1use 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}