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 $(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 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 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#[derive(Clone)]
127pub enum Value<'host> {
128 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#[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#[derive(Clone, Debug)]
272pub enum Type {
273 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 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#[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 #[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 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 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 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 #[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 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 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 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
953impl<'host> Value<'host> {
955 pub fn into_unit(self) -> Result<(), Error> {
959 self.try_into()
960 }
961
962 pub fn into_tuple(self) -> Result<Tuple<Value<'host>>, Error> {
966 self.try_into()
967 }
968
969 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 pub fn into_bool(self) -> Result<bool, Error> {
986 self.try_into()
987 }
988
989 pub fn into_i64(self) -> Result<i64, Error> {
993 self.try_into()
994 }
995
996 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 pub fn into_function(self) -> Result<Function<'host>, Error> {
1016 self.try_into()
1017 }
1018
1019 pub fn into_enum_variant(self) -> Result<Rc<EnumVariant<'host>>, Error> {
1023 self.try_into()
1024 }
1025
1026 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 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 pub fn into_complex_type(self) -> Result<ComplexType, Error> {
1050 self.try_into()
1051 }
1052
1053 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#[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#[derive(Clone, Debug)]
1285pub struct Function<'host> {
1286 action: FunctionAction<'host>,
1287 argument: Value<'host>,
1288}
1289
1290#[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 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 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#[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 #[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#[derive(Clone, Debug)]
1673pub struct FunctionType {
1674 pub input: ComplexType,
1675 pub output: ComplexType,
1676}
1677
1678#[derive(Clone, Debug)]
1688pub struct EnumVariant<'host> {
1689 contents: Value<'host>,
1690 variant: usize,
1691 definition: Rc<EnumType>,
1692}
1693
1694#[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#[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
1766fn 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#[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 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 let absolute_program_counter =
1981 frame.bytecode.as_ptr() as usize - block(&self.bytes, 0)?.as_ptr() as usize;
1982
1983 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 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 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 frame.pop()?;
2200 frame.push((**contents).clone());
2201 frame.push(true.into());
2202 }
2203 (None, false) => {
2204 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 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 fn index<'host>(self: Rc<Self>, index: Value<'host>) -> Result<Value<'host>, Error>;
2336
2337 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 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}