forked from Orchid/orchid
Significantly extended stdlib
This commit is contained in:
@@ -6,7 +6,7 @@ use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::future::{LocalBoxFuture, join_all};
|
||||
use futures::{AsyncWrite, FutureExt};
|
||||
use itertools::Itertools;
|
||||
use never::Never;
|
||||
@@ -14,6 +14,7 @@ use orchid_api_traits::Encode;
|
||||
use orchid_base::clone;
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::format::{FmtCtx, FmtUnit};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use task_local::task_local;
|
||||
use trait_set::trait_set;
|
||||
@@ -24,7 +25,7 @@ use crate::atom_owned::{DeserializeCtx, OwnedAtom, OwnedVariant};
|
||||
use crate::conv::ToExpr;
|
||||
use crate::coroutine_exec::{ExecHandle, exec};
|
||||
use crate::expr::Expr;
|
||||
use crate::gen_expr::GExpr;
|
||||
use crate::gen_expr::{GExpr, new_atom};
|
||||
use crate::system::sys_id;
|
||||
|
||||
trait_set! {
|
||||
@@ -44,6 +45,16 @@ pub fn get_arg(idx: usize) -> Expr {
|
||||
.expect("get_arg called outside ExprFunc")
|
||||
}
|
||||
|
||||
pub fn get_argc() -> usize {
|
||||
ARGV.try_with(|argv| argv.len()).expect("get_arg called outside ExprFunc")
|
||||
}
|
||||
|
||||
pub async fn get_arg_posv(idxes: impl IntoIterator<Item = usize>) -> impl Iterator<Item = Pos> {
|
||||
let args = (ARGV.try_with(|argv| idxes.into_iter().map(|i| &argv[i]).cloned().collect_vec()))
|
||||
.expect("get_arg_posv called outside ExprFunc");
|
||||
join_all(args.iter().map(|expr| expr.pos())).await.into_iter()
|
||||
}
|
||||
|
||||
pub trait ExprFunc<I, O>: Clone + 'static {
|
||||
fn argtyps() -> &'static [TypeId];
|
||||
fn apply<'a>(&self, hand: ExecHandle<'a>, v: Vec<Expr>) -> impl Future<Output = OrcRes<GExpr>>;
|
||||
@@ -123,7 +134,7 @@ impl OwnedAtom for Fun {
|
||||
if new_args.len() == self.record.argtyps.len() {
|
||||
(self.record.fun)(new_args).await.to_gen().await
|
||||
} else {
|
||||
Self { args: new_args, record: self.record.clone(), path: self.path.clone() }.to_gen().await
|
||||
new_atom(Self { args: new_args, record: self.record.clone(), path: self.path.clone() })
|
||||
}
|
||||
}
|
||||
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
|
||||
@@ -169,7 +180,7 @@ impl OwnedAtom for Lambda {
|
||||
if new_args.len() == self.record.argtyps.len() {
|
||||
(self.record.fun)(new_args).await.to_gen().await
|
||||
} else {
|
||||
Self { args: new_args, record: self.record.clone() }.to_gen().await
|
||||
new_atom(Self { args: new_args, record: self.record.clone() })
|
||||
}
|
||||
}
|
||||
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
|
||||
@@ -181,7 +192,7 @@ mod expr_func_derives {
|
||||
|
||||
use orchid_base::error::OrcRes;
|
||||
|
||||
use super::ExprFunc;
|
||||
use super::{ARGV, ExprFunc};
|
||||
use crate::conv::{ToExpr, TryFromExpr};
|
||||
use crate::func_atom::{ExecHandle, Expr};
|
||||
use crate::gen_expr::GExpr;
|
||||
@@ -200,8 +211,9 @@ mod expr_func_derives {
|
||||
}
|
||||
async fn apply<'a>(&self, _: ExecHandle<'a>, v: Vec<Expr>) -> OrcRes<GExpr> {
|
||||
assert_eq!(v.len(), Self::argtyps().len(), "Arity mismatch");
|
||||
let argv = v.clone();
|
||||
let [$([< $t:lower >],)*] = v.try_into().unwrap_or_else(|_| panic!("Checked above"));
|
||||
Ok(self($($t::try_from_expr([< $t:lower >]).await?,)*).await.to_gen().await)
|
||||
Ok(ARGV.scope(argv, self($($t::try_from_expr([< $t:lower >]).await?,)*)).await.to_gen().await)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user