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;
121const TAG: usize = 0b1111;
122const FALSE_VALUE: usize = Tag::Boolean as usize;
123
124#[repr(transparent)]
127pub struct Value(*const ());
128
129impl Value {
130 pub fn new(v: UnpackedValue) -> Self {
135 v.into_value()
136 }
137
138 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 pub unsafe fn from_raw(raw: *const ()) -> Self {
157 Self(raw)
158 }
159
160 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 pub fn into_raw(val: Self) -> *const () {
207 ManuallyDrop::new(val).0
208 }
209
210 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 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 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 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 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 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 pub fn from_rust_type<T: SchemeCompatible>(t: T) -> Self {
304 Self::from(Record::from_rust_type(t))
305 }
306
307 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 #[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 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 pub fn equal(&self, rhs: &Self) -> bool {
406 equal(self, rhs)
407 }
408
409 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 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 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 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 unsafe { ManuallyDrop::drop(&mut ManuallyDrop::new(Self(self.0).unpack())) }
515 }
516}
517
518impl Hash for Value {
521 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
522 self.eqv_hash(state)
523 }
524}
525
526impl PartialEq for Value {
529 fn eq(&self, rhs: &Value) -> bool {
530 self.eqv(rhs)
531 }
532}
533
534impl 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#[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
589pub 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 fn from(value: Option<T>) -> Self {
617 match value {
618 Some(t) => Self::from(t),
619 None => Self::from(false),
620 }
621 }
622}
623
624impl 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
659impl 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#[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#[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 (Self::Undefined, Self::Undefined) => true,
825 (Self::Boolean(a), Self::Boolean(b)) => a == b,
827 (Self::Symbol(a), Self::Symbol(b)) => a == b,
829 (Self::Number(a), Self::Number(b)) => a.eqv(b),
830 (Self::Character(a), Self::Character(b)) => a == b,
832 (Self::Null, Self::Null) => true,
834 (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
895pub 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
1227impl_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
1259impl_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 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
1413pub 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 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
1439pub 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
1457fn 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}