espy_paws/
lib.rs

1mod error;
2
3pub use anyhow;
4pub use error::{DebugInfoError, Error, ErrorKind, InvalidBytecode};
5
6use espy_heart::prelude::*;
7use std::any::Any;
8use std::borrow::Borrow;
9use std::cell::RefCell;
10use std::mem;
11use std::num::NonZero;
12use std::rc::{Rc, Weak};
13
14#[macro_export]
15macro_rules! extern_impl {
16    {
17        $(#[espy(
18            $(debug = $description:literal)?
19        )])?
20        $vis:vis fn $this:ident <$host:lifetime> (&self, $argument:ident)
21            $body:tt
22    } => {
23        #[derive(
24            ::std::clone::Clone,
25            ::std::marker::Copy,
26            ::std::fmt::Debug,
27            ::std::default::Default
28        )]
29        $vis struct $this;
30
31        impl $crate::ExternFn for $this {
32            fn call<$host>(
33                &$host self, $argument: $crate::Value<$host>
34            ) -> ::std::result::Result<$crate::Value<$host>, $crate::Error>
35                $body
36
37            fn to_static(&self) -> ::std::option::Option<$crate::StaticFunction> {
38                Some($crate::StaticFunction::borrow(&$this))
39            }
40
41            $($(
42                fn debug(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
43                    ::std::write!(f, $description)
44                }
45            )?)?
46        }
47    };
48    {
49        $(#[espy(
50            // Allows the user to set adebug string to be shown used by the Extern trait.
51            //
52            // This is a format string, and the `self` parameter may be bound
53            // by using square brackets after "debug".
54            // Using `self` directly will not work because it is not considered in scope of the macro.
55            $(debug$([$debug_name:ident])? = $description:literal)?
56        )])?
57        $vis:vis struct $this:ident {
58            $($name:ident: $value:expr),* $(,)?
59        }
60    } => {
61        #[derive(
62            ::std::clone::Clone,
63            ::std::marker::Copy,
64            ::std::fmt::Debug,
65            ::std::default::Default
66        )]
67        $vis struct $this;
68
69        impl $crate::Extern for $this {
70            fn index<'host>(
71                &'host self, index: $crate::Value<'host>
72            ) -> ::std::result::Result<$crate::Value<'host>, $crate::Error> {
73                let index = index.into_str()?;
74                match &*index {
75                    $(stringify!($name) => Ok($crate::Value::from($value)),)*
76                    _ => Err($crate::Error::index_not_found(
77                        &$crate::Value::borrow(self),
78                        &index.into(),
79                    )),
80                }
81            }
82
83            fn to_static<'host>(&self, partial_index: ::std::option::Option<::std::rc::Rc<$crate::Value<'host>>>) -> ::std::option::Option<$crate::StaticValue> {
84                ::std::option::Option::Some($crate::StaticValue::Borrow(&$this, partial_index.and_then(|x| x.to_static().map(::std::rc::Rc::new))))
85            }
86
87            fn any(&self) -> ::std::option::Option<&dyn ::std::any::Any> {
88                ::std::option::Option::Some(self)
89            }
90
91            fn debug(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
92                ::std::write!(f, "std.string module")
93            }
94        }
95    };
96}
97
98fn rc_slice_try_from_iter<T, E>(
99    len: usize,
100    iter: impl Iterator<Item = Result<T, E>>,
101) -> Result<Rc<[T]>, E> {
102    let mut tuple = Rc::new_uninit_slice(len);
103    // SAFETY: `get_mut` only returns `None` if the `Rc` has been cloned.
104    let mutable_tuple = unsafe { Rc::get_mut(&mut tuple).unwrap_unchecked() };
105    let mut count = 0;
106    for (entry, value) in mutable_tuple.iter_mut().zip(iter) {
107        entry.write(value?);
108        count += 1;
109    }
110    assert!(
111        count == len,
112        "iter did not produce enough values ({count}) to initialize slice of length {len}"
113    );
114    // SAFETY: Since `count` == `len`, the slice is initialized.
115    unsafe { Ok(tuple.assume_init()) }
116}
117
118fn rc_slice_from_iter<T>(len: usize, iter: impl Iterator<Item = T>) -> Rc<[T]> {
119    rc_slice_try_from_iter(len, iter.map(Ok::<_, ()>)).expect("iter is always Ok")
120}
121
122/// The root type of every espy value. All interoperation starts here.
123///
124/// Don't be afraid to [`Clone`] this type;
125/// it contains only [`Copy`] types and [`Rc`]s.
126#[derive(Clone)]
127pub enum Value<'host> {
128    /// Unit is the absense of a value.
129    /// It can be thought of as both an empty tuple and an empty named tuple.
130    Unit,
131    Tuple(Tuple<Value<'host>>),
132
133    Borrow(&'host dyn Extern, Option<Rc<Value<'host>>>),
134    Owned(Rc<dyn ExternOwned>, Option<Rc<Value<'host>>>),
135    I64(i64),
136    Bool(bool),
137    String(Rc<str>),
138    Function(Rc<Function<'host>>),
139    EnumVariant(Rc<EnumVariant<'host>>),
140    Option {
141        contents: Option<Rc<Value<'host>>>,
142        ty: ComplexType,
143    },
144    Mut(Mut<'host>),
145
146    Type(Type),
147}
148
149impl std::fmt::Debug for Value<'_> {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        match self {
152            Value::Unit => write!(f, "Unit"),
153            Value::Tuple(tuple) => write!(f, "{tuple:?}"),
154            Value::Borrow(external, partial_index) => {
155                write!(f, "Borrow(")?;
156                external.debug(f)?;
157                if let Some(partial_index) = partial_index {
158                    write!(f, ", {partial_index:?}")?;
159                }
160                write!(f, ")")
161            }
162            Value::Owned(external, partial_index) => {
163                write!(f, "Owned(")?;
164                external.debug(f)?;
165                if let Some(partial_index) = partial_index {
166                    write!(f, ", {partial_index:?}")?;
167                }
168                write!(f, ")")
169            }
170            Value::I64(i) => write!(f, "I64({i:?})"),
171            Value::Bool(i) => write!(f, "Bool({i:?})"),
172            Value::String(i) => write!(f, "String({i:?})"),
173            Value::Function(function) => write!(f, "{function:?}"),
174            Value::EnumVariant(enum_variant) => write!(f, "{enum_variant:?}"),
175            Value::Option { contents, ty: _ } => write!(f, "{contents:?}"),
176            Value::Mut(inner) => write!(f, "{inner:?}"),
177            Value::Type(t) => write!(f, "{t:?}"),
178        }
179    }
180}
181
182/// A version of [`Value`] with a static lifetime.
183///
184/// Must be cast back to a runtime-compatible [`Value`] using
185/// [`StaticValue::to_runtime`] to be used.
186///
187/// The difference between this type and [`Value<'static>`] is the lack
188/// of [`Mut`], which contains a [`RefCell`] and makes [`Value<'static>`]
189/// [invariant](https://doc.rust-lang.org/nomicon/subtyping.html#variance) over
190/// `'host`. This means that a [`Value<'static>`] cannot be combined with
191/// non `'static` values in the same runtime,  which would prevent useful things
192/// like a static [`Function`] accepting a borrowed [`Extern`] value with a
193/// non-`'static` lifetime.
194#[derive(Clone)]
195pub enum StaticValue {
196    Unit,
197    Tuple(Tuple<StaticValue>),
198
199    Borrow(&'static dyn Extern, Option<Rc<StaticValue>>),
200    Owned(Rc<dyn ExternOwned>, Option<Rc<StaticValue>>),
201    I64(i64),
202    Bool(bool),
203    String(Rc<str>),
204    Function(Rc<StaticFunction>),
205    EnumVariant(Rc<StaticEnumVariant>),
206    Option {
207        contents: Option<Rc<StaticValue>>,
208        ty: ComplexType,
209    },
210
211    Type(Type),
212}
213
214impl std::fmt::Debug for StaticValue {
215    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216        write!(f, "{:?}", self.to_runtime())
217    }
218}
219
220impl StaticValue {
221    #[must_use]
222    pub fn to_runtime<'host>(&self) -> Value<'host> {
223        match self {
224            StaticValue::Unit => Value::Unit,
225            StaticValue::Tuple(tuple) => Value::Tuple(tuple.to_runtime()),
226            StaticValue::Borrow(extern_ref, partial_index) => Value::Borrow(
227                *extern_ref,
228                partial_index.as_ref().map(|x| x.to_runtime().into()),
229            ),
230            StaticValue::Owned(extern_owned, partial_index) => Value::Owned(
231                extern_owned.clone(),
232                partial_index.as_ref().map(|x| x.to_runtime().into()),
233            ),
234            StaticValue::I64(i) => Value::I64(*i),
235            StaticValue::Bool(i) => Value::Bool(*i),
236            StaticValue::String(i) => Value::String(i.clone()),
237            StaticValue::Function(static_function) => {
238                Value::Function(Rc::new(static_function.to_runtime()))
239            }
240            StaticValue::EnumVariant(static_enum_variant) => {
241                Value::EnumVariant(Rc::new(EnumVariant {
242                    contents: static_enum_variant.contents.clone().into(),
243                    variant: static_enum_variant.variant,
244                    definition: static_enum_variant.definition.clone(),
245                }))
246            }
247            StaticValue::Option { contents, ty } => Value::Option {
248                contents: contents.as_ref().map(|x| x.to_runtime().into()),
249                ty: ty.clone(),
250            },
251            StaticValue::Type(i) => Value::Type(i.clone()),
252        }
253    }
254}
255
256impl<'host, T: Borrow<StaticValue>> From<T> for Value<'host> {
257    fn from(value: T) -> Self {
258        value.borrow().to_runtime()
259    }
260}
261
262/// The type of a singular espy values.
263///
264/// This enum does *not* represent the type of tuples;
265/// for that, see [`ComplexType`]
266///
267/// [`Type`] itself is a type, [`Type::Type`], because it may appear within an espy value.
268///
269/// Note that [`Value::type_of`] returns [`Type::Any`] for [`Value::Borrow`]
270/// and [`Value::Owned`].
271#[derive(Clone, Debug)]
272pub enum Type {
273    /// Any is the type of a value with unknown capabilities.
274    ///
275    /// Any is the type of all external values because they have arbitrary, unknowable properties.
276    /// This means that external values must be casted to trait objects to interact with them.
277    Any,
278    I64,
279    Bool,
280    String,
281    Function(Rc<FunctionType>),
282    Enum(Rc<EnumType>),
283    Option(Rc<ComplexType>),
284    Mut(Rc<ComplexType>),
285
286    /// The type of types.
287    Type,
288    Unit,
289}
290
291impl PartialEq for Type {
292    fn eq(&self, other: &Self) -> bool {
293        match (self, other) {
294            (Self::Enum(l), Self::Enum(r)) => l == r,
295            (Self::Option(l), Self::Option(r)) => l == r,
296            _ => mem::discriminant(self) == mem::discriminant(other),
297        }
298    }
299}
300
301impl Eq for Type {}
302
303/// The type of any espy value.
304///
305/// [`ComplexType`] is usually the only form of [`Type`] that the espy
306/// interpreter is concerned with, but it cannot be represented within espy
307/// itself (tuples of types represent [`ComplexType`]s, instead).
308#[derive(Clone, Debug, PartialEq, Eq)]
309pub enum ComplexType {
310    Simple(Type),
311    Complex(Tuple<ComplexType>),
312}
313
314impl ComplexType {
315    #[must_use]
316    pub fn compare(&self, r: &Self) -> bool {
317        match (self, r) {
318            (ComplexType::Simple(Type::Any), _) | (_, ComplexType::Simple(Type::Any)) => true,
319            (ComplexType::Simple(l), ComplexType::Simple(r)) => l == r,
320            (ComplexType::Complex(l), ComplexType::Complex(r)) => {
321                l.values().zip(r.values()).all(|(l, r)| l.compare(r))
322            }
323            _ => false,
324        }
325    }
326}
327
328impl From<Type> for ComplexType {
329    fn from(value: Type) -> Self {
330        Self::Simple(value)
331    }
332}
333
334impl From<Tuple<ComplexType>> for ComplexType {
335    fn from(value: Tuple<ComplexType>) -> Self {
336        Self::Complex(value)
337    }
338}
339
340impl From<ComplexType> for Value<'_> {
341    fn from(value: ComplexType) -> Self {
342        match value {
343            ComplexType::Simple(ty) => ty.into(),
344            ComplexType::Complex(tuple) => Value::Tuple(tuple.into()),
345        }
346    }
347}
348
349impl From<Type> for Value<'_> {
350    fn from(t: Type) -> Self {
351        Self::Type(t)
352    }
353}
354
355impl<'host> Value<'host> {
356    /// Returns None if `self` contains any [`Value::Borrow`] or [`Value::Mut`].
357    ///
358    /// [`Value::Borrow`] is not static for obvious reasons,
359    /// and [`Value::Mut`] cannot be made static because of refcell subtyping.
360    /// Instead, hosts using to_static should provide mutable state outside of
361    /// the espy runtime.
362    #[must_use]
363    pub fn to_static(&self) -> Option<StaticValue> {
364        match self {
365            Value::Unit => Some(StaticValue::Unit),
366            Value::Tuple(tuple) => Some(StaticValue::Tuple(tuple.to_static()?)),
367            Value::Borrow(extern_borrow, partial_index) => {
368                extern_borrow.to_static(partial_index.clone())
369            }
370            Value::Owned(extern_owned, partial_index) => Some(StaticValue::Owned(
371                extern_owned.clone(),
372                partial_index
373                    .as_ref()
374                    .and_then(|x| x.to_static().map(Rc::new)),
375            )),
376            Value::I64(x) => Some(StaticValue::I64(*x)),
377            Value::Bool(x) => Some(StaticValue::Bool(*x)),
378            Value::String(x) => Some(StaticValue::String(x.clone())),
379            Value::Function(function) => Some(StaticValue::Function(function.to_static()?.into())),
380            Value::EnumVariant(enum_variant) => {
381                Some(StaticValue::EnumVariant(Rc::new(StaticEnumVariant {
382                    contents: enum_variant.contents.to_static()?,
383                    variant: enum_variant.variant,
384                    definition: enum_variant.definition.clone(),
385                })))
386            }
387            Value::Option { contents, ty } => Some(StaticValue::Option {
388                contents: contents
389                    .as_ref()
390                    .map(|x| x.to_static().ok_or(()))
391                    .transpose()
392                    .ok()?
393                    .map(Rc::new),
394                ty: ty.clone(),
395            }),
396            Value::Mut(_) => None,
397            Value::Type(x) => Some(StaticValue::Type(x.clone())),
398        }
399    }
400
401    /// Convenience method for indexing values of various types by an integer.
402    ///
403    /// Usually this is most useful for reading function arguments by index,
404    /// which are passed as a tuple by convention.
405    ///
406    /// # Errors
407    ///
408    /// Returns [`ErrorKind::IndexNotFound`] if `self` cannot be indexed or the index is out of range for the container.
409    ///
410    /// [`Extern`] and [`ExternOwned`] implementations may return arbitary errors.
411    pub fn get(&self, index: i64) -> Result<Value<'host>, Error> {
412        match self {
413            Value::Tuple(tuple) => usize::try_from(index)
414                .ok()
415                .and_then(|index| tuple.value(index))
416                .cloned()
417                .ok_or(Error::index_not_found(self, &index.into())),
418            Value::Type(Type::Enum(ty)) => usize::try_from(index)
419                .ok()
420                .filter(|index| *index < ty.variants.len())
421                .map(|index| {
422                    Value::Function(Rc::new(
423                        FunctionAction::Enum {
424                            variant: index,
425                            definition: ty.clone(),
426                        }
427                        .into(),
428                    ))
429                })
430                .ok_or_else(|| Error::index_not_found(self, &index.into())),
431            Value::Type(Type::Option(ty)) => match index {
432                0 => Ok(Value::Function(Rc::new(
433                    FunctionAction::OptionCase {
434                        some: true,
435                        ty: (**ty).clone(),
436                    }
437                    .into(),
438                ))),
439                1 => Ok(Value::Function(Rc::new(
440                    FunctionAction::OptionCase {
441                        some: false,
442                        ty: (**ty).clone(),
443                    }
444                    .into(),
445                ))),
446                _ => Err(Error::index_not_found(self, &index.into())),
447            },
448            _ => Err(Error::index_not_found(self, &index.into())),
449        }
450    }
451
452    /// Convenience methods for indexing values of various types by a string.
453    ///
454    /// # Errors
455    ///
456    /// Returns [`Error::index_not_found`] if `self` cannot be indexed or the index is not found in the container.
457    ///
458    /// [`Value::Borrow`] and [`Value::Owned`] implementations may return arbitary errors.
459    pub fn find(&self, index: Rc<str>) -> Result<Value<'host>, Error> {
460        match self {
461            Value::Tuple(tuple) => tuple
462                .find_value(&index)
463                .cloned()
464                .ok_or(Error::index_not_found(self, &index.into())),
465            Value::Type(Type::Enum(ty)) => {
466                if let Some(variant_id) = ty
467                    .variants
468                    .as_ref()
469                    .iter()
470                    .enumerate()
471                    .find(|(_, (variant, _))| *variant == index)
472                    .map(|(i, _)| i)
473                {
474                    Ok(Value::Function(Rc::new(
475                        FunctionAction::Enum {
476                            variant: variant_id,
477                            definition: ty.clone(),
478                        }
479                        .into(),
480                    )))
481                } else {
482                    Err(Error::index_not_found(self, &index.into()))
483                }
484            }
485            Value::Type(Type::Option(ty)) => match &*index {
486                "Some" => Ok(Value::Function(Rc::new(
487                    FunctionAction::OptionCase {
488                        some: true,
489                        ty: (**ty).clone(),
490                    }
491                    .into(),
492                ))),
493                "None" => Ok(Value::Function(Rc::new(
494                    FunctionAction::OptionCase {
495                        some: false,
496                        ty: (**ty).clone(),
497                    }
498                    .into(),
499                ))),
500                _ => Err(Error::index_not_found(self, &index.into())),
501            },
502            _ => Err(Error::index_not_found(self, &index.into())),
503        }
504    }
505
506    /// Convenience methods for indexing values of various types.
507    ///
508    /// # Errors
509    ///
510    /// Returns [`Error::index_not_found`] if `self` cannot be indexed or the index is not found in the container.
511    ///
512    /// [`Value::Borrow`] and [`Value::Owned`] implementations may return arbitary errors.
513    pub fn index(&self, index: impl Into<Value<'host>>) -> Result<Value<'host>, Error> {
514        match (self, index.into()) {
515            (Value::Borrow(external, partial_index), index) => {
516                external.index(if let Some(partial_index) = partial_index {
517                    Value::concat((**partial_index).clone(), index)
518                } else {
519                    index
520                })
521            }
522            (Value::Owned(external, partial_index), index) => {
523                external
524                    .clone()
525                    .index(if let Some(partial_index) = partial_index {
526                        Value::concat((**partial_index).clone(), index)
527                    } else {
528                        index
529                    })
530            }
531            (_, Value::I64(index)) => self.get(index),
532            (_, Value::String(index)) => self.find(index),
533            (_, index) => Err(Error::index_not_found(self, &index)),
534        }
535    }
536
537    /// Attempts to downcast instances of [`Value::Borrow`] and [`Value::Owned`] into `&T`.
538    ///
539    /// Note that [`Extern`] and [`ExternOwned`] implementations have to opt into this behavior
540    /// by implementing their `any` functions.
541    /// The default `any` implementation will result in this function returning `None`.
542    #[must_use]
543    pub fn downcast_extern<T: Any>(&self) -> Option<&T> {
544        match self {
545            Value::Borrow(borrow, ..) => (*borrow).any()?.downcast_ref(),
546            Value::Owned(owned, ..) => (*owned).any()?.downcast_ref(),
547            _ => None,
548        }
549    }
550
551    /// # Errors
552    ///
553    /// Returns an error if `self` and `other` are incomparable.
554    pub fn eq(self, other: Self) -> Result<bool, Error> {
555        match (self, other) {
556            (Value::Unit, Value::Unit) => Ok(true),
557            (Value::Tuple(l), Value::Tuple(r)) if l.len() == r.len() => {
558                for (l, r) in l.values().zip(r.values()) {
559                    if !l.clone().eq(r.clone())? {
560                        return Ok(false);
561                    }
562                }
563                Ok(true)
564            }
565            (Value::I64(l), Value::I64(r)) => Ok(l == r),
566            (Value::Bool(l), Value::Bool(r)) => Ok(l == r),
567            (Value::String(l), Value::String(r)) => Ok(l == r),
568            (Value::EnumVariant(l), Value::EnumVariant(r)) => Ok(l.variant == r.variant
569                && Rc::ptr_eq(&l.definition, &r.definition)
570                && Rc::try_unwrap(l)
571                    .map_or_else(|l| l.contents.clone(), |l| l.contents)
572                    .eq(Rc::try_unwrap(r).map_or_else(|r| r.contents.clone(), |r| r.contents))?),
573            (
574                Value::Option {
575                    contents: l,
576                    ty: l_type,
577                },
578                Value::Option {
579                    contents: r,
580                    ty: r_type,
581                },
582            ) if l_type == r_type => Ok(l.is_none() && r.is_none()
583                || l.zip(r).map_or(Ok(false), |(l, r)| {
584                    Rc::unwrap_or_clone(l).eq(Rc::unwrap_or_clone(r))
585                })?),
586            (Value::Type(l), Value::Type(r)) => Ok(l == r),
587            (this, other) => Err(Error::incomparable_values(&this, &other)),
588        }
589    }
590
591    /// # Errors
592    ///
593    /// Returns an error if a mutable reference is being mutably borrowed.
594    ///
595    /// This can be safely ignored by the host if it has not deliberately borrowed an espy value.
596    pub fn type_of(&self) -> Result<ComplexType, Error> {
597        Ok(match &self {
598            Value::Unit => Type::Unit.into(),
599            Value::Tuple(tuple) => {
600                let complex = match &tuple.0 {
601                    TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(
602                        rc_slice_try_from_iter(items.len(), items.iter().map(Value::type_of))?,
603                    )),
604                    TupleStorage::Named(items) => {
605                        Tuple(TupleStorage::Named(rc_slice_try_from_iter(
606                            items.len(),
607                            items.iter().map(|(name, value)| {
608                                value.type_of().map(|value| (name.clone(), value))
609                            }),
610                        )?))
611                    }
612                };
613                // The type of a tuple containing only types is `type`, not `(type, type, ..)`
614                if complex
615                    .values()
616                    .all(|x| matches!(x, ComplexType::Simple(Type::Type)))
617                {
618                    Type::Type.into()
619                } else {
620                    complex.into()
621                }
622            }
623            Value::Borrow(..) | Value::Owned(..) => Type::Any.into(),
624            Value::I64(_) => Type::I64.into(),
625            Value::Bool(_) => Type::Bool.into(),
626            Value::String(_) => Type::String.into(),
627            Value::Function(function) => match &function.action {
628                FunctionAction::With { signature, .. } => {
629                    Type::Function(Rc::new(signature.clone())).into()
630                }
631                _ => Type::Function(Rc::new(FunctionType {
632                    input: Type::Any.into(),
633                    output: Type::Any.into(),
634                }))
635                .into(),
636            },
637            Value::EnumVariant(enum_variant) => Type::Enum(enum_variant.definition.clone()).into(),
638            Value::Option { contents: _, ty } => Type::Option(Rc::new(ty.clone())).into(),
639            Value::Mut(inner) => Type::Mut(
640                inner
641                    .upgrade()
642                    .ok_or(ErrorKind::OutOfScopeMut)?
643                    .try_borrow()
644                    .map_err(Error::other)?
645                    .type_of()?
646                    .into(),
647            )
648            .into(),
649            Value::Type(_) => Type::Type.into(),
650        })
651    }
652
653    #[must_use]
654    pub fn concat(self, r: Self) -> Self {
655        match (self, r) {
656            (
657                Value::Tuple(Tuple(TupleStorage::Numeric(l))),
658                Value::Tuple(Tuple(TupleStorage::Numeric(r))),
659            ) => Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
660                l.len() + r.len(),
661                l.iter().chain(r.iter()).cloned(),
662            )))),
663            (
664                Value::Tuple(Tuple(TupleStorage::Named(l))),
665                Value::Tuple(Tuple(TupleStorage::Named(r))),
666            ) => Value::Tuple(Tuple(TupleStorage::Named(rc_slice_from_iter(
667                l.len() + r.len(),
668                l.iter().chain(r.iter()).cloned(),
669            )))),
670            (l, Value::Unit) => l,
671            (Value::Unit, r) => r,
672            (Value::Tuple(Tuple(TupleStorage::Numeric(l))), r) => {
673                Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
674                    l.len() + 1,
675                    l.iter().cloned().chain([r]),
676                ))))
677            }
678            (l, Value::Tuple(Tuple(TupleStorage::Numeric(r)))) => {
679                Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
680                    1 + r.len(),
681                    [l].into_iter().chain(r.iter().cloned()),
682                ))))
683            }
684            (l, r) => Value::Tuple(Tuple(TupleStorage::Numeric(Rc::new([l, r])))),
685        }
686    }
687
688    pub fn borrow(external: &'host dyn Extern) -> Self {
689        Value::Borrow(external, None)
690    }
691
692    pub fn owned(external: Rc<dyn ExternOwned>) -> Self {
693        Value::Owned(external, None)
694    }
695}
696
697impl From<()> for Value<'_> {
698    fn from((): ()) -> Self {
699        Value::Unit
700    }
701}
702
703impl From<Option<()>> for Value<'_> {
704    fn from(value: Option<()>) -> Self {
705        Value::Option {
706            contents: value.map(|()| Rc::new(Value::Unit)),
707            ty: Type::Unit.into(),
708        }
709    }
710}
711
712impl From<bool> for Value<'_> {
713    fn from(value: bool) -> Self {
714        Value::Bool(value)
715    }
716}
717
718impl From<Option<bool>> for Value<'_> {
719    fn from(value: Option<bool>) -> Self {
720        Value::Option {
721            contents: value.map(|value| Rc::new(Value::Bool(value))),
722            ty: Type::Bool.into(),
723        }
724    }
725}
726
727impl From<i64> for Value<'_> {
728    fn from(i: i64) -> Self {
729        Value::I64(i)
730    }
731}
732
733impl From<Option<i64>> for Value<'_> {
734    fn from(value: Option<i64>) -> Self {
735        Value::Option {
736            contents: value.map(|value| Rc::new(Value::I64(value))),
737            ty: Type::I64.into(),
738        }
739    }
740}
741
742impl From<&str> for Value<'_> {
743    fn from(s: &str) -> Self {
744        Value::String(Rc::from(s))
745    }
746}
747
748impl From<Rc<str>> for Value<'_> {
749    fn from(s: Rc<str>) -> Self {
750        Value::String(s)
751    }
752}
753
754impl From<Option<&str>> for Value<'_> {
755    fn from(value: Option<&str>) -> Self {
756        Value::Option {
757            contents: value.map(|value| Rc::new(Value::String(Rc::from(value)))),
758            ty: Type::String.into(),
759        }
760    }
761}
762
763impl From<Option<Rc<str>>> for Value<'_> {
764    fn from(value: Option<Rc<str>>) -> Self {
765        Value::Option {
766            contents: value.map(|value| Rc::new(Value::String(value))),
767            ty: Type::String.into(),
768        }
769    }
770}
771
772impl<'host> From<Rc<[Value<'host>]>> for Value<'host> {
773    fn from(value: Rc<[Value<'host>]>) -> Self {
774        Self::Tuple(Tuple::from(value))
775    }
776}
777
778impl<'host, T: Into<Value<'host>>, const N: usize> From<[T; N]> for Value<'host> {
779    fn from(value: [T; N]) -> Self {
780        let slice = rc_slice_from_iter(value.len(), value.into_iter().map(Into::into));
781        Self::Tuple(Tuple::from(slice))
782    }
783}
784
785impl<'host> From<Rc<[(Rc<str>, Value<'host>)]>> for Value<'host> {
786    fn from(value: Rc<[(Rc<str>, Value<'host>)]>) -> Self {
787        Self::Tuple(Tuple::from(value))
788    }
789}
790
791impl<'host, K: Into<Rc<str>>, const N: usize> From<[(K, Value<'host>); N]> for Value<'host> {
792    fn from(value: [(K, Value<'host>); N]) -> Self {
793        Self::Tuple(Tuple::from(value))
794    }
795}
796
797impl<'host> From<Option<Value<'host>>> for Value<'host> {
798    fn from(value: Option<Self>) -> Self {
799        value.map(Rc::new).into()
800    }
801}
802
803impl<'host> From<Option<Rc<Value<'host>>>> for Value<'host> {
804    fn from(value: Option<Rc<Self>>) -> Self {
805        Value::Option {
806            contents: value,
807            ty: Type::String.into(),
808        }
809    }
810}
811
812impl<'host> From<Rc<Function<'host>>> for Value<'host> {
813    fn from(f: Rc<Function<'host>>) -> Self {
814        Value::Function(f)
815    }
816}
817
818impl<'host> From<Function<'host>> for Value<'host> {
819    fn from(f: Function<'host>) -> Self {
820        Rc::new(f).into()
821    }
822}
823
824impl<'host> TryFrom<Value<'host>> for () {
825    type Error = Error;
826
827    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
828        if let Value::Unit = value {
829            Ok(())
830        } else {
831            Err(Error::type_error(&value, &Type::Unit.into()))
832        }
833    }
834}
835
836impl<'host> TryFrom<Value<'host>> for Tuple<Value<'host>> {
837    type Error = Error;
838
839    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
840        if let Value::Tuple(value) = value {
841            Ok(value)
842        } else {
843            Err(Error::expected_tuple(&value))
844        }
845    }
846}
847
848impl<'host> TryFrom<Value<'host>> for bool {
849    type Error = Error;
850
851    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
852        if let Value::Bool(bool) = value {
853            Ok(bool)
854        } else {
855            Err(Error::type_error(&value, &Type::Unit.into()))
856        }
857    }
858}
859
860impl<'host> TryFrom<Value<'host>> for i64 {
861    type Error = Error;
862
863    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
864        if let Value::I64(value) = value {
865            Ok(value)
866        } else {
867            Err(Error::type_error(&value, &Type::I64.into()))
868        }
869    }
870}
871
872impl<'host> TryFrom<Value<'host>> for Rc<str> {
873    type Error = Error;
874
875    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
876        if let Value::String(value) = value {
877            Ok(value)
878        } else {
879            Err(Error::type_error(&value, &Type::String.into()))
880        }
881    }
882}
883
884impl<'host> TryFrom<Value<'host>> for Rc<Function<'host>> {
885    type Error = Error;
886    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
887        if let Value::Function(value) = value {
888            Ok(value)
889        } else {
890            Err(Error::expected_function(&value))
891        }
892    }
893}
894
895impl<'host> TryFrom<Value<'host>> for Function<'host> {
896    type Error = Error;
897
898    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
899        Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
900    }
901}
902
903impl<'host> TryFrom<Value<'host>> for Rc<EnumVariant<'host>> {
904    type Error = Error;
905    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
906        if let Value::EnumVariant(value) = value {
907            Ok(value)
908        } else {
909            Err(Error::expected_enum_variant(&value))
910        }
911    }
912}
913
914impl<'host> TryFrom<Value<'host>> for EnumVariant<'host> {
915    type Error = Error;
916
917    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
918        Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
919    }
920}
921
922impl<'host> TryFrom<Value<'host>> for ComplexType {
923    type Error = Error;
924
925    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
926        match value {
927            Value::Type(t) => Ok(t.into()),
928            Value::Tuple(tuple) => Ok(ComplexType::Complex(tuple.try_into()?)),
929            _ => Err(Error::type_error(&value, &Type::Type.into())),
930        }
931    }
932}
933
934impl<'host> TryFrom<Value<'host>> for Rc<EnumType> {
935    type Error = Error;
936    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
937        if let Value::Type(Type::Enum(value)) = value {
938            Ok(value)
939        } else {
940            Err(Error::expected_enum_type(&value))
941        }
942    }
943}
944
945impl<'host> TryFrom<Value<'host>> for EnumType {
946    type Error = Error;
947
948    fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
949        Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
950    }
951}
952
953/// [`TryInto`] shortcuts
954impl<'host> Value<'host> {
955    /// # Errors
956    ///
957    /// Returns an error if `self` is not a [`Value::Unit`]
958    pub fn into_unit(self) -> Result<(), Error> {
959        self.try_into()
960    }
961
962    /// # Errors
963    ///
964    /// Returns an error if `self` is not a [`Value::Tuple`]
965    pub fn into_tuple(self) -> Result<Tuple<Value<'host>>, Error> {
966        self.try_into()
967    }
968
969    /// Turns this value into a vector of values.
970    ///
971    /// [`Value::Tuple`]'s members will be collected into the vector.
972    /// [`Value::Unit`] will produce an empty vector.
973    /// All other variants will produce a vector with just one member.
974    pub fn into_vec(self) -> Vec<Value<'host>> {
975        match self {
976            Value::Unit => Vec::new(),
977            Value::Tuple(tup) => tup.values().map(Value::clone).collect(),
978            _ => Vec::from([self]),
979        }
980    }
981
982    /// # Errors
983    ///
984    /// Returns an error if `self` is not a [`Value::Bool`]
985    pub fn into_bool(self) -> Result<bool, Error> {
986        self.try_into()
987    }
988
989    /// # Errors
990    ///
991    /// Returns an error if `self` is not a [`Value::I64`]
992    pub fn into_i64(self) -> Result<i64, Error> {
993        self.try_into()
994    }
995
996    /// # Errors
997    ///
998    /// Returns an error if `self` is not a [`Value::String`]
999    pub fn into_str(self) -> Result<Rc<str>, Error> {
1000        self.try_into()
1001    }
1002
1003    #[must_use]
1004    pub fn as_str(&self) -> Option<&str> {
1005        if let Value::String(s) = &self {
1006            Some(s)
1007        } else {
1008            None
1009        }
1010    }
1011
1012    /// # Errors
1013    ///
1014    /// Returns an error if `self` is not a [`Value::Function`]
1015    pub fn into_function(self) -> Result<Function<'host>, Error> {
1016        self.try_into()
1017    }
1018
1019    /// # Errors
1020    ///
1021    /// Returns an error if `self` is not a [`Value::EnumVariant`]
1022    pub fn into_enum_variant(self) -> Result<Rc<EnumVariant<'host>>, Error> {
1023        self.try_into()
1024    }
1025
1026    /// # Errors
1027    ///
1028    /// Returns an error if `self` is not a [`Value::Option`]
1029    pub fn into_option(self) -> Result<Option<Value<'host>>, Error> {
1030        match self {
1031            Value::Option { contents, ty: _ } => Ok(contents.map(|x| (*x).clone())),
1032            _ => Err(Error::expected_option(&self)),
1033        }
1034    }
1035
1036    /// # Errors
1037    ///
1038    /// Returns an error if `self` is not a [`Value::Mut`]
1039    pub fn into_refcell(self) -> Result<Rc<RefCell<Value<'host>>>, Error> {
1040        match &self {
1041            Value::Mut(inner) => Ok(inner.upgrade().ok_or(ErrorKind::OutOfScopeMut)?),
1042            _ => Err(Error::expected_reference(&self)),
1043        }
1044    }
1045
1046    /// # Errors
1047    ///
1048    /// Returns an error if `self` is not a [`Value::Type`] or [`Value::Tuple`] or types.
1049    pub fn into_complex_type(self) -> Result<ComplexType, Error> {
1050        self.try_into()
1051    }
1052
1053    /// # Errors
1054    ///
1055    /// Returns an error if `self` is not a [`Value::Type`] containing a [`Type::Enum`]
1056    pub fn into_enum_type(self) -> Result<Rc<EnumType>, Error> {
1057        self.try_into()
1058    }
1059}
1060
1061#[derive(Clone, Debug, PartialEq, Eq)]
1062enum TupleStorage<T> {
1063    Numeric(Rc<[T]>),
1064    Named(Rc<[(Rc<str>, T)]>),
1065}
1066
1067/// This type is used to store anything shaped like an espy tuple.
1068///
1069/// This includes:
1070/// - Tuple<[`Value`]> (an espy tuple)
1071/// - Tuple<[`StaticValue`]> (an espy tuple with a static lifetime)
1072/// - Tuple<[`ComplexType`]> (the type of an espy tuple)
1073///
1074/// It is either a "numeric" tuple (indexed only by order) or a "named" tuple
1075/// (indexed by both order and name).
1076#[derive(Clone, Debug, PartialEq, Eq)]
1077pub struct Tuple<T>(TupleStorage<T>);
1078
1079impl<T> Tuple<T> {
1080    #[must_use]
1081    pub fn len(&self) -> usize {
1082        match &self.0 {
1083            TupleStorage::Numeric(items) => items.len(),
1084            TupleStorage::Named(items) => items.len(),
1085        }
1086    }
1087
1088    #[must_use]
1089    pub fn is_empty(&self) -> bool {
1090        self.len() == 0
1091    }
1092
1093    #[must_use]
1094    pub fn value(&self, index: usize) -> Option<&T> {
1095        match &self.0 {
1096            TupleStorage::Numeric(items) => items.get(index),
1097            TupleStorage::Named(items) => items.get(index).map(|(_name, value)| value),
1098        }
1099    }
1100
1101    #[must_use]
1102    pub fn find_value(&self, name: &str) -> Option<&T> {
1103        let TupleStorage::Named(items) = &self.0 else {
1104            return None;
1105        };
1106        items
1107            .iter()
1108            .find_map(|(n, v)| if **n == *name { Some(v) } else { None })
1109    }
1110
1111    pub fn values(&self) -> impl Iterator<Item = &T> {
1112        (0..self.len()).map(|i| match &self.0 {
1113            TupleStorage::Numeric(items) => &items[i],
1114            TupleStorage::Named(items) => &items[i].1,
1115        })
1116    }
1117
1118    #[must_use]
1119    pub fn as_numeric(&self) -> Option<&[T]> {
1120        match &self.0 {
1121            TupleStorage::Numeric(items) => Some(items),
1122            TupleStorage::Named(_) => None,
1123        }
1124    }
1125
1126    #[must_use]
1127    pub fn as_named(&self) -> Option<&[(Rc<str>, T)]> {
1128        match &self.0 {
1129            TupleStorage::Numeric(_) => None,
1130            TupleStorage::Named(items) => Some(items),
1131        }
1132    }
1133}
1134
1135impl<'host> Tuple<Value<'host>> {
1136    fn to_static(&self) -> Option<Tuple<StaticValue>> {
1137        match &self.0 {
1138            TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1139                items.len(),
1140                items
1141                    .iter()
1142                    .map(|value: &Value| value.to_static().ok_or(())),
1143            )
1144            .map(TupleStorage::Numeric)
1145            .map(Tuple)
1146            .ok(),
1147            TupleStorage::Named(items) => rc_slice_try_from_iter(
1148                items.len(),
1149                items.iter().map(|(name, value)| {
1150                    value
1151                        .to_static()
1152                        .map(|value| (name.clone(), value))
1153                        .ok_or(())
1154                }),
1155            )
1156            .map(TupleStorage::Named)
1157            .map(Tuple)
1158            .ok(),
1159        }
1160    }
1161}
1162
1163impl Tuple<StaticValue> {
1164    #[must_use]
1165    pub fn to_runtime<'host>(&self) -> Tuple<Value<'host>> {
1166        match &self.0 {
1167            TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(rc_slice_from_iter(
1168                items.len(),
1169                items.iter().map(Value::from),
1170            ))),
1171            TupleStorage::Named(items) => Tuple(TupleStorage::Named(rc_slice_from_iter(
1172                items.len(),
1173                items
1174                    .iter()
1175                    .map(|(name, value)| (name.clone(), value.into())),
1176            ))),
1177        }
1178    }
1179}
1180
1181impl<'host, T: Borrow<Tuple<StaticValue>>> From<T> for Tuple<Value<'host>> {
1182    fn from(value: T) -> Self {
1183        value.borrow().to_runtime()
1184    }
1185}
1186
1187impl<'host> TryFrom<Tuple<Value<'host>>> for Tuple<ComplexType> {
1188    type Error = Error;
1189
1190    fn try_from(tuple: Tuple<Value<'host>>) -> Result<Self, Self::Error> {
1191        match &tuple.0 {
1192            TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1193                items.len(),
1194                items.iter().map(|value| value.clone().try_into()),
1195            )
1196            .map(TupleStorage::Numeric)
1197            .map(Tuple),
1198            TupleStorage::Named(items) => rc_slice_try_from_iter(
1199                items.len(),
1200                items.iter().map(|(name, value)| {
1201                    value.clone().try_into().map(|value| (name.clone(), value))
1202                }),
1203            )
1204            .map(TupleStorage::Named)
1205            .map(Tuple),
1206        }
1207    }
1208}
1209
1210impl From<Tuple<ComplexType>> for Tuple<Value<'_>> {
1211    fn from(tuple: Tuple<ComplexType>) -> Self {
1212        match &tuple.0 {
1213            TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(rc_slice_from_iter(
1214                items.len(),
1215                items.iter().map(|value| value.clone().into()),
1216            ))),
1217            TupleStorage::Named(items) => Tuple(TupleStorage::Named(rc_slice_from_iter(
1218                items.len(),
1219                items
1220                    .iter()
1221                    .map(|(name, value)| (name.clone(), value.clone().into())),
1222            ))),
1223        }
1224    }
1225}
1226
1227impl<'host> TryFrom<Tuple<Value<'host>>> for Tuple<Function<'host>> {
1228    type Error = Error;
1229
1230    fn try_from(tuple: Tuple<Value<'host>>) -> Result<Self, Self::Error> {
1231        match &tuple.0 {
1232            TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1233                items.len(),
1234                items.iter().map(|value| value.clone().try_into()),
1235            )
1236            .map(TupleStorage::Numeric)
1237            .map(Tuple),
1238            TupleStorage::Named(items) => rc_slice_try_from_iter(
1239                items.len(),
1240                items.iter().map(|(name, value)| {
1241                    value.clone().try_into().map(|value| (name.clone(), value))
1242                }),
1243            )
1244            .map(TupleStorage::Named)
1245            .map(Tuple),
1246        }
1247    }
1248}
1249
1250impl<T> From<Rc<[T]>> for Tuple<T> {
1251    fn from(value: Rc<[T]>) -> Self {
1252        Self(TupleStorage::Numeric(value))
1253    }
1254}
1255
1256impl<const N: usize, T> From<[T; N]> for Tuple<T> {
1257    fn from(value: [T; N]) -> Self {
1258        Self(TupleStorage::Numeric(Rc::from(value)))
1259    }
1260}
1261
1262impl<T> From<Rc<[(Rc<str>, T)]>> for Tuple<T> {
1263    fn from(value: Rc<[(Rc<str>, T)]>) -> Self {
1264        Self(TupleStorage::Named(value))
1265    }
1266}
1267
1268impl<const N: usize, K: Into<Rc<str>>, T> From<[(K, T); N]> for Tuple<T> {
1269    fn from(value: [(K, T); N]) -> Self {
1270        let slice = rc_slice_from_iter(value.len(), value.into_iter().map(|(k, v)| (k.into(), v)));
1271        Self(TupleStorage::Named(slice))
1272    }
1273}
1274
1275/// An function which is callable by espy or its host.
1276///
1277/// This differs from [`Program`] in that it may accept an argument;
1278/// use [`Function::pipe`] or [`Function::piped`] to provide one,
1279/// and [`Function::eval`] to evaluate the function.
1280///
1281/// To instead provide a Rust function to espy, use [`Function::borrow`] or
1282/// [`Function::owned`] with the [`ExternFn`] and [`ExternFnOwned`] traits,
1283/// respectively.
1284#[derive(Clone, Debug)]
1285pub struct Function<'host> {
1286    action: FunctionAction<'host>,
1287    argument: Value<'host>,
1288}
1289
1290/// A version of [`Function`] with a static lifetime.
1291///
1292/// See [`StaticValue`] for the difference between this and [`Function<'static>`].
1293#[derive(Clone)]
1294pub struct StaticFunction {
1295    action: StaticFunctionAction,
1296    argument: StaticValue,
1297}
1298
1299impl std::fmt::Debug for StaticFunction {
1300    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1301        write!(f, "{:?}", self.to_runtime())
1302    }
1303}
1304
1305impl StaticFunction {
1306    #[must_use]
1307    pub fn to_runtime<'host>(&self) -> Function<'host> {
1308        Function {
1309            action: match &self.action {
1310                StaticFunctionAction::With {
1311                    program,
1312                    block_id,
1313                    program_counter,
1314                    signature,
1315                    captures,
1316                } => FunctionAction::With {
1317                    program: program.clone(),
1318                    block_id: *block_id,
1319                    program_counter: *program_counter,
1320                    signature: signature.clone(),
1321                    captures: rc_slice_from_iter(
1322                        captures.len(),
1323                        captures
1324                            .iter()
1325                            .map(|value: &StaticValue| value.clone().into()),
1326                    ),
1327                },
1328                StaticFunctionAction::Never { signature } => FunctionAction::Never {
1329                    signature: signature.clone(),
1330                },
1331                StaticFunctionAction::Enum {
1332                    variant,
1333                    definition,
1334                } => FunctionAction::Enum {
1335                    variant: *variant,
1336                    definition: definition.clone(),
1337                },
1338                StaticFunctionAction::Mut => FunctionAction::Mut,
1339                StaticFunctionAction::OptionConstructor => FunctionAction::OptionConstructor,
1340                StaticFunctionAction::OptionCase { some, ty } => FunctionAction::OptionCase {
1341                    some: *some,
1342                    ty: ty.clone(),
1343                },
1344                StaticFunctionAction::Borrow(extern_fn) => FunctionAction::Borrow(*extern_fn),
1345                StaticFunctionAction::Owned(extern_fn_owned) => {
1346                    FunctionAction::Owned(extern_fn_owned.clone())
1347                }
1348            },
1349            argument: self.argument.to_runtime(),
1350        }
1351    }
1352}
1353
1354impl<'host, T: Borrow<StaticFunction>> From<T> for Function<'host> {
1355    fn from(value: T) -> Self {
1356        value.borrow().to_runtime()
1357    }
1358}
1359
1360impl StaticFunction {
1361    pub fn borrow(external: &'static dyn ExternFn) -> Self {
1362        StaticFunction {
1363            action: StaticFunctionAction::Borrow(external),
1364            argument: StaticValue::Unit,
1365        }
1366    }
1367
1368    pub fn owned(external: Rc<dyn ExternFnOwned>) -> Self {
1369        StaticFunction {
1370            action: StaticFunctionAction::Owned(external),
1371            argument: StaticValue::Unit,
1372        }
1373    }
1374}
1375
1376impl<'host> Function<'host> {
1377    pub fn borrow(external: &'host dyn ExternFn) -> Self {
1378        Function {
1379            action: FunctionAction::Borrow(external),
1380            argument: ().into(),
1381        }
1382    }
1383
1384    pub fn owned(external: Rc<dyn ExternFnOwned>) -> Self {
1385        Function {
1386            action: FunctionAction::Owned(external),
1387            argument: ().into(),
1388        }
1389    }
1390
1391    #[must_use]
1392    pub fn to_static(&self) -> Option<StaticFunction> {
1393        Some(StaticFunction {
1394            action: match &self.action {
1395                FunctionAction::With {
1396                    program,
1397                    block_id,
1398                    program_counter,
1399                    signature,
1400                    captures,
1401                } => StaticFunctionAction::With {
1402                    program: program.clone(),
1403                    block_id: *block_id,
1404                    program_counter: *program_counter,
1405                    signature: signature.clone(),
1406                    captures: captures
1407                        .iter()
1408                        .map(|x| x.to_static())
1409                        .collect::<Option<_>>()?,
1410                },
1411                FunctionAction::Never { signature } => StaticFunctionAction::Never {
1412                    signature: signature.clone(),
1413                },
1414                FunctionAction::Enum {
1415                    variant,
1416                    definition,
1417                } => StaticFunctionAction::Enum {
1418                    variant: *variant,
1419                    definition: definition.clone(),
1420                },
1421                FunctionAction::Mut => StaticFunctionAction::Mut,
1422                FunctionAction::OptionConstructor => StaticFunctionAction::OptionConstructor,
1423                FunctionAction::OptionCase { some, ty } => StaticFunctionAction::OptionCase {
1424                    some: *some,
1425                    ty: ty.clone(),
1426                },
1427                FunctionAction::Borrow(extern_fn_borrow) => return extern_fn_borrow.to_static(),
1428                FunctionAction::Owned(extern_fn_owned) => {
1429                    StaticFunctionAction::Owned(extern_fn_owned.clone())
1430                }
1431            },
1432            argument: self.argument.to_static()?,
1433        })
1434    }
1435
1436    /// # Errors
1437    ///
1438    /// Returns an error if evaluating the function results in an error
1439    pub fn eval(self) -> Result<Value<'host>, Error> {
1440        let result = match self.action {
1441            FunctionAction::With {
1442                program,
1443                block_id,
1444                program_counter,
1445                signature: FunctionType { input, output },
1446                captures,
1447            } => {
1448                if !self.argument.type_of()?.compare(&input) {
1449                    return Err(Error::type_error(&self.argument, &input));
1450                }
1451                let result =
1452                    program.eval_block(block_id, program_counter, captures, self.argument)?;
1453                if !result.type_of()?.compare(&output) {
1454                    return Err(Error::type_error(&result, &output));
1455                }
1456                result
1457            }
1458            FunctionAction::Never { signature: _ } => {
1459                return Err(ErrorKind::CalledNeverFunction.into());
1460            }
1461            FunctionAction::Enum {
1462                variant,
1463                definition,
1464            } => {
1465                let ty = &definition.variants[variant].1;
1466                if *ty != Type::Any.into() && self.argument.type_of()? != *ty {
1467                    return Err(Error::type_error(&self.argument, ty));
1468                }
1469                Value::EnumVariant(Rc::new(EnumVariant {
1470                    contents: self.argument,
1471                    variant,
1472                    definition,
1473                }))
1474            }
1475            FunctionAction::Mut => {
1476                if let Ok(ty) = ComplexType::try_from(self.argument.clone()) {
1477                    Type::Mut(Rc::new(ty)).into()
1478                } else {
1479                    Value::Mut(Mut::new(Rc::new(RefCell::new(self.argument))))
1480                }
1481            }
1482            FunctionAction::OptionConstructor => {
1483                Type::Option(Rc::new(self.argument.into_complex_type()?)).into()
1484            }
1485            FunctionAction::OptionCase { some: true, ty } => {
1486                if self.argument.type_of()? != ty {
1487                    return Err(Error::type_error(&self.argument, &ty));
1488                }
1489                Value::Option {
1490                    contents: Some(Rc::new(self.argument)),
1491                    ty,
1492                }
1493            }
1494            FunctionAction::OptionCase { some: false, ty } => {
1495                self.argument.into_unit()?;
1496                Value::Option { contents: None, ty }
1497            }
1498            FunctionAction::Borrow(external) => external.call(self.argument)?,
1499            FunctionAction::Owned(external) => external.call(self.argument)?,
1500        };
1501        Ok(result)
1502    }
1503
1504    /// Concatentes the function's argument list with `argument`.
1505    pub fn pipe(&mut self, argument: Value<'host>) {
1506        let mut arguments = ().into();
1507        mem::swap(&mut arguments, &mut self.argument);
1508        arguments = Value::concat(arguments, argument);
1509        mem::swap(&mut arguments, &mut self.argument);
1510    }
1511
1512    #[must_use]
1513    pub fn piped(mut self, argument: Value<'host>) -> Self {
1514        self.pipe(argument);
1515        self
1516    }
1517}
1518
1519#[derive(Clone)]
1520enum FunctionAction<'host> {
1521    With {
1522        program: Program,
1523        block_id: usize,
1524        program_counter: usize,
1525        signature: FunctionType,
1526        captures: Rc<[Value<'host>]>,
1527    },
1528    Never {
1529        signature: FunctionType,
1530    },
1531    Enum {
1532        variant: usize,
1533        definition: Rc<EnumType>,
1534    },
1535    Mut,
1536    OptionConstructor,
1537    OptionCase {
1538        some: bool,
1539        ty: ComplexType,
1540    },
1541    Borrow(&'host dyn ExternFn),
1542    Owned(Rc<dyn ExternFnOwned>),
1543}
1544
1545#[derive(Clone)]
1546enum StaticFunctionAction {
1547    With {
1548        program: Program,
1549        block_id: usize,
1550        program_counter: usize,
1551        signature: FunctionType,
1552        captures: Rc<[StaticValue]>,
1553    },
1554    Never {
1555        signature: FunctionType,
1556    },
1557    Enum {
1558        variant: usize,
1559        definition: Rc<EnumType>,
1560    },
1561    Mut,
1562    OptionConstructor,
1563    OptionCase {
1564        some: bool,
1565        ty: ComplexType,
1566    },
1567    Borrow(&'static dyn ExternFn),
1568    Owned(Rc<dyn ExternFnOwned>),
1569}
1570
1571impl<'host> From<FunctionAction<'host>> for Function<'host> {
1572    fn from(action: FunctionAction<'host>) -> Self {
1573        Self {
1574            action,
1575            argument: ().into(),
1576        }
1577    }
1578}
1579
1580impl std::fmt::Debug for FunctionAction<'_> {
1581    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1582        match self {
1583            Self::With {
1584                program,
1585                block_id,
1586                program_counter,
1587                signature,
1588                captures,
1589            } => f
1590                .debug_struct("Block")
1591                .field("program", &Rc::as_ptr(&program.bytes))
1592                .field("block_id", block_id)
1593                .field("program_counter", program_counter)
1594                .field("signature", signature)
1595                .field("captures", captures)
1596                .finish(),
1597            Self::Never { signature } => f
1598                .debug_struct("Never")
1599                .field("signature", signature)
1600                .finish(),
1601            Self::Enum {
1602                variant,
1603                definition,
1604            } => f
1605                .debug_struct("Enum")
1606                .field("variant", variant)
1607                .field("definition", definition)
1608                .finish(),
1609            Self::Mut => write!(f, "Mut"),
1610            Self::OptionConstructor => write!(f, "Option"),
1611            Self::OptionCase { some: true, ty } => f.debug_tuple("Some").field(ty).finish(),
1612            Self::OptionCase { some: false, ty } => f.debug_tuple("None").field(ty).finish(),
1613            Self::Borrow(arg0) => arg0.debug(f),
1614            Self::Owned(arg0) => arg0.debug(f),
1615        }
1616    }
1617}
1618
1619#[derive(Debug)]
1620enum MutRefSource<'host> {
1621    Origin(Rc<RefCell<Value<'host>>>),
1622    Child(Weak<RefCell<Value<'host>>>),
1623}
1624
1625/// A mutable reference to an espy value.
1626///
1627/// espy does not have inherited mutability, only interior mutability.
1628/// This means that [`Mut`] contains a [`RefCell`].
1629///
1630/// Only the original [`Mut`] contains a strong [`Rc`] to its contained
1631/// value; any time the mutable reference is copied the copy is instead a weak
1632/// reference. This prevents reference cycles from being constructed by espy
1633/// programs to leak memory. However, [`Mut::upgrade`] is provided for hosts to
1634/// upgrade weak references into strong ones should the need arise.
1635#[derive(Debug)]
1636pub struct Mut<'host> {
1637    source: MutRefSource<'host>,
1638}
1639
1640impl<'host> Mut<'host> {
1641    pub fn new(rc: Rc<RefCell<Value<'host>>>) -> Self {
1642        Self {
1643            source: MutRefSource::Origin(rc),
1644        }
1645    }
1646
1647    /// Creates a strong reference to the mutable reference's origin if it still exists.
1648    ///
1649    /// This can be used to create reference cycles and leak memory,
1650    /// so it should only be exposed to trusted espy programs.
1651    #[must_use]
1652    pub fn upgrade(&self) -> Option<Rc<RefCell<Value<'host>>>> {
1653        match &self.source {
1654            MutRefSource::Origin(rc) => Some(rc.clone()),
1655            MutRefSource::Child(weak) => weak.upgrade(),
1656        }
1657    }
1658}
1659
1660impl Clone for Mut<'_> {
1661    fn clone(&self) -> Self {
1662        Self {
1663            source: MutRefSource::Child(match &self.source {
1664                MutRefSource::Origin(rc) => Rc::downgrade(rc),
1665                MutRefSource::Child(weak) => weak.clone(),
1666            }),
1667        }
1668    }
1669}
1670
1671/// The combined type of a [`Function`]'s input and output.
1672#[derive(Clone, Debug)]
1673pub struct FunctionType {
1674    pub input: ComplexType,
1675    pub output: ComplexType,
1676}
1677
1678/// An instance of an [`EnumType`].
1679///
1680/// Use [`EnumVariant::variant`] to determine which variant this is intended to be,
1681/// and [`EnumVariant::contents`] to read that variant's value.
1682///
1683/// If you're interested in the [`EnumType`] this variant corresponds to, you
1684/// can use [`EnumVariant::definition`]. Conversely if you care only about the
1685/// enum's reported name and value and not the type it originated from, use
1686/// [`EnumVariant::unwrap`].
1687#[derive(Clone, Debug)]
1688pub struct EnumVariant<'host> {
1689    contents: Value<'host>,
1690    variant: usize,
1691    definition: Rc<EnumType>,
1692}
1693
1694/// A version of [`EnumVariant`] with a static lifetime.
1695///
1696/// See [`StaticValue`] for the difference between this and [`EnumVariant<'static>`].
1697#[derive(Clone, Debug)]
1698pub struct StaticEnumVariant {
1699    contents: StaticValue,
1700    variant: usize,
1701    definition: Rc<EnumType>,
1702}
1703
1704impl StaticEnumVariant {
1705    #[must_use]
1706    pub fn to_runtime<'host>(&self) -> EnumVariant<'host> {
1707        EnumVariant {
1708            contents: self.contents.to_runtime(),
1709            variant: self.variant,
1710            definition: self.definition.clone(),
1711        }
1712    }
1713}
1714
1715impl<'host, T: Borrow<StaticEnumVariant>> From<T> for EnumVariant<'host> {
1716    fn from(value: T) -> Self {
1717        value.borrow().to_runtime()
1718    }
1719}
1720
1721impl<'host> EnumVariant<'host> {
1722    #[must_use]
1723    pub fn contents(&self) -> &Value<'host> {
1724        &self.contents
1725    }
1726
1727    #[must_use]
1728    pub fn definition(&self) -> &Rc<EnumType> {
1729        &self.definition
1730    }
1731
1732    #[must_use]
1733    pub fn variant(&self) -> usize {
1734        self.variant
1735    }
1736
1737    #[must_use]
1738    pub fn unwrap(self) -> (Rc<str>, Value<'host>) {
1739        (
1740            self.definition.variants[self.variant].0.clone(),
1741            self.contents,
1742        )
1743    }
1744}
1745
1746/// The definition of an espy enum.
1747///
1748/// See [`EnumVariant`] also.
1749#[derive(Clone, Debug, PartialEq, Eq)]
1750pub struct EnumType {
1751    pub variants: Rc<[(Rc<str>, ComplexType)]>,
1752}
1753
1754impl From<Rc<EnumType>> for Type {
1755    fn from(value: Rc<EnumType>) -> Self {
1756        Type::Enum(value)
1757    }
1758}
1759
1760impl From<EnumType> for Type {
1761    fn from(value: EnumType) -> Self {
1762        Rc::new(value).into()
1763    }
1764}
1765
1766/// Reads a u32 and casts it to usize for convenience.
1767fn read_header(bytes: &[u8], at: usize) -> Result<usize, InvalidBytecode> {
1768    let (((a, b), c), d) = bytes
1769        .get(at)
1770        .zip(bytes.get(at + 1))
1771        .zip(bytes.get(at + 2))
1772        .zip(bytes.get(at + 3))
1773        .ok_or(InvalidBytecode::MalformedHeader)?;
1774    Ok(u32::from_le_bytes([*a, *b, *c, *d]) as usize)
1775}
1776
1777fn block_count(bytes: &[u8]) -> Result<usize, InvalidBytecode> {
1778    read_header(bytes, 0)
1779}
1780
1781fn string_count(bytes: &[u8]) -> Result<usize, InvalidBytecode> {
1782    read_header(bytes, size_of::<u32>())
1783}
1784
1785fn offsets(bytes: &[u8]) -> Result<&[u8], InvalidBytecode> {
1786    let offset_count = block_count(bytes)? + string_count(bytes)?;
1787    let first_offset = size_of::<u32>() * 2;
1788    let last_offset = first_offset + size_of::<u32>() * offset_count;
1789    bytes
1790        .get(first_offset..last_offset)
1791        .ok_or(InvalidBytecode::MalformedHeader)
1792}
1793
1794fn block(bytes: &[u8], block_id: usize) -> Result<&[u8], InvalidBytecode> {
1795    let offsets = offsets(bytes)?;
1796    let block_position = size_of::<u32>() * block_id;
1797    let start = read_header(offsets, block_position)?;
1798    let end = read_header(offsets, size_of::<u32>() + block_position).unwrap_or(bytes.len());
1799    bytes
1800        .get(start..end)
1801        .ok_or(InvalidBytecode::MalformedHeader)
1802}
1803
1804struct Frame<'a, 'host> {
1805    bytecode: &'a [u8],
1806    pc: usize,
1807    captures: Option<(Rc<[Value<'host>]>, NonZero<usize>)>,
1808    stack: Vec<Value<'host>>,
1809}
1810
1811impl<'host> Frame<'_, 'host> {
1812    fn next(&mut self) -> Result<u8, InvalidBytecode> {
1813        let next = self
1814            .bytecode
1815            .get(self.pc)
1816            .ok_or(InvalidBytecode::ProgramOutOfBounds)?;
1817        self.pc += 1;
1818        Ok(*next)
1819    }
1820
1821    fn next4(&mut self) -> Result<usize, InvalidBytecode> {
1822        Ok(u32::from_le_bytes([self.next()?, self.next()?, self.next()?, self.next()?]) as usize)
1823    }
1824
1825    fn next_i64(&mut self) -> Result<i64, InvalidBytecode> {
1826        Ok(i64::from_le_bytes([
1827            self.next()?,
1828            self.next()?,
1829            self.next()?,
1830            self.next()?,
1831            self.next()?,
1832            self.next()?,
1833            self.next()?,
1834            self.next()?,
1835        ]))
1836    }
1837
1838    fn stack_len(&self) -> usize {
1839        self.captures
1840            .as_ref()
1841            .map_or(0, |captures| captures.1.into())
1842            + self.stack.len()
1843    }
1844
1845    fn get(&self, index: usize) -> Result<&Value<'host>, InvalidBytecode> {
1846        if let Some((captures, len)) = &self.captures {
1847            if index < usize::from(*len) {
1848                captures.get(index)
1849            } else {
1850                self.stack.get(index - usize::from(*len))
1851            }
1852        } else {
1853            self.stack.get(index)
1854        }
1855        .ok_or(InvalidBytecode::StackOutOfBounds)
1856    }
1857
1858    fn push(&'_ mut self, value: Value<'host>) {
1859        self.stack.push(value);
1860    }
1861
1862    fn pop(&'_ mut self) -> Result<Value<'host>, Error> {
1863        self.stack.pop().map_or_else(
1864            || {
1865                if let Some((captures, len)) = &mut self.captures {
1866                    let capture = captures[usize::from(*len) - 1].clone();
1867                    if let Ok(new_len) = NonZero::try_from(usize::from(*len) - 1) {
1868                        *len = new_len;
1869                    } else {
1870                        self.captures = None;
1871                    }
1872                    Ok(capture)
1873                } else {
1874                    Err(InvalidBytecode::StackUnderflow.into())
1875                }
1876            },
1877            Ok,
1878        )
1879    }
1880
1881    fn into_bind(mut self, program: Program, block_id: usize) -> Result<Value<'host>, Error> {
1882        Ok(Value::Tuple(
1883            [
1884                self.pop()?,
1885                Function {
1886                    action: FunctionAction::With {
1887                        program,
1888                        block_id,
1889                        program_counter: self.pc,
1890                        signature: FunctionType {
1891                            input: Type::Any.into(),
1892                            output: Type::Any.into(),
1893                        },
1894                        captures: rc_slice_from_iter(
1895                            self.stack_len(),
1896                            self.captures
1897                                .iter()
1898                                .flat_map(|captures| {
1899                                    captures.0[0..captures.1.into()].iter().cloned()
1900                                })
1901                                .chain(self.stack),
1902                        ),
1903                    },
1904                    argument: Value::Unit,
1905                }
1906                .into(),
1907            ]
1908            .into(),
1909        ))
1910    }
1911}
1912
1913enum StepOutcome<'a, 'host> {
1914    Frame(Frame<'a, 'host>),
1915    Yield(Value<'host>),
1916}
1917
1918/// An espy program which has been loaded into memory and is ready to be executed.
1919///
1920/// This program will be kept alive by any [`Function`]s it produces. If you
1921/// intend on returning a small function from a large program and are concerned
1922/// about the memory usage, consider moving that function and its dependencies
1923/// to its own program, whose memory can then be managed separately.
1924#[derive(Clone, Debug)]
1925pub struct Program {
1926    pub(crate) bytes: Rc<[u8]>,
1927    owned_strings: Rc<[Rc<str>]>,
1928}
1929
1930impl TryFrom<Rc<[u8]>> for Program {
1931    type Error = Error;
1932
1933    fn try_from(bytes: Rc<[u8]>) -> Result<Self, Self::Error> {
1934        let string_count = string_count(&bytes)?;
1935        let owned_strings = (0..string_count)
1936            .map(|string| {
1937                let string = size_of::<u32>() * (string + block_count(&bytes)?);
1938                let offsets = offsets(&bytes)?;
1939                let start = read_header(offsets, string)?;
1940                let end = read_header(offsets, size_of::<u32>() + string).unwrap_or(bytes.len());
1941                let string_bytes = bytes
1942                    .get(start..end)
1943                    .ok_or(InvalidBytecode::MalformedHeader)?;
1944                let string = str::from_utf8(string_bytes).map_err(InvalidBytecode::Utf8Error)?;
1945                Ok(Rc::from(string))
1946            })
1947            .collect::<Result<_, Error>>()?;
1948        Ok(Self {
1949            bytes,
1950            owned_strings,
1951        })
1952    }
1953}
1954
1955impl Program {
1956    /// # Errors
1957    ///
1958    /// Returns an error if the evaluating the program results in an error
1959    pub fn eval<'host>(&self) -> Result<Value<'host>, Error> {
1960        self.eval_block(0, 0, None, None)
1961    }
1962
1963    fn eval_block<'host>(
1964        &self,
1965        block_id: usize,
1966        program_counter: usize,
1967        captures: impl Into<Option<Rc<[Value<'host>]>>>,
1968        argument: impl Into<Option<Value<'host>>>,
1969    ) -> Result<Value<'host>, Error> {
1970        let captures = captures
1971            .into()
1972            .and_then(|x| x.len().try_into().ok().map(|len| (x, len)));
1973        let mut frame = Frame {
1974            bytecode: block(&self.bytes, block_id)?,
1975            pc: program_counter,
1976            captures,
1977            stack: argument.into().into_iter().collect(),
1978        };
1979        // Program counter, ignoring block boundries.
1980        let absolute_program_counter =
1981            frame.bytecode.as_ptr() as usize - block(&self.bytes, 0)?.as_ptr() as usize;
1982
1983        // The program counter reaching the first (and only the first)
1984        // out-of-bounds byte should be considered a return.
1985        while frame.pc != frame.bytecode.len() {
1986            let pc = frame.pc;
1987            frame = match self
1988                .eval_step(block_id, frame)
1989                .map_err(|e| e.suggest_location(absolute_program_counter + pc))?
1990            {
1991                StepOutcome::Frame(frame) => frame,
1992                StepOutcome::Yield(value) => return Ok(value),
1993            }
1994        }
1995        frame.pop()
1996    }
1997
1998    fn eval_step<'a, 'host>(
1999        &self,
2000        block_id: usize,
2001        mut frame: Frame<'a, 'host>,
2002    ) -> Result<StepOutcome<'a, 'host>, Error> {
2003        macro_rules! bi_op {
2004            (let $l:ident, $r:ident: $type:ident => $expr_type:ident: $expr:expr) => {{
2005                let $r = frame.pop()?;
2006                let $l = frame.pop()?;
2007                match (&$l, &$r) {
2008                    (Value::$type($l), Value::$type($r)) => frame.push(Value::$expr_type($expr)),
2009                    _ => return Err(Error::expected_integers(&$l, &$r)),
2010                }
2011            }};
2012        }
2013        macro_rules! bi_num {
2014            (let $l:ident, $r:ident => $expr:expr) => {
2015                bi_op!(let $l, $r: I64 => I64: $expr)
2016            };
2017        }
2018        macro_rules! bi_cmp {
2019            (let $l:ident, $r:ident => $expr:expr) => {
2020                bi_op!(let $l, $r: I64 => Bool: $expr)
2021            };
2022        }
2023        let instruction = frame.next()?;
2024        match instruction {
2025            instruction::CLONE => {
2026                let index = frame.next4()?;
2027                #[allow(
2028                    clippy::cast_possible_truncation,
2029                    clippy::cast_possible_wrap,
2030                    reason = "next4 only returns 32 bits"
2031                )]
2032                match index as i32 {
2033                    0.. => {
2034                        let value = frame.get(index)?;
2035                        frame.push(value.clone());
2036                    }
2037                    builtins::ANY => {
2038                        frame.push(Type::Any.into());
2039                    }
2040                    builtins::UNIT => {
2041                        frame.push(Type::Unit.into());
2042                    }
2043                    builtins::I64 => {
2044                        frame.push(Type::I64.into());
2045                    }
2046                    builtins::STRING => {
2047                        frame.push(Type::String.into());
2048                    }
2049                    builtins::OPTION => {
2050                        frame.push(Value::Function(Rc::new(
2051                            FunctionAction::OptionConstructor.into(),
2052                        )));
2053                    }
2054                    builtins::MUT => {
2055                        frame.push(Value::Function(Rc::new(FunctionAction::Mut.into())));
2056                    }
2057                    _ => Err(InvalidBytecode::InvalidBuiltin)?,
2058                }
2059            }
2060            instruction::POP => {
2061                frame.pop()?;
2062            }
2063            instruction::COLLAPSE => {
2064                let value = frame.pop()?;
2065                for _ in 0..(frame.stack_len() - frame.next4()?) {
2066                    frame.pop()?;
2067                }
2068                frame.push(value);
2069            }
2070            instruction::JUMP => {
2071                frame.pc = frame.next4()?;
2072            }
2073            instruction::IF => {
2074                let target = frame.next4()?;
2075                if let Value::Bool(false) = frame.pop()? {
2076                    frame.pc = target;
2077                }
2078            }
2079
2080            instruction::PUSH_UNIT => {
2081                frame.push(().into());
2082            }
2083            instruction::PUSH_TRUE => {
2084                frame.push(true.into());
2085            }
2086            instruction::PUSH_FALSE => {
2087                frame.push(false.into());
2088            }
2089            instruction::PUSH_I64 => {
2090                let i = frame.next_i64()?.into();
2091                frame.push(i);
2092            }
2093            instruction::PUSH_STRING => {
2094                let string_id = frame.next4()?;
2095                let string = self
2096                    .owned_strings
2097                    .get(string_id)
2098                    .ok_or(InvalidBytecode::InvalidStringId)?
2099                    .clone();
2100                frame.push(string.into());
2101            }
2102            instruction::PUSH_FUNCTION => {
2103                let captures = frame.next4()?;
2104                let function = frame.next4()?;
2105                let output = frame.pop()?;
2106                let input = frame.pop()?;
2107                if function == 0 {
2108                    // ignore captures if the function will never be called.
2109                    for _ in 0..captures {
2110                        frame.pop()?;
2111                    }
2112                    frame.push(Value::Function(Rc::new(
2113                        FunctionAction::Never {
2114                            signature: FunctionType {
2115                                input: input.try_into()?,
2116                                output: output.try_into()?,
2117                            },
2118                        }
2119                        .into(),
2120                    )));
2121                } else {
2122                    let new_stack = rc_slice_from_iter(
2123                        captures,
2124                        frame.stack.drain((frame.stack.len() - captures)..),
2125                    );
2126                    frame.push(Value::Function(Rc::new(
2127                        FunctionAction::With {
2128                            program: self.clone(),
2129                            signature: FunctionType {
2130                                input: input.try_into()?,
2131                                output: output.try_into()?,
2132                            },
2133                            block_id: function,
2134                            program_counter: 0,
2135                            captures: new_stack,
2136                        }
2137                        .into(),
2138                    )));
2139                }
2140            }
2141            instruction::PUSH_ENUM => {
2142                let variants = frame.pop()?;
2143                let Value::Tuple(Tuple(TupleStorage::Named(variants))) = variants else {
2144                    Err(Error::expected_named_tuple(&variants))?
2145                };
2146                let variants = rc_slice_try_from_iter(
2147                    variants.len(),
2148                    variants.iter().map(|(name, value)| {
2149                        value.clone().try_into().map(|value| (name.clone(), value))
2150                    }),
2151                )?;
2152                frame.push(Type::from(EnumType { variants }).into());
2153            }
2154
2155            instruction::ADD => bi_num!(let l, r => l + r),
2156            instruction::SUB => bi_num!(let l, r => l - r),
2157            instruction::MUL => bi_num!(let l, r => l * r),
2158            instruction::DIV => bi_num!(let l, r => l / r),
2159            instruction::BITWISE_AND => bi_num!(let l, r => l & r),
2160            instruction::BITWISE_OR => bi_num!(let l, r => l | r),
2161            instruction::BITWISE_XOR => bi_num!(let l, r => l ^ r),
2162            instruction::GREATER => bi_cmp!(let l, r => l > r),
2163            instruction::GREATER_EQUAL => bi_cmp!(let l, r => l >= r),
2164            instruction::LESSER => bi_cmp!(let l, r => l < r),
2165            instruction::LESSER_EQUAL => bi_cmp!(let l, r => l <= r),
2166            instruction::MATCHES => {
2167                let candidate = frame.pop()?;
2168                let subject = frame.pop()?;
2169                if let Value::EnumVariant(subject) = &subject
2170                    && let Value::Function(function) = &candidate
2171                    && let FunctionAction::Enum {
2172                        variant,
2173                        definition,
2174                    } = &function.action
2175                    && subject.definition == *definition
2176                {
2177                    // Destructuring changes the value forwarded to the match arm.
2178                    if subject.variant == *variant {
2179                        frame.pop()?;
2180                        frame.push(subject.contents.clone());
2181
2182                        frame.push(true.into());
2183                    } else {
2184                        frame.push(false.into());
2185                    }
2186                } else if let Value::Option { contents, ty } = &subject
2187                    && let Value::Function(function) = &candidate
2188                    && let FunctionAction::OptionCase {
2189                        some,
2190                        ty: expected_ty,
2191                    } = &function.action
2192                {
2193                    match (contents, some) {
2194                        (Some(contents), true) => {
2195                            if !ty.compare(expected_ty) {
2196                                return Err(Error::type_error(&subject, expected_ty));
2197                            }
2198                            // Destructuring changes the value forwarded to the match arm.
2199                            frame.pop()?;
2200                            frame.push((**contents).clone());
2201                            frame.push(true.into());
2202                        }
2203                        (None, false) => {
2204                            // Destructuring changes the value forwarded to the match arm.
2205                            frame.pop()?;
2206                            frame.push(().into());
2207                            frame.push(true.into());
2208                        }
2209                        _ => {
2210                            frame.push(false.into());
2211                        }
2212                    }
2213                } else {
2214                    frame.push(subject.clone().eq(candidate)?.into());
2215                }
2216            }
2217            instruction::EQUAL_TO => {
2218                let r = frame.pop()?;
2219                let l = frame.pop()?;
2220                frame.push(l.eq(r)?.into());
2221            }
2222            instruction::NOT_EQUAL_TO => {
2223                let r = frame.pop()?;
2224                let l = frame.pop()?;
2225                frame.push((!l.eq(r)?).into());
2226            }
2227            instruction::LOGICAL_AND => bi_op!(let l, r: Bool => Bool: *l && *r),
2228            instruction::LOGICAL_OR => bi_op!(let l, r: Bool => Bool: *l || *r),
2229            instruction::PIPE => {
2230                let mut function = Rc::<Function>::try_from(frame.pop()?)?;
2231                let argument = frame.pop()?;
2232                let function_mut = Rc::make_mut(&mut function);
2233                let mut arguments = ().into();
2234                mem::swap(&mut arguments, &mut function_mut.argument);
2235                arguments = Value::concat(arguments, argument);
2236                mem::swap(&mut arguments, &mut function_mut.argument);
2237                frame.push(Value::Function(function));
2238            }
2239
2240            instruction::CALL => {
2241                let argument = frame.pop()?;
2242                let function = frame.pop()?;
2243                let result = match function {
2244                    Value::Function(function) => Rc::<Function>::try_unwrap(function)
2245                        .unwrap_or_else(|function| (*function).clone())
2246                        .piped(argument)
2247                        .eval()?,
2248                    function => Err(Error::expected_function(&function))?,
2249                };
2250                frame.push(result);
2251            }
2252            instruction::TUPLE => {
2253                let r = frame.pop()?;
2254                let l = frame.pop()?;
2255                frame.push(Value::concat(l, r));
2256            }
2257            instruction::INDEX => {
2258                let index = frame.pop()?;
2259                let container = frame.pop()?;
2260                frame.push(container.index(index)?);
2261            }
2262            instruction::NAME => {
2263                let name_id = frame.next4()?;
2264                let name = self
2265                    .owned_strings
2266                    .get(name_id)
2267                    .ok_or(InvalidBytecode::InvalidStringId)?
2268                    .clone();
2269                let value = frame.pop()?;
2270                frame.push(Value::Tuple(Tuple::from([(name, value)])));
2271            }
2272            instruction::NEST => {
2273                let value = frame.pop()?;
2274                frame.push(Value::Tuple(Tuple::from([value])));
2275            }
2276            instruction::NEGATIVE => {
2277                let value = frame.pop()?.into_i64()?;
2278                frame.push((-value).into());
2279            }
2280            instruction::DEREF => {
2281                let value = frame.pop()?.into_refcell()?;
2282                frame.push(value.try_borrow().map_err(Error::other)?.clone());
2283            }
2284            instruction::SET => {
2285                let value = frame.pop()?;
2286                let target = frame.pop()?.into_refcell()?;
2287                *target.borrow_mut() = value;
2288            }
2289            instruction::BIND => {
2290                let bind = frame.pop()?.into_function()?;
2291                return Ok(StepOutcome::Yield(
2292                    bind.piped(frame.into_bind(self.clone(), block_id)?)
2293                        .eval()?,
2294                ));
2295            }
2296            instruction::YIELD => {
2297                return Ok(StepOutcome::Yield(frame.into_bind(self.clone(), block_id)?));
2298            }
2299
2300            _ => Err(InvalidBytecode::InvalidInstruction)?,
2301        };
2302        Ok(StepOutcome::Frame(frame))
2303    }
2304}
2305
2306#[allow(clippy::missing_errors_doc)]
2307pub trait Extern {
2308    fn index<'host>(&'host self, index: Value<'host>) -> Result<Value<'host>, Error>;
2309
2310    #[allow(
2311        unused_variables,
2312        reason = "anyone implementing this should use partial_index"
2313    )]
2314    fn to_static<'host>(&self, partial_index: Option<Rc<Value<'host>>>) -> Option<StaticValue> {
2315        None
2316    }
2317
2318    /// Allows the [`Extern`] trait object to be downcasted back into its original type.
2319    ///
2320    /// Implementing this method is optional.
2321    /// The default implementation will always return `None` and reject all downcasting attempts via [`Value::downcast_extern`].
2322    fn any(&self) -> Option<&dyn Any> {
2323        None
2324    }
2325
2326    fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2327        write!(f, "{{external value}}")
2328    }
2329}
2330
2331#[allow(clippy::missing_errors_doc)]
2332pub trait ExternOwned {
2333    /// Note that self's reference count will always be greater than one,
2334    /// so [`Rc::unwrap_or_clone`], [`Rc::get_mut`], etc. are useless.
2335    fn index<'host>(self: Rc<Self>, index: Value<'host>) -> Result<Value<'host>, Error>;
2336
2337    /// Allows the [`ExternOwned`] trait object to be downcasted back into its original type.
2338    ///
2339    /// Implementing this method is optional.
2340    /// The default implementation will always return `None` and reject all downcasting attempts via [`Value::downcast_extern`].
2341    ///
2342    /// There is no way to downcast from an [`Rc<dyn Any>`],
2343    /// so this functin has the same signature as [`Extern`]'s equivalent.
2344    fn any(&self) -> Option<&dyn Any> {
2345        None
2346    }
2347
2348    fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2349        write!(f, "{{external value}}")
2350    }
2351}
2352
2353#[allow(clippy::missing_errors_doc)]
2354pub trait ExternFn {
2355    fn call<'host>(&'host self, argument: Value<'host>) -> Result<Value<'host>, Error>;
2356
2357    fn to_static(&self) -> Option<StaticFunction> {
2358        None
2359    }
2360
2361    fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2362        write!(f, "{{external function}}")
2363    }
2364}
2365
2366#[allow(clippy::missing_errors_doc)]
2367pub trait ExternFnOwned {
2368    /// Note that self's reference count will always be greater than one when a function is called from espy,
2369    /// so [`Rc::unwrap_or_clone`], [`Rc::get_mut`], etc. are useless.
2370    fn call<'host>(self: Rc<Self>, argument: Value<'host>) -> Result<Value<'host>, Error>;
2371
2372    fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2373        write!(f, "{{external function}}")
2374    }
2375}