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:
@@ -1,17 +1,18 @@
|
||||
use std::mem;
|
||||
use std::pin::{Pin, pin};
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::FutureExt;
|
||||
use orchid_base::error::{OrcErr, OrcErrv};
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::{match_mapping, tl_cache};
|
||||
use futures::{FutureExt, Stream, StreamExt, stream};
|
||||
use orchid_base::{
|
||||
FmtCtx, FmtUnit, Format, OrcErr, OrcErrv, Pos, Sym, Variants, match_mapping, tl_cache,
|
||||
};
|
||||
|
||||
use crate::api;
|
||||
use crate::atom::{AtomFactory, ToAtom};
|
||||
use crate::atom::{AtomFactory, AtomicFeatures};
|
||||
use crate::conv::{ToExpr, ToExprFuture};
|
||||
use crate::entrypoint::request;
|
||||
use crate::expr::Expr;
|
||||
use crate::system::sys_id;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GExpr {
|
||||
@@ -39,7 +40,7 @@ impl GExpr {
|
||||
}
|
||||
pub fn at(self, pos: Pos) -> Self { GExpr { pos, kind: self.kind } }
|
||||
pub async fn create(self) -> Expr {
|
||||
Expr::deserialize(request(api::Create(self.serialize().await)).await).await
|
||||
Expr::deserialize(request(api::Create(sys_id(), self.serialize().await)).await).await
|
||||
}
|
||||
}
|
||||
impl Format for GExpr {
|
||||
@@ -55,6 +56,7 @@ pub enum GExprKind {
|
||||
Arg(u64),
|
||||
Seq(Box<GExpr>, Box<GExpr>),
|
||||
Const(Sym),
|
||||
#[allow(private_interfaces)]
|
||||
NewAtom(AtomFactory),
|
||||
Slot(Expr),
|
||||
Bottom(OrcErrv),
|
||||
@@ -105,27 +107,105 @@ impl Format for GExprKind {
|
||||
|
||||
fn inherit(kind: GExprKind) -> GExpr { GExpr { pos: Pos::Inherit, kind } }
|
||||
|
||||
pub fn sym_ref(path: Sym) -> GExpr { inherit(GExprKind::Const(path)) }
|
||||
/// Creates an expression from a new atom that we own.
|
||||
pub fn new_atom<A: ToAtom>(atom: A) -> GExpr { inherit(GExprKind::NewAtom(atom.to_atom_factory())) }
|
||||
|
||||
pub fn seq(deps: impl IntoIterator<Item = GExpr>, val: GExpr) -> GExpr {
|
||||
fn recur(mut ops: impl Iterator<Item = GExpr>) -> Option<GExpr> {
|
||||
let op = ops.next()?;
|
||||
Some(match recur(ops) {
|
||||
None => op,
|
||||
Some(rec) => inherit(GExprKind::Seq(Box::new(op), Box::new(rec))),
|
||||
})
|
||||
impl ToExpr for Sym {
|
||||
async fn to_expr(self) -> Expr
|
||||
where Self: Sized {
|
||||
self.to_gen().await.create().await
|
||||
}
|
||||
recur(deps.into_iter().chain([val])).expect("Empty list provided to seq!")
|
||||
async fn to_gen(self) -> GExpr { inherit(GExprKind::Const(self)) }
|
||||
}
|
||||
/// Creates an expression from a new atom that we own.
|
||||
pub fn new_atom<A: AtomicFeatures>(atom: A) -> GExpr { inherit(GExprKind::NewAtom(atom.factory())) }
|
||||
|
||||
pub fn seq(
|
||||
deps: impl IntoGExprStream,
|
||||
val: impl ToExpr,
|
||||
) -> ToExprFuture<impl Future<Output = GExpr>> {
|
||||
ToExprFuture(async {
|
||||
async fn recur(mut ops: Pin<&mut impl Stream<Item = GExpr>>) -> Option<GExpr> {
|
||||
let op = ops.next().await?.to_gen().await;
|
||||
Some(match recur(ops).boxed_local().await {
|
||||
None => op,
|
||||
Some(rec) => inherit(GExprKind::Seq(Box::new(op), Box::new(rec))),
|
||||
})
|
||||
}
|
||||
recur(pin!(deps.into_gexpr_stream().chain(stream::iter([val.to_gen().await]))))
|
||||
.await
|
||||
.expect("Empty list provided to seq!")
|
||||
})
|
||||
}
|
||||
|
||||
pub fn arg(n: u64) -> GExpr { inherit(GExprKind::Arg(n)) }
|
||||
|
||||
pub fn lambda(n: u64, [b]: [GExpr; 1]) -> GExpr { inherit(GExprKind::Lambda(n, Box::new(b))) }
|
||||
pub fn lam<const N: u64>(b: impl ToExpr) -> ToExprFuture<impl Future<Output = GExpr>> {
|
||||
dyn_lambda(N, b)
|
||||
}
|
||||
|
||||
pub fn call(f: GExpr, argv: impl IntoIterator<Item = GExpr>) -> GExpr {
|
||||
(argv.into_iter()).fold(f, |f, x| inherit(GExprKind::Call(Box::new(f), Box::new(x))))
|
||||
pub fn dyn_lambda(n: u64, b: impl ToExpr) -> ToExprFuture<impl Future<Output = GExpr>> {
|
||||
ToExprFuture(async move { inherit(GExprKind::Lambda(n, Box::new(b.to_gen().await))) })
|
||||
}
|
||||
|
||||
pub trait IntoGExprStream {
|
||||
fn into_gexpr_stream(self) -> impl Stream<Item = GExpr>;
|
||||
}
|
||||
impl<T: ToExpr> IntoGExprStream for T {
|
||||
fn into_gexpr_stream(self) -> impl Stream<Item = GExpr> { (self,).into_gexpr_stream() }
|
||||
}
|
||||
impl IntoGExprStream for Vec<GExpr> {
|
||||
fn into_gexpr_stream(self) -> impl Stream<Item = GExpr> { stream::iter(self) }
|
||||
}
|
||||
|
||||
mod tuple_impls {
|
||||
use futures::{Stream, StreamExt, stream};
|
||||
|
||||
use super::IntoGExprStream;
|
||||
use crate::conv::ToExpr;
|
||||
use crate::gen_expr::GExpr;
|
||||
|
||||
macro_rules! tuple_impl {
|
||||
($($T:ident)*) => {
|
||||
pastey::paste!{
|
||||
impl<$($T: ToExpr),*> IntoGExprStream for ($($T,)*) {
|
||||
fn into_gexpr_stream(self) -> impl Stream<Item = GExpr> {
|
||||
let ($([< $T:snake >],)*) = self;
|
||||
stream::once(async { stream::iter([$([< $T:snake >].to_gen().await,)*]) }).flatten()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tuple_impl!();
|
||||
tuple_impl!(A);
|
||||
tuple_impl!(A B);
|
||||
tuple_impl!(A B C);
|
||||
tuple_impl!(A B C D);
|
||||
tuple_impl!(A B C D E);
|
||||
tuple_impl!(A B C D E F);
|
||||
}
|
||||
|
||||
pub fn call(
|
||||
f: impl ToExpr,
|
||||
argv: impl IntoGExprStream,
|
||||
) -> ToExprFuture<impl Future<Output = GExpr>> {
|
||||
ToExprFuture(async {
|
||||
(argv.into_gexpr_stream())
|
||||
.fold(f.to_gen().await, async |f, x| inherit(GExprKind::Call(Box::new(f), Box::new(x))))
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
pub fn call_v(
|
||||
f: impl ToExpr,
|
||||
argv: impl IntoIterator<Item: ToExpr>,
|
||||
) -> ToExprFuture<impl Future<Output = GExpr>> {
|
||||
ToExprFuture(async {
|
||||
stream::iter(argv)
|
||||
.fold(f.to_gen().await, async |f, x| {
|
||||
inherit(GExprKind::Call(Box::new(f), Box::new(x.to_gen().await)))
|
||||
})
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bot(ev: impl IntoIterator<Item = OrcErr>) -> GExpr {
|
||||
|
||||
Reference in New Issue
Block a user