Skip to main content

scheme_rs/
value.rs

1//! Scheme values.
2//!
3//! Scheme values are dynamic and can contain essentially any value, similar to
4//! an [`Arc<dyn Any>`](std::any::Any). Any type that has a valid scheme
5//! representation (see [scheme types](#scheme-types) for more information) can
6//! be converted easily to a Scheme `Value`. Converting a Rust primitive or
7//! standard library type can be done simply with the `From` trait:
8//!
9//! ```
10//! # use scheme_rs::value::Value;
11//! let value = Value::from(3.1415926f64);
12//! ```
13//!
14//! Converting a Value back to a concrete rust type can be done via the
15//! [`TryFrom`] trait or by obtaining an enum through the
16//! [`unpack`](Value::unpack) or [`unpacked_ref`](Value::unpacked_ref)
17//! functions:
18//!
19//! ```
20//! # use scheme_rs::value::{Value, UnpackedValue};
21//! # let value = Value::from(3.1415926f64);
22//! let float: f64 = value.clone().try_into().unwrap();
23//! let float: f64 = match value.unpack() {
24//!     UnpackedValue::Number(num) => num.try_into().unwrap(),
25//!     _ => unreachable!(),
26//! };
27//! ```
28//!
29//! It is generally preferrable to use `try_into` as opposed to `unpack` since
30//! `UnpackedValue` is an enumeration that is subject to change.
31//!
32//! Alternatively, the [`cast_to_scheme_type`](Value::cast_to_scheme_type)
33//! method can be used to obtain an Option from a reference for more ergonomic
34//! casting. There is also the [`try_to_scheme_type`](Value::try_to_scheme_type)
35//! function that is similarly more ergonomic:
36//!
37//! ```
38//! # use scheme_rs::value::{Value, UnpackedValue};
39//! let value = Value::from(3);
40//! let float = value.cast_to_scheme_type::<f64>().unwrap();
41//! let int = value.cast_to_scheme_type::<i64>().unwrap();
42//! ```
43//!
44//! ## Converting to and from arbitrary Rust types
45//!
46//! Besides primitives and standard library types, scheme-rs supports converting
47//! arbitrary Rust types (such as structs and enums) to `Values` by representing
48//! them as [`Records`](Record). To do this, the type must implement the
49//! [`SchemeCompatible`] trait (see [`records`](scheme_rs::records) for more
50//! information).
51//!
52//! `Value` provides three convenience methods to facilitate these conversions:
53//! - [`from_rust_type`](Value::from_rust_type): convert a `SchemeCompatible`
54//!   type to a record type, and then to a `Value`.
55//! - [`try_to_rust_type`](Value::try_to_rust_type): attempt to convert the
56//!   value to a `Gc<T>` where `T: SchemeCompatible` providing a detailed error
57//!   on failure.
58//! - [`cast_to_rust_type`](Value::cast_to_rust_type): attempt to convert the
59//!   value to a `Gc<T>` where `T: SchemeCompatible`, returning `None` on
60//!   failure.
61//!
62//! ## Scheme types:
63//!
64//! Scheme values can inhabit at most one of any of the following types:
65//! - **Undefined**: Variables with this value throw an error upon being read.
66//! - **Null**: Can only be one possible value which is itself. Conceptually the
67//!   same as the [`()`](https://doc.rust-lang.org/std/primitive.unit.html) type.
68//! - **Pair**: A [collection of two Values](Pair). Conceptually similar to a
69//!   Rust [two-tuple](https://doc.rust-lang.org/std/primitive.tuple.html).
70//! - **Boolean**: Can either be `true` or `false`.
71//! - **Character**: A unicode code point. Same thing as a [`char`](std::char).
72//! - **Number**: A numerical value on the numerical tower. Represented by a
73//!   [`Arc<Number>`](crate::num::Number).
74//! - **String**: An array of [`chars`](std::char).
75//! - **Symbol**: A [`Symbol`].
76//! - **Vector**: A [`Vector`].
77//! - **Byte-vector**: A [`ByteVector`].
78//! - **Syntax**: A [`Syntax`].
79//! - **Procedure**: A [`Procedure`].
80//! - **Record**: A [`Record`], which can possibly be a [`SchemeCompatible`].
81//! - **Record Type Descriptor**: A [descriptor of a record's type](RecordTypeDescriptor).
82//! - **Hashtable**: A [`HashTable`].
83//! - **Port**: A value that can handle [input/output](scheme_rs::ports::Port)
84//!   from the outside world.
85//! - **Cell**: A mutable reference to another Value. This type is completely
86//!   transparent and impossible to observe.
87
88use indexmap::{IndexMap, IndexSet};
89use malachite::Integer;
90use parking_lot::RwLock;
91
92use crate::{
93    exceptions::Exception,
94    gc::{Gc, GcInner, Trace},
95    hashtables::{HashTable, HashTableInner},
96    lists::{self, Pair, PairInner},
97    num::{ComplexNumber, Number, NumberInner, SimpleNumber},
98    ports::{Port, PortInner},
99    proc::{Procedure, ProcedureInner},
100    records::{Record, RecordInner, RecordTypeDescriptor, SchemeCompatible},
101    registry::bridge,
102    strings::{WideString, WideStringInner},
103    symbols::Symbol,
104    syntax::{Identifier, Syntax},
105    vectors::{self, ByteVector, Vector, VectorInner},
106};
107use std::{
108    collections::HashMap,
109    convert::Infallible,
110    fmt,
111    hash::{Hash, Hasher},
112    marker::PhantomData,
113    mem::ManuallyDrop,
114    ops::Deref,
115    ptr::null,
116    sync::Arc,
117};
118
119const ALIGNMENT: usize = 16;
120const TAG_BITS: usize = ALIGNMENT.ilog2() as usize;
121const TAG: usize = 0b1111;
122const FALSE_VALUE: usize = Tag::Boolean as usize;
123
124/// A Scheme value. See [the module documentation](scheme_rs::value) for more
125/// information.
126#[repr(transparent)]
127pub struct Value(*const ());
128
129impl Value {
130    /// Create a new `Value` from an `UnpackedValue`.
131    ///
132    /// This is generally discouraged as it's cumbersome; try using `From`
133    /// instead.
134    pub fn new(v: UnpackedValue) -> Self {
135        v.into_value()
136    }
137
138    /// #f is false, everything else is true
139    pub fn is_true(&self) -> bool {
140        self.0 as usize != FALSE_VALUE
141    }
142
143    pub fn is_null(&self) -> bool {
144        self.0 as usize == Tag::Pair as usize
145    }
146
147    pub fn is_undefined(&self) -> bool {
148        self.type_of() == ValueType::Undefined
149    }
150
151    /// Creates a new Value from a raw u64.
152    ///
153    /// # Safety
154    /// Calling this function is undefined behavior if the raw u64 was not obtained
155    /// via [into_raw](Value::into_raw)
156    pub unsafe fn from_raw(raw: *const ()) -> Self {
157        Self(raw)
158    }
159
160    /// Creates a new Value from a raw u64, incrementing the reference count.
161    ///
162    /// # Safety
163    /// Calling this function is undefined behavior if the raw u64 was not obtained
164    /// via [into_raw](Value::into_raw)
165    pub unsafe fn from_raw_inc_rc(raw: *const ()) -> Self {
166        let tag = Tag::from(raw as usize & TAG);
167        let untagged = raw.map_addr(|raw| raw & !TAG);
168        unsafe {
169            match tag {
170                Tag::Number => Arc::increment_strong_count(untagged as *const NumberInner),
171                Tag::String => Arc::increment_strong_count(untagged as *const WideStringInner),
172                Tag::Vector => {
173                    Gc::increment_reference_count(untagged as *mut GcInner<VectorInner<Value>>)
174                }
175                Tag::ByteVector => Arc::increment_strong_count(untagged as *const VectorInner<u8>),
176                Tag::Syntax => Gc::increment_reference_count(untagged as *mut GcInner<Syntax>),
177                Tag::Procedure => {
178                    Gc::increment_reference_count(untagged as *mut GcInner<ProcedureInner>)
179                }
180                Tag::Record => Gc::increment_reference_count(untagged as *mut GcInner<RecordInner>),
181                Tag::RecordTypeDescriptor => {
182                    Arc::increment_strong_count(untagged as *const RecordTypeDescriptor)
183                }
184                Tag::Pair => {
185                    if !untagged.is_null() {
186                        Gc::increment_reference_count(untagged as *mut GcInner<PairInner>)
187                    }
188                }
189                Tag::Port => Arc::increment_strong_count(untagged as *const PortInner),
190                Tag::HashTable => {
191                    Gc::increment_reference_count(untagged as *mut GcInner<HashTableInner>)
192                }
193                Tag::Cell => {
194                    Gc::increment_reference_count(untagged as *mut GcInner<Value>);
195                }
196                Tag::Undefined | Tag::Symbol | Tag::Boolean | Tag::Character => (),
197            }
198        }
199        Self(raw)
200    }
201
202    /// Creates a raw u64 from a Value. Does not decrement the reference count.
203    /// Calling this function without turning the raw value into a Value via
204    /// [from_raw](Value::from_raw) is equivalent to calling mem::forget on the
205    /// value.
206    pub fn into_raw(val: Self) -> *const () {
207        ManuallyDrop::new(val).0
208    }
209
210    /// Creates a raw u64 from the Value. Does not decrement the reference count.
211    pub fn as_raw(this: &Self) -> *const () {
212        this.0
213    }
214
215    fn from_ptr_and_tag<T: Send + Sync>(ptr: *const T, tag: Tag) -> Self {
216        Self(ptr.map_addr(|raw| raw | tag as usize) as *const ())
217    }
218
219    fn from_mut_ptr_and_tag<T: Send + Sync>(ptr: *mut T, tag: Tag) -> Self {
220        Self(ptr.map_addr(|raw| raw | tag as usize) as *const ())
221    }
222
223    pub fn undefined() -> Self {
224        Self(null::<()>().map_addr(|raw| raw | Tag::Undefined as usize))
225    }
226
227    pub fn null() -> Self {
228        Self(null::<()>().map_addr(|raw| raw | Tag::Pair as usize))
229    }
230
231    /// Convert a [`Syntax`] into its corresponding datum representation.
232    pub fn datum_from_syntax(syntax: &Syntax) -> Self {
233        match syntax {
234            Syntax::Wrapped { value, .. } => value.clone(),
235            Syntax::List { list, .. } => {
236                let mut curr = Self::datum_from_syntax(list.last().unwrap());
237                for item in list[..list.len() - 1].iter().rev() {
238                    curr = Self::from(Pair::new(Self::datum_from_syntax(item), curr, false));
239                }
240                curr
241            }
242            Syntax::Vector { vector, .. } => Self::from(
243                vector
244                    .iter()
245                    .map(Self::datum_from_syntax)
246                    .collect::<Vec<_>>(),
247            ),
248            Syntax::Identifier { ident, .. } => Self::new(UnpackedValue::Symbol(ident.sym)),
249        }
250    }
251
252    pub fn type_of(&self) -> ValueType {
253        self.unpacked_ref().type_of()
254    }
255
256    pub fn type_name(&self) -> &'static str {
257        self.unpacked_ref().type_name()
258    }
259
260    /// Attempt to cast the value into a Scheme primitive type.
261    pub fn cast_to_scheme_type<T>(&self) -> Option<T>
262    where
263        for<'a> &'a Self: Into<Option<T>>,
264    {
265        self.into()
266    }
267
268    /// Attempt to cast the value into a Scheme primitive type and return a
269    /// descriptive error on failure.
270    pub fn try_to_scheme_type<T>(&self) -> Result<T, Exception>
271    where
272        T: for<'a> TryFrom<&'a Self, Error = Exception>,
273    {
274        self.try_into()
275    }
276
277    /// Attempt to cast the value into a Rust type that implements
278    /// [`SchemeCompatible`].
279    pub fn cast_to_rust_type<T: SchemeCompatible>(&self) -> Option<Gc<T>> {
280        let UnpackedValue::Record(record) = self.clone().unpack() else {
281            return None;
282        };
283        record.cast::<T>()
284    }
285
286    /// Attempt to cast the value into a Rust type and return a descriptive
287    /// error on failure.
288    pub fn try_to_rust_type<T: SchemeCompatible>(&self) -> Result<Gc<T>, Exception> {
289        let type_name = T::rtd().name.to_str();
290        let this = self.clone().unpack();
291        let record = match this {
292            UnpackedValue::Record(record) => record,
293            e => return Err(Exception::type_error(&type_name, e.type_name())),
294        };
295
296        record
297            .cast::<T>()
298            .ok_or_else(|| Exception::type_error(&type_name, &record.rtd().name.to_str()))
299    }
300
301    /// Automatically convert a `SchemeCompatible` type to a `Record` and then
302    /// into a `Value`.
303    pub fn from_rust_type<T: SchemeCompatible>(t: T) -> Self {
304        Self::from(Record::from_rust_type(t))
305    }
306
307    /// Unpack the value into an enum representation.
308    pub fn unpack(self) -> UnpackedValue {
309        let raw = ManuallyDrop::new(self).0;
310        let tag = Tag::from(raw as usize & TAG);
311        let untagged = raw.map_addr(|raw| raw & !TAG);
312        match tag {
313            Tag::Undefined => UnpackedValue::Undefined,
314            Tag::Boolean => {
315                let untagged = untagged as usize >> TAG_BITS;
316                UnpackedValue::Boolean(untagged != 0)
317            }
318            Tag::Character => {
319                let untagged = (untagged as usize >> TAG_BITS) as u32;
320                UnpackedValue::Character(char::from_u32(untagged).unwrap())
321            }
322            Tag::Number => {
323                let number = unsafe { Arc::from_raw(untagged as *const NumberInner) };
324                UnpackedValue::Number(Number(number))
325            }
326            Tag::String => {
327                let str = unsafe { Arc::from_raw(untagged as *const WideStringInner) };
328                UnpackedValue::String(WideString(str))
329            }
330            Tag::Symbol => {
331                let untagged = (untagged as usize >> TAG_BITS) as u32;
332                UnpackedValue::Symbol(Symbol(untagged))
333            }
334            Tag::Vector => {
335                let vec = unsafe { Gc::from_raw(untagged as *mut GcInner<VectorInner<Self>>) };
336                UnpackedValue::Vector(Vector(vec))
337            }
338            Tag::ByteVector => {
339                let bvec = unsafe { Arc::from_raw(untagged as *const VectorInner<u8>) };
340                UnpackedValue::ByteVector(ByteVector(bvec))
341            }
342            Tag::Syntax => {
343                let syn = unsafe { Gc::from_raw(untagged as *mut GcInner<Syntax>) };
344                UnpackedValue::Syntax(syn)
345            }
346            Tag::Procedure => {
347                let clos = unsafe { Gc::from_raw(untagged as *mut GcInner<ProcedureInner>) };
348                UnpackedValue::Procedure(Procedure(clos))
349            }
350            Tag::Record => {
351                let rec = unsafe { Gc::from_raw(untagged as *mut GcInner<RecordInner>) };
352                UnpackedValue::Record(Record(rec))
353            }
354            Tag::RecordTypeDescriptor => {
355                let rt = unsafe { Arc::from_raw(untagged as *const RecordTypeDescriptor) };
356                UnpackedValue::RecordTypeDescriptor(rt)
357            }
358            Tag::Pair => {
359                if untagged.is_null() {
360                    UnpackedValue::Null
361                } else {
362                    let pair = unsafe { Gc::from_raw(untagged as *mut GcInner<PairInner>) };
363                    UnpackedValue::Pair(Pair(pair))
364                }
365            }
366            Tag::Port => {
367                let port_inner = unsafe { Arc::from_raw(untagged as *const PortInner) };
368                UnpackedValue::Port(Port(port_inner))
369            }
370            Tag::HashTable => {
371                let ht = unsafe { Gc::from_raw(untagged as *mut GcInner<HashTableInner>) };
372                UnpackedValue::HashTable(HashTable(ht))
373            }
374            Tag::Cell => {
375                let cell = unsafe { Gc::from_raw(untagged as *mut GcInner<RwLock<Value>>) };
376                UnpackedValue::Cell(Cell(cell))
377            }
378        }
379    }
380
381    pub fn unpacked_ref(&self) -> UnpackedValueRef<'_> {
382        let unpacked = ManuallyDrop::new(Value(self.0).unpack());
383        UnpackedValueRef {
384            unpacked,
385            marker: PhantomData,
386        }
387    }
388
389    /// The eq? predicate as defined by the R6RS specification.
390    #[allow(clippy::should_implement_trait)]
391    pub fn eq(&self, rhs: &Self) -> bool {
392        let obj1 = self.unpacked_ref();
393        let obj2 = rhs.unpacked_ref();
394        obj1.eq(&obj2)
395    }
396
397    /// The eqv? predicate as defined by the R6RS specification.
398    pub fn eqv(&self, rhs: &Self) -> bool {
399        let obj1 = self.unpacked_ref();
400        let obj2 = rhs.unpacked_ref();
401        obj1.eqv(&obj2)
402    }
403
404    /// The equal? predicate as defined by the R6RS specification.
405    pub fn equal(&self, rhs: &Self) -> bool {
406        equal(self, rhs)
407    }
408
409    /// Performs a hash suitable for use with eq? as an equivalance function
410    pub fn eq_hash<H: Hasher>(&self, state: &mut H) {
411        let unpacked = self.unpacked_ref();
412        std::mem::discriminant(&*unpacked).hash(state);
413        match &*unpacked {
414            UnpackedValue::Undefined => (),
415            UnpackedValue::Null => (),
416            UnpackedValue::Boolean(b) => b.hash(state),
417            UnpackedValue::Character(c) => c.hash(state),
418            UnpackedValue::Number(n) => Arc::as_ptr(&n.0).hash(state),
419            UnpackedValue::String(s) => Arc::as_ptr(&s.0).hash(state),
420            UnpackedValue::Symbol(s) => s.hash(state),
421            UnpackedValue::ByteVector(v) => Arc::as_ptr(&v.0).hash(state),
422            UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
423            UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
424            UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
425            UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
426            UnpackedValue::Pair(p) => Gc::as_ptr(&p.0).hash(state),
427            UnpackedValue::Vector(v) => Gc::as_ptr(&v.0).hash(state),
428            UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
429            UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
430            UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
431        }
432    }
433
434    /// Performs a hash suitable for use with eqv? as an equivalance function
435    pub fn eqv_hash<H: Hasher>(&self, state: &mut H) {
436        let unpacked = self.unpacked_ref();
437        std::mem::discriminant(&*unpacked).hash(state);
438        match &*unpacked {
439            UnpackedValue::Undefined => (),
440            UnpackedValue::Null => (),
441            UnpackedValue::Boolean(b) => b.hash(state),
442            UnpackedValue::Character(c) => c.hash(state),
443            UnpackedValue::Number(n) => n.hash(state),
444            UnpackedValue::String(s) => Arc::as_ptr(&s.0).hash(state),
445            UnpackedValue::Symbol(s) => s.hash(state),
446            UnpackedValue::ByteVector(v) => Arc::as_ptr(&v.0).hash(state),
447            UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
448            UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
449            UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
450            UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
451            UnpackedValue::Pair(p) => Gc::as_ptr(&p.0).hash(state),
452            UnpackedValue::Vector(v) => Gc::as_ptr(&v.0).hash(state),
453            UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
454            UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
455            UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
456        }
457    }
458
459    /// Performs a hash suitable for use with equal? as an equivalance function
460    pub fn equal_hash<H: Hasher>(&self, recursive: &mut IndexSet<Value>, state: &mut H) {
461        let unpacked = self.unpacked_ref();
462        std::mem::discriminant(&*unpacked).hash(state);
463
464        // I think this is fine, because types that would be recursive will
465        // write out at least two values here where we're only writing out one.
466        if let Some(index) = recursive.get_index_of(self) {
467            state.write_usize(index);
468            return;
469        }
470
471        match &*unpacked {
472            UnpackedValue::Undefined => (),
473            UnpackedValue::Null => (),
474            UnpackedValue::Boolean(b) => b.hash(state),
475            UnpackedValue::Character(c) => c.hash(state),
476            UnpackedValue::Number(n) => n.hash(state),
477            UnpackedValue::String(s) => s.hash(state),
478            UnpackedValue::Symbol(s) => s.hash(state),
479            UnpackedValue::ByteVector(v) => v.hash(state),
480            UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
481            UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
482            UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
483            UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
484            UnpackedValue::Pair(p) => {
485                recursive.insert(self.clone());
486                let (car, cdr) = p.clone().into();
487                car.equal_hash(recursive, state);
488                cdr.equal_hash(recursive, state);
489            }
490            UnpackedValue::Vector(v) => {
491                recursive.insert(self.clone());
492                let v_read = v.0.vec.read();
493                state.write_usize(v_read.len());
494                for val in v_read.iter() {
495                    val.equal_hash(recursive, state);
496                }
497            }
498            UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
499            UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
500            UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
501        }
502    }
503}
504
505impl Clone for Value {
506    fn clone(&self) -> Self {
507        unsafe { Self::from_raw_inc_rc(self.0) }
508    }
509}
510
511impl Drop for Value {
512    fn drop(&mut self) {
513        // FIXME: This is a pretty dumb way to do this, do it manually!
514        unsafe { ManuallyDrop::drop(&mut ManuallyDrop::new(Self(self.0).unpack())) }
515    }
516}
517
518/// Default Hash implementation for Value is [Value::eqv_hash]. This produces
519/// reasonable hash maps.
520impl Hash for Value {
521    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
522        self.eqv_hash(state)
523    }
524}
525
526/// Default PartialEq implementation for Value is [Value::eqv]. This allows us
527/// to implement [Eq].
528impl PartialEq for Value {
529    fn eq(&self, rhs: &Value) -> bool {
530        self.eqv(rhs)
531    }
532}
533
534/// Eq can be implemented reasonably for Value since (eqv? +nan.0 +nan.0) is
535/// true
536impl Eq for Value {}
537
538unsafe impl Send for Value {}
539unsafe impl Sync for Value {}
540
541impl fmt::Display for Value {
542    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
543        let mut circular_values = IndexSet::default();
544        determine_circularity(self, &mut IndexSet::default(), &mut circular_values);
545        let mut circular_values = circular_values.into_iter().map(|k| (k, false)).collect();
546        write_value(self, display_value, &mut circular_values, f)
547    }
548}
549
550impl fmt::Debug for Value {
551    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552        let mut circular_values = IndexSet::default();
553        determine_circularity(self, &mut IndexSet::default(), &mut circular_values);
554        let mut circular_values = circular_values.into_iter().map(|k| (k, false)).collect();
555        write_value(self, debug_value, &mut circular_values, f)
556    }
557}
558
559unsafe impl Trace for Value {
560    unsafe fn visit_children(&self, visitor: &mut dyn FnMut(crate::gc::OpaqueGcPtr)) {
561        unsafe {
562            self.unpacked_ref().visit_children(visitor);
563        }
564    }
565
566    unsafe fn finalize(&mut self) {
567        unsafe { ManuallyDrop::new(Self(self.0).unpack()).finalize() }
568    }
569}
570
571/// A Cell is a value that is mutable, essentially a variable.
572#[derive(Clone, Trace)]
573pub struct Cell(pub(crate) Gc<RwLock<Value>>);
574
575impl Cell {
576    pub fn new(val: Value) -> Self {
577        Self(Gc::new(RwLock::new(val)))
578    }
579
580    pub fn get(&self) -> Value {
581        self.0.read().clone()
582    }
583
584    pub fn set(&self, new_val: Value) {
585        *self.0.write() = new_val;
586    }
587}
588
589/// A reference to an [`UnpackedValue`]. Allows for unpacking a `Value` without
590/// cloning/modifying the reference count.
591pub struct UnpackedValueRef<'a> {
592    unpacked: ManuallyDrop<UnpackedValue>,
593    marker: PhantomData<&'a UnpackedValue>,
594}
595
596impl Deref for UnpackedValueRef<'_> {
597    type Target = UnpackedValue;
598
599    fn deref(&self) -> &Self::Target {
600        &self.unpacked
601    }
602}
603
604impl AsRef<UnpackedValue> for UnpackedValueRef<'_> {
605    fn as_ref(&self) -> &UnpackedValue {
606        &self.unpacked
607    }
608}
609
610impl<T> From<Option<T>> for Value
611where
612    Value: From<T>,
613    Value: From<bool>,
614{
615    // Probably not the best way to do this, but whatever
616    fn from(value: Option<T>) -> Self {
617        match value {
618            Some(t) => Self::from(t),
619            None => Self::from(false),
620        }
621    }
622}
623
624/*
625impl From<ast::Literal> for Value {
626    fn from(lit: ast::Literal) -> Self {
627        Value::new(lit.into())
628    }
629}
630*/
631
632impl From<Exception> for Value {
633    fn from(value: Exception) -> Self {
634        value.0
635    }
636}
637
638#[repr(u64)]
639#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
640pub(crate) enum Tag {
641    Undefined = 0,
642    Pair = 1,
643    Boolean = 2,
644    Character = 3,
645    Number = 4,
646    String = 5,
647    Symbol = 6,
648    Vector = 7,
649    ByteVector = 8,
650    Syntax = 9,
651    Procedure = 10,
652    Record = 11,
653    RecordTypeDescriptor = 12,
654    HashTable = 13,
655    Port = 14,
656    Cell = 15,
657}
658
659// TODO: Make TryFrom with error
660impl From<usize> for Tag {
661    fn from(tag: usize) -> Self {
662        match tag {
663            0 => Self::Undefined,
664            1 => Self::Pair,
665            2 => Self::Boolean,
666            3 => Self::Character,
667            4 => Self::Number,
668            5 => Self::String,
669            6 => Self::Symbol,
670            7 => Self::Vector,
671            8 => Self::ByteVector,
672            9 => Self::Syntax,
673            10 => Self::Procedure,
674            11 => Self::Record,
675            12 => Self::RecordTypeDescriptor,
676            13 => Self::HashTable,
677            14 => Self::Port,
678            15 => Self::Cell,
679            tag => panic!("Invalid tag: {tag}"),
680        }
681    }
682}
683
684/// Different possible types that a Value can inhabit.
685#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
686pub enum ValueType {
687    Undefined,
688    Null,
689    Pair,
690    Boolean,
691    Character,
692    Number,
693    String,
694    Symbol,
695    Vector,
696    ByteVector,
697    Syntax,
698    Procedure,
699    Record,
700    RecordTypeDescriptor,
701    HashTable,
702    Port,
703}
704
705/// The external, unpacked, enumeration representation of a scheme value.
706///
707/// Values that are not potentially cyclical, such as syntax objects and byte
708/// vectors use Arcs as they are much less expensive than Gc types.
709#[non_exhaustive]
710#[derive(Trace, Clone)]
711pub enum UnpackedValue {
712    Undefined,
713    Null,
714    Boolean(bool),
715    Character(char),
716    Number(Number),
717    String(WideString),
718    Symbol(Symbol),
719    Vector(Vector),
720    ByteVector(ByteVector),
721    Syntax(Gc<Syntax>),
722    Procedure(Procedure),
723    Record(Record),
724    RecordTypeDescriptor(Arc<RecordTypeDescriptor>),
725    Pair(Pair),
726    Port(Port),
727    HashTable(HashTable),
728    Cell(Cell),
729}
730
731impl UnpackedValue {
732    pub fn into_value(self) -> Value {
733        match self {
734            Self::Undefined => Value::undefined(),
735            Self::Null => Value::null(),
736            Self::Boolean(b) => {
737                Value::from_ptr_and_tag(((b as usize) << TAG_BITS) as *const (), Tag::Boolean)
738            }
739            Self::Character(c) => {
740                Value::from_ptr_and_tag(((c as usize) << TAG_BITS) as *const (), Tag::Character)
741            }
742            Self::Number(num) => {
743                let untagged = Arc::into_raw(num.0);
744                Value::from_ptr_and_tag(untagged, Tag::Number)
745            }
746            Self::String(str) => {
747                let untagged = Arc::into_raw(str.0);
748                Value::from_ptr_and_tag(untagged, Tag::String)
749            }
750            Self::Symbol(sym) => {
751                Value::from_ptr_and_tag(((sym.0 as usize) << TAG_BITS) as *const (), Tag::Symbol)
752            }
753            Self::Vector(vec) => {
754                let untagged = Gc::into_raw(vec.0);
755                Value::from_mut_ptr_and_tag(untagged, Tag::Vector)
756            }
757            Self::ByteVector(b_vec) => {
758                let untagged = Arc::into_raw(b_vec.0);
759                Value::from_ptr_and_tag(untagged, Tag::ByteVector)
760            }
761            Self::Syntax(syn) => {
762                let untagged = Gc::into_raw(syn);
763                Value::from_mut_ptr_and_tag(untagged, Tag::Syntax)
764            }
765            Self::Procedure(clos) => {
766                let untagged = Gc::into_raw(clos.0);
767                Value::from_mut_ptr_and_tag(untagged, Tag::Procedure)
768            }
769            Self::Record(rec) => {
770                let untagged = Gc::into_raw(rec.0);
771                Value::from_mut_ptr_and_tag(untagged, Tag::Record)
772            }
773            Self::RecordTypeDescriptor(rt) => {
774                let untagged = Arc::into_raw(rt);
775                Value::from_ptr_and_tag(untagged, Tag::RecordTypeDescriptor)
776            }
777            Self::Pair(pair) => {
778                let untagged = Gc::into_raw(pair.0);
779                Value::from_mut_ptr_and_tag(untagged, Tag::Pair)
780            }
781            Self::Port(port) => {
782                let untagged = Arc::into_raw(port.0);
783                Value::from_ptr_and_tag(untagged, Tag::Port)
784            }
785            Self::HashTable(ht) => {
786                let untagged = Gc::into_raw(ht.0);
787                Value::from_ptr_and_tag(untagged, Tag::HashTable)
788            }
789            Self::Cell(cell) => {
790                let untagged = Gc::into_raw(cell.0);
791                Value::from_mut_ptr_and_tag(untagged, Tag::Cell)
792            }
793        }
794    }
795
796    #[allow(clippy::should_implement_trait)]
797    pub fn eq(&self, rhs: &Self) -> bool {
798        match (self, rhs) {
799            (Self::Boolean(a), Self::Boolean(b)) => a == b,
800            (Self::Symbol(a), Self::Symbol(b)) => a == b,
801            (Self::Number(a), Self::Number(b)) => Arc::ptr_eq(&a.0, &b.0),
802            (Self::Character(a), Self::Character(b)) => a == b,
803            (Self::Null, Self::Null) => true,
804            (Self::String(a), Self::String(b)) => Arc::ptr_eq(&a.0, &b.0),
805            (Self::Pair(a), Self::Pair(b)) => Gc::ptr_eq(&a.0, &b.0),
806            (Self::Vector(a), Self::Vector(b)) => Gc::ptr_eq(&a.0, &b.0),
807            (Self::ByteVector(a), Self::ByteVector(b)) => Arc::ptr_eq(&a.0, &b.0),
808            (Self::Procedure(a), Self::Procedure(b)) => Gc::ptr_eq(&a.0, &b.0),
809            (Self::Syntax(a), Self::Syntax(b)) => Gc::ptr_eq(a, b),
810            (Self::Record(a), Self::Record(b)) => Gc::ptr_eq(&a.0, &b.0),
811            (Self::RecordTypeDescriptor(a), Self::RecordTypeDescriptor(b)) => Arc::ptr_eq(a, b),
812            (Self::Port(a), Self::Port(b)) => Arc::ptr_eq(&a.0, &b.0),
813            (Self::HashTable(a), Self::HashTable(b)) => Gc::ptr_eq(&a.0, &b.0),
814            (Self::Cell(a), b) => a.0.read().unpacked_ref().eq(b),
815            (a, Self::Cell(b)) => a.eq(&b.0.read().unpacked_ref()),
816            _ => false,
817        }
818    }
819
820    pub fn eqv(&self, rhs: &Self) -> bool {
821        match (self, rhs) {
822            // Undefined is equivalent to undefined since it is impossible to
823            // read
824            (Self::Undefined, Self::Undefined) => true,
825            // boolean=?
826            (Self::Boolean(a), Self::Boolean(b)) => a == b,
827            // symbol=?
828            (Self::Symbol(a), Self::Symbol(b)) => a == b,
829            (Self::Number(a), Self::Number(b)) => a.eqv(b),
830            // char=?
831            (Self::Character(a), Self::Character(b)) => a == b,
832            // Both obj1 and obj2 are the empty list
833            (Self::Null, Self::Null) => true,
834            // Everything else is pointer equivalence
835            (Self::String(a), Self::String(b)) => Arc::ptr_eq(&a.0, &b.0),
836            (Self::Pair(a), Self::Pair(b)) => Gc::ptr_eq(&a.0, &b.0),
837            (Self::Vector(a), Self::Vector(b)) => Gc::ptr_eq(&a.0, &b.0),
838            (Self::ByteVector(a), Self::ByteVector(b)) => Arc::ptr_eq(&a.0, &b.0),
839            (Self::Procedure(a), Self::Procedure(b)) => Gc::ptr_eq(&a.0, &b.0),
840            (Self::Syntax(a), Self::Syntax(b)) => Gc::ptr_eq(a, b),
841            (Self::Record(a), Self::Record(b)) => Gc::ptr_eq(&a.0, &b.0),
842            (Self::RecordTypeDescriptor(a), Self::RecordTypeDescriptor(b)) => Arc::ptr_eq(a, b),
843            (Self::Port(a), Self::Port(b)) => Arc::ptr_eq(&a.0, &b.0),
844            (Self::HashTable(a), Self::HashTable(b)) => Gc::ptr_eq(&a.0, &b.0),
845            (Self::Cell(a), b) => a.0.read().unpacked_ref().eqv(b),
846            (a, Self::Cell(b)) => a.eqv(&b.0.read().unpacked_ref()),
847            _ => false,
848        }
849    }
850
851    pub fn type_name(&self) -> &'static str {
852        match self {
853            Self::Undefined => "undefined",
854            Self::Boolean(_) => "bool",
855            Self::Number(_) => "number",
856            Self::Character(_) => "character",
857            Self::String(_) => "string",
858            Self::Symbol(_) => "symbol",
859            Self::Pair(_) | Self::Null => "pair",
860            Self::Vector(_) => "vector",
861            Self::ByteVector(_) => "byte vector",
862            Self::Syntax(_) => "syntax",
863            Self::Procedure(_) => "procedure",
864            Self::Record(_) => "record",
865            Self::RecordTypeDescriptor(_) => "rtd",
866            Self::Port(_) => "port",
867            Self::HashTable(_) => "hashtable",
868            Self::Cell(cell) => cell.0.read().type_name(),
869        }
870    }
871
872    pub fn type_of(&self) -> ValueType {
873        match self {
874            Self::Undefined => ValueType::Undefined,
875            Self::Null => ValueType::Null,
876            Self::Boolean(_) => ValueType::Boolean,
877            Self::Number(_) => ValueType::Number,
878            Self::Character(_) => ValueType::Character,
879            Self::String(_) => ValueType::String,
880            Self::Symbol(_) => ValueType::Symbol,
881            Self::Pair(_) => ValueType::Pair,
882            Self::Vector(_) => ValueType::Vector,
883            Self::ByteVector(_) => ValueType::ByteVector,
884            Self::Syntax(_) => ValueType::Syntax,
885            Self::Procedure(_) => ValueType::Procedure,
886            Self::Record(_) => ValueType::Record,
887            Self::RecordTypeDescriptor(_) => ValueType::RecordTypeDescriptor,
888            Self::Port(_) => ValueType::Port,
889            Self::HashTable(_) => ValueType::HashTable,
890            Self::Cell(cell) => cell.0.read().type_of(),
891        }
892    }
893}
894
895/// Determine if two objects are equal in an extremely granular sense.
896///
897/// This implementation is a Rust translation of Efficient Dondestructive
898/// Equality Checking for Trees and Graphs by Michael D. Adams and R. Kent
899/// Dybvig.
900pub fn equal(obj1: &Value, obj2: &Value) -> bool {
901    interleave(&mut HashMap::default(), obj1, obj2, K0)
902}
903
904const K0: i64 = 400;
905const KB: i64 = -40;
906
907fn interleave(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> bool {
908    e(ht, obj1, obj2, k).is_some()
909}
910
911fn e(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
912    match k {
913        KB => fast(ht, obj1, obj2, rand::random_range(0..(K0 * 2))),
914        k if k <= 0 => slow(ht, obj1, obj2, k),
915        k => fast(ht, obj1, obj2, k),
916    }
917}
918
919fn fast(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
920    let k = k - 1;
921    if obj1.eqv(obj2) {
922        return Some(k);
923    }
924    match (obj1.type_of(), obj2.type_of()) {
925        (ValueType::Pair, ValueType::Pair) => pair_eq(ht, obj1, obj2, k),
926        (ValueType::Vector, ValueType::Vector) => vector_eq(ht, obj1, obj2, k),
927        (ValueType::ByteVector, ValueType::ByteVector) => bytevector_eq(obj1, obj2, k),
928        (ValueType::String, ValueType::String) => string_eq(obj1, obj2, k),
929        _ => None,
930    }
931}
932
933fn slow(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
934    if obj1.eqv(obj2) {
935        return Some(k);
936    }
937    match (obj1.type_of(), obj2.type_of()) {
938        (ValueType::Pair, ValueType::Pair) => {
939            if union_find(ht, obj1, obj2) {
940                return Some(0);
941            }
942            pair_eq(ht, obj1, obj2, k)
943        }
944        (ValueType::Vector, ValueType::Vector) => {
945            if union_find(ht, obj1, obj2) {
946                return Some(0);
947            }
948            vector_eq(ht, obj1, obj2, k)
949        }
950        (ValueType::ByteVector, ValueType::ByteVector) => bytevector_eq(obj1, obj2, k),
951        (ValueType::String, ValueType::String) => string_eq(obj1, obj2, k),
952        _ => None,
953    }
954}
955
956fn pair_eq(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
957    let obj1: Pair = obj1.clone().try_into().unwrap();
958    let obj2: Pair = obj2.clone().try_into().unwrap();
959    let (car_x, cdr_x) = obj1.into();
960    let (car_y, cdr_y) = obj2.into();
961    e(ht, &car_x, &car_y, k - 1).and_then(|k| e(ht, &cdr_x, &cdr_y, k))
962}
963
964fn vector_eq(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
965    let vobj1: Vector = obj1.clone().try_into().unwrap();
966    let vobj2: Vector = obj2.clone().try_into().unwrap();
967    let vobj1 = vobj1.0.vec.read();
968    let vobj2 = vobj2.0.vec.read();
969    if vobj1.len() != vobj2.len() {
970        return None;
971    }
972    let mut k = k - 1;
973    for (x, y) in vobj1.iter().zip(vobj2.iter()) {
974        k = e(ht, x, y, k)?;
975    }
976    Some(k)
977}
978
979fn bytevector_eq(obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
980    let obj1: ByteVector = obj1.clone().try_into().unwrap();
981    let obj2: ByteVector = obj2.clone().try_into().unwrap();
982    (*obj1.0.vec.read() == *obj2.0.vec.read()).then_some(k)
983}
984
985fn string_eq(obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
986    let obj1: WideString = obj1.clone().try_into().unwrap();
987    let obj2: WideString = obj2.clone().try_into().unwrap();
988    (obj1 == obj2).then_some(k)
989}
990
991fn union_find(ht: &mut HashMap<Value, Value>, x: &Value, y: &Value) -> bool {
992    let bx = ht.get(x).cloned();
993    let by = ht.get(y).cloned();
994    match (bx, by) {
995        (None, None) => {
996            let b = boxv(Value::from(Number::from(1)));
997            ht.insert(x.clone(), b.clone());
998            ht.insert(y.clone(), b);
999        }
1000        (None, Some(by)) => {
1001            let ry = find(by);
1002            ht.insert(x.clone(), ry);
1003        }
1004        (Some(bx), None) => {
1005            let rx = find(bx);
1006            ht.insert(y.clone(), rx);
1007        }
1008        (Some(bx), Some(by)) => {
1009            let rx = find(bx);
1010            let ry = find(by);
1011            if rx.eqv(&ry) {
1012                return true;
1013            }
1014            let nx = unbox_to_num(&rx);
1015            let ny = unbox_to_num(&ry);
1016            if nx > ny {
1017                set_box(&ry, rx.clone());
1018                set_box(&rx, nx + ny);
1019            } else {
1020                set_box(&rx, ry.clone());
1021                set_box(&ry, nx + ny);
1022            }
1023        }
1024    }
1025    false
1026}
1027
1028fn find(mut b: Value) -> Value {
1029    let mut n = unbox(&b);
1030    if is_box(&n) {
1031        loop {
1032            let nn = unbox(&n);
1033            if !is_box(&nn) {
1034                return n;
1035            }
1036            set_box(&b, nn.clone());
1037            b = n;
1038            n = nn;
1039        }
1040    } else {
1041        b
1042    }
1043}
1044
1045fn boxv(v: Value) -> Value {
1046    Value::from(Pair::new(v.clone(), Value::null(), true))
1047}
1048
1049fn unbox(v: &Value) -> Value {
1050    let pair: Pair = v.clone().try_into().unwrap();
1051    pair.car()
1052}
1053
1054fn unbox_to_num(v: &Value) -> Number {
1055    let pair: Pair = v.clone().try_into().unwrap();
1056    pair.car().try_into().unwrap()
1057}
1058
1059fn is_box(v: &Value) -> bool {
1060    v.type_of() == ValueType::Pair
1061}
1062
1063fn set_box(b: &Value, val: impl Into<Value>) {
1064    let pair: Pair = b.clone().try_into().unwrap();
1065    pair.set_car(val.into()).unwrap();
1066}
1067
1068macro_rules! impl_try_from_value_for {
1069    ($ty:ty, $variant:ident, $type_name:literal) => {
1070        impl From<$ty> for UnpackedValue {
1071            fn from(v: $ty) -> Self {
1072                Self::$variant(v)
1073            }
1074        }
1075
1076        impl From<$ty> for Value {
1077            fn from(v: $ty) -> Self {
1078                UnpackedValue::from(v).into_value()
1079            }
1080        }
1081
1082        impl From<UnpackedValue> for Option<$ty> {
1083            fn from(v: UnpackedValue) -> Self {
1084                match v {
1085                    UnpackedValue::$variant(v) => Some(v),
1086                    _ => None,
1087                }
1088            }
1089        }
1090
1091        impl From<Value> for Option<$ty> {
1092            fn from(v: Value) -> Self {
1093                v.unpack().into()
1094            }
1095        }
1096
1097        impl From<&'_ Value> for Option<$ty> {
1098            fn from(v: &Value) -> Self {
1099                v.clone().unpack().into()
1100            }
1101        }
1102
1103        impl TryFrom<UnpackedValue> for $ty {
1104            type Error = Exception;
1105
1106            fn try_from(v: UnpackedValue) -> Result<Self, Self::Error> {
1107                match v {
1108                    UnpackedValue::$variant(v) => Ok(v),
1109                    UnpackedValue::Cell(cell) => cell.0.read().clone().try_into(),
1110                    e => Err(Exception::type_error($type_name, e.type_name())),
1111                }
1112            }
1113        }
1114
1115        impl TryFrom<Value> for $ty {
1116            type Error = Exception;
1117
1118            fn try_from(v: Value) -> Result<Self, Self::Error> {
1119                v.unpack().try_into()
1120            }
1121        }
1122
1123        impl TryFrom<&Value> for $ty {
1124            type Error = Exception;
1125
1126            fn try_from(v: &Value) -> Result<Self, Self::Error> {
1127                v.clone().unpack().try_into()
1128            }
1129        }
1130    };
1131}
1132
1133impl From<Infallible> for Value {
1134    fn from(value: Infallible) -> Self {
1135        match value {}
1136    }
1137}
1138
1139impl From<()> for UnpackedValue {
1140    fn from((): ()) -> Self {
1141        Self::Null
1142    }
1143}
1144
1145impl From<()> for Value {
1146    fn from((): ()) -> Self {
1147        UnpackedValue::Null.into_value()
1148    }
1149}
1150
1151impl TryFrom<UnpackedValue> for () {
1152    type Error = Exception;
1153
1154    fn try_from(value: UnpackedValue) -> Result<Self, Self::Error> {
1155        match value {
1156            UnpackedValue::Null => Ok(()),
1157            e => Err(Exception::type_error("null", e.type_name())),
1158        }
1159    }
1160}
1161
1162impl TryFrom<Value> for () {
1163    type Error = Exception;
1164
1165    fn try_from(value: Value) -> Result<Self, Self::Error> {
1166        value.unpack().try_into()
1167    }
1168}
1169
1170impl From<Cell> for UnpackedValue {
1171    fn from(cell: Cell) -> Self {
1172        Self::Cell(cell)
1173    }
1174}
1175
1176impl From<Cell> for Value {
1177    fn from(cell: Cell) -> Self {
1178        UnpackedValue::from(cell).into_value()
1179    }
1180}
1181
1182impl TryFrom<UnpackedValue> for Cell {
1183    type Error = Exception;
1184
1185    fn try_from(v: UnpackedValue) -> Result<Self, Self::Error> {
1186        match v {
1187            UnpackedValue::Cell(cell) => Ok(cell.clone()),
1188            e => Err(Exception::type_error("cell", e.type_name())),
1189        }
1190    }
1191}
1192
1193impl TryFrom<Value> for Cell {
1194    type Error = Exception;
1195
1196    fn try_from(v: Value) -> Result<Self, Self::Error> {
1197        v.unpack().try_into()
1198    }
1199}
1200
1201impl TryFrom<&Value> for Cell {
1202    type Error = Exception;
1203
1204    fn try_from(v: &Value) -> Result<Self, Self::Error> {
1205        v.clone().unpack().try_into()
1206    }
1207}
1208
1209impl From<Value> for bool {
1210    fn from(value: Value) -> Self {
1211        value.is_true()
1212    }
1213}
1214
1215impl From<bool> for UnpackedValue {
1216    fn from(value: bool) -> Self {
1217        Self::Boolean(value)
1218    }
1219}
1220
1221impl From<bool> for Value {
1222    fn from(value: bool) -> Self {
1223        UnpackedValue::from(value).into_value()
1224    }
1225}
1226
1227// impl_try_from_value_for!(bool, Boolean, "bool");
1228
1229impl_try_from_value_for!(char, Character, "char");
1230impl_try_from_value_for!(Number, Number, "number");
1231impl_try_from_value_for!(WideString, String, "string");
1232impl_try_from_value_for!(Symbol, Symbol, "symbol");
1233impl_try_from_value_for!(Vector, Vector, "vector");
1234impl_try_from_value_for!(ByteVector, ByteVector, "byte-vector");
1235impl_try_from_value_for!(Gc<Syntax>, Syntax, "syntax");
1236impl_try_from_value_for!(Procedure, Procedure, "procedure");
1237impl_try_from_value_for!(Pair, Pair, "pair");
1238impl_try_from_value_for!(Record, Record, "record");
1239impl_try_from_value_for!(Port, Port, "port");
1240impl_try_from_value_for!(HashTable, HashTable, "hashtable");
1241impl_try_from_value_for!(Arc<RecordTypeDescriptor>, RecordTypeDescriptor, "rt");
1242
1243macro_rules! impl_from_wrapped_for {
1244    ($ty:ty, $variant:ident, $wrapper:expr_2021) => {
1245        impl From<$ty> for UnpackedValue {
1246            fn from(v: $ty) -> Self {
1247                Self::$variant(($wrapper)(v))
1248            }
1249        }
1250
1251        impl From<$ty> for Value {
1252            fn from(v: $ty) -> Self {
1253                UnpackedValue::from(v).into_value()
1254            }
1255        }
1256    };
1257}
1258
1259// impl_from_wrapped_for!(Number, Number, Arc::new);
1260impl_from_wrapped_for!(String, String, WideString::new);
1261impl_from_wrapped_for!(Vec<Value>, Vector, Vector::new);
1262impl_from_wrapped_for!(Vec<u8>, ByteVector, ByteVector::new);
1263impl_from_wrapped_for!(Syntax, Syntax, Gc::new);
1264impl_from_wrapped_for!((Value, Value), Pair, |(car, cdr)| Pair::new(
1265    car, cdr, false
1266));
1267
1268impl From<UnpackedValue> for Option<(Value, Value)> {
1269    fn from(val: UnpackedValue) -> Self {
1270        match val {
1271            UnpackedValue::Pair(pair) => Some(pair.into()),
1272            _ => None,
1273        }
1274    }
1275}
1276
1277impl TryFrom<UnpackedValue> for (Value, Value) {
1278    type Error = Exception;
1279
1280    fn try_from(val: UnpackedValue) -> Result<Self, Self::Error> {
1281        match val {
1282            UnpackedValue::Pair(pair) => Ok(pair.into()),
1283            e => Err(Exception::type_error("pair", e.type_name())),
1284        }
1285    }
1286}
1287
1288macro_rules! impl_num_conversion {
1289    ($ty:ty) => {
1290        // TODO: Can we reverse these?
1291        impl TryFrom<&Value> for $ty {
1292            type Error = Exception;
1293
1294            fn try_from(value: &Value) -> Result<$ty, Self::Error> {
1295                match &*value.unpacked_ref() {
1296                    UnpackedValue::Number(num) => num.try_into(),
1297                    e => Err(Exception::type_error("number", e.type_name())),
1298                }
1299            }
1300        }
1301
1302        impl TryFrom<Value> for $ty {
1303            type Error = Exception;
1304
1305            fn try_from(value: Value) -> Result<$ty, Self::Error> {
1306                (&value).try_into()
1307            }
1308        }
1309
1310        impl From<&Value> for Option<$ty> {
1311            fn from(value: &Value) -> Self {
1312                match &*value.unpacked_ref() {
1313                    UnpackedValue::Number(num) => num.into(),
1314                    _ => None,
1315                }
1316            }
1317        }
1318
1319        impl From<Value> for Option<$ty> {
1320            fn from(value: Value) -> Self {
1321                match value.unpack() {
1322                    UnpackedValue::Number(num) => num.into(),
1323                    _ => None,
1324                }
1325            }
1326        }
1327
1328        impl From<$ty> for Value {
1329            fn from(n: $ty) -> Self {
1330                Self::from(Number::from(n))
1331            }
1332        }
1333    };
1334}
1335
1336impl_num_conversion!(u8);
1337impl_num_conversion!(u16);
1338impl_num_conversion!(u32);
1339impl_num_conversion!(u64);
1340impl_num_conversion!(u128);
1341impl_num_conversion!(usize);
1342impl_num_conversion!(i8);
1343impl_num_conversion!(i16);
1344impl_num_conversion!(i32);
1345impl_num_conversion!(i64);
1346impl_num_conversion!(i128);
1347impl_num_conversion!(isize);
1348impl_num_conversion!(f64);
1349impl_num_conversion!(Integer);
1350impl_num_conversion!(SimpleNumber);
1351impl_num_conversion!(ComplexNumber);
1352
1353impl From<&Value> for Option<Identifier> {
1354    fn from(value: &Value) -> Self {
1355        match &*value.unpacked_ref() {
1356            UnpackedValue::Syntax(syn) => match syn.as_ref() {
1357                Syntax::Identifier { ident, .. } => Some(ident.clone()),
1358                _ => None,
1359            },
1360            _ => None,
1361        }
1362    }
1363}
1364
1365impl TryFrom<&Value> for Identifier {
1366    type Error = Exception;
1367
1368    fn try_from(value: &Value) -> Result<Self, Self::Error> {
1369        match Option::<Identifier>::from(value) {
1370            Some(ident) => Ok(ident),
1371            None => Err(Exception::type_error("identifier", value.type_name())),
1372        }
1373    }
1374}
1375
1376impl From<Value> for Option<(Value, Value)> {
1377    fn from(value: Value) -> Self {
1378        value.unpack().into()
1379    }
1380}
1381
1382impl From<&Value> for Option<(Value, Value)> {
1383    fn from(value: &Value) -> Self {
1384        value.clone().unpack().into()
1385    }
1386}
1387
1388impl TryFrom<Value> for (Value, Value) {
1389    type Error = Exception;
1390
1391    fn try_from(val: Value) -> Result<Self, Self::Error> {
1392        Self::try_from(val.unpack())
1393    }
1394}
1395
1396impl TryFrom<&Value> for (Value, Value) {
1397    type Error = Exception;
1398
1399    fn try_from(val: &Value) -> Result<Self, Self::Error> {
1400        Self::try_from(val.clone().unpack())
1401    }
1402}
1403
1404impl TryFrom<Value> for String {
1405    type Error = Exception;
1406
1407    fn try_from(value: Value) -> Result<Self, Self::Error> {
1408        let string: WideString = value.try_into()?;
1409        Ok(string.into())
1410    }
1411}
1412
1413/// Trait for converting vecs of values into arrays
1414pub trait ExpectN<T> {
1415    fn expect_n<const N: usize>(self) -> Result<[T; N], Exception>;
1416}
1417
1418impl<T> ExpectN<T> for Vec<Value>
1419where
1420    Value: TryInto<T>,
1421    Exception: From<<Value as TryInto<T>>::Error>,
1422{
1423    fn expect_n<const N: usize>(self) -> Result<[T; N], Exception> {
1424        if self.len() != N {
1425            return Err(Exception::error("wrong number of values"));
1426        }
1427        // Safety: we've already determined that self is the correct size, so we
1428        // can safely use unwrap_unchecked
1429        Ok(unsafe {
1430            self.into_iter()
1431                .map(Value::try_into)
1432                .collect::<Result<Vec<_>, _>>()?
1433                .try_into()
1434                .unwrap_unchecked()
1435        })
1436    }
1437}
1438
1439/// Trait for converting vecs of values into one type
1440pub trait Expect1<T> {
1441    fn expect1(self) -> Result<T, Exception>;
1442}
1443
1444impl<T> Expect1<T> for Vec<Value>
1445where
1446    Value: TryInto<T>,
1447    Exception: From<<Value as TryInto<T>>::Error>,
1448{
1449    fn expect1(self) -> Result<T, Exception> {
1450        let [val] = self
1451            .try_into()
1452            .map_err(|_| Exception::error("wrong number of values"))?;
1453        val.try_into().map_err(Exception::from)
1454    }
1455}
1456
1457/// Determines which children of the given list are circular, i.e. have children
1458/// that refer to back to them. This is just a depth-first search.
1459fn determine_circularity(
1460    curr: &Value,
1461    visited: &mut IndexSet<Value>,
1462    circular: &mut IndexSet<Value>,
1463) {
1464    if visited.contains(curr) {
1465        circular.insert(curr.clone());
1466        return;
1467    }
1468
1469    visited.insert(curr.clone());
1470
1471    match curr.clone().unpack() {
1472        UnpackedValue::Pair(pair) => {
1473            let (car, cdr) = pair.into();
1474            determine_circularity(&car, visited, circular);
1475            determine_circularity(&cdr, visited, circular);
1476        }
1477        UnpackedValue::Vector(vec) => {
1478            let vec_read = vec.0.vec.read();
1479            for item in vec_read.iter() {
1480                determine_circularity(item, visited, circular);
1481            }
1482        }
1483        _ => (),
1484    }
1485
1486    visited.swap_remove(curr);
1487}
1488
1489pub(crate) fn write_value(
1490    val: &Value,
1491    fmt: fn(&Value, &mut IndexMap<Value, bool>, &mut fmt::Formatter<'_>) -> fmt::Result,
1492    circular_values: &mut IndexMap<Value, bool>,
1493    f: &mut fmt::Formatter<'_>,
1494) -> fmt::Result {
1495    if let Some((idx, _, seen)) = circular_values.get_full_mut(val) {
1496        if *seen {
1497            write!(f, "#{idx}#")?;
1498            return Ok(());
1499        } else {
1500            write!(f, "#{idx}=")?;
1501            *seen = true;
1502        }
1503    }
1504
1505    fmt(val, circular_values, f)
1506}
1507
1508fn display_value(
1509    val: &Value,
1510    circular_values: &mut IndexMap<Value, bool>,
1511    f: &mut fmt::Formatter<'_>,
1512) -> fmt::Result {
1513    match val.clone().unpack() {
1514        UnpackedValue::Undefined => write!(f, "<undefined>"),
1515        UnpackedValue::Null => write!(f, "()"),
1516        UnpackedValue::Boolean(true) => write!(f, "#t"),
1517        UnpackedValue::Boolean(false) => write!(f, "#f"),
1518        UnpackedValue::Number(number) => write!(f, "{number}"),
1519        UnpackedValue::Character(c) => write!(f, "#\\{c}"),
1520        UnpackedValue::String(string) => write!(f, "{string}"),
1521        UnpackedValue::Symbol(symbol) => write!(f, "{symbol}"),
1522        UnpackedValue::Pair(pair) => {
1523            let (car, cdr) = pair.into();
1524            lists::write_list(&car, &cdr, display_value, circular_values, f)
1525        }
1526        UnpackedValue::Vector(v) => vectors::write_vec(&v, display_value, circular_values, f),
1527        UnpackedValue::ByteVector(v) => vectors::write_bytevec(&v, f),
1528        UnpackedValue::Procedure(_) => write!(f, "<procedure>"),
1529        UnpackedValue::Record(record) => write!(f, "{record:?}"),
1530        UnpackedValue::Syntax(syntax) => write!(f, "#<syntax {syntax:#?}>"),
1531        UnpackedValue::RecordTypeDescriptor(rtd) => write!(f, "{rtd:?}"),
1532        UnpackedValue::Port(_) => write!(f, "<port>"),
1533        UnpackedValue::HashTable(hashtable) => write!(f, "{hashtable:?}"),
1534        UnpackedValue::Cell(cell) => display_value(&cell.0.read(), circular_values, f),
1535    }
1536}
1537
1538fn debug_value(
1539    val: &Value,
1540    circular_values: &mut IndexMap<Value, bool>,
1541    f: &mut fmt::Formatter<'_>,
1542) -> fmt::Result {
1543    match val.clone().unpack() {
1544        UnpackedValue::Undefined => write!(f, "<undefined>"),
1545        UnpackedValue::Null => write!(f, "()"),
1546        UnpackedValue::Boolean(true) => write!(f, "#t"),
1547        UnpackedValue::Boolean(false) => write!(f, "#f"),
1548        UnpackedValue::Number(number) => write!(f, "{number}"),
1549        UnpackedValue::Character(c) => write!(f, "#\\{c}"),
1550        UnpackedValue::String(string) => write!(f, "{string:?}"),
1551        UnpackedValue::Symbol(symbol) => write!(f, "{symbol}"),
1552        UnpackedValue::Pair(pair) => {
1553            let (car, cdr) = pair.into();
1554            lists::write_list(&car, &cdr, debug_value, circular_values, f)
1555        }
1556        UnpackedValue::Vector(v) => vectors::write_vec(&v, debug_value, circular_values, f),
1557        UnpackedValue::ByteVector(v) => vectors::write_bytevec(&v, f),
1558        UnpackedValue::Syntax(syntax) => {
1559            let span = syntax.span();
1560            write!(f, "#<syntax:{span} {syntax:#?}>")
1561        }
1562        UnpackedValue::Procedure(proc) => write!(f, "#<procedure {proc:?}>"),
1563        UnpackedValue::Record(record) => write!(f, "{record:#?}"),
1564        UnpackedValue::RecordTypeDescriptor(rtd) => write!(f, "{rtd:?}"),
1565        UnpackedValue::Port(_) => write!(f, "<port>"),
1566        UnpackedValue::HashTable(hashtable) => write!(f, "{hashtable:?}"),
1567        UnpackedValue::Cell(cell) => debug_value(&cell.0.read(), circular_values, f),
1568    }
1569}
1570#[bridge(name = "not", lib = "(rnrs base builtins (6))")]
1571pub fn not(a: &Value) -> Result<Vec<Value>, Exception> {
1572    Ok(vec![Value::from(a.0 as usize == Tag::Boolean as usize)])
1573}
1574
1575#[bridge(name = "eqv?", lib = "(rnrs base builtins (6))")]
1576pub fn eqv(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1577    Ok(vec![Value::from(a.eqv(b))])
1578}
1579
1580#[bridge(name = "eq?", lib = "(rnrs base builtins (6))")]
1581pub fn eq(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1582    Ok(vec![Value::from(a.eqv(b))])
1583}
1584
1585#[bridge(name = "equal?", lib = "(rnrs base builtins (6))")]
1586pub fn equal_pred(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1587    Ok(vec![Value::from(a.equal(b))])
1588}
1589
1590#[bridge(name = "boolean?", lib = "(rnrs base builtins (6))")]
1591pub fn boolean_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1592    Ok(vec![Value::from(arg.type_of() == ValueType::Boolean)])
1593}
1594
1595#[bridge(name = "boolean=?", lib = "(rnrs base builtins (6))")]
1596pub fn boolean_eq_pred(a: &Value, args: &[Value]) -> Result<Vec<Value>, Exception> {
1597    let res = if a.type_of() == ValueType::Boolean {
1598        args.iter().all(|arg| arg == a)
1599    } else {
1600        false
1601    };
1602    Ok(vec![Value::from(res)])
1603}
1604
1605#[bridge(name = "symbol?", lib = "(rnrs base builtins (6))")]
1606pub fn symbol_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1607    Ok(vec![Value::from(arg.type_of() == ValueType::Symbol)])
1608}
1609
1610#[bridge(name = "char?", lib = "(rnrs base builtins (6))")]
1611pub fn char_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1612    Ok(vec![Value::from(arg.type_of() == ValueType::Character)])
1613}
1614
1615#[bridge(name = "vector?", lib = "(rnrs base builtins (6))")]
1616pub fn vector_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1617    Ok(vec![Value::from(arg.type_of() == ValueType::Vector)])
1618}
1619
1620#[bridge(name = "null?", lib = "(rnrs base builtins (6))")]
1621pub fn null_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1622    Ok(vec![Value::from(arg.type_of() == ValueType::Null)])
1623}
1624
1625#[bridge(name = "pair?", lib = "(rnrs base builtins (6))")]
1626pub fn pair_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1627    Ok(vec![Value::from(matches!(
1628        *arg.unpacked_ref(),
1629        UnpackedValue::Pair(_)
1630    ))])
1631}
1632
1633#[bridge(name = "procedure?", lib = "(rnrs base builtins (6))")]
1634pub fn procedure_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1635    Ok(vec![Value::from(arg.type_of() == ValueType::Procedure)])
1636}