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<&'static dyn $crate::ExternFn> {
38 Some(&$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 $(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.string()?;
74 match index.as_str() {
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) -> ::std::option::Option<&'static dyn $crate::Extern> {
84 ::std::option::Option::Some(&$this)
85 }
86
87 fn any(&self) -> ::std::option::Option<&dyn ::std::any::Any> {
88 ::std::option::Option::Some(self)
89 }
90
91 $($(
92 fn debug(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
93 $(let $debug_name = self;)?
94 ::std::write!(f, $description)
95 }
96 )?)?
97 }
98 };
99}
100
101fn rc_slice_try_from_iter_ordered<T, E>(
102 len: usize,
103 iter: impl Iterator<Item = Result<T, E>>,
104 rev: bool,
105) -> Result<Rc<[T]>, E> {
106 let mut tuple = Rc::new_uninit_slice(len);
107 let mutable_tuple = unsafe { Rc::get_mut(&mut tuple).unwrap_unchecked() };
109 let mut count = 0;
110 if rev {
114 for (entry, value) in mutable_tuple.iter_mut().rev().zip(iter) {
115 entry.write(value?);
116 count += 1;
117 }
118 } else {
119 for (entry, value) in mutable_tuple.iter_mut().zip(iter) {
120 entry.write(value?);
121 count += 1;
122 }
123 }
124 assert!(
125 count == len,
126 "iter did not produce enough values ({count}) to initialize slice of length {len}"
127 );
128 unsafe { Ok(tuple.assume_init()) }
130}
131
132fn rc_slice_try_from_iter<T, E>(
133 len: usize,
134 iter: impl Iterator<Item = Result<T, E>>,
135) -> Result<Rc<[T]>, E> {
136 rc_slice_try_from_iter_ordered(len, iter, false)
137}
138
139fn rc_slice_try_from_iter_rev<T, E>(
142 len: usize,
143 iter: impl Iterator<Item = Result<T, E>>,
144) -> Result<Rc<[T]>, E> {
145 rc_slice_try_from_iter_ordered(len, iter, true)
146}
147
148fn rc_slice_from_iter<T>(len: usize, iter: impl Iterator<Item = T>) -> Rc<[T]> {
149 rc_slice_try_from_iter(len, iter.map(Ok::<_, ()>)).expect("iter is always Ok")
150}
151
152#[derive(Clone)]
157pub enum Value<'host> {
158 Unit,
161 Tuple(Tuple<Value<'host>>),
162
163 Borrow(&'host dyn Extern, Option<Rc<Value<'host>>>),
164 Owned(Rc<dyn ExternOwned>, Option<Rc<Value<'host>>>),
165 I64(i64),
166 Bool(bool),
167 String(String),
168 Function(Rc<Function<'host>>),
169 EnumVariant(Rc<EnumVariant<'host>>),
170 Option {
171 contents: Option<Rc<Value<'host>>>,
172 ty: ComplexType,
173 },
174 Mut(Mut<'host>),
175
176 Type(Type),
177}
178
179impl std::fmt::Debug for Value<'_> {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 match self {
182 Value::Unit => write!(f, "Unit"),
183 Value::Tuple(tuple) => write!(f, "{tuple:?}"),
184 Value::Borrow(external, partial_index) => {
185 write!(f, "Borrow(")?;
186 external.debug(f)?;
187 if let Some(partial_index) = partial_index {
188 write!(f, ", {partial_index:?}")?;
189 }
190 write!(f, ")")
191 }
192 Value::Owned(external, partial_index) => {
193 write!(f, "Owned(")?;
194 external.debug(f)?;
195 if let Some(partial_index) = partial_index {
196 write!(f, ", {partial_index:?}")?;
197 }
198 write!(f, ")")
199 }
200 Value::I64(i) => write!(f, "I64({i:?})"),
201 Value::Bool(i) => write!(f, "Bool({i:?})"),
202 Value::String(i) => write!(f, "String({i:?})"),
203 Value::Function(function) => write!(f, "{function:?}"),
204 Value::EnumVariant(enum_variant) => write!(f, "{enum_variant:?}"),
205 Value::Option { contents, ty: _ } => write!(f, "{contents:?}"),
206 Value::Mut(inner) => write!(f, "{inner:?}"),
207 Value::Type(t) => write!(f, "{t:?}"),
208 }
209 }
210}
211
212#[derive(Clone)]
225pub enum StaticValue {
226 Unit,
227 Tuple(Tuple<StaticValue>),
228
229 Borrow(&'static dyn Extern, Option<Rc<StaticValue>>),
230 Owned(Rc<dyn ExternOwned>, Option<Rc<StaticValue>>),
231 I64(i64),
232 Bool(bool),
233 String(String),
234 Function(Rc<StaticFunction>),
235 EnumVariant(Rc<StaticEnumVariant>),
236 Option {
237 contents: Option<Rc<StaticValue>>,
238 ty: ComplexType,
239 },
240
241 Type(Type),
242}
243
244impl std::fmt::Debug for StaticValue {
245 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246 write!(f, "{:?}", self.to_runtime())
247 }
248}
249
250impl StaticValue {
251 #[must_use]
252 pub fn to_runtime<'host>(&self) -> Value<'host> {
253 match self {
254 StaticValue::Unit => Value::Unit,
255 StaticValue::Tuple(tuple) => Value::Tuple(tuple.to_runtime()),
256 StaticValue::Borrow(extern_ref, partial_index) => Value::Borrow(
257 *extern_ref,
258 partial_index.as_ref().map(|x| x.to_runtime().into()),
259 ),
260 StaticValue::Owned(extern_owned, partial_index) => Value::Owned(
261 extern_owned.clone(),
262 partial_index.as_ref().map(|x| x.to_runtime().into()),
263 ),
264 StaticValue::I64(i) => Value::I64(*i),
265 StaticValue::Bool(i) => Value::Bool(*i),
266 StaticValue::String(i) => Value::String(i.clone()),
267 StaticValue::Function(static_function) => {
268 Value::Function(Rc::new(static_function.to_runtime()))
269 }
270 StaticValue::EnumVariant(static_enum_variant) => {
271 Value::EnumVariant(Rc::new(EnumVariant {
272 contents: static_enum_variant.contents.clone().into(),
273 variant: static_enum_variant.variant,
274 definition: static_enum_variant.definition.clone(),
275 }))
276 }
277 StaticValue::Option { contents, ty } => Value::Option {
278 contents: contents.as_ref().map(|x| x.to_runtime().into()),
279 ty: ty.clone(),
280 },
281 StaticValue::Type(i) => Value::Type(i.clone()),
282 }
283 }
284}
285
286impl<'host, T: Borrow<StaticValue>> From<T> for Value<'host> {
287 fn from(value: T) -> Self {
288 value.borrow().to_runtime()
289 }
290}
291
292#[derive(Clone, Debug)]
302pub enum Type {
303 Any,
308 I64,
309 Bool,
310 String,
311 Function(Rc<FunctionType>),
312 Enum(Rc<EnumType>),
313 Option(Rc<ComplexType>),
314 Mut(Rc<ComplexType>),
315
316 Type,
318 Unit,
319}
320
321impl PartialEq for Type {
322 fn eq(&self, other: &Self) -> bool {
323 match (self, other) {
324 (Self::Enum(l), Self::Enum(r)) => l == r,
325 (Self::Option(l), Self::Option(r)) => l == r,
326 _ => mem::discriminant(self) == mem::discriminant(other),
327 }
328 }
329}
330
331impl Eq for Type {}
332
333#[derive(Clone, Debug, PartialEq, Eq)]
339pub enum ComplexType {
340 Simple(Type),
341 Complex(Tuple<ComplexType>),
342}
343
344impl ComplexType {
345 #[must_use]
346 pub fn compare(&self, r: &Self) -> bool {
347 match (self, r) {
348 (ComplexType::Simple(Type::Any), _) | (_, ComplexType::Simple(Type::Any)) => true,
349 (ComplexType::Simple(l), ComplexType::Simple(r)) => l == r,
350 (ComplexType::Complex(l), ComplexType::Complex(r)) => {
351 l.values().zip(r.values()).all(|(l, r)| l.compare(r))
352 }
353 _ => false,
354 }
355 }
356}
357
358impl From<Type> for ComplexType {
359 fn from(value: Type) -> Self {
360 Self::Simple(value)
361 }
362}
363
364impl From<Tuple<ComplexType>> for ComplexType {
365 fn from(value: Tuple<ComplexType>) -> Self {
366 Self::Complex(value)
367 }
368}
369
370impl From<ComplexType> for Value<'_> {
371 fn from(value: ComplexType) -> Self {
372 match value {
373 ComplexType::Simple(ty) => ty.into(),
374 ComplexType::Complex(tuple) => Value::Tuple(tuple.into()),
375 }
376 }
377}
378
379impl From<Type> for Value<'_> {
380 fn from(t: Type) -> Self {
381 Self::Type(t)
382 }
383}
384
385impl<'host> Value<'host> {
386 pub fn to_static(&self) -> Result<StaticValue, Error> {
398 match self {
399 Value::Unit => Ok(StaticValue::Unit),
400 Value::Tuple(tuple) => Ok(StaticValue::Tuple(tuple.to_static()?)),
401 Value::Borrow(extern_borrow, partial_index) => Ok(StaticValue::Borrow(
402 extern_borrow
403 .to_static()
404 .ok_or(Error::from(ErrorKind::NotStatic))?,
405 partial_index
406 .as_ref()
407 .map(|x| x.to_static().map(Rc::new))
408 .transpose()?,
409 )),
410 Value::Owned(extern_owned, partial_index) => Ok(StaticValue::Owned(
411 extern_owned.clone(),
412 partial_index
413 .as_ref()
414 .map(|x| x.to_static().map(Rc::new))
415 .transpose()?,
416 )),
417 Value::I64(x) => Ok(StaticValue::I64(*x)),
418 Value::Bool(x) => Ok(StaticValue::Bool(*x)),
419 Value::String(x) => Ok(StaticValue::String(x.clone())),
420 Value::Function(function) => Ok(StaticValue::Function(function.to_static()?.into())),
421 Value::EnumVariant(enum_variant) => {
422 Ok(StaticValue::EnumVariant(Rc::new(StaticEnumVariant {
423 contents: enum_variant.contents.to_static()?,
424 variant: enum_variant.variant,
425 definition: enum_variant.definition.clone(),
426 })))
427 }
428 Value::Option { contents, ty } => Ok(StaticValue::Option {
429 contents: contents
430 .as_ref()
431 .map(|x| x.to_static())
432 .transpose()?
433 .map(Rc::new),
434 ty: ty.clone(),
435 }),
436 Value::Mut(_) => Err(ErrorKind::NotStatic.into()),
437 Value::Type(x) => Ok(StaticValue::Type(x.clone())),
438 }
439 }
440
441 pub fn try_get(&self, index: i64) -> Result<Value<'host>, Error> {
452 match self {
453 Value::Tuple(tuple) => usize::try_from(index)
454 .ok()
455 .and_then(|index| tuple.get(index))
456 .ok_or(Error::index_not_found(self, &index.into())),
457 Value::Type(Type::Enum(ty)) => usize::try_from(index)
458 .ok()
459 .filter(|index| *index < ty.variants.len())
460 .map(|index| {
461 Value::Function(Rc::new(
462 FunctionAction::Enum {
463 variant: index,
464 definition: ty.clone(),
465 }
466 .into(),
467 ))
468 })
469 .ok_or_else(|| Error::index_not_found(self, &index.into())),
470 Value::Type(Type::Option(ty)) => match index {
471 0 => Ok(Value::Function(Rc::new(
472 FunctionAction::OptionCase {
473 some: true,
474 ty: (**ty).clone(),
475 }
476 .into(),
477 ))),
478 1 => Ok(Value::Function(Rc::new(
479 FunctionAction::OptionCase {
480 some: false,
481 ty: (**ty).clone(),
482 }
483 .into(),
484 ))),
485 _ => Err(Error::index_not_found(self, &index.into())),
486 },
487 _ => Err(Error::index_not_found(self, &index.into())),
488 }
489 }
490
491 #[must_use]
492 pub fn get(&self, index: i64) -> Option<Value<'host>> {
493 self.try_get(index).ok()
494 }
495
496 pub fn try_find(&self, index: impl Into<String>) -> Result<Value<'host>, Error> {
504 let index = index.into();
505 match self {
506 Value::Tuple(tuple) => tuple
507 .find(index.clone())
508 .ok_or(Error::index_not_found(self, &index.into())),
509 Value::Type(Type::Enum(ty)) => {
510 if let Some(variant_id) = ty
511 .variants
512 .as_ref()
513 .iter()
514 .enumerate()
515 .find(|(_, (variant, _))| *variant == index)
516 .map(|(i, _)| i)
517 {
518 Ok(Value::Function(Rc::new(
519 FunctionAction::Enum {
520 variant: variant_id,
521 definition: ty.clone(),
522 }
523 .into(),
524 )))
525 } else {
526 Err(Error::index_not_found(self, &index.into()))
527 }
528 }
529 Value::Type(Type::Option(ty)) => match index.as_str() {
530 "Some" => Ok(Value::Function(Rc::new(
531 FunctionAction::OptionCase {
532 some: true,
533 ty: (**ty).clone(),
534 }
535 .into(),
536 ))),
537 "None" => Ok(Value::Function(Rc::new(
538 FunctionAction::OptionCase {
539 some: false,
540 ty: (**ty).clone(),
541 }
542 .into(),
543 ))),
544 _ => Err(Error::index_not_found(self, &index.into())),
545 },
546 _ => Err(Error::index_not_found(self, &index.into())),
547 }
548 }
549
550 #[must_use]
551 pub fn find(&self, index: impl Into<String>) -> Option<Value<'host>> {
552 self.try_find(index).ok()
553 }
554
555 pub fn index(&self, index: impl Into<Value<'host>>) -> Result<Value<'host>, Error> {
563 match (self, index.into()) {
564 (Value::Borrow(external, partial_index), index) => {
565 external.index(if let Some(partial_index) = partial_index {
566 Value::concat((**partial_index).clone(), index)
567 } else {
568 index
569 })
570 }
571 (Value::Owned(external, partial_index), index) => {
572 external
573 .clone()
574 .index(if let Some(partial_index) = partial_index {
575 Value::concat((**partial_index).clone(), index)
576 } else {
577 index
578 })
579 }
580 (_, Value::I64(index)) => self.try_get(index),
581 (_, Value::String(index)) => self.try_find(index),
582 (_, index) => Err(Error::index_not_found(self, &index)),
583 }
584 }
585
586 #[must_use]
592 pub fn downcast_extern<T: Any>(&self) -> Option<&T> {
593 match self {
594 Value::Borrow(borrow, ..) => (*borrow).any()?.downcast_ref(),
595 Value::Owned(owned, ..) => (*owned).any()?.downcast_ref(),
596 _ => None,
597 }
598 }
599
600 pub fn eq(self, other: Self) -> Result<bool, Error> {
604 match (self, other) {
605 (Value::Unit, Value::Unit) => Ok(true),
606 (Value::Tuple(l), Value::Tuple(r)) if l.len() == r.len() => {
607 for (l, r) in l.values().zip(r.values()) {
608 if !l.clone().eq(r.clone())? {
609 return Ok(false);
610 }
611 }
612 Ok(true)
613 }
614 (Value::I64(l), Value::I64(r)) => Ok(l == r),
615 (Value::Bool(l), Value::Bool(r)) => Ok(l == r),
616 (Value::String(l), Value::String(r)) => Ok(l == r),
617 (Value::EnumVariant(l), Value::EnumVariant(r)) => Ok(l.variant == r.variant
618 && Rc::ptr_eq(&l.definition, &r.definition)
619 && Rc::try_unwrap(l)
620 .map_or_else(|l| l.contents.clone(), |l| l.contents)
621 .eq(Rc::try_unwrap(r).map_or_else(|r| r.contents.clone(), |r| r.contents))?),
622 (
623 Value::Option {
624 contents: l,
625 ty: l_type,
626 },
627 Value::Option {
628 contents: r,
629 ty: r_type,
630 },
631 ) if l_type.compare(&r_type) => Ok(l.is_none() && r.is_none()
632 || l.zip(r).map_or(Ok(false), |(l, r)| {
633 Rc::unwrap_or_clone(l).eq(Rc::unwrap_or_clone(r))
634 })?),
635 (Value::Type(l), Value::Type(r)) => Ok(l == r),
636 (this, other) => Err(Error::incomparable_values(&this, &other)),
637 }
638 }
639
640 pub fn type_of(&self) -> Result<ComplexType, Error> {
646 Ok(match &self {
647 Value::Unit => Type::Unit.into(),
648 Value::Tuple(tuple) => {
649 let complex = match &tuple.0 {
650 TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(
651 rc_slice_try_from_iter(items.len(), items.iter().map(Value::type_of))?,
652 )),
653 TupleStorage::Named(items) => {
654 Tuple(TupleStorage::Named(rc_slice_try_from_iter(
655 items.len(),
656 items.iter().map(|(name, value)| {
657 value.type_of().map(|value| (name.clone(), value))
658 }),
659 )?))
660 }
661 };
662 if complex
664 .values()
665 .all(|x| matches!(x, ComplexType::Simple(Type::Type)))
666 {
667 Type::Type.into()
668 } else {
669 complex.into()
670 }
671 }
672 Value::Borrow(..) | Value::Owned(..) => Type::Any.into(),
673 Value::I64(_) => Type::I64.into(),
674 Value::Bool(_) => Type::Bool.into(),
675 Value::String(_) => Type::String.into(),
676 Value::Function(function) => match &function.action {
677 FunctionAction::With { signature, .. } => {
678 Type::Function(Rc::new(signature.clone())).into()
679 }
680 _ => Type::Function(Rc::new(FunctionType {
681 input: Type::Any.into(),
682 output: Type::Any.into(),
683 }))
684 .into(),
685 },
686 Value::EnumVariant(enum_variant) => Type::Enum(enum_variant.definition.clone()).into(),
687 Value::Option { contents: _, ty } => Type::Option(Rc::new(ty.clone())).into(),
688 Value::Mut(inner) => Type::Mut(
689 inner
690 .upgrade()
691 .ok_or(ErrorKind::OutOfScopeMut)?
692 .try_borrow()
693 .map_err(Error::other)?
694 .type_of()?
695 .into(),
696 )
697 .into(),
698 Value::Type(_) => Type::Type.into(),
699 })
700 }
701
702 #[must_use]
703 pub fn concat(self, r: Self) -> Self {
704 match (self, r) {
705 (
706 Value::Tuple(Tuple(TupleStorage::Numeric(l))),
707 Value::Tuple(Tuple(TupleStorage::Numeric(r))),
708 ) => Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
709 l.len() + r.len(),
710 l.iter().chain(r.iter()).cloned(),
711 )))),
712 (
713 Value::Tuple(Tuple(TupleStorage::Named(l))),
714 Value::Tuple(Tuple(TupleStorage::Named(r))),
715 ) => Value::Tuple(Tuple(TupleStorage::Named(rc_slice_from_iter(
716 l.len() + r.len(),
717 l.iter().chain(r.iter()).cloned(),
718 )))),
719 (l, Value::Unit) => l,
720 (Value::Unit, r) => r,
721 (Value::Tuple(Tuple(TupleStorage::Numeric(l))), r) => {
722 Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
723 l.len() + 1,
724 l.iter().cloned().chain([r]),
725 ))))
726 }
727 (l, Value::Tuple(Tuple(TupleStorage::Numeric(r)))) => {
728 Value::Tuple(Tuple(TupleStorage::Numeric(rc_slice_from_iter(
729 1 + r.len(),
730 [l].into_iter().chain(r.iter().cloned()),
731 ))))
732 }
733 (l, r) => Value::Tuple(Tuple(TupleStorage::Numeric(Rc::new([l, r])))),
734 }
735 }
736
737 pub fn borrow(external: &'host dyn Extern) -> Self {
738 Value::Borrow(external, None)
739 }
740
741 pub fn owned(external: Rc<dyn ExternOwned>) -> Self {
742 Value::Owned(external, None)
743 }
744}
745
746impl From<()> for Value<'_> {
747 fn from((): ()) -> Self {
748 Value::Unit
749 }
750}
751
752impl From<Option<()>> for Value<'_> {
753 fn from(value: Option<()>) -> Self {
754 Value::Option {
755 contents: value.map(|()| Rc::new(Value::Unit)),
756 ty: Type::Unit.into(),
757 }
758 }
759}
760
761impl From<bool> for Value<'_> {
762 fn from(value: bool) -> Self {
763 Value::Bool(value)
764 }
765}
766
767impl From<Option<bool>> for Value<'_> {
768 fn from(value: Option<bool>) -> Self {
769 Value::Option {
770 contents: value.map(|value| Rc::new(Value::Bool(value))),
771 ty: Type::Bool.into(),
772 }
773 }
774}
775
776impl From<i64> for Value<'_> {
777 fn from(i: i64) -> Self {
778 Value::I64(i)
779 }
780}
781
782impl From<Option<i64>> for Value<'_> {
783 fn from(value: Option<i64>) -> Self {
784 Value::Option {
785 contents: value.map(|value| Rc::new(Value::I64(value))),
786 ty: Type::I64.into(),
787 }
788 }
789}
790
791impl From<&'static str> for Value<'_> {
792 fn from(s: &'static str) -> Self {
793 Value::String(s.into())
794 }
795}
796
797impl From<Rc<str>> for Value<'_> {
798 fn from(s: Rc<str>) -> Self {
799 Value::String(s.into())
800 }
801}
802
803impl From<String> for Value<'_> {
804 fn from(s: String) -> Self {
805 Value::String(s)
806 }
807}
808
809impl<T: Into<String>> From<Option<T>> for Value<'_> {
810 fn from(value: Option<T>) -> Self {
811 Value::Option {
812 contents: value.map(|value| Rc::new(Value::String(value.into()))),
813 ty: Type::String.into(),
814 }
815 }
816}
817
818impl<'host> From<Rc<[Value<'host>]>> for Value<'host> {
819 fn from(value: Rc<[Value<'host>]>) -> Self {
820 Self::Tuple(Tuple::from(value))
821 }
822}
823
824impl<'host, T: Into<Value<'host>>, const N: usize> From<[T; N]> for Value<'host> {
825 fn from(value: [T; N]) -> Self {
826 let slice = rc_slice_from_iter(value.len(), value.into_iter().map(Into::into));
827 Self::Tuple(Tuple::from(slice))
828 }
829}
830
831impl<'host> From<Rc<[(String, Value<'host>)]>> for Value<'host> {
832 fn from(value: Rc<[(String, Value<'host>)]>) -> Self {
833 Self::Tuple(Tuple::from(value))
834 }
835}
836
837impl<'host> From<Tuple<Value<'host>>> for Value<'host> {
838 fn from(value: Tuple<Value<'host>>) -> Self {
839 Self::Tuple(value)
840 }
841}
842
843impl<'host, K: Into<String>, const N: usize> From<[(K, Value<'host>); N]> for Value<'host> {
844 fn from(value: [(K, Value<'host>); N]) -> Self {
845 Self::Tuple(Tuple::from(value))
846 }
847}
848
849impl<'host> From<Option<Value<'host>>> for Value<'host> {
850 fn from(value: Option<Self>) -> Self {
851 value.map(Rc::new).into()
852 }
853}
854
855impl<'host> From<Option<Rc<Value<'host>>>> for Value<'host> {
856 fn from(value: Option<Rc<Self>>) -> Self {
857 Value::Option {
858 contents: value,
859 ty: Type::Any.into(),
860 }
861 }
862}
863
864impl<'host> From<Rc<Function<'host>>> for Value<'host> {
865 fn from(f: Rc<Function<'host>>) -> Self {
866 Value::Function(f)
867 }
868}
869
870impl<'host> From<Function<'host>> for Value<'host> {
871 fn from(f: Function<'host>) -> Self {
872 Rc::new(f).into()
873 }
874}
875
876impl<'host> TryFrom<Value<'host>> for () {
877 type Error = Error;
878
879 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
880 if let Value::Unit = value {
881 Ok(())
882 } else {
883 Err(Error::type_error(&value, &Type::Unit.into()))
884 }
885 }
886}
887
888impl<'host> TryFrom<Value<'host>> for Tuple<Value<'host>> {
889 type Error = Error;
890
891 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
892 if let Value::Tuple(value) = value {
893 Ok(value)
894 } else {
895 Err(Error::expected_tuple(&value))
896 }
897 }
898}
899
900impl<'host> TryFrom<Value<'host>> for bool {
901 type Error = Error;
902
903 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
904 if let Value::Bool(bool) = value {
905 Ok(bool)
906 } else {
907 Err(Error::type_error(&value, &Type::Unit.into()))
908 }
909 }
910}
911
912impl<'host> TryFrom<Value<'host>> for i64 {
913 type Error = Error;
914
915 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
916 if let Value::I64(value) = value {
917 Ok(value)
918 } else {
919 Err(Error::type_error(&value, &Type::I64.into()))
920 }
921 }
922}
923
924impl<'host> TryFrom<Value<'host>> for String {
925 type Error = Error;
926
927 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
928 if let Value::String(value) = value {
929 Ok(value)
930 } else {
931 Err(Error::type_error(&value, &Type::String.into()))
932 }
933 }
934}
935
936impl<'host> TryFrom<Value<'host>> for Rc<Function<'host>> {
937 type Error = Error;
938 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
939 if let Value::Function(value) = value {
940 Ok(value)
941 } else {
942 Err(Error::expected_function(&value))
943 }
944 }
945}
946
947impl<'host> TryFrom<Value<'host>> for Function<'host> {
948 type Error = Error;
949
950 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
951 Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
952 }
953}
954
955impl<'host> TryFrom<Value<'host>> for Rc<EnumVariant<'host>> {
956 type Error = Error;
957 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
958 if let Value::EnumVariant(value) = value {
959 Ok(value)
960 } else {
961 Err(Error::expected_enum_variant(&value))
962 }
963 }
964}
965
966impl<'host> TryFrom<Value<'host>> for EnumVariant<'host> {
967 type Error = Error;
968
969 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
970 Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
971 }
972}
973
974impl<'host> TryFrom<Value<'host>> for ComplexType {
975 type Error = Error;
976
977 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
978 match value {
979 Value::Type(t) => Ok(t.into()),
980 Value::Tuple(tuple) => Ok(ComplexType::Complex(tuple.try_into()?)),
981 _ => Err(Error::type_error(&value, &Type::Type.into())),
982 }
983 }
984}
985
986impl<'host> TryFrom<Value<'host>> for Rc<EnumType> {
987 type Error = Error;
988 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
989 if let Value::Type(Type::Enum(value)) = value {
990 Ok(value)
991 } else {
992 Err(Error::expected_enum_type(&value))
993 }
994 }
995}
996
997impl<'host> TryFrom<Value<'host>> for EnumType {
998 type Error = Error;
999
1000 fn try_from(value: Value<'host>) -> Result<Self, Self::Error> {
1001 Ok(Rc::unwrap_or_clone(Rc::<Self>::try_from(value)?))
1002 }
1003}
1004
1005impl<'host> Value<'host> {
1007 pub fn unit(self) -> Result<(), Error> {
1011 self.try_into()
1012 }
1013
1014 pub fn tuple(self) -> Result<Tuple<Value<'host>>, Error> {
1018 self.try_into()
1019 }
1020
1021 pub fn bool(self) -> Result<bool, Error> {
1025 self.try_into()
1026 }
1027
1028 pub fn i64(self) -> Result<i64, Error> {
1032 self.try_into()
1033 }
1034
1035 pub fn string(self) -> Result<String, Error> {
1039 self.try_into()
1040 }
1041
1042 pub fn function(self) -> Result<Function<'host>, Error> {
1046 self.try_into()
1047 }
1048
1049 pub fn enum_variant(self) -> Result<Rc<EnumVariant<'host>>, Error> {
1053 self.try_into()
1054 }
1055
1056 pub fn option(self) -> Result<Option<Value<'host>>, Error> {
1060 match self {
1061 Value::Option { contents, ty: _ } => Ok(contents.map(|x| (*x).clone())),
1062 _ => Err(Error::expected_option(&self)),
1063 }
1064 }
1065
1066 pub fn into_refcell(self) -> Result<Rc<RefCell<Value<'host>>>, Error> {
1070 match &self {
1071 Value::Mut(inner) => Ok(inner.upgrade().ok_or(ErrorKind::OutOfScopeMut)?),
1072 _ => Err(Error::expected_reference(&self)),
1073 }
1074 }
1075
1076 pub fn into_complex_type(self) -> Result<ComplexType, Error> {
1080 self.try_into()
1081 }
1082
1083 pub fn into_enum_type(self) -> Result<Rc<EnumType>, Error> {
1087 self.try_into()
1088 }
1089
1090 #[must_use]
1091 pub fn as_str(&self) -> Option<&str> {
1092 if let Value::String(s) = &self {
1093 Some(s.as_str())
1094 } else {
1095 None
1096 }
1097 }
1098
1099 pub fn into_vec(self) -> Vec<Value<'host>> {
1105 match self {
1106 Value::Unit => Vec::new(),
1107 Value::Tuple(tup) => tup.values().map(Value::clone).collect(),
1108 _ => Vec::from([self]),
1109 }
1110 }
1111}
1112
1113#[derive(Clone)]
1114enum StringStorage {
1115 Static(&'static str),
1116 Floating(Rc<str>),
1117}
1118
1119#[derive(Clone)]
1124pub struct String(StringStorage);
1125
1126impl String {
1127 #[must_use]
1134 pub fn as_str(&self) -> &str {
1135 match &self.0 {
1136 StringStorage::Static(s) => s,
1137 StringStorage::Floating(s) => s,
1138 }
1139 }
1140
1141 #[must_use]
1146 pub fn into_str(self) -> Rc<str> {
1147 match self.0 {
1148 StringStorage::Static(s) => s.into(),
1149 StringStorage::Floating(s) => s,
1150 }
1151 }
1152
1153 #[must_use]
1155 pub fn owned(s: &str) -> Self {
1156 Rc::<str>::from(s).into()
1157 }
1158}
1159
1160impl Default for String {
1161 fn default() -> Self {
1162 Self::from("")
1163 }
1164}
1165
1166impl std::fmt::Display for String {
1167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1168 self.as_str().fmt(f)
1169 }
1170}
1171
1172impl std::fmt::Debug for String {
1173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1174 self.as_str().fmt(f)
1175 }
1176}
1177
1178impl PartialEq for String {
1179 fn eq(&self, other: &Self) -> bool {
1180 self.as_str() == other.as_str()
1181 }
1182}
1183
1184impl Eq for String {}
1185
1186impl From<&'static str> for String {
1187 fn from(value: &'static str) -> Self {
1188 Self(StringStorage::Static(value))
1189 }
1190}
1191
1192impl From<std::string::String> for String {
1193 fn from(value: std::string::String) -> Self {
1194 Self(StringStorage::Floating(value.into()))
1195 }
1196}
1197
1198impl From<Rc<str>> for String {
1199 fn from(value: Rc<str>) -> Self {
1200 Self(StringStorage::Floating(value))
1201 }
1202}
1203
1204impl From<String> for Rc<str> {
1205 fn from(value: String) -> Self {
1206 value.into_str()
1207 }
1208}
1209
1210impl Borrow<str> for &String {
1211 fn borrow(&self) -> &str {
1212 self.as_str()
1213 }
1214}
1215
1216impl std::ops::Deref for String {
1217 type Target = str;
1218
1219 fn deref(&self) -> &Self::Target {
1220 self.as_str()
1221 }
1222}
1223
1224#[derive(Clone, Debug, PartialEq, Eq)]
1225enum TupleStorage<T> {
1226 Numeric(Rc<[T]>),
1227 Named(Rc<[(String, T)]>),
1228}
1229
1230#[derive(Clone, Debug, PartialEq, Eq)]
1240pub struct Tuple<T>(TupleStorage<T>);
1241
1242impl<T> Tuple<T> {
1243 #[must_use]
1244 pub fn len(&self) -> usize {
1245 match &self.0 {
1246 TupleStorage::Numeric(items) => items.len(),
1247 TupleStorage::Named(items) => items.len(),
1248 }
1249 }
1250
1251 #[must_use]
1252 pub fn is_empty(&self) -> bool {
1253 self.len() == 0
1254 }
1255
1256 #[must_use]
1257 pub fn get_ref(&self, index: usize) -> Option<&T> {
1258 match &self.0 {
1259 TupleStorage::Numeric(items) => items.get(index),
1260 TupleStorage::Named(items) => items.get(index).map(|(_name, value)| value),
1261 }
1262 }
1263
1264 #[must_use]
1265 pub fn find_ref(&self, name: impl Borrow<str>) -> Option<&T> {
1266 let TupleStorage::Named(items) = &self.0 else {
1267 return None;
1268 };
1269 items.iter().find_map(|(n, v)| {
1270 if n.as_str() == name.borrow() {
1271 Some(v)
1272 } else {
1273 None
1274 }
1275 })
1276 }
1277
1278 pub fn values(&self) -> impl Iterator<Item = &T> {
1279 (0..self.len()).map(|i| match &self.0 {
1280 TupleStorage::Numeric(items) => &items[i],
1281 TupleStorage::Named(items) => &items[i].1,
1282 })
1283 }
1284
1285 #[must_use]
1286 pub fn as_numeric(&self) -> Option<&[T]> {
1287 match &self.0 {
1288 TupleStorage::Numeric(items) => Some(items),
1289 TupleStorage::Named(_) => None,
1290 }
1291 }
1292
1293 #[must_use]
1294 pub fn as_named(&self) -> Option<&[(String, T)]> {
1295 match &self.0 {
1296 TupleStorage::Numeric(_) => None,
1297 TupleStorage::Named(items) => Some(items),
1298 }
1299 }
1300}
1301
1302impl<T: Clone> Tuple<T> {
1303 #[must_use]
1304 pub fn get(&self, index: usize) -> Option<T> {
1305 match &self.0 {
1306 TupleStorage::Numeric(items) => items.get(index).cloned(),
1307 TupleStorage::Named(items) => items.get(index).map(|(_name, value)| value).cloned(),
1308 }
1309 }
1310
1311 #[must_use]
1312 pub fn find(&self, name: impl Into<String>) -> Option<T> {
1313 let TupleStorage::Named(items) = &self.0 else {
1314 return None;
1315 };
1316 let name = name.into();
1317 items.iter().find_map(|(n, v)| {
1318 if n.as_str() == name.as_str() {
1319 Some(v.clone())
1320 } else {
1321 None
1322 }
1323 })
1324 }
1325}
1326
1327impl<'host> Tuple<Value<'host>> {
1328 pub fn try_get_ref(&self, index: usize) -> Result<&Value<'host>, Error> {
1332 let value = match &self.0 {
1333 TupleStorage::Numeric(items) => items.get(index),
1334 TupleStorage::Named(items) => items.get(index).map(|(_name, value)| value),
1335 };
1336 value
1337 .ok_or_else(|| Error::index_not_found(&self.clone().into(), &Value::from(index as i64)))
1338 }
1339
1340 pub fn try_find_ref(&self, name: impl Into<String>) -> Result<&Value<'host>, Error> {
1344 let name = name.into();
1345 if let TupleStorage::Named(items) = &self.0
1346 && let Some(value) = items.iter().find_map(|(n, v)| {
1347 if n.as_str() == name.as_str() {
1348 Some(v)
1349 } else {
1350 None
1351 }
1352 })
1353 {
1354 Ok(value)
1355 } else {
1356 Err(Error::index_not_found(&self.clone().into(), &name.into()))
1357 }
1358 }
1359
1360 pub fn try_get(&self, index: usize) -> Result<Value<'host>, Error> {
1364 self.try_get_ref(index).cloned()
1365 }
1366
1367 pub fn try_find(&self, name: impl Into<String>) -> Result<Value<'host>, Error> {
1371 self.try_find_ref(name).cloned()
1372 }
1373}
1374
1375impl<'host> Tuple<Value<'host>> {
1376 fn to_static(&self) -> Result<Tuple<StaticValue>, Error> {
1377 match &self.0 {
1378 TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1379 items.len(),
1380 items.iter().map(|value: &Value| value.to_static()),
1381 )
1382 .map(TupleStorage::Numeric)
1383 .map(Tuple),
1384 TupleStorage::Named(items) => rc_slice_try_from_iter(
1385 items.len(),
1386 items
1387 .iter()
1388 .map(|(name, value)| value.to_static().map(|value| (name.clone(), value))),
1389 )
1390 .map(TupleStorage::Named)
1391 .map(Tuple),
1392 }
1393 }
1394}
1395
1396impl Tuple<StaticValue> {
1397 #[must_use]
1398 pub fn to_runtime<'host>(&self) -> Tuple<Value<'host>> {
1399 match &self.0 {
1400 TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(rc_slice_from_iter(
1401 items.len(),
1402 items.iter().map(Value::from),
1403 ))),
1404 TupleStorage::Named(items) => Tuple(TupleStorage::Named(rc_slice_from_iter(
1405 items.len(),
1406 items
1407 .iter()
1408 .map(|(name, value)| (name.clone(), value.into())),
1409 ))),
1410 }
1411 }
1412}
1413
1414impl<'host, T: Borrow<Tuple<StaticValue>>> From<T> for Tuple<Value<'host>> {
1415 fn from(value: T) -> Self {
1416 value.borrow().to_runtime()
1417 }
1418}
1419
1420impl<'host> TryFrom<Tuple<Value<'host>>> for Tuple<ComplexType> {
1421 type Error = Error;
1422
1423 fn try_from(tuple: Tuple<Value<'host>>) -> Result<Self, Self::Error> {
1424 match &tuple.0 {
1425 TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1426 items.len(),
1427 items.iter().map(|value| value.clone().try_into()),
1428 )
1429 .map(TupleStorage::Numeric)
1430 .map(Tuple),
1431 TupleStorage::Named(items) => rc_slice_try_from_iter(
1432 items.len(),
1433 items.iter().map(|(name, value)| {
1434 value.clone().try_into().map(|value| (name.clone(), value))
1435 }),
1436 )
1437 .map(TupleStorage::Named)
1438 .map(Tuple),
1439 }
1440 }
1441}
1442
1443impl From<Tuple<ComplexType>> for Tuple<Value<'_>> {
1444 fn from(tuple: Tuple<ComplexType>) -> Self {
1445 match &tuple.0 {
1446 TupleStorage::Numeric(items) => Tuple(TupleStorage::Numeric(rc_slice_from_iter(
1447 items.len(),
1448 items.iter().map(|value| value.clone().into()),
1449 ))),
1450 TupleStorage::Named(items) => Tuple(TupleStorage::Named(rc_slice_from_iter(
1451 items.len(),
1452 items
1453 .iter()
1454 .map(|(name, value)| (name.clone(), value.clone().into())),
1455 ))),
1456 }
1457 }
1458}
1459
1460impl<'host> TryFrom<Tuple<Value<'host>>> for Tuple<Function<'host>> {
1461 type Error = Error;
1462
1463 fn try_from(tuple: Tuple<Value<'host>>) -> Result<Self, Self::Error> {
1464 match &tuple.0 {
1465 TupleStorage::Numeric(items) => rc_slice_try_from_iter(
1466 items.len(),
1467 items.iter().map(|value| value.clone().try_into()),
1468 )
1469 .map(TupleStorage::Numeric)
1470 .map(Tuple),
1471 TupleStorage::Named(items) => rc_slice_try_from_iter(
1472 items.len(),
1473 items.iter().map(|(name, value)| {
1474 value.clone().try_into().map(|value| (name.clone(), value))
1475 }),
1476 )
1477 .map(TupleStorage::Named)
1478 .map(Tuple),
1479 }
1480 }
1481}
1482
1483impl<T> From<Rc<[T]>> for Tuple<T> {
1484 fn from(value: Rc<[T]>) -> Self {
1485 Self(TupleStorage::Numeric(value))
1486 }
1487}
1488
1489impl<const N: usize, T> From<[T; N]> for Tuple<T> {
1490 fn from(value: [T; N]) -> Self {
1491 Self(TupleStorage::Numeric(Rc::from(value)))
1492 }
1493}
1494
1495impl<T> From<Rc<[(String, T)]>> for Tuple<T> {
1496 fn from(value: Rc<[(String, T)]>) -> Self {
1497 Self(TupleStorage::Named(value))
1498 }
1499}
1500
1501impl<const N: usize, K: Into<String>, T> From<[(K, T); N]> for Tuple<T> {
1502 fn from(value: [(K, T); N]) -> Self {
1503 let slice = rc_slice_from_iter(value.len(), value.into_iter().map(|(k, v)| (k.into(), v)));
1504 Self(TupleStorage::Named(slice))
1505 }
1506}
1507
1508#[derive(Clone, Debug)]
1518pub struct Function<'host> {
1519 action: FunctionAction<'host>,
1520 argument: Value<'host>,
1521}
1522
1523#[derive(Clone)]
1527pub struct StaticFunction {
1528 action: StaticFunctionAction,
1529 argument: StaticValue,
1530}
1531
1532impl std::fmt::Debug for StaticFunction {
1533 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1534 write!(f, "{:?}", self.to_runtime())
1535 }
1536}
1537
1538impl StaticFunction {
1539 #[must_use]
1540 pub fn to_runtime<'host>(&self) -> Function<'host> {
1541 Function {
1542 action: match &self.action {
1543 StaticFunctionAction::With {
1544 program,
1545 block_id,
1546 program_counter,
1547 signature,
1548 captures,
1549 } => FunctionAction::With {
1550 program: program.clone(),
1551 block_id: *block_id,
1552 program_counter: *program_counter,
1553 signature: signature.clone(),
1554 captures: rc_slice_from_iter(
1555 captures.len(),
1556 captures
1557 .iter()
1558 .map(|value: &StaticValue| value.clone().into()),
1559 ),
1560 },
1561 StaticFunctionAction::Never { signature } => FunctionAction::Never {
1562 signature: signature.clone(),
1563 },
1564 StaticFunctionAction::Enum {
1565 variant,
1566 definition,
1567 } => FunctionAction::Enum {
1568 variant: *variant,
1569 definition: definition.clone(),
1570 },
1571 StaticFunctionAction::Mut => FunctionAction::Mut,
1572 StaticFunctionAction::OptionConstructor => FunctionAction::OptionConstructor,
1573 StaticFunctionAction::OptionCase { some, ty } => FunctionAction::OptionCase {
1574 some: *some,
1575 ty: ty.clone(),
1576 },
1577 StaticFunctionAction::Borrow(extern_fn) => FunctionAction::Borrow(*extern_fn),
1578 StaticFunctionAction::Owned(extern_fn_owned) => {
1579 FunctionAction::Owned(extern_fn_owned.clone())
1580 }
1581 },
1582 argument: self.argument.to_runtime(),
1583 }
1584 }
1585}
1586
1587impl<'host, T: Borrow<StaticFunction>> From<T> for Function<'host> {
1588 fn from(value: T) -> Self {
1589 value.borrow().to_runtime()
1590 }
1591}
1592
1593impl StaticFunction {
1594 pub fn borrow(external: &'static dyn ExternFn) -> Self {
1595 StaticFunction {
1596 action: StaticFunctionAction::Borrow(external),
1597 argument: StaticValue::Unit,
1598 }
1599 }
1600
1601 pub fn owned(external: Rc<dyn ExternFnOwned>) -> Self {
1602 StaticFunction {
1603 action: StaticFunctionAction::Owned(external),
1604 argument: StaticValue::Unit,
1605 }
1606 }
1607}
1608
1609impl<'host> Function<'host> {
1610 pub fn borrow(external: &'host dyn ExternFn) -> Self {
1611 Function {
1612 action: FunctionAction::Borrow(external),
1613 argument: ().into(),
1614 }
1615 }
1616
1617 pub fn owned(external: Rc<dyn ExternFnOwned>) -> Self {
1618 Function {
1619 action: FunctionAction::Owned(external),
1620 argument: ().into(),
1621 }
1622 }
1623
1624 pub fn to_static(&self) -> Result<StaticFunction, Error> {
1629 Ok(StaticFunction {
1630 action: match &self.action {
1631 FunctionAction::With {
1632 program,
1633 block_id,
1634 program_counter,
1635 signature,
1636 captures,
1637 } => StaticFunctionAction::With {
1638 program: program.clone(),
1639 block_id: *block_id,
1640 program_counter: *program_counter,
1641 signature: signature.clone(),
1642 captures: captures
1643 .iter()
1644 .map(|x| x.to_static())
1645 .collect::<Result<_, Error>>()?,
1646 },
1647 FunctionAction::Never { signature } => StaticFunctionAction::Never {
1648 signature: signature.clone(),
1649 },
1650 FunctionAction::Enum {
1651 variant,
1652 definition,
1653 } => StaticFunctionAction::Enum {
1654 variant: *variant,
1655 definition: definition.clone(),
1656 },
1657 FunctionAction::Mut => StaticFunctionAction::Mut,
1658 FunctionAction::OptionConstructor => StaticFunctionAction::OptionConstructor,
1659 FunctionAction::OptionCase { some, ty } => StaticFunctionAction::OptionCase {
1660 some: *some,
1661 ty: ty.clone(),
1662 },
1663 FunctionAction::Borrow(extern_fn_borrow) => StaticFunctionAction::Borrow(
1664 extern_fn_borrow
1665 .to_static()
1666 .ok_or(Error::from(ErrorKind::NotStatic))?,
1667 ),
1668 FunctionAction::Owned(extern_fn_owned) => {
1669 StaticFunctionAction::Owned(extern_fn_owned.clone())
1670 }
1671 },
1672 argument: self.argument.to_static()?,
1673 })
1674 }
1675
1676 pub fn eval(self) -> Result<Value<'host>, Error> {
1680 let result = match self.action {
1681 FunctionAction::With {
1682 program,
1683 block_id,
1684 program_counter,
1685 signature: FunctionType { input, output },
1686 captures,
1687 } => {
1688 if !self.argument.type_of()?.compare(&input) {
1689 return Err(Error::type_error(&self.argument, &input));
1690 }
1691 let result =
1692 program.eval_block(block_id, program_counter, captures, self.argument)?;
1693 if !result.type_of()?.compare(&output) {
1694 return Err(Error::type_error(&result, &output));
1695 }
1696 result
1697 }
1698 FunctionAction::Never { signature: _ } => {
1699 return Err(ErrorKind::CalledNeverFunction.into());
1700 }
1701 FunctionAction::Enum {
1702 variant,
1703 definition,
1704 } => {
1705 let ty = &definition.variants[variant].1;
1706 if *ty != Type::Any.into() && self.argument.type_of()? != *ty {
1707 return Err(Error::type_error(&self.argument, ty));
1708 }
1709 Value::EnumVariant(Rc::new(EnumVariant {
1710 contents: self.argument,
1711 variant,
1712 definition,
1713 }))
1714 }
1715 FunctionAction::Mut => {
1716 if let Ok(ty) = ComplexType::try_from(self.argument.clone()) {
1717 Type::Mut(Rc::new(ty)).into()
1718 } else {
1719 Value::Mut(Mut::new(Rc::new(RefCell::new(self.argument))))
1720 }
1721 }
1722 FunctionAction::OptionConstructor => {
1723 Type::Option(Rc::new(self.argument.into_complex_type()?)).into()
1724 }
1725 FunctionAction::OptionCase { some: true, ty } => {
1726 if self.argument.type_of()? != ty {
1727 return Err(Error::type_error(&self.argument, &ty));
1728 }
1729 Value::Option {
1730 contents: Some(Rc::new(self.argument)),
1731 ty,
1732 }
1733 }
1734 FunctionAction::OptionCase { some: false, ty } => {
1735 self.argument.unit()?;
1736 Value::Option { contents: None, ty }
1737 }
1738 FunctionAction::Borrow(external) => external.call(self.argument)?,
1739 FunctionAction::Owned(external) => external.call(self.argument)?,
1740 };
1741 Ok(result)
1742 }
1743
1744 pub fn pipe(&mut self, argument: Value<'host>) {
1746 let mut arguments = ().into();
1747 mem::swap(&mut arguments, &mut self.argument);
1748 arguments = Value::concat(arguments, argument);
1749 mem::swap(&mut arguments, &mut self.argument);
1750 }
1751
1752 #[must_use]
1753 pub fn piped(mut self, argument: Value<'host>) -> Self {
1754 self.pipe(argument);
1755 self
1756 }
1757}
1758
1759#[derive(Clone)]
1760enum FunctionAction<'host> {
1761 With {
1762 program: Program,
1763 block_id: usize,
1764 program_counter: usize,
1765 signature: FunctionType,
1766 captures: Rc<[Value<'host>]>,
1767 },
1768 Never {
1769 signature: FunctionType,
1770 },
1771 Enum {
1772 variant: usize,
1773 definition: Rc<EnumType>,
1774 },
1775 Mut,
1776 OptionConstructor,
1777 OptionCase {
1778 some: bool,
1779 ty: ComplexType,
1780 },
1781 Borrow(&'host dyn ExternFn),
1782 Owned(Rc<dyn ExternFnOwned>),
1783}
1784
1785#[derive(Clone)]
1786enum StaticFunctionAction {
1787 With {
1788 program: Program,
1789 block_id: usize,
1790 program_counter: usize,
1791 signature: FunctionType,
1792 captures: Rc<[StaticValue]>,
1793 },
1794 Never {
1795 signature: FunctionType,
1796 },
1797 Enum {
1798 variant: usize,
1799 definition: Rc<EnumType>,
1800 },
1801 Mut,
1802 OptionConstructor,
1803 OptionCase {
1804 some: bool,
1805 ty: ComplexType,
1806 },
1807 Borrow(&'static dyn ExternFn),
1808 Owned(Rc<dyn ExternFnOwned>),
1809}
1810
1811impl<'host> From<FunctionAction<'host>> for Function<'host> {
1812 fn from(action: FunctionAction<'host>) -> Self {
1813 Self {
1814 action,
1815 argument: ().into(),
1816 }
1817 }
1818}
1819
1820impl std::fmt::Debug for FunctionAction<'_> {
1821 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1822 match self {
1823 Self::With {
1824 program,
1825 block_id,
1826 program_counter,
1827 signature,
1828 captures,
1829 } => f
1830 .debug_struct("Block")
1831 .field("program", &Rc::as_ptr(&program.bytes))
1832 .field("block_id", block_id)
1833 .field("program_counter", program_counter)
1834 .field("signature", signature)
1835 .field("captures", captures)
1836 .finish(),
1837 Self::Never { signature } => f
1838 .debug_struct("Never")
1839 .field("signature", signature)
1840 .finish(),
1841 Self::Enum {
1842 variant,
1843 definition,
1844 } => f
1845 .debug_struct("Enum")
1846 .field("variant", variant)
1847 .field("definition", definition)
1848 .finish(),
1849 Self::Mut => write!(f, "Mut"),
1850 Self::OptionConstructor => write!(f, "Option"),
1851 Self::OptionCase { some: true, ty } => f.debug_tuple("Some").field(ty).finish(),
1852 Self::OptionCase { some: false, ty } => f.debug_tuple("None").field(ty).finish(),
1853 Self::Borrow(arg0) => arg0.debug(f),
1854 Self::Owned(arg0) => arg0.debug(f),
1855 }
1856 }
1857}
1858
1859#[derive(Debug)]
1860enum MutRefSource<'host> {
1861 Origin(Rc<RefCell<Value<'host>>>),
1862 Child(Weak<RefCell<Value<'host>>>),
1863}
1864
1865#[derive(Debug)]
1876pub struct Mut<'host> {
1877 source: MutRefSource<'host>,
1878}
1879
1880impl<'host> Mut<'host> {
1881 pub fn new(rc: Rc<RefCell<Value<'host>>>) -> Self {
1882 Self {
1883 source: MutRefSource::Origin(rc),
1884 }
1885 }
1886
1887 #[must_use]
1892 pub fn upgrade(&self) -> Option<Rc<RefCell<Value<'host>>>> {
1893 match &self.source {
1894 MutRefSource::Origin(rc) => Some(rc.clone()),
1895 MutRefSource::Child(weak) => weak.upgrade(),
1896 }
1897 }
1898}
1899
1900impl Clone for Mut<'_> {
1901 fn clone(&self) -> Self {
1902 Self {
1903 source: MutRefSource::Child(match &self.source {
1904 MutRefSource::Origin(rc) => Rc::downgrade(rc),
1905 MutRefSource::Child(weak) => weak.clone(),
1906 }),
1907 }
1908 }
1909}
1910
1911#[derive(Clone, Debug)]
1913pub struct FunctionType {
1914 pub input: ComplexType,
1915 pub output: ComplexType,
1916}
1917
1918#[derive(Clone, Debug)]
1928pub struct EnumVariant<'host> {
1929 contents: Value<'host>,
1930 variant: usize,
1931 definition: Rc<EnumType>,
1932}
1933
1934#[derive(Clone, Debug)]
1938pub struct StaticEnumVariant {
1939 contents: StaticValue,
1940 variant: usize,
1941 definition: Rc<EnumType>,
1942}
1943
1944impl StaticEnumVariant {
1945 #[must_use]
1946 pub fn to_runtime<'host>(&self) -> EnumVariant<'host> {
1947 EnumVariant {
1948 contents: self.contents.to_runtime(),
1949 variant: self.variant,
1950 definition: self.definition.clone(),
1951 }
1952 }
1953}
1954
1955impl<'host, T: Borrow<StaticEnumVariant>> From<T> for EnumVariant<'host> {
1956 fn from(value: T) -> Self {
1957 value.borrow().to_runtime()
1958 }
1959}
1960
1961impl<'host> EnumVariant<'host> {
1962 #[must_use]
1963 pub fn contents(&self) -> &Value<'host> {
1964 &self.contents
1965 }
1966
1967 #[must_use]
1968 pub fn definition(&self) -> &Rc<EnumType> {
1969 &self.definition
1970 }
1971
1972 #[must_use]
1973 pub fn variant(&self) -> usize {
1974 self.variant
1975 }
1976
1977 #[must_use]
1978 pub fn split(self) -> (String, Value<'host>) {
1979 (
1980 self.definition.variants[self.variant].0.clone(),
1981 self.contents,
1982 )
1983 }
1984}
1985
1986#[derive(Clone, Debug, PartialEq, Eq)]
1990pub struct EnumType {
1991 pub variants: Rc<[(String, ComplexType)]>,
1992}
1993
1994impl From<Rc<EnumType>> for Type {
1995 fn from(value: Rc<EnumType>) -> Self {
1996 Type::Enum(value)
1997 }
1998}
1999
2000impl From<EnumType> for Type {
2001 fn from(value: EnumType) -> Self {
2002 Rc::new(value).into()
2003 }
2004}
2005
2006fn read_header(bytes: &[u8], at: usize) -> Result<usize, InvalidBytecode> {
2008 let (((a, b), c), d) = bytes
2009 .get(at)
2010 .zip(bytes.get(at + 1))
2011 .zip(bytes.get(at + 2))
2012 .zip(bytes.get(at + 3))
2013 .ok_or(InvalidBytecode::MalformedHeader)?;
2014 Ok(u32::from_le_bytes([*a, *b, *c, *d]) as usize)
2015}
2016
2017fn block_count(bytes: &[u8]) -> Result<usize, InvalidBytecode> {
2018 read_header(bytes, 0)
2019}
2020
2021fn string_count(bytes: &[u8]) -> Result<usize, InvalidBytecode> {
2022 read_header(bytes, size_of::<u32>())
2023}
2024
2025fn offsets(bytes: &[u8]) -> Result<&[u8], InvalidBytecode> {
2026 let offset_count = block_count(bytes)? + string_count(bytes)?;
2027 let first_offset = size_of::<u32>() * 2;
2028 let last_offset = first_offset + size_of::<u32>() * offset_count;
2029 bytes
2030 .get(first_offset..last_offset)
2031 .ok_or(InvalidBytecode::MalformedHeader)
2032}
2033
2034fn block(bytes: &[u8], block_id: usize) -> Result<&[u8], InvalidBytecode> {
2035 let offsets = offsets(bytes)?;
2036 let block_position = size_of::<u32>() * block_id;
2037 let start = read_header(offsets, block_position)?;
2038 let end = read_header(offsets, size_of::<u32>() + block_position).unwrap_or(bytes.len());
2039 bytes
2040 .get(start..end)
2041 .ok_or(InvalidBytecode::MalformedHeader)
2042}
2043
2044struct Frame<'a, 'host> {
2045 bytecode: &'a [u8],
2046 pc: usize,
2047 captures: Option<(Rc<[Value<'host>]>, NonZero<usize>)>,
2048 stack: Vec<Value<'host>>,
2049}
2050
2051impl<'host> Frame<'_, 'host> {
2052 fn next(&mut self) -> Result<u8, InvalidBytecode> {
2053 let next = self
2054 .bytecode
2055 .get(self.pc)
2056 .ok_or(InvalidBytecode::ProgramOutOfBounds)?;
2057 self.pc += 1;
2058 Ok(*next)
2059 }
2060
2061 fn next4(&mut self) -> Result<usize, InvalidBytecode> {
2062 Ok(u32::from_le_bytes([self.next()?, self.next()?, self.next()?, self.next()?]) as usize)
2063 }
2064
2065 fn next_i64(&mut self) -> Result<i64, InvalidBytecode> {
2066 Ok(i64::from_le_bytes([
2067 self.next()?,
2068 self.next()?,
2069 self.next()?,
2070 self.next()?,
2071 self.next()?,
2072 self.next()?,
2073 self.next()?,
2074 self.next()?,
2075 ]))
2076 }
2077
2078 fn stack_len(&self) -> usize {
2079 self.captures
2080 .as_ref()
2081 .map_or(0, |captures| captures.1.into())
2082 + self.stack.len()
2083 }
2084
2085 fn get(&self, index: usize) -> Result<&Value<'host>, InvalidBytecode> {
2086 if let Some((captures, len)) = &self.captures {
2087 if index < usize::from(*len) {
2088 captures.get(index)
2089 } else {
2090 self.stack.get(index - usize::from(*len))
2091 }
2092 } else {
2093 self.stack.get(index)
2094 }
2095 .ok_or(InvalidBytecode::StackOutOfBounds)
2096 }
2097
2098 fn push(&'_ mut self, value: Value<'host>) {
2099 self.stack.push(value);
2100 }
2101
2102 fn pop(&'_ mut self) -> Result<Value<'host>, Error> {
2103 self.stack.pop().map_or_else(
2104 || {
2105 if let Some((captures, len)) = &mut self.captures {
2106 let capture = captures[usize::from(*len) - 1].clone();
2107 if let Ok(new_len) = NonZero::try_from(usize::from(*len) - 1) {
2108 *len = new_len;
2109 } else {
2110 self.captures = None;
2111 }
2112 Ok(capture)
2113 } else {
2114 Err(InvalidBytecode::StackUnderflow.into())
2115 }
2116 },
2117 Ok,
2118 )
2119 }
2120
2121 fn into_bind(mut self, program: Program, block_id: usize) -> Result<Value<'host>, Error> {
2122 Ok(Value::Tuple(
2123 [
2124 self.pop()?,
2125 Function {
2126 action: FunctionAction::With {
2127 program,
2128 block_id,
2129 program_counter: self.pc,
2130 signature: FunctionType {
2131 input: Type::Any.into(),
2132 output: Type::Any.into(),
2133 },
2134 captures: rc_slice_from_iter(
2135 self.stack_len(),
2136 self.captures
2137 .iter()
2138 .flat_map(|captures| {
2139 captures.0[0..captures.1.into()].iter().cloned()
2140 })
2141 .chain(self.stack),
2142 ),
2143 },
2144 argument: Value::Unit,
2145 }
2146 .into(),
2147 ]
2148 .into(),
2149 ))
2150 }
2151}
2152
2153enum StepOutcome<'a, 'host> {
2154 Frame(Frame<'a, 'host>),
2155 Yield(Value<'host>),
2156}
2157
2158#[derive(Clone, Debug)]
2165pub struct Program {
2166 pub(crate) bytes: Rc<[u8]>,
2167 owned_strings: Rc<[Rc<str>]>,
2168}
2169
2170impl TryFrom<Rc<[u8]>> for Program {
2171 type Error = Error;
2172
2173 fn try_from(bytes: Rc<[u8]>) -> Result<Self, Self::Error> {
2174 let string_count = string_count(&bytes)?;
2175 let owned_strings = (0..string_count)
2176 .map(|string| {
2177 let string = size_of::<u32>() * (string + block_count(&bytes)?);
2178 let offsets = offsets(&bytes)?;
2179 let start = read_header(offsets, string)?;
2180 let end = read_header(offsets, size_of::<u32>() + string).unwrap_or(bytes.len());
2181 let string_bytes = bytes
2182 .get(start..end)
2183 .ok_or(InvalidBytecode::MalformedHeader)?;
2184 let string = str::from_utf8(string_bytes).map_err(InvalidBytecode::Utf8Error)?;
2185 Ok(Rc::from(string))
2186 })
2187 .collect::<Result<_, Error>>()?;
2188 Ok(Self {
2189 bytes,
2190 owned_strings,
2191 })
2192 }
2193}
2194
2195impl Program {
2196 pub fn eval<'host>(&self) -> Result<Value<'host>, Error> {
2200 self.eval_block(0, 0, None, None)
2201 }
2202
2203 fn eval_block<'host>(
2204 &self,
2205 block_id: usize,
2206 program_counter: usize,
2207 captures: impl Into<Option<Rc<[Value<'host>]>>>,
2208 argument: impl Into<Option<Value<'host>>>,
2209 ) -> Result<Value<'host>, Error> {
2210 let captures = captures
2211 .into()
2212 .and_then(|x| x.len().try_into().ok().map(|len| (x, len)));
2213 let mut frame = Frame {
2214 bytecode: block(&self.bytes, block_id)?,
2215 pc: program_counter,
2216 captures,
2217 stack: argument.into().into_iter().collect(),
2218 };
2219 let absolute_program_counter =
2221 frame.bytecode.as_ptr() as usize - block(&self.bytes, 0)?.as_ptr() as usize;
2222
2223 while frame.pc != frame.bytecode.len() {
2226 let pc = frame.pc;
2227 frame = match self
2228 .eval_step(block_id, frame)
2229 .map_err(|e| e.suggest_location(absolute_program_counter + pc))?
2230 {
2231 StepOutcome::Frame(frame) => frame,
2232 StepOutcome::Yield(value) => return Ok(value),
2233 }
2234 }
2235 frame.pop()
2236 }
2237
2238 fn eval_step<'a, 'host>(
2239 &self,
2240 block_id: usize,
2241 mut frame: Frame<'a, 'host>,
2242 ) -> Result<StepOutcome<'a, 'host>, Error> {
2243 macro_rules! bi_op {
2244 (let $l:ident, $r:ident: $type:ident => $expr_type:ident: $expr:expr) => {{
2245 let $r = frame.pop()?;
2246 let $l = frame.pop()?;
2247 match (&$l, &$r) {
2248 (Value::$type($l), Value::$type($r)) => frame.push(Value::$expr_type($expr)),
2249 _ => return Err(Error::expected_integers(&$l, &$r)),
2250 }
2251 }};
2252 }
2253 macro_rules! bi_num {
2254 (let $l:ident, $r:ident => $expr:expr) => {
2255 bi_op!(let $l, $r: I64 => I64: $expr)
2256 };
2257 }
2258 macro_rules! bi_cmp {
2259 (let $l:ident, $r:ident => $expr:expr) => {
2260 bi_op!(let $l, $r: I64 => Bool: $expr)
2261 };
2262 }
2263 let instruction = frame.next()?;
2264 match instruction {
2265 instruction::CLONE => {
2266 let index = frame.next4()?;
2267 #[allow(
2268 clippy::cast_possible_truncation,
2269 clippy::cast_possible_wrap,
2270 reason = "next4 only returns 32 bits"
2271 )]
2272 match index as i32 {
2273 0.. => {
2274 let value = frame.get(index)?;
2275 frame.push(value.clone());
2276 }
2277 builtins::ANY => {
2278 frame.push(Type::Any.into());
2279 }
2280 builtins::UNIT => {
2281 frame.push(Type::Unit.into());
2282 }
2283 builtins::I64 => {
2284 frame.push(Type::I64.into());
2285 }
2286 builtins::STRING => {
2287 frame.push(Type::String.into());
2288 }
2289 builtins::OPTION => {
2290 frame.push(Value::Function(Rc::new(
2291 FunctionAction::OptionConstructor.into(),
2292 )));
2293 }
2294 builtins::MUT => {
2295 frame.push(Value::Function(Rc::new(FunctionAction::Mut.into())));
2296 }
2297 _ => Err(InvalidBytecode::InvalidBuiltin)?,
2298 }
2299 }
2300 instruction::POP => {
2301 frame.pop()?;
2302 }
2303 instruction::COLLAPSE => {
2304 let value = frame.pop()?;
2305 for _ in 0..(frame.stack_len() - frame.next4()?) {
2306 frame.pop()?;
2307 }
2308 frame.push(value);
2309 }
2310 instruction::JUMP => {
2311 frame.pc = frame.next4()?;
2312 }
2313 instruction::IF => {
2314 let target = frame.next4()?;
2315 if let Value::Bool(false) = frame.pop()? {
2316 frame.pc = target;
2317 }
2318 }
2319
2320 instruction::PUSH_UNIT => {
2321 frame.push(().into());
2322 }
2323 instruction::PUSH_TRUE => {
2324 frame.push(true.into());
2325 }
2326 instruction::PUSH_FALSE => {
2327 frame.push(false.into());
2328 }
2329 instruction::PUSH_I64 => {
2330 let i = frame.next_i64()?.into();
2331 frame.push(i);
2332 }
2333 instruction::PUSH_STRING => {
2334 let string_id = frame.next4()?;
2335 let string = self
2336 .owned_strings
2337 .get(string_id)
2338 .ok_or(InvalidBytecode::InvalidStringId)?
2339 .clone();
2340 frame.push(string.into());
2341 }
2342 instruction::PUSH_FUNCTION => {
2343 let captures = frame.next4()?;
2344 let function = frame.next4()?;
2345 let output = frame.pop()?;
2346 let input = frame.pop()?;
2347 if function == 0 {
2348 for _ in 0..captures {
2350 frame.pop()?;
2351 }
2352 frame.push(Value::Function(Rc::new(
2353 FunctionAction::Never {
2354 signature: FunctionType {
2355 input: input.try_into()?,
2356 output: output.try_into()?,
2357 },
2358 }
2359 .into(),
2360 )));
2361 } else {
2362 let new_stack =
2363 rc_slice_try_from_iter_rev(captures, (0..captures).map(|_| frame.pop()))?;
2364 frame.push(Value::Function(Rc::new(
2365 FunctionAction::With {
2366 program: self.clone(),
2367 signature: FunctionType {
2368 input: input.try_into()?,
2369 output: output.try_into()?,
2370 },
2371 block_id: function,
2372 program_counter: 0,
2373 captures: new_stack,
2374 }
2375 .into(),
2376 )));
2377 }
2378 }
2379 instruction::PUSH_ENUM => {
2380 let variants = frame.pop()?;
2381 let Value::Tuple(Tuple(TupleStorage::Named(variants))) = variants else {
2382 Err(Error::expected_named_tuple(&variants))?
2383 };
2384 let variants = rc_slice_try_from_iter(
2385 variants.len(),
2386 variants.iter().map(|(name, value)| {
2387 value.clone().try_into().map(|value| (name.clone(), value))
2388 }),
2389 )?;
2390 frame.push(Type::from(EnumType { variants }).into());
2391 }
2392
2393 instruction::ADD => bi_num!(let l, r => l + r),
2394 instruction::SUB => bi_num!(let l, r => l - r),
2395 instruction::MUL => bi_num!(let l, r => l * r),
2396 instruction::DIV => bi_num!(let l, r => l / r),
2397 instruction::BITWISE_AND => bi_num!(let l, r => l & r),
2398 instruction::BITWISE_OR => bi_num!(let l, r => l | r),
2399 instruction::BITWISE_XOR => bi_num!(let l, r => l ^ r),
2400 instruction::GREATER => bi_cmp!(let l, r => l > r),
2401 instruction::GREATER_EQUAL => bi_cmp!(let l, r => l >= r),
2402 instruction::LESSER => bi_cmp!(let l, r => l < r),
2403 instruction::LESSER_EQUAL => bi_cmp!(let l, r => l <= r),
2404 instruction::MATCHES => {
2405 let candidate = frame.pop()?;
2406 let subject = frame.pop()?;
2407 if let Value::EnumVariant(subject) = &subject
2408 && let Value::Function(function) = &candidate
2409 && let FunctionAction::Enum {
2410 variant,
2411 definition,
2412 } = &function.action
2413 && subject.definition == *definition
2414 {
2415 if subject.variant == *variant {
2417 frame.pop()?;
2418 frame.push(subject.contents.clone());
2419
2420 frame.push(true.into());
2421 } else {
2422 frame.push(false.into());
2423 }
2424 } else if let Value::Option { contents, ty } = &subject
2425 && let Value::Function(function) = &candidate
2426 && let FunctionAction::OptionCase {
2427 some,
2428 ty: expected_ty,
2429 } = &function.action
2430 {
2431 match (contents, some) {
2432 (Some(contents), true) => {
2433 if !ty.compare(expected_ty) {
2434 return Err(Error::type_error(&subject, expected_ty));
2435 }
2436 frame.pop()?;
2438 frame.push((**contents).clone());
2439 frame.push(true.into());
2440 }
2441 (None, false) => {
2442 frame.pop()?;
2444 frame.push(().into());
2445 frame.push(true.into());
2446 }
2447 _ => {
2448 frame.push(false.into());
2449 }
2450 }
2451 } else {
2452 frame.push(subject.clone().eq(candidate)?.into());
2453 }
2454 }
2455 instruction::EQUAL_TO => {
2456 let r = frame.pop()?;
2457 let l = frame.pop()?;
2458 frame.push(l.eq(r)?.into());
2459 }
2460 instruction::NOT_EQUAL_TO => {
2461 let r = frame.pop()?;
2462 let l = frame.pop()?;
2463 frame.push((!l.eq(r)?).into());
2464 }
2465 instruction::LOGICAL_AND => bi_op!(let l, r: Bool => Bool: *l && *r),
2466 instruction::LOGICAL_OR => bi_op!(let l, r: Bool => Bool: *l || *r),
2467 instruction::PIPE => {
2468 let mut function = Rc::<Function>::try_from(frame.pop()?)?;
2469 let argument = frame.pop()?;
2470 let function_mut = Rc::make_mut(&mut function);
2471 let mut arguments = ().into();
2472 mem::swap(&mut arguments, &mut function_mut.argument);
2473 arguments = Value::concat(arguments, argument);
2474 mem::swap(&mut arguments, &mut function_mut.argument);
2475 frame.push(Value::Function(function));
2476 }
2477
2478 instruction::CALL => {
2479 let argument = frame.pop()?;
2480 let function = frame.pop()?;
2481 let result = match function {
2482 Value::Function(function) => Rc::<Function>::try_unwrap(function)
2483 .unwrap_or_else(|function| (*function).clone())
2484 .piped(argument)
2485 .eval()?,
2486 function => Err(Error::expected_function(&function))?,
2487 };
2488 frame.push(result);
2489 }
2490 instruction::JOIN => {
2491 let r = frame.pop()?;
2492 let l = frame.pop()?;
2493 frame.push(Value::concat(l, r));
2494 }
2495 instruction::LIST => {
2496 let length = frame.next4()?;
2497 let tuple = rc_slice_try_from_iter_rev(length, (0..length).map(|_| frame.pop()))?;
2498 frame.push(Tuple::from(tuple).into());
2499 }
2500 instruction::INDEX => {
2501 let index = frame.pop()?;
2502 let container = frame.pop()?;
2503 frame.push(container.index(index)?);
2504 }
2505 instruction::TRY_INDEX => {
2506 let index = frame.pop()?;
2507 let container = frame.pop()?;
2508 frame.push(container.index(index).ok().into());
2509 }
2510 instruction::NAME => {
2511 let name_id = frame.next4()?;
2512 let name = self
2513 .owned_strings
2514 .get(name_id)
2515 .ok_or(InvalidBytecode::InvalidStringId)?
2516 .clone();
2517 let value = frame.pop()?;
2518 frame.push(Value::Tuple(Tuple::from([(name, value)])));
2519 }
2520 instruction::NEGATIVE => {
2521 let value = frame.pop()?.i64()?;
2522 frame.push((-value).into());
2523 }
2524 instruction::DEREF => {
2525 let value = frame.pop()?.into_refcell()?;
2526 frame.push(value.try_borrow().map_err(Error::other)?.clone());
2527 }
2528 instruction::SET => {
2529 let value = frame.pop()?;
2530 let target = frame.pop()?.into_refcell()?;
2531 *target.borrow_mut() = value;
2532 }
2533 instruction::BIND => {
2534 let bind = frame.pop()?.function()?;
2535 return Ok(StepOutcome::Yield(
2536 bind.piped(frame.into_bind(self.clone(), block_id)?)
2537 .eval()?,
2538 ));
2539 }
2540 instruction::YIELD => {
2541 return Ok(StepOutcome::Yield(frame.into_bind(self.clone(), block_id)?));
2542 }
2543
2544 _ => Err(InvalidBytecode::InvalidInstruction)?,
2545 };
2546 Ok(StepOutcome::Frame(frame))
2547 }
2548}
2549
2550#[allow(clippy::missing_errors_doc)]
2551pub trait Extern {
2552 fn index<'host>(&'host self, index: Value<'host>) -> Result<Value<'host>, Error>;
2553
2554 fn to_static(&self) -> Option<&'static dyn Extern> {
2555 None
2556 }
2557
2558 fn any(&self) -> Option<&dyn Any> {
2563 None
2564 }
2565
2566 fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2567 write!(f, "{{external value}}")
2568 }
2569}
2570
2571#[allow(clippy::missing_errors_doc)]
2572pub trait ExternOwned {
2573 fn index<'host>(self: Rc<Self>, index: Value<'host>) -> Result<Value<'host>, Error>;
2576
2577 fn any(&self) -> Option<&dyn Any> {
2585 None
2586 }
2587
2588 fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2589 write!(f, "{{external value}}")
2590 }
2591}
2592
2593#[allow(clippy::missing_errors_doc)]
2594pub trait ExternFn {
2595 fn call<'host>(&'host self, argument: Value<'host>) -> Result<Value<'host>, Error>;
2596
2597 fn to_static(&self) -> Option<&'static dyn ExternFn> {
2598 None
2599 }
2600
2601 fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2602 write!(f, "{{external function}}")
2603 }
2604}
2605
2606#[allow(clippy::missing_errors_doc)]
2607pub trait ExternFnOwned {
2608 fn call<'host>(self: Rc<Self>, argument: Value<'host>) -> Result<Value<'host>, Error>;
2611
2612 fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2613 write!(f, "{{external function}}")
2614 }
2615}