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