1#[cfg(target_endian = "little")]
4use crate::symbols::Symbol;
5use crate::{
6 exceptions::Exception,
7 gc::{Gc, Trace},
8 lists::{List, slice_to_list},
9 registry::bridge,
10 value::{Value, ValueType, write_value},
11};
12use indexmap::IndexMap;
13use parking_lot::{
14 MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
15};
16use std::{clone::Clone, fmt, hash::Hash, ops::Range, sync::Arc};
17
18#[derive(Trace)]
19#[repr(align(16))]
20pub(crate) struct VectorInner<T: Trace> {
21 pub(crate) vec: RwLock<Vec<T>>,
23 pub(crate) mutable: bool,
25}
26
27#[derive(Clone, Trace)]
29pub struct Vector(pub(crate) Gc<VectorInner<Value>>);
30
31impl Vector {
32 pub fn new(vec: Vec<Value>) -> Self {
33 Self::from(vec)
34 }
35
36 pub fn new_mutable(vec: Vec<Value>) -> Self {
37 Self(Gc::new(VectorInner {
38 vec: RwLock::new(vec),
39 mutable: true,
40 }))
41 }
42
43 pub fn to_list(&self) -> Value {
46 slice_to_list(&self.0.vec.read())
47 }
48
49 pub fn clone_inner_vec(&self) -> Vec<Value> {
50 self.0.vec.read().clone()
51 }
52
53 pub fn iter(&self) -> impl Iterator<Item = Value> {
54 self.0.vec.read().clone().into_iter()
55 }
56}
57
58impl From<Vec<Value>> for Vector {
59 fn from(vec: Vec<Value>) -> Self {
60 Self(Gc::new(VectorInner {
61 vec: RwLock::new(vec),
62 mutable: false,
63 }))
64 }
65}
66
67#[derive(Clone, Trace)]
69pub struct ByteVector(pub(crate) Arc<VectorInner<u8>>);
70
71impl ByteVector {
72 pub fn new(vec: Vec<u8>) -> Self {
73 Self::from(vec)
74 }
75
76 pub fn new_mutable(vec: Vec<u8>) -> Self {
77 Self(Arc::new(VectorInner {
78 vec: RwLock::new(vec),
79 mutable: true,
80 }))
81 }
82
83 pub fn as_slice(&self) -> MappedRwLockReadGuard<'_, [u8]> {
84 RwLockReadGuard::map(self.0.vec.read(), |vec| vec.as_slice())
85 }
86
87 pub fn as_mut_slice(&self) -> MappedRwLockWriteGuard<'_, [u8]> {
88 RwLockWriteGuard::map(self.0.vec.write(), |vec| vec.as_mut_slice())
89 }
90
91 pub fn as_mut_vec(&self) -> RwLockWriteGuard<'_, Vec<u8>> {
92 self.0.vec.write()
93 }
94
95 pub fn is_empty(&self) -> bool {
96 self.len() == 0
97 }
98
99 pub fn len(&self) -> usize {
100 self.0.vec.read().len()
101 }
102
103 pub fn clear(&self) {
104 self.0.vec.write().clear();
105 }
106
107 pub fn get(&self, idx: usize) -> Option<u8> {
108 self.0.vec.read().get(idx).copied()
109 }
110}
111
112impl From<Vec<u8>> for ByteVector {
113 fn from(vec: Vec<u8>) -> Self {
114 Self(Arc::new(VectorInner {
115 vec: RwLock::new(vec),
116 mutable: false,
117 }))
118 }
119}
120
121impl Hash for ByteVector {
122 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
123 self.0.vec.read().hash(state)
124 }
125}
126
127impl PartialEq<[u8]> for ByteVector {
128 fn eq(&self, rhs: &[u8]) -> bool {
129 *self.0.vec.read() == rhs
130 }
131}
132
133impl PartialEq for ByteVector {
134 fn eq(&self, rhs: &Self) -> bool {
135 *self.0.vec.read() == *rhs.0.vec.read()
136 }
137}
138
139pub(crate) fn write_vec(
140 v: &Vector,
141 fmt: fn(&Value, &mut IndexMap<Value, bool>, &mut fmt::Formatter<'_>) -> fmt::Result,
142 circular_values: &mut IndexMap<Value, bool>,
143 f: &mut fmt::Formatter<'_>,
144) -> Result<(), fmt::Error> {
145 write!(f, "#(")?;
146
147 let values = v.0.vec.read();
148
149 for (i, value) in values.iter().enumerate() {
150 if i > 0 {
151 write!(f, " ")?;
152 }
153 write_value(value, fmt, circular_values, f)?;
154 }
155
156 write!(f, ")")
157}
158
159pub(crate) fn write_bytevec(v: &ByteVector, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
160 write!(f, "#vu8(")?;
161
162 let bytes = v.0.vec.read();
163 for (i, byte) in bytes.iter().enumerate() {
164 if i > 0 {
165 write!(f, " ")?;
166 }
167 write!(f, "{byte}")?;
168 }
169
170 write!(f, ")")
171}
172
173fn try_make_range(start: usize, end: usize) -> Result<Range<usize>, Exception> {
174 if end < start {
175 Err(Exception::error(format!(
176 "Range end {end} cannot be less than start {start}",
177 )))
178 } else {
179 Ok(start..end)
180 }
181}
182
183trait Indexer {
184 type Collection: TryFrom<Value, Error = Exception>;
185
186 fn get_len(_: &Self::Collection) -> usize;
187
188 fn get_range(_: &Self::Collection, _: Range<usize>) -> Self::Collection;
189
190 fn index(from: &Value, range: &[Value]) -> Result<Self::Collection, Exception> {
191 let collection = Self::Collection::try_from(from.clone())?;
192 let len = Self::get_len(&collection);
193
194 let start: usize = range
195 .first()
196 .cloned()
197 .map(Value::try_into)
198 .transpose()?
199 .unwrap_or(0);
200 let end: usize = range
201 .get(1)
202 .cloned()
203 .map(Value::try_into)
204 .transpose()?
205 .unwrap_or(len);
206
207 let range = try_make_range(start, end)?;
208 if range.end > len {
209 return Err(Exception::invalid_range(range, len));
210 }
211
212 Ok(Self::get_range(&collection, range))
213 }
214}
215
216struct VectorIndexer;
217
218impl Indexer for VectorIndexer {
219 type Collection = Vector;
221
222 fn get_len(vec: &Self::Collection) -> usize {
223 vec.0.vec.read().len()
224 }
225
226 fn get_range(vec: &Self::Collection, range: Range<usize>) -> Self::Collection {
227 let subvec: Vec<Value> = vec
228 .0
229 .vec
230 .read()
231 .iter()
232 .skip(range.start)
233 .take(range.end - range.start)
234 .cloned()
235 .collect();
236 Vector(Gc::new(VectorInner {
237 vec: RwLock::new(subvec),
238 mutable: true,
239 }))
240 }
241}
242
243#[bridge(name = "make-vector", lib = "(rnrs base builtins (6))")]
244pub fn make_vector(n: &Value, with: &[Value]) -> Result<Vec<Value>, Exception> {
245 let n: usize = n.try_to_scheme_type()?;
246
247 Ok(vec![Value::from(Vector(Gc::new(VectorInner {
248 vec: RwLock::new(
249 (0..n)
250 .map(|_| with.first().cloned().unwrap_or_else(Value::null))
251 .collect::<Vec<_>>(),
252 ),
253 mutable: true,
254 })))])
255}
256
257#[bridge(name = "vector", lib = "(rnrs base builtins (6))")]
258pub fn vector(args: &[Value]) -> Result<Vec<Value>, Exception> {
259 Ok(vec![Value::from(Vector(Gc::new(VectorInner {
260 vec: RwLock::new(args.to_vec()),
261 mutable: true,
262 })))])
263}
264
265#[bridge(name = "vector-ref", lib = "(rnrs base builtins (6))")]
266pub fn vector_ref(vec: &Value, index: &Value) -> Result<Vec<Value>, Exception> {
267 let vec: Vector = vec.clone().try_into()?;
268 let index: usize = index.clone().try_into()?;
269 let vec_read = vec.0.vec.read();
270
271 Ok(vec![
272 vec_read
273 .get(index)
274 .ok_or_else(|| Exception::invalid_index(index, vec_read.len()))?
275 .clone(),
276 ])
277}
278
279#[bridge(name = "vector-length", lib = "(rnrs base builtins (6))")]
280pub fn vector_len(vec: &Value) -> Result<Vec<Value>, Exception> {
281 let vec: Vector = vec.clone().try_into()?;
282 let len = vec.0.vec.read().len();
283
284 Ok(vec![Value::from(len)])
285}
286
287#[bridge(name = "bytevector-length", lib = "(rnrs base builtins (6))")]
288pub fn bytevector_len(vec: &Value) -> Result<Vec<Value>, Exception> {
289 let vec: ByteVector = vec.clone().try_into()?;
290 let len = vec.0.vec.read().len();
291
292 Ok(vec![Value::from(len)])
293}
294
295#[bridge(name = "vector-set!", lib = "(rnrs base builtins (6))")]
296pub fn vector_set_bang(vec: &Value, index: &Value, with: &Value) -> Result<Vec<Value>, Exception> {
297 let vec: Vector = vec.clone().try_into()?;
298
299 if !vec.0.mutable {
300 return Err(Exception::error("vector is immutable"));
301 }
302
303 let mut vec_write = vec.0.vec.write();
304 let vec_len = vec_write.len();
305 let index: usize = index.clone().try_into()?;
306
307 *vec_write
308 .get_mut(index)
309 .ok_or_else(|| Exception::invalid_index(index, vec_len))? = with.clone();
310
311 Ok(vec![])
312}
313
314#[bridge(name = "vector->list", lib = "(rnrs base builtins (6))")]
315pub fn vector_to_list(from: &Value, range: &[Value]) -> Result<Vec<Value>, Exception> {
316 let vec = VectorIndexer::index(from, range)?;
317 let vec_read = vec.0.vec.read();
318 Ok(vec![slice_to_list(&vec_read)])
319}
320
321#[bridge(name = "vector->string", lib = "(rnrs base builtins (6))")]
322pub fn vector_to_string(from: &Value, range: &[Value]) -> Result<Vec<Value>, Exception> {
323 let vec = VectorIndexer::index(from, range)?;
324 let vec_read = vec.0.vec.read();
325 Ok(vec![Value::from(
326 vec_read
327 .iter()
328 .cloned()
329 .map(<Value as TryInto<char>>::try_into)
330 .collect::<Result<String, _>>()?,
331 )])
332}
333
334#[bridge(name = "vector-copy", lib = "(rnrs base builtins (6))")]
335pub fn vector_copy(from: &Value, range: &[Value]) -> Result<Vec<Value>, Exception> {
336 Ok(vec![Value::from(VectorIndexer::index(from, range)?)])
337}
338
339#[bridge(name = "vector-copy!", lib = "(rnrs base builtins (6))")]
340pub fn vector_copy_to(
341 to: &Value,
342 at: &Value,
343 from: &Value,
344 range: &[Value],
345) -> Result<Vec<Value>, Exception> {
346 let to: Vector = to.clone().try_into()?;
347 let mut to = to.0.vec.write();
348
349 let at: usize = at.clone().try_into()?;
350
351 if at >= to.len() {
352 return Err(Exception::invalid_index(at, to.len()));
353 }
354
355 let copies = VectorIndexer::index(from, range)?;
356 let copies = copies.0.vec.read();
357 if copies.len() + at >= to.len() {
358 return Err(Exception::invalid_range(at..at + copies.len(), to.len()));
359 }
360
361 copies
362 .iter()
363 .enumerate()
364 .map(|(i, copy)| (i + at, copy))
365 .for_each(|(i, copy)| {
366 if let Some(i) = to.get_mut(i) {
367 *i = copy.clone();
368 }
369 });
370
371 Ok(Vec::new())
372}
373
374#[bridge(name = "vector-append", lib = "(rnrs base builtins (6))")]
375pub fn vector_append(args: &[Value]) -> Result<Vec<Value>, Exception> {
376 if args.is_empty() {
377 return Err(Exception::wrong_num_of_var_args(1..usize::MAX, 0));
378 }
379
380 Ok(vec![Value::from(
381 args.iter()
382 .map(|arg| {
383 let vec: Vector = arg.clone().try_into()?;
384 let vec_read = vec.0.vec.read();
385 Ok(vec_read.clone())
386 })
387 .collect::<Result<Vec<_>, Exception>>()?
388 .into_iter()
389 .flatten()
390 .collect::<Vec<_>>(),
391 )])
392}
393
394#[bridge(name = "vector-fill!", lib = "(rnrs base builtins (6))")]
395pub fn vector_fill(
396 vector: &Value,
397 with: &Value,
398 start: &Value,
399 end: &[Value],
400) -> Result<Vec<Value>, Exception> {
401 let vector: Vector = vector.clone().try_into()?;
402 let mut vector = vector.0.vec.write();
403
404 let start: usize = start.clone().try_into()?;
405 let end = match end.first() {
406 Some(end) => end.clone().try_into()?,
407 None => vector.len(),
408 };
409
410 let range = try_make_range(start, end)?;
411 if range.end > vector.len() {
412 return Err(Exception::invalid_range(range, vector.len()));
413 }
414
415 range.for_each(|i| {
416 if let Some(slot) = vector.get_mut(i) {
417 *slot = with.clone()
418 }
419 });
420
421 Ok(vec![])
422}
423
424#[bridge(name = "native-endianness", lib = "(rnrs bytevectors (6))")]
425pub fn native_endianness() -> Result<Vec<Value>, Exception> {
426 #[cfg(target_endian = "little")]
427 {
428 Ok(vec![Value::from(Symbol::intern("little"))])
429 }
430 #[cfg(target_endian = "big")]
431 {
432 Ok(vec![Value::from(Symbol::intern("big"))])
433 }
434}
435
436#[bridge(name = "bytevector?", lib = "(rnrs bytevectors (6))")]
437pub fn bytevector_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
438 Ok(vec![Value::from(arg.type_of() == ValueType::ByteVector)])
439}
440
441#[bridge(name = "make-bytevector", lib = "(rnrs bytevectors (6))")]
442pub fn make_bytevector(k: usize, fill: &[Value]) -> Result<Vec<Value>, Exception> {
443 let fill: u8 = match fill {
444 [] => 0u8,
445 [fill] => fill.try_into()?,
446 _ => return Err(Exception::wrong_num_of_var_args(1..2, 1 + fill.len())),
447 };
448 Ok(vec![Value::from(ByteVector::new_mutable(vec![fill; k]))])
449}
450
451#[bridge(name = "bytevector-length", lib = "(rnrs bytevectors (6))")]
452pub fn bytevector_length(bytevector: ByteVector) -> Result<Vec<Value>, Exception> {
453 Ok(vec![Value::from(bytevector.len())])
454}
455
456#[bridge(name = "bytevector=?", lib = "(rnrs bytevectors (6))")]
457pub fn bytevector_equal_pred(lhs: ByteVector, rhs: ByteVector) -> Result<Vec<Value>, Exception> {
458 Ok(vec![Value::from(lhs == rhs)])
459}
460
461#[bridge(name = "u8-list->bytevector", lib = "(rnrs bytevectors (6))")]
462pub fn u8_list_to_bytevector(list: List) -> Result<Vec<Value>, Exception> {
463 Ok(vec![Value::from(ByteVector::new_mutable(
464 list.into_iter()
465 .map(u8::try_from)
466 .collect::<Result<Vec<_>, _>>()?,
467 ))])
468}