Skip to main content

scheme_rs/
vectors.rs

1//! Growable mutable vectors.
2
3#[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    /// Inner vector.
22    pub(crate) vec: RwLock<Vec<T>>,
23    /// Whether or not the vector is mutable
24    pub(crate) mutable: bool,
25}
26
27/// A vector of values
28#[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    // TODO: Add more convenience functions here
44
45    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/// A vector of bytes
68#[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 = Gc<RwLock<AlignedVector<Value>>>;
220    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}