New macro system and stdlib additions

This commit is contained in:
2025-11-21 14:25:03 +01:00
parent b77653f841
commit 603efef28e
230 changed files with 3033 additions and 16640 deletions

View File

@@ -19,11 +19,11 @@ use trait_set::trait_set;
use crate::atom::Atomic;
use crate::atom_owned::{DeserializeCtx, OwnedAtom, OwnedVariant};
use crate::context::{SysCtxEntry, ctx, i};
use crate::conv::ToExpr;
use crate::coroutine_exec::{ExecHandle, exec};
use crate::expr::Expr;
use crate::gen_expr::GExpr;
use crate::system::{SysCtx, SysCtxEntry};
trait_set! {
trait FunCB = Fn(Vec<Expr>) -> LocalBoxFuture<'static, OrcRes<GExpr>> + 'static;
@@ -43,14 +43,11 @@ struct FunRecord {
fun: Rc<dyn FunCB>,
}
fn process_args<I, O, F: ExprFunc<I, O>>(
debug: impl AsRef<str> + Clone + 'static,
f: F,
) -> FunRecord {
fn process_args<I, O, F: ExprFunc<I, O>>(f: F) -> FunRecord {
let argtyps = F::argtyps();
let fun = Rc::new(move |v: Vec<Expr>| {
clone!(f, v mut);
exec(debug.clone(), async move |mut hand| {
exec(async move |mut hand| {
let mut norm_args = Vec::with_capacity(v.len());
for (expr, typ) in v.into_iter().zip(argtyps) {
if *typ != TypeId::of::<Expr>() {
@@ -77,13 +74,14 @@ pub(crate) struct Fun {
record: FunRecord,
}
impl Fun {
pub async fn new<I, O, F: ExprFunc<I, O>>(path: Sym, ctx: SysCtx, f: F) -> Self {
pub async fn new<I, O, F: ExprFunc<I, O>>(path: Sym, f: F) -> Self {
let ctx = ctx();
let funs: &FunsCtx = ctx.get_or_default();
let mut fung = funs.0.lock().await;
let record = if let Some(record) = fung.get(&path) {
record.clone()
} else {
let record = process_args(path.to_string(), f);
let record = process_args(f);
fung.insert(path.clone(), record.clone());
record
};
@@ -101,20 +99,19 @@ impl OwnedAtom for Fun {
async fn call_ref(&self, arg: Expr) -> GExpr {
let new_args = self.args.iter().cloned().chain([arg]).collect_vec();
if new_args.len() == self.record.argtyps.len() {
(self.record.fun)(new_args).await.to_expr().await
(self.record.fun)(new_args).await.to_gen().await
} else {
Self { args: new_args, record: self.record.clone(), path: self.path.clone() }.to_expr().await
Self { args: new_args, record: self.record.clone(), path: self.path.clone() }.to_gen().await
}
}
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
async fn serialize(&self, write: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
self.path.to_api().encode(write).await;
self.args.clone()
}
async fn deserialize(mut ctx: impl DeserializeCtx, args: Self::Refs) -> Self {
let sys = ctx.sys();
let path = Sym::from_api(ctx.decode().await, sys.i()).await;
let record = (sys.get::<FunsCtx>().0.lock().await.get(&path))
async fn deserialize(mut ds_cx: impl DeserializeCtx, args: Self::Refs) -> Self {
let path = Sym::from_api(ds_cx.decode().await, &i()).await;
let record = (ctx().get::<FunsCtx>().0.lock().await.get(&path))
.expect("Function missing during deserialization")
.clone();
Self { args, path, record }
@@ -134,8 +131,8 @@ pub struct Lambda {
record: FunRecord,
}
impl Lambda {
pub fn new<I, O, F: ExprFunc<I, O>>(debug: impl AsRef<str> + Clone + 'static, f: F) -> Self {
Self { args: vec![], record: process_args(debug, f) }
pub fn new<I, O, F: ExprFunc<I, O>>(f: F) -> Self {
Self { args: vec![], record: process_args(f) }
}
}
impl Atomic for Lambda {
@@ -148,9 +145,9 @@ impl OwnedAtom for Lambda {
async fn call_ref(&self, arg: Expr) -> GExpr {
let new_args = self.args.iter().cloned().chain([arg]).collect_vec();
if new_args.len() == self.record.argtyps.len() {
(self.record.fun)(new_args).await.to_expr().await
(self.record.fun)(new_args).await.to_gen().await
} else {
Self { args: new_args, record: self.record.clone() }.to_expr().await
Self { args: new_args, record: self.record.clone() }.to_gen().await
}
}
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
@@ -182,7 +179,7 @@ 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 [$([< $t:lower >],)*] = v.try_into().unwrap_or_else(|_| panic!("Checked above"));
Ok(self($($t::try_from_expr([< $t:lower >]).await?,)*).await.to_expr().await)
Ok(self($($t::try_from_expr([< $t:lower >]).await?,)*).await.to_gen().await)
}
}
}