partway towards commands

I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
This commit is contained in:
2026-03-13 16:48:42 +01:00
parent cdcca694c5
commit 09cfcb1839
146 changed files with 3582 additions and 2822 deletions

View File

@@ -3,16 +3,17 @@ use std::pin::Pin;
use dyn_clone::DynClone;
use never::Never;
use orchid_base::error::{OrcErrv, OrcRes, mk_errv};
use orchid_base::format::{Format, fmt};
use orchid_base::interner::is;
use orchid_base::location::Pos;
use orchid_base::{Format, OrcErrv, OrcRes, Pos, fmt, is, mk_errv};
use trait_set::trait_set;
use crate::atom::{AtomicFeatures, ForeignAtom, TAtom};
use crate::expr::{Expr, ExprKind};
use crate::gen_expr::{GExpr, bot};
/// Attempt to cast a generic Orchid expression reference to a concrete value.
/// Note that this cannot evaluate the expression, and if it is not already
/// evaluated, it will simply fail. Use [crate::ExecHandle::exec] inside
/// [crate::exec] to wait for an expression to be evaluated
pub trait TryFromExpr: Sized {
fn try_from_expr(expr: Expr) -> impl Future<Output = OrcRes<Self>>;
}
@@ -27,6 +28,8 @@ impl<T: TryFromExpr, U: TryFromExpr> TryFromExpr for (T, U) {
}
}
/// Error raised when a composite expression was assumed to be an
/// [crate::Atomic], or if the expression was not evaluated yet
async fn err_not_atom(pos: Pos, value: &impl Format) -> OrcErrv {
mk_errv(is("Expected an atom").await, format!("{} is not an atom", fmt(value).await), [pos])
}
@@ -46,21 +49,43 @@ impl TryFromExpr for ForeignAtom {
impl<A: AtomicFeatures> TryFromExpr for TAtom<A> {
async fn try_from_expr(expr: Expr) -> OrcRes<Self> {
let f = ForeignAtom::try_from_expr(expr).await?;
match f.clone().downcast::<A>().await {
match f.clone().downcast::<A>() {
Ok(a) => Ok(a),
Err(e) => Err(e.mk_err().await),
}
}
}
/// Values that are convertible to an Orchid expression. This could mean that
/// the value owns an [Expr] or it may involve more complex operations
pub trait ToExpr {
/// Inline the value in an expression returned from a function or included in
/// the const tree returned by [crate::System::env]
fn to_gen(self) -> impl Future<Output = GExpr>;
/// Convert the value into a freestanding expression
fn to_expr(self) -> impl Future<Output = Expr>
where Self: Sized {
async { self.to_gen().await.create().await }
}
}
pub struct ToExprFuture<F>(pub F);
impl<F: Future<Output: ToExpr>> ToExpr for ToExprFuture<F> {
async fn to_gen(self) -> GExpr { self.0.await.to_gen().await }
async fn to_expr(self) -> Expr
where Self: Sized {
self.0.await.to_expr().await
}
}
impl<F: Future> Future for ToExprFuture<F> {
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
unsafe { self.map_unchecked_mut(|this| &mut this.0) }.poll(cx)
}
}
/// Type-erased [ToExpr]
pub trait ToExprDyn {
fn to_gen_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = GExpr> + 'a>>
where Self: 'a;
@@ -79,6 +104,8 @@ impl<T: ToExpr> ToExprDyn for T {
}
}
trait_set! {
/// type-erased [ToExpr] and [Clone]. Needed for a value to be
/// included in [crate::System::env]
pub trait ClonableToExprDyn = ToExprDyn + DynClone;
}
impl ToExpr for Box<dyn ToExprDyn> {