1use 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;
121pub(crate) const TAG: usize = 0b1111;
122pub(crate) const NULL_VALUE: usize = Tag::Pair as usize;
123pub(crate) const TRUE_VALUE: usize = Tag::Boolean as usize | 1 << TAG_BITS;
124pub(crate) const FALSE_VALUE: usize = Tag::Boolean as usize;
125
126#[repr(transparent)]
129pub struct Value(*const ());
130
131impl Value {
132 pub fn new(v: UnpackedValue) -> Self {
137 v.into_value()
138 }
139
140 pub fn is_true(&self) -> bool {
142 self.0 as usize != FALSE_VALUE
143 }
144
145 pub fn is_null(&self) -> bool {
146 self.0 as usize == Tag::Pair as usize
147 }
148
149 pub fn is_undefined(&self) -> bool {
150 self.type_of() == ValueType::Undefined
151 }
152
153 pub unsafe fn from_raw(raw: *const ()) -> Self {
159 Self(raw)
160 }
161
162 pub unsafe fn from_raw_inc_rc(raw: *const ()) -> Self {
168 let tag = Tag::from(raw as usize & TAG);
169 let untagged = raw.map_addr(|raw| raw & !TAG);
170 unsafe {
171 match tag {
172 Tag::Number => Arc::increment_strong_count(untagged as *const NumberInner),
173 Tag::String => Arc::increment_strong_count(untagged as *const WideStringInner),
174 Tag::Vector => {
175 Gc::increment_reference_count(untagged as *mut GcInner<VectorInner<Value>>)
176 }
177 Tag::ByteVector => Arc::increment_strong_count(untagged as *const VectorInner<u8>),
178 Tag::Syntax => Gc::increment_reference_count(untagged as *mut GcInner<Syntax>),
179 Tag::Procedure => {
180 Gc::increment_reference_count(untagged as *mut GcInner<ProcedureInner>)
181 }
182 Tag::Record => Gc::increment_reference_count(untagged as *mut GcInner<RecordInner>),
183 Tag::RecordTypeDescriptor => {
184 Arc::increment_strong_count(untagged as *const RecordTypeDescriptor)
185 }
186 Tag::Pair => {
187 if !untagged.is_null() {
188 Gc::increment_reference_count(untagged as *mut GcInner<PairInner>)
189 }
190 }
191 Tag::Port => Arc::increment_strong_count(untagged as *const PortInner),
192 Tag::HashTable => {
193 Gc::increment_reference_count(untagged as *mut GcInner<HashTableInner>)
194 }
195 Tag::Cell => {
196 Gc::increment_reference_count(untagged as *mut GcInner<Value>);
197 }
198 Tag::Undefined | Tag::Symbol | Tag::Boolean | Tag::Character => (),
199 }
200 }
201 Self(raw)
202 }
203
204 pub fn into_raw(val: Self) -> *const () {
209 ManuallyDrop::new(val).0
210 }
211
212 pub fn as_raw(this: &Self) -> *const () {
214 this.0
215 }
216
217 fn from_ptr_and_tag<T: Send + Sync>(ptr: *const T, tag: Tag) -> Self {
218 Self(ptr.map_addr(|raw| raw | tag as usize) as *const ())
219 }
220
221 fn from_mut_ptr_and_tag<T: Send + Sync>(ptr: *mut T, tag: Tag) -> Self {
222 Self(ptr.map_addr(|raw| raw | tag as usize) as *const ())
223 }
224
225 pub fn undefined() -> Self {
226 Self(null::<()>().map_addr(|raw| raw | Tag::Undefined as usize))
227 }
228
229 pub fn null() -> Self {
230 Self(null::<()>().map_addr(|raw| raw | Tag::Pair as usize))
231 }
232
233 pub fn datum_from_syntax(syntax: &Syntax) -> Self {
235 match syntax {
236 Syntax::Wrapped { value, .. } => value.clone(),
237 Syntax::List { list, .. } => {
238 let mut curr = Self::datum_from_syntax(list.last().unwrap());
239 for item in list[..list.len() - 1].iter().rev() {
240 curr = Self::from(Pair::immutable(Self::datum_from_syntax(item), curr));
241 }
242 curr
243 }
244 Syntax::Vector { vector, .. } => Self::from(
245 vector
246 .iter()
247 .map(Self::datum_from_syntax)
248 .collect::<Vec<_>>(),
249 ),
250 Syntax::Identifier { ident, .. } => Self::new(UnpackedValue::Symbol(ident.sym)),
251 }
252 }
253
254 pub fn type_of(&self) -> ValueType {
255 self.unpacked_ref().type_of()
256 }
257
258 pub fn type_name(&self) -> &'static str {
259 self.unpacked_ref().type_name()
260 }
261
262 pub fn cast_to_scheme_type<T>(&self) -> Option<T>
264 where
265 for<'a> &'a Self: Into<Option<T>>,
266 {
267 self.into()
268 }
269
270 pub fn try_to_scheme_type<T>(&self) -> Result<T, Exception>
273 where
274 T: for<'a> TryFrom<&'a Self, Error = Exception>,
275 {
276 self.try_into()
277 }
278
279 pub fn cast_to_rust_type<T: SchemeCompatible>(&self) -> Option<Gc<T>> {
282 let UnpackedValue::Record(record) = self.clone().unpack() else {
283 return None;
284 };
285 record.cast::<T>()
286 }
287
288 pub fn try_to_rust_type<T: SchemeCompatible>(&self) -> Result<Gc<T>, Exception> {
291 let type_name = T::rtd().name.to_str();
292 let this = self.clone().unpack();
293 let record = match this {
294 UnpackedValue::Record(record) => record,
295 e => return Err(Exception::type_error(&type_name, e.type_name())),
296 };
297
298 record
299 .cast::<T>()
300 .ok_or_else(|| Exception::type_error(&type_name, &record.rtd().name.to_str()))
301 }
302
303 pub fn from_rust_type<T: SchemeCompatible>(t: T) -> Self {
306 Self::from(Record::from_rust_type(t))
307 }
308
309 pub fn unpack(self) -> UnpackedValue {
311 let raw = ManuallyDrop::new(self).0;
312 let tag = Tag::from(raw as usize & TAG);
313 let untagged = raw.map_addr(|raw| raw & !TAG);
314 match tag {
315 Tag::Undefined => UnpackedValue::Undefined,
316 Tag::Boolean => {
317 let untagged = untagged as usize >> TAG_BITS;
318 UnpackedValue::Boolean(untagged != 0)
319 }
320 Tag::Character => {
321 let untagged = (untagged as usize >> TAG_BITS) as u32;
322 UnpackedValue::Character(char::from_u32(untagged).unwrap())
323 }
324 Tag::Number => {
325 let number = unsafe { Arc::from_raw(untagged as *const NumberInner) };
326 UnpackedValue::Number(Number(number))
327 }
328 Tag::String => {
329 let str = unsafe { Arc::from_raw(untagged as *const WideStringInner) };
330 UnpackedValue::String(WideString(str))
331 }
332 Tag::Symbol => {
333 let untagged = (untagged as usize >> TAG_BITS) as u32;
334 UnpackedValue::Symbol(Symbol(untagged))
335 }
336 Tag::Vector => {
337 let vec = unsafe { Gc::from_raw(untagged as *mut GcInner<VectorInner<Self>>) };
338 UnpackedValue::Vector(Vector(vec))
339 }
340 Tag::ByteVector => {
341 let bvec = unsafe { Arc::from_raw(untagged as *const VectorInner<u8>) };
342 UnpackedValue::ByteVector(ByteVector(bvec))
343 }
344 Tag::Syntax => {
345 let syn = unsafe { Gc::from_raw(untagged as *mut GcInner<Syntax>) };
346 UnpackedValue::Syntax(syn)
347 }
348 Tag::Procedure => {
349 let clos = unsafe { Gc::from_raw(untagged as *mut GcInner<ProcedureInner>) };
350 UnpackedValue::Procedure(Procedure(clos))
351 }
352 Tag::Record => {
353 let rec = unsafe { Gc::from_raw(untagged as *mut GcInner<RecordInner>) };
354 UnpackedValue::Record(Record(rec))
355 }
356 Tag::RecordTypeDescriptor => {
357 let rt = unsafe { Arc::from_raw(untagged as *const RecordTypeDescriptor) };
358 UnpackedValue::RecordTypeDescriptor(rt)
359 }
360 Tag::Pair => {
361 if untagged.is_null() {
362 UnpackedValue::Null
363 } else {
364 let pair = unsafe { Gc::from_raw(untagged as *mut GcInner<PairInner>) };
365 UnpackedValue::Pair(Pair(pair))
366 }
367 }
368 Tag::Port => {
369 let port_inner = unsafe { Arc::from_raw(untagged as *const PortInner) };
370 UnpackedValue::Port(Port(port_inner))
371 }
372 Tag::HashTable => {
373 let ht = unsafe { Gc::from_raw(untagged as *mut GcInner<HashTableInner>) };
374 UnpackedValue::HashTable(HashTable(ht))
375 }
376 Tag::Cell => {
377 let cell = unsafe { Gc::from_raw(untagged as *mut GcInner<RwLock<Value>>) };
378 UnpackedValue::Cell(Cell(cell))
379 }
380 }
381 }
382
383 pub fn unpacked_ref(&self) -> UnpackedValueRef<'_> {
384 let unpacked = ManuallyDrop::new(Value(self.0).unpack());
385 UnpackedValueRef {
386 unpacked,
387 marker: PhantomData,
388 }
389 }
390
391 #[allow(clippy::should_implement_trait)]
393 pub fn eq(&self, rhs: &Self) -> bool {
394 let obj1 = self.unpacked_ref();
395 let obj2 = rhs.unpacked_ref();
396 obj1.eq(&obj2)
397 }
398
399 pub fn eqv(&self, rhs: &Self) -> bool {
401 let obj1 = self.unpacked_ref();
402 let obj2 = rhs.unpacked_ref();
403 obj1.eqv(&obj2)
404 }
405
406 pub fn equal(&self, rhs: &Self) -> bool {
408 equal(self, rhs)
409 }
410
411 pub fn eq_hash<H: Hasher>(&self, state: &mut H) {
413 let unpacked = self.unpacked_ref();
414 std::mem::discriminant(&*unpacked).hash(state);
415 match &*unpacked {
416 UnpackedValue::Undefined => (),
417 UnpackedValue::Null => (),
418 UnpackedValue::Boolean(b) => b.hash(state),
419 UnpackedValue::Character(c) => c.hash(state),
420 UnpackedValue::Number(n) => Arc::as_ptr(&n.0).hash(state),
421 UnpackedValue::String(s) => Arc::as_ptr(&s.0).hash(state),
422 UnpackedValue::Symbol(s) => s.hash(state),
423 UnpackedValue::ByteVector(v) => Arc::as_ptr(&v.0).hash(state),
424 UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
425 UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
426 UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
427 UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
428 UnpackedValue::Pair(p) => Gc::as_ptr(&p.0).hash(state),
429 UnpackedValue::Vector(v) => Gc::as_ptr(&v.0).hash(state),
430 UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
431 UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
432 UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
433 }
434 }
435
436 pub fn eqv_hash<H: Hasher>(&self, state: &mut H) {
438 let unpacked = self.unpacked_ref();
439 std::mem::discriminant(&*unpacked).hash(state);
440 match &*unpacked {
441 UnpackedValue::Undefined => (),
442 UnpackedValue::Null => (),
443 UnpackedValue::Boolean(b) => b.hash(state),
444 UnpackedValue::Character(c) => c.hash(state),
445 UnpackedValue::Number(n) => n.hash(state),
446 UnpackedValue::String(s) => Arc::as_ptr(&s.0).hash(state),
447 UnpackedValue::Symbol(s) => s.hash(state),
448 UnpackedValue::ByteVector(v) => Arc::as_ptr(&v.0).hash(state),
449 UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
450 UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
451 UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
452 UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
453 UnpackedValue::Pair(p) => Gc::as_ptr(&p.0).hash(state),
454 UnpackedValue::Vector(v) => Gc::as_ptr(&v.0).hash(state),
455 UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
456 UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
457 UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
458 }
459 }
460
461 pub fn equal_hash<H: Hasher>(&self, recursive: &mut IndexSet<Value>, state: &mut H) {
463 let unpacked = self.unpacked_ref();
464 std::mem::discriminant(&*unpacked).hash(state);
465
466 if let Some(index) = recursive.get_index_of(self) {
469 state.write_usize(index);
470 return;
471 }
472
473 match &*unpacked {
474 UnpackedValue::Undefined => (),
475 UnpackedValue::Null => (),
476 UnpackedValue::Boolean(b) => b.hash(state),
477 UnpackedValue::Character(c) => c.hash(state),
478 UnpackedValue::Number(n) => n.hash(state),
479 UnpackedValue::String(s) => s.hash(state),
480 UnpackedValue::Symbol(s) => s.hash(state),
481 UnpackedValue::ByteVector(v) => v.hash(state),
482 UnpackedValue::Syntax(s) => Gc::as_ptr(s).hash(state),
483 UnpackedValue::Procedure(c) => Gc::as_ptr(&c.0).hash(state),
484 UnpackedValue::Record(r) => Gc::as_ptr(&r.0).hash(state),
485 UnpackedValue::RecordTypeDescriptor(rt) => Arc::as_ptr(rt).hash(state),
486 UnpackedValue::Pair(p) => {
487 recursive.insert(self.clone());
488 let (car, cdr) = p.clone().into();
489 car.equal_hash(recursive, state);
490 cdr.equal_hash(recursive, state);
491 }
492 UnpackedValue::Vector(v) => {
493 recursive.insert(self.clone());
494 let v_read = v.0.vec.read();
495 state.write_usize(v_read.len());
496 for val in v_read.iter() {
497 val.equal_hash(recursive, state);
498 }
499 }
500 UnpackedValue::Port(p) => Arc::as_ptr(&p.0).hash(state),
501 UnpackedValue::HashTable(ht) => Gc::as_ptr(&ht.0).hash(state),
502 UnpackedValue::Cell(c) => c.0.read().eqv_hash(state),
503 }
504 }
505}
506
507impl Clone for Value {
508 fn clone(&self) -> Self {
509 unsafe { Self::from_raw_inc_rc(self.0) }
510 }
511}
512
513impl Drop for Value {
514 fn drop(&mut self) {
515 unsafe { ManuallyDrop::drop(&mut ManuallyDrop::new(Self(self.0).unpack())) }
517 }
518}
519
520impl Hash for Value {
523 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
524 self.eqv_hash(state)
525 }
526}
527
528impl PartialEq for Value {
531 fn eq(&self, rhs: &Value) -> bool {
532 self.eqv(rhs)
533 }
534}
535
536impl Eq for Value {}
539
540unsafe impl Send for Value {}
541unsafe impl Sync for Value {}
542
543impl fmt::Display for Value {
544 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
545 let mut circular_values = IndexSet::default();
546 determine_circularity(self, &mut IndexSet::default(), &mut circular_values);
547 let mut circular_values = circular_values.into_iter().map(|k| (k, false)).collect();
548 write_value(self, display_value, &mut circular_values, f)
549 }
550}
551
552impl fmt::Debug for Value {
553 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
554 let mut circular_values = IndexSet::default();
555 determine_circularity(self, &mut IndexSet::default(), &mut circular_values);
556 let mut circular_values = circular_values.into_iter().map(|k| (k, false)).collect();
557 write_value(self, debug_value, &mut circular_values, f)
558 }
559}
560
561unsafe impl Trace for Value {
562 unsafe fn visit_children(&self, visitor: &mut dyn FnMut(crate::gc::OpaqueGcPtr)) {
563 unsafe {
564 self.unpacked_ref().visit_children(visitor);
565 }
566 }
567
568 unsafe fn finalize(&mut self) {
569 unsafe { ManuallyDrop::new(Self(self.0).unpack()).finalize() }
570 }
571}
572
573#[derive(Clone, Trace)]
575pub struct Cell(pub(crate) Gc<RwLock<Value>>);
576
577impl Cell {
578 pub fn new(val: Value) -> Self {
579 Self(Gc::new(RwLock::new(val)))
580 }
581
582 pub fn get(&self) -> Value {
583 self.0.read().clone()
584 }
585
586 pub fn set(&self, new_val: Value) {
587 *self.0.write() = new_val;
588 }
589}
590
591pub struct UnpackedValueRef<'a> {
594 unpacked: ManuallyDrop<UnpackedValue>,
595 marker: PhantomData<&'a UnpackedValue>,
596}
597
598impl Deref for UnpackedValueRef<'_> {
599 type Target = UnpackedValue;
600
601 fn deref(&self) -> &Self::Target {
602 &self.unpacked
603 }
604}
605
606impl AsRef<UnpackedValue> for UnpackedValueRef<'_> {
607 fn as_ref(&self) -> &UnpackedValue {
608 &self.unpacked
609 }
610}
611
612impl<T> From<Option<T>> for Value
613where
614 Value: From<T>,
615 Value: From<bool>,
616{
617 fn from(value: Option<T>) -> Self {
619 match value {
620 Some(t) => Self::from(t),
621 None => Self::from(false),
622 }
623 }
624}
625
626impl From<Exception> for Value {
635 fn from(value: Exception) -> Self {
636 value.0
637 }
638}
639
640#[repr(u64)]
641#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
642pub(crate) enum Tag {
643 Undefined = 0,
644 Pair = 1,
645 Boolean = 2,
646 Character = 3,
647 Number = 4,
648 String = 5,
649 Symbol = 6,
650 Vector = 7,
651 ByteVector = 8,
652 Syntax = 9,
653 Procedure = 10,
654 Record = 11,
655 RecordTypeDescriptor = 12,
656 HashTable = 13,
657 Port = 14,
658 Cell = 15,
659}
660
661impl From<usize> for Tag {
663 fn from(tag: usize) -> Self {
664 match tag {
665 0 => Self::Undefined,
666 1 => Self::Pair,
667 2 => Self::Boolean,
668 3 => Self::Character,
669 4 => Self::Number,
670 5 => Self::String,
671 6 => Self::Symbol,
672 7 => Self::Vector,
673 8 => Self::ByteVector,
674 9 => Self::Syntax,
675 10 => Self::Procedure,
676 11 => Self::Record,
677 12 => Self::RecordTypeDescriptor,
678 13 => Self::HashTable,
679 14 => Self::Port,
680 15 => Self::Cell,
681 tag => panic!("Invalid tag: {tag}"),
682 }
683 }
684}
685
686#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
688pub enum ValueType {
689 Undefined,
690 Null,
691 Pair,
692 Boolean,
693 Character,
694 Number,
695 String,
696 Symbol,
697 Vector,
698 ByteVector,
699 Syntax,
700 Procedure,
701 Record,
702 RecordTypeDescriptor,
703 HashTable,
704 Port,
705}
706
707#[non_exhaustive]
712#[derive(Trace, Clone)]
713pub enum UnpackedValue {
714 Undefined,
715 Null,
716 Boolean(bool),
717 Character(char),
718 Number(Number),
719 String(WideString),
720 Symbol(Symbol),
721 Vector(Vector),
722 ByteVector(ByteVector),
723 Syntax(Gc<Syntax>),
724 Procedure(Procedure),
725 Record(Record),
726 RecordTypeDescriptor(Arc<RecordTypeDescriptor>),
727 Pair(Pair),
728 Port(Port),
729 HashTable(HashTable),
730 Cell(Cell),
731}
732
733impl UnpackedValue {
734 pub fn into_value(self) -> Value {
735 match self {
736 Self::Undefined => Value::undefined(),
737 Self::Null => Value::null(),
738 Self::Boolean(b) => {
739 Value::from_ptr_and_tag(((b as usize) << TAG_BITS) as *const (), Tag::Boolean)
740 }
741 Self::Character(c) => {
742 Value::from_ptr_and_tag(((c as usize) << TAG_BITS) as *const (), Tag::Character)
743 }
744 Self::Number(num) => {
745 let untagged = Arc::into_raw(num.0);
746 Value::from_ptr_and_tag(untagged, Tag::Number)
747 }
748 Self::String(str) => {
749 let untagged = Arc::into_raw(str.0);
750 Value::from_ptr_and_tag(untagged, Tag::String)
751 }
752 Self::Symbol(sym) => {
753 Value::from_ptr_and_tag(((sym.0 as usize) << TAG_BITS) as *const (), Tag::Symbol)
754 }
755 Self::Vector(vec) => {
756 let untagged = Gc::into_raw(vec.0);
757 Value::from_mut_ptr_and_tag(untagged, Tag::Vector)
758 }
759 Self::ByteVector(b_vec) => {
760 let untagged = Arc::into_raw(b_vec.0);
761 Value::from_ptr_and_tag(untagged, Tag::ByteVector)
762 }
763 Self::Syntax(syn) => {
764 let untagged = Gc::into_raw(syn);
765 Value::from_mut_ptr_and_tag(untagged, Tag::Syntax)
766 }
767 Self::Procedure(clos) => {
768 let untagged = Gc::into_raw(clos.0);
769 Value::from_mut_ptr_and_tag(untagged, Tag::Procedure)
770 }
771 Self::Record(rec) => {
772 let untagged = Gc::into_raw(rec.0);
773 Value::from_mut_ptr_and_tag(untagged, Tag::Record)
774 }
775 Self::RecordTypeDescriptor(rt) => {
776 let untagged = Arc::into_raw(rt);
777 Value::from_ptr_and_tag(untagged, Tag::RecordTypeDescriptor)
778 }
779 Self::Pair(pair) => {
780 let untagged = Gc::into_raw(pair.0);
781 Value::from_mut_ptr_and_tag(untagged, Tag::Pair)
782 }
783 Self::Port(port) => {
784 let untagged = Arc::into_raw(port.0);
785 Value::from_ptr_and_tag(untagged, Tag::Port)
786 }
787 Self::HashTable(ht) => {
788 let untagged = Gc::into_raw(ht.0);
789 Value::from_ptr_and_tag(untagged, Tag::HashTable)
790 }
791 Self::Cell(cell) => {
792 let untagged = Gc::into_raw(cell.0);
793 Value::from_mut_ptr_and_tag(untagged, Tag::Cell)
794 }
795 }
796 }
797
798 #[allow(clippy::should_implement_trait)]
799 pub fn eq(&self, rhs: &Self) -> bool {
800 match (self, rhs) {
801 (Self::Boolean(a), Self::Boolean(b)) => a == b,
802 (Self::Symbol(a), Self::Symbol(b)) => a == b,
803 (Self::Number(a), Self::Number(b)) => Arc::ptr_eq(&a.0, &b.0),
804 (Self::Character(a), Self::Character(b)) => a == b,
805 (Self::Null, Self::Null) => true,
806 (Self::String(a), Self::String(b)) => Arc::ptr_eq(&a.0, &b.0),
807 (Self::Pair(a), Self::Pair(b)) => Gc::ptr_eq(&a.0, &b.0),
808 (Self::Vector(a), Self::Vector(b)) => Gc::ptr_eq(&a.0, &b.0),
809 (Self::ByteVector(a), Self::ByteVector(b)) => Arc::ptr_eq(&a.0, &b.0),
810 (Self::Procedure(a), Self::Procedure(b)) => Gc::ptr_eq(&a.0, &b.0),
811 (Self::Syntax(a), Self::Syntax(b)) => Gc::ptr_eq(a, b),
812 (Self::Record(a), Self::Record(b)) => Gc::ptr_eq(&a.0, &b.0),
813 (Self::RecordTypeDescriptor(a), Self::RecordTypeDescriptor(b)) => Arc::ptr_eq(a, b),
814 (Self::Port(a), Self::Port(b)) => Arc::ptr_eq(&a.0, &b.0),
815 (Self::HashTable(a), Self::HashTable(b)) => Gc::ptr_eq(&a.0, &b.0),
816 (Self::Cell(a), b) => a.0.read().unpacked_ref().eq(b),
817 (a, Self::Cell(b)) => a.eq(&b.0.read().unpacked_ref()),
818 _ => false,
819 }
820 }
821
822 pub fn eqv(&self, rhs: &Self) -> bool {
823 match (self, rhs) {
824 (Self::Undefined, Self::Undefined) => true,
827 (Self::Boolean(a), Self::Boolean(b)) => a == b,
829 (Self::Symbol(a), Self::Symbol(b)) => a == b,
831 (Self::Number(a), Self::Number(b)) => a.eqv(b),
832 (Self::Character(a), Self::Character(b)) => a == b,
834 (Self::Null, Self::Null) => true,
836 (Self::String(a), Self::String(b)) => Arc::ptr_eq(&a.0, &b.0),
838 (Self::Pair(a), Self::Pair(b)) => Gc::ptr_eq(&a.0, &b.0),
839 (Self::Vector(a), Self::Vector(b)) => Gc::ptr_eq(&a.0, &b.0),
840 (Self::ByteVector(a), Self::ByteVector(b)) => Arc::ptr_eq(&a.0, &b.0),
841 (Self::Procedure(a), Self::Procedure(b)) => Gc::ptr_eq(&a.0, &b.0),
842 (Self::Syntax(a), Self::Syntax(b)) => Gc::ptr_eq(a, b),
843 (Self::Record(a), Self::Record(b)) => Gc::ptr_eq(&a.0, &b.0),
844 (Self::RecordTypeDescriptor(a), Self::RecordTypeDescriptor(b)) => Arc::ptr_eq(a, b),
845 (Self::Port(a), Self::Port(b)) => Arc::ptr_eq(&a.0, &b.0),
846 (Self::HashTable(a), Self::HashTable(b)) => Gc::ptr_eq(&a.0, &b.0),
847 (Self::Cell(a), b) => a.0.read().unpacked_ref().eqv(b),
848 (a, Self::Cell(b)) => a.eqv(&b.0.read().unpacked_ref()),
849 _ => false,
850 }
851 }
852
853 pub fn type_name(&self) -> &'static str {
854 match self {
855 Self::Undefined => "undefined",
856 Self::Boolean(_) => "bool",
857 Self::Number(_) => "number",
858 Self::Character(_) => "character",
859 Self::String(_) => "string",
860 Self::Symbol(_) => "symbol",
861 Self::Pair(_) | Self::Null => "pair",
862 Self::Vector(_) => "vector",
863 Self::ByteVector(_) => "byte vector",
864 Self::Syntax(_) => "syntax",
865 Self::Procedure(_) => "procedure",
866 Self::Record(_) => "record",
867 Self::RecordTypeDescriptor(_) => "rtd",
868 Self::Port(_) => "port",
869 Self::HashTable(_) => "hashtable",
870 Self::Cell(cell) => cell.0.read().type_name(),
871 }
872 }
873
874 pub fn type_of(&self) -> ValueType {
875 match self {
876 Self::Undefined => ValueType::Undefined,
877 Self::Null => ValueType::Null,
878 Self::Boolean(_) => ValueType::Boolean,
879 Self::Number(_) => ValueType::Number,
880 Self::Character(_) => ValueType::Character,
881 Self::String(_) => ValueType::String,
882 Self::Symbol(_) => ValueType::Symbol,
883 Self::Pair(_) => ValueType::Pair,
884 Self::Vector(_) => ValueType::Vector,
885 Self::ByteVector(_) => ValueType::ByteVector,
886 Self::Syntax(_) => ValueType::Syntax,
887 Self::Procedure(_) => ValueType::Procedure,
888 Self::Record(_) => ValueType::Record,
889 Self::RecordTypeDescriptor(_) => ValueType::RecordTypeDescriptor,
890 Self::Port(_) => ValueType::Port,
891 Self::HashTable(_) => ValueType::HashTable,
892 Self::Cell(cell) => cell.0.read().type_of(),
893 }
894 }
895}
896
897pub fn equal(obj1: &Value, obj2: &Value) -> bool {
903 interleave(&mut HashMap::default(), obj1, obj2, K0)
904}
905
906const K0: i64 = 400;
907const KB: i64 = -40;
908
909fn interleave(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> bool {
910 e(ht, obj1, obj2, k).is_some()
911}
912
913fn e(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
914 match k {
915 KB => fast(ht, obj1, obj2, rand::random_range(0..(K0 * 2))),
916 k if k <= 0 => slow(ht, obj1, obj2, k),
917 k => fast(ht, obj1, obj2, k),
918 }
919}
920
921fn fast(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
922 let k = k - 1;
923 if obj1.eqv(obj2) {
924 return Some(k);
925 }
926 match (obj1.type_of(), obj2.type_of()) {
927 (ValueType::Pair, ValueType::Pair) => pair_eq(ht, obj1, obj2, k),
928 (ValueType::Vector, ValueType::Vector) => vector_eq(ht, obj1, obj2, k),
929 (ValueType::ByteVector, ValueType::ByteVector) => bytevector_eq(obj1, obj2, k),
930 (ValueType::String, ValueType::String) => string_eq(obj1, obj2, k),
931 _ => None,
932 }
933}
934
935fn slow(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
936 if obj1.eqv(obj2) {
937 return Some(k);
938 }
939 match (obj1.type_of(), obj2.type_of()) {
940 (ValueType::Pair, ValueType::Pair) => {
941 if union_find(ht, obj1, obj2) {
942 return Some(0);
943 }
944 pair_eq(ht, obj1, obj2, k)
945 }
946 (ValueType::Vector, ValueType::Vector) => {
947 if union_find(ht, obj1, obj2) {
948 return Some(0);
949 }
950 vector_eq(ht, obj1, obj2, k)
951 }
952 (ValueType::ByteVector, ValueType::ByteVector) => bytevector_eq(obj1, obj2, k),
953 (ValueType::String, ValueType::String) => string_eq(obj1, obj2, k),
954 _ => None,
955 }
956}
957
958fn pair_eq(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
959 let obj1: Pair = obj1.clone().try_into().unwrap();
960 let obj2: Pair = obj2.clone().try_into().unwrap();
961 let (car_x, cdr_x) = obj1.into();
962 let (car_y, cdr_y) = obj2.into();
963 e(ht, &car_x, &car_y, k - 1).and_then(|k| e(ht, &cdr_x, &cdr_y, k))
964}
965
966fn vector_eq(ht: &mut HashMap<Value, Value>, obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
967 let vobj1: Vector = obj1.clone().try_into().unwrap();
968 let vobj2: Vector = obj2.clone().try_into().unwrap();
969 let vobj1 = vobj1.0.vec.read();
970 let vobj2 = vobj2.0.vec.read();
971 if vobj1.len() != vobj2.len() {
972 return None;
973 }
974 let mut k = k - 1;
975 for (x, y) in vobj1.iter().zip(vobj2.iter()) {
976 k = e(ht, x, y, k)?;
977 }
978 Some(k)
979}
980
981fn bytevector_eq(obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
982 let obj1: ByteVector = obj1.clone().try_into().unwrap();
983 let obj2: ByteVector = obj2.clone().try_into().unwrap();
984 (*obj1.0.vec.read() == *obj2.0.vec.read()).then_some(k)
985}
986
987fn string_eq(obj1: &Value, obj2: &Value, k: i64) -> Option<i64> {
988 let obj1: WideString = obj1.clone().try_into().unwrap();
989 let obj2: WideString = obj2.clone().try_into().unwrap();
990 (obj1 == obj2).then_some(k)
991}
992
993fn union_find(ht: &mut HashMap<Value, Value>, x: &Value, y: &Value) -> bool {
994 let bx = ht.get(x).cloned();
995 let by = ht.get(y).cloned();
996 match (bx, by) {
997 (None, None) => {
998 let b = boxv(Value::from(Number::from(1)));
999 ht.insert(x.clone(), b.clone());
1000 ht.insert(y.clone(), b);
1001 }
1002 (None, Some(by)) => {
1003 let ry = find(by);
1004 ht.insert(x.clone(), ry);
1005 }
1006 (Some(bx), None) => {
1007 let rx = find(bx);
1008 ht.insert(y.clone(), rx);
1009 }
1010 (Some(bx), Some(by)) => {
1011 let rx = find(bx);
1012 let ry = find(by);
1013 if rx.eqv(&ry) {
1014 return true;
1015 }
1016 let nx = unbox_to_num(&rx);
1017 let ny = unbox_to_num(&ry);
1018 if nx > ny {
1019 set_box(&ry, rx.clone());
1020 set_box(&rx, nx + ny);
1021 } else {
1022 set_box(&rx, ry.clone());
1023 set_box(&ry, nx + ny);
1024 }
1025 }
1026 }
1027 false
1028}
1029
1030fn find(mut b: Value) -> Value {
1031 let mut n = unbox(&b);
1032 if is_box(&n) {
1033 loop {
1034 let nn = unbox(&n);
1035 if !is_box(&nn) {
1036 return n;
1037 }
1038 set_box(&b, nn.clone());
1039 b = n;
1040 n = nn;
1041 }
1042 } else {
1043 b
1044 }
1045}
1046
1047fn boxv(v: Value) -> Value {
1048 Value::from(Pair::mutable(v.clone(), Value::null()))
1049}
1050
1051fn unbox(v: &Value) -> Value {
1052 let pair: Pair = v.clone().try_into().unwrap();
1053 pair.car()
1054}
1055
1056fn unbox_to_num(v: &Value) -> Number {
1057 let pair: Pair = v.clone().try_into().unwrap();
1058 pair.car().try_into().unwrap()
1059}
1060
1061fn is_box(v: &Value) -> bool {
1062 v.type_of() == ValueType::Pair
1063}
1064
1065fn set_box(b: &Value, val: impl Into<Value>) {
1066 let pair: Pair = b.clone().try_into().unwrap();
1067 pair.set_car(val.into()).unwrap();
1068}
1069
1070macro_rules! impl_try_from_value_for {
1071 ($ty:ty, $variant:ident, $type_name:literal) => {
1072 impl From<$ty> for UnpackedValue {
1073 fn from(v: $ty) -> Self {
1074 Self::$variant(v)
1075 }
1076 }
1077
1078 impl From<$ty> for Value {
1079 fn from(v: $ty) -> Self {
1080 UnpackedValue::from(v).into_value()
1081 }
1082 }
1083
1084 impl From<UnpackedValue> for Option<$ty> {
1085 fn from(v: UnpackedValue) -> Self {
1086 match v {
1087 UnpackedValue::$variant(v) => Some(v),
1088 _ => None,
1089 }
1090 }
1091 }
1092
1093 impl From<Value> for Option<$ty> {
1094 fn from(v: Value) -> Self {
1095 v.unpack().into()
1096 }
1097 }
1098
1099 impl From<&'_ Value> for Option<$ty> {
1100 fn from(v: &Value) -> Self {
1101 v.clone().unpack().into()
1102 }
1103 }
1104
1105 impl TryFrom<UnpackedValue> for $ty {
1106 type Error = Exception;
1107
1108 fn try_from(v: UnpackedValue) -> Result<Self, Self::Error> {
1109 match v {
1110 UnpackedValue::$variant(v) => Ok(v),
1111 UnpackedValue::Cell(cell) => cell.0.read().clone().try_into(),
1112 e => Err(Exception::type_error($type_name, e.type_name())),
1113 }
1114 }
1115 }
1116
1117 impl TryFrom<Value> for $ty {
1118 type Error = Exception;
1119
1120 fn try_from(v: Value) -> Result<Self, Self::Error> {
1121 v.unpack().try_into()
1122 }
1123 }
1124
1125 impl TryFrom<&Value> for $ty {
1126 type Error = Exception;
1127
1128 fn try_from(v: &Value) -> Result<Self, Self::Error> {
1129 v.clone().unpack().try_into()
1130 }
1131 }
1132 };
1133}
1134
1135impl From<Infallible> for Value {
1136 fn from(value: Infallible) -> Self {
1137 match value {}
1138 }
1139}
1140
1141impl From<()> for UnpackedValue {
1142 fn from((): ()) -> Self {
1143 Self::Null
1144 }
1145}
1146
1147impl From<()> for Value {
1148 fn from((): ()) -> Self {
1149 UnpackedValue::Null.into_value()
1150 }
1151}
1152
1153impl TryFrom<UnpackedValue> for () {
1154 type Error = Exception;
1155
1156 fn try_from(value: UnpackedValue) -> Result<Self, Self::Error> {
1157 match value {
1158 UnpackedValue::Null => Ok(()),
1159 e => Err(Exception::type_error("null", e.type_name())),
1160 }
1161 }
1162}
1163
1164impl TryFrom<Value> for () {
1165 type Error = Exception;
1166
1167 fn try_from(value: Value) -> Result<Self, Self::Error> {
1168 value.unpack().try_into()
1169 }
1170}
1171
1172impl From<Cell> for UnpackedValue {
1173 fn from(cell: Cell) -> Self {
1174 Self::Cell(cell)
1175 }
1176}
1177
1178impl From<Cell> for Value {
1179 fn from(cell: Cell) -> Self {
1180 UnpackedValue::from(cell).into_value()
1181 }
1182}
1183
1184impl TryFrom<UnpackedValue> for Cell {
1185 type Error = Exception;
1186
1187 fn try_from(v: UnpackedValue) -> Result<Self, Self::Error> {
1188 match v {
1189 UnpackedValue::Cell(cell) => Ok(cell.clone()),
1190 e => Err(Exception::type_error("cell", e.type_name())),
1191 }
1192 }
1193}
1194
1195impl TryFrom<Value> for Cell {
1196 type Error = Exception;
1197
1198 fn try_from(v: Value) -> Result<Self, Self::Error> {
1199 v.unpack().try_into()
1200 }
1201}
1202
1203impl TryFrom<&Value> for Cell {
1204 type Error = Exception;
1205
1206 fn try_from(v: &Value) -> Result<Self, Self::Error> {
1207 v.clone().unpack().try_into()
1208 }
1209}
1210
1211impl From<Value> for bool {
1212 fn from(value: Value) -> Self {
1213 value.is_true()
1214 }
1215}
1216
1217impl From<bool> for UnpackedValue {
1218 fn from(value: bool) -> Self {
1219 Self::Boolean(value)
1220 }
1221}
1222
1223impl From<bool> for Value {
1224 fn from(value: bool) -> Self {
1225 UnpackedValue::from(value).into_value()
1226 }
1227}
1228
1229impl_try_from_value_for!(char, Character, "char");
1232impl_try_from_value_for!(Number, Number, "number");
1233impl_try_from_value_for!(WideString, String, "string");
1234impl_try_from_value_for!(Symbol, Symbol, "symbol");
1235impl_try_from_value_for!(Vector, Vector, "vector");
1236impl_try_from_value_for!(ByteVector, ByteVector, "byte-vector");
1237impl_try_from_value_for!(Gc<Syntax>, Syntax, "syntax");
1238impl_try_from_value_for!(Procedure, Procedure, "procedure");
1239impl_try_from_value_for!(Pair, Pair, "pair");
1240impl_try_from_value_for!(Record, Record, "record");
1241impl_try_from_value_for!(Port, Port, "port");
1242impl_try_from_value_for!(HashTable, HashTable, "hashtable");
1243impl_try_from_value_for!(Arc<RecordTypeDescriptor>, RecordTypeDescriptor, "rt");
1244
1245macro_rules! impl_from_wrapped_for {
1246 ($ty:ty, $variant:ident, $wrapper:expr_2021) => {
1247 impl From<$ty> for UnpackedValue {
1248 fn from(v: $ty) -> Self {
1249 Self::$variant(($wrapper)(v))
1250 }
1251 }
1252
1253 impl From<$ty> for Value {
1254 fn from(v: $ty) -> Self {
1255 UnpackedValue::from(v).into_value()
1256 }
1257 }
1258 };
1259}
1260
1261impl_from_wrapped_for!(String, String, WideString::immutable);
1262impl_from_wrapped_for!(Vec<Value>, Vector, Vector::immutable);
1263impl_from_wrapped_for!(Vec<u8>, ByteVector, ByteVector::immutable);
1264impl_from_wrapped_for!(Syntax, Syntax, Gc::new);
1265impl_from_wrapped_for!((Value, Value), Pair, |(car, cdr)| Pair::immutable(car, cdr));
1266
1267impl From<UnpackedValue> for Option<(Value, Value)> {
1268 fn from(val: UnpackedValue) -> Self {
1269 match val {
1270 UnpackedValue::Pair(pair) => Some(pair.into()),
1271 _ => None,
1272 }
1273 }
1274}
1275
1276impl TryFrom<UnpackedValue> for (Value, Value) {
1277 type Error = Exception;
1278
1279 fn try_from(val: UnpackedValue) -> Result<Self, Self::Error> {
1280 match val {
1281 UnpackedValue::Pair(pair) => Ok(pair.into()),
1282 e => Err(Exception::type_error("pair", e.type_name())),
1283 }
1284 }
1285}
1286
1287macro_rules! impl_num_conversion {
1288 ($ty:ty) => {
1289 impl TryFrom<&Value> for $ty {
1291 type Error = Exception;
1292
1293 fn try_from(value: &Value) -> Result<$ty, Self::Error> {
1294 match &*value.unpacked_ref() {
1295 UnpackedValue::Number(num) => num.try_into(),
1296 e => Err(Exception::type_error("number", e.type_name())),
1297 }
1298 }
1299 }
1300
1301 impl TryFrom<Value> for $ty {
1302 type Error = Exception;
1303
1304 fn try_from(value: Value) -> Result<$ty, Self::Error> {
1305 (&value).try_into()
1306 }
1307 }
1308
1309 impl From<&Value> for Option<$ty> {
1310 fn from(value: &Value) -> Self {
1311 match &*value.unpacked_ref() {
1312 UnpackedValue::Number(num) => num.into(),
1313 _ => None,
1314 }
1315 }
1316 }
1317
1318 impl From<Value> for Option<$ty> {
1319 fn from(value: Value) -> Self {
1320 match value.unpack() {
1321 UnpackedValue::Number(num) => num.into(),
1322 _ => None,
1323 }
1324 }
1325 }
1326
1327 impl From<$ty> for Value {
1328 fn from(n: $ty) -> Self {
1329 Self::from(Number::from(n))
1330 }
1331 }
1332 };
1333}
1334
1335impl_num_conversion!(u8);
1336impl_num_conversion!(u16);
1337impl_num_conversion!(u32);
1338impl_num_conversion!(u64);
1339impl_num_conversion!(u128);
1340impl_num_conversion!(usize);
1341impl_num_conversion!(i8);
1342impl_num_conversion!(i16);
1343impl_num_conversion!(i32);
1344impl_num_conversion!(i64);
1345impl_num_conversion!(i128);
1346impl_num_conversion!(isize);
1347impl_num_conversion!(f64);
1348impl_num_conversion!(Integer);
1349impl_num_conversion!(SimpleNumber);
1350impl_num_conversion!(ComplexNumber);
1351
1352impl From<&Value> for Option<Identifier> {
1353 fn from(value: &Value) -> Self {
1354 match &*value.unpacked_ref() {
1355 UnpackedValue::Syntax(syn) => match syn.as_ref() {
1356 Syntax::Identifier { ident, .. } => Some(ident.clone()),
1357 _ => None,
1358 },
1359 _ => None,
1360 }
1361 }
1362}
1363
1364impl TryFrom<&Value> for Identifier {
1365 type Error = Exception;
1366
1367 fn try_from(value: &Value) -> Result<Self, Self::Error> {
1368 match Option::<Identifier>::from(value) {
1369 Some(ident) => Ok(ident),
1370 None => Err(Exception::type_error("identifier", value.type_name())),
1371 }
1372 }
1373}
1374
1375impl From<Value> for Option<(Value, Value)> {
1376 fn from(value: Value) -> Self {
1377 value.unpack().into()
1378 }
1379}
1380
1381impl From<&Value> for Option<(Value, Value)> {
1382 fn from(value: &Value) -> Self {
1383 value.clone().unpack().into()
1384 }
1385}
1386
1387impl TryFrom<Value> for (Value, Value) {
1388 type Error = Exception;
1389
1390 fn try_from(val: Value) -> Result<Self, Self::Error> {
1391 Self::try_from(val.unpack())
1392 }
1393}
1394
1395impl TryFrom<&Value> for (Value, Value) {
1396 type Error = Exception;
1397
1398 fn try_from(val: &Value) -> Result<Self, Self::Error> {
1399 Self::try_from(val.clone().unpack())
1400 }
1401}
1402
1403impl TryFrom<Value> for String {
1404 type Error = Exception;
1405
1406 fn try_from(value: Value) -> Result<Self, Self::Error> {
1407 let string: WideString = value.try_into()?;
1408 Ok(string.into())
1409 }
1410}
1411
1412pub trait ExpectN<T> {
1414 fn expect_n<const N: usize>(self) -> Result<[T; N], Exception>;
1415}
1416
1417impl<T> ExpectN<T> for Vec<Value>
1418where
1419 Value: TryInto<T>,
1420 Exception: From<<Value as TryInto<T>>::Error>,
1421{
1422 fn expect_n<const N: usize>(self) -> Result<[T; N], Exception> {
1423 if self.len() != N {
1424 return Err(Exception::error("wrong number of values"));
1425 }
1426 Ok(unsafe {
1429 self.into_iter()
1430 .map(Value::try_into)
1431 .collect::<Result<Vec<_>, _>>()?
1432 .try_into()
1433 .unwrap_unchecked()
1434 })
1435 }
1436}
1437
1438pub trait Expect1<T> {
1440 fn expect1(self) -> Result<T, Exception>;
1441}
1442
1443impl<T> Expect1<T> for Vec<Value>
1444where
1445 Value: TryInto<T>,
1446 Exception: From<<Value as TryInto<T>>::Error>,
1447{
1448 fn expect1(self) -> Result<T, Exception> {
1449 let [val] = self
1450 .try_into()
1451 .map_err(|_| Exception::error("wrong number of values"))?;
1452 val.try_into().map_err(Exception::from)
1453 }
1454}
1455
1456fn determine_circularity(
1459 curr: &Value,
1460 visited: &mut IndexSet<Value>,
1461 circular: &mut IndexSet<Value>,
1462) {
1463 if visited.contains(curr) {
1464 circular.insert(curr.clone());
1465 return;
1466 }
1467
1468 visited.insert(curr.clone());
1469
1470 match curr.clone().unpack() {
1471 UnpackedValue::Pair(pair) => {
1472 let (car, cdr) = pair.into();
1473 determine_circularity(&car, visited, circular);
1474 determine_circularity(&cdr, visited, circular);
1475 }
1476 UnpackedValue::Vector(vec) => {
1477 let vec_read = vec.0.vec.read();
1478 for item in vec_read.iter() {
1479 determine_circularity(item, visited, circular);
1480 }
1481 }
1482 _ => (),
1483 }
1484
1485 visited.swap_remove(curr);
1486}
1487
1488pub(crate) fn write_value(
1489 val: &Value,
1490 fmt: fn(&Value, &mut IndexMap<Value, bool>, &mut fmt::Formatter<'_>) -> fmt::Result,
1491 circular_values: &mut IndexMap<Value, bool>,
1492 f: &mut fmt::Formatter<'_>,
1493) -> fmt::Result {
1494 if let Some((idx, _, seen)) = circular_values.get_full_mut(val) {
1495 if *seen {
1496 write!(f, "#{idx}#")?;
1497 return Ok(());
1498 } else {
1499 write!(f, "#{idx}=")?;
1500 *seen = true;
1501 }
1502 }
1503
1504 fmt(val, circular_values, f)
1505}
1506
1507fn display_value(
1508 val: &Value,
1509 circular_values: &mut IndexMap<Value, bool>,
1510 f: &mut fmt::Formatter<'_>,
1511) -> fmt::Result {
1512 match val.clone().unpack() {
1513 UnpackedValue::Undefined => write!(f, "<undefined>"),
1514 UnpackedValue::Null => write!(f, "()"),
1515 UnpackedValue::Boolean(true) => write!(f, "#t"),
1516 UnpackedValue::Boolean(false) => write!(f, "#f"),
1517 UnpackedValue::Number(number) => write!(f, "{number}"),
1518 UnpackedValue::Character(c) => write!(f, "#\\{c}"),
1519 UnpackedValue::String(string) => write!(f, "{string}"),
1520 UnpackedValue::Symbol(symbol) => write!(f, "{symbol}"),
1521 UnpackedValue::Pair(pair) => {
1522 let (car, cdr) = pair.into();
1523 lists::write_list(&car, &cdr, display_value, circular_values, f)
1524 }
1525 UnpackedValue::Vector(v) => vectors::write_vec(&v, display_value, circular_values, f),
1526 UnpackedValue::ByteVector(v) => vectors::write_bytevec(&v, f),
1527 UnpackedValue::Procedure(_) => write!(f, "<procedure>"),
1528 UnpackedValue::Record(record) => write!(f, "{record:?}"),
1529 UnpackedValue::Syntax(syntax) => write!(f, "#<syntax {syntax:#?}>"),
1530 UnpackedValue::RecordTypeDescriptor(rtd) => write!(f, "{rtd:?}"),
1531 UnpackedValue::Port(_) => write!(f, "<port>"),
1532 UnpackedValue::HashTable(hashtable) => write!(f, "{hashtable:?}"),
1533 UnpackedValue::Cell(cell) => display_value(&cell.0.read(), circular_values, f),
1534 }
1535}
1536
1537fn debug_value(
1538 val: &Value,
1539 circular_values: &mut IndexMap<Value, bool>,
1540 f: &mut fmt::Formatter<'_>,
1541) -> fmt::Result {
1542 match val.clone().unpack() {
1543 UnpackedValue::Undefined => write!(f, "<undefined>"),
1544 UnpackedValue::Null => write!(f, "()"),
1545 UnpackedValue::Boolean(true) => write!(f, "#t"),
1546 UnpackedValue::Boolean(false) => write!(f, "#f"),
1547 UnpackedValue::Number(number) => write!(f, "{number}"),
1548 UnpackedValue::Character(c) => write!(f, "#\\{c}"),
1549 UnpackedValue::String(string) => write!(f, "{string:?}"),
1550 UnpackedValue::Symbol(symbol) => write!(f, "{symbol}"),
1551 UnpackedValue::Pair(pair) => {
1552 let (car, cdr) = pair.into();
1553 lists::write_list(&car, &cdr, debug_value, circular_values, f)
1554 }
1555 UnpackedValue::Vector(v) => vectors::write_vec(&v, debug_value, circular_values, f),
1556 UnpackedValue::ByteVector(v) => vectors::write_bytevec(&v, f),
1557 UnpackedValue::Syntax(syntax) => {
1558 let span = syntax.span();
1559 write!(f, "#<syntax:{span} {syntax:#?}>")
1560 }
1561 UnpackedValue::Procedure(proc) => write!(f, "#<procedure {proc:?}>"),
1562 UnpackedValue::Record(record) => write!(f, "{record:#?}"),
1563 UnpackedValue::RecordTypeDescriptor(rtd) => write!(f, "{rtd:?}"),
1564 UnpackedValue::Port(_) => write!(f, "<port>"),
1565 UnpackedValue::HashTable(hashtable) => write!(f, "{hashtable:?}"),
1566 UnpackedValue::Cell(cell) => debug_value(&cell.0.read(), circular_values, f),
1567 }
1568}
1569#[bridge(name = "not", lib = "(rnrs base builtins (6))")]
1570pub fn not(a: &Value) -> Result<Vec<Value>, Exception> {
1571 Ok(vec![Value::from(a.0 as usize == Tag::Boolean as usize)])
1572}
1573
1574#[bridge(name = "eqv?", lib = "(rnrs base builtins (6))")]
1575pub fn eqv(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1576 Ok(vec![Value::from(a.eqv(b))])
1577}
1578
1579#[bridge(name = "eq?", lib = "(rnrs base builtins (6))")]
1580pub fn eq(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1581 Ok(vec![Value::from(a.eqv(b))])
1582}
1583
1584#[bridge(name = "equal?", lib = "(rnrs base builtins (6))")]
1585pub fn equal_pred(a: &Value, b: &Value) -> Result<Vec<Value>, Exception> {
1586 Ok(vec![Value::from(a.equal(b))])
1587}
1588
1589#[bridge(name = "boolean?", lib = "(rnrs base builtins (6))")]
1590pub fn boolean_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1591 Ok(vec![Value::from(arg.type_of() == ValueType::Boolean)])
1592}
1593
1594#[bridge(name = "boolean=?", lib = "(rnrs base builtins (6))")]
1595pub fn boolean_eq_pred(a: &Value, args: &[Value]) -> Result<Vec<Value>, Exception> {
1596 let res = if a.type_of() == ValueType::Boolean {
1597 args.iter().all(|arg| arg == a)
1598 } else {
1599 false
1600 };
1601 Ok(vec![Value::from(res)])
1602}
1603
1604#[bridge(name = "symbol?", lib = "(rnrs base builtins (6))")]
1605pub fn symbol_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1606 Ok(vec![Value::from(arg.type_of() == ValueType::Symbol)])
1607}
1608
1609#[bridge(name = "char?", lib = "(rnrs base builtins (6))")]
1610pub fn char_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1611 Ok(vec![Value::from(arg.type_of() == ValueType::Character)])
1612}
1613
1614#[bridge(name = "vector?", lib = "(rnrs base builtins (6))")]
1615pub fn vector_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1616 Ok(vec![Value::from(arg.type_of() == ValueType::Vector)])
1617}
1618
1619#[bridge(name = "null?", lib = "(rnrs base builtins (6))")]
1620pub fn null_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1621 Ok(vec![Value::from(arg.type_of() == ValueType::Null)])
1622}
1623
1624#[bridge(name = "pair?", lib = "(rnrs base builtins (6))")]
1625pub fn pair_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1626 Ok(vec![Value::from(matches!(
1627 *arg.unpacked_ref(),
1628 UnpackedValue::Pair(_)
1629 ))])
1630}
1631
1632#[bridge(name = "procedure?", lib = "(rnrs base builtins (6))")]
1633pub fn procedure_pred(arg: &Value) -> Result<Vec<Value>, Exception> {
1634 Ok(vec![Value::from(arg.type_of() == ValueType::Procedure)])
1635}