New plans for macros

About to move them completely to stdlib
This commit is contained in:
2024-08-18 22:57:06 +02:00
parent 11951ede43
commit 3a63894de2
78 changed files with 2557 additions and 1980 deletions

View File

@@ -1,17 +1,16 @@
use std::any::{type_name, Any, TypeId};
use std::io::Write;
use std::marker::PhantomData;
use std::sync::Arc;
use orchid_api::atom::LocalAtom;
use orchid_api::expr::ExprTicket;
use orchid_api_traits::{Coding, Decode, Encode};
use orchid_api::ExprTicket;
use orchid_api_traits::{enc_vec, Coding, Decode};
use orchid_base::error::OrcRes;
use crate::api;
use crate::atom::{
get_info, AtomCard, AtomCtx, AtomDynfo, AtomFactory, Atomic, AtomicFeaturesImpl, AtomicVariant,
ErrNotCallable, ReqPck, RequestPack,
err_not_callable, err_not_command, get_info, AtomCard, AtomCtx, AtomDynfo, AtomFactory, Atomic,
AtomicFeaturesImpl, AtomicVariant, ReqPck, RequestPack,
};
use crate::error::ProjectResult;
use crate::expr::{bot, ExprHandle, GenExpr};
use crate::system::SysCtx;
@@ -19,10 +18,11 @@ pub struct ThinVariant;
impl AtomicVariant for ThinVariant {}
impl<A: ThinAtom + Atomic<Variant = ThinVariant>> AtomicFeaturesImpl<ThinVariant> for A {
fn _factory(self) -> AtomFactory {
AtomFactory::new(move |sys| {
let mut buf = get_info::<A>(sys.dyn_card()).0.enc_vec();
AtomFactory::new(move |ctx| {
let (id, _) = get_info::<A>(ctx.cted.inst().card());
let mut buf = enc_vec(&id);
self.encode(&mut buf);
LocalAtom { drop: false, data: buf }
api::Atom { drop: None, data: buf, owner: ctx.id }
})
}
type _Info = ThinAtomDynfo<Self>;
@@ -31,48 +31,59 @@ impl<A: ThinAtom + Atomic<Variant = ThinVariant>> AtomicFeaturesImpl<ThinVariant
pub struct ThinAtomDynfo<T: ThinAtom>(PhantomData<T>);
impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
fn print(&self, AtomCtx(buf, ctx): AtomCtx<'_>) -> String { T::decode(&mut &buf[..]).print(ctx) }
fn print(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> String {
T::decode(&mut &buf[..]).print(ctx)
}
fn tid(&self) -> TypeId { TypeId::of::<T>() }
fn name(&self) -> &'static str { type_name::<T>() }
fn decode(&self, AtomCtx(buf, _): AtomCtx) -> Box<dyn Any> { Box::new(T::decode(&mut &buf[..])) }
fn call(&self, AtomCtx(buf, ctx): AtomCtx, arg: ExprTicket) -> GenExpr {
fn decode(&self, AtomCtx(buf, ..): AtomCtx) -> Box<dyn Any> { Box::new(T::decode(&mut &buf[..])) }
fn call(&self, AtomCtx(buf, _, ctx): AtomCtx, arg: api::ExprTicket) -> GenExpr {
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
}
fn call_ref(&self, AtomCtx(buf, ctx): AtomCtx, arg: ExprTicket) -> GenExpr {
fn call_ref(&self, AtomCtx(buf, _, ctx): AtomCtx, arg: api::ExprTicket) -> GenExpr {
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
}
fn handle_req(
&self,
AtomCtx(buf, ctx): AtomCtx,
AtomCtx(buf, _, sys): AtomCtx,
req: &mut dyn std::io::Read,
rep: &mut dyn Write,
write: &mut dyn Write,
) {
T::decode(&mut &buf[..]).handle_req(ctx, RequestPack::<T, dyn Write>(Decode::decode(req), rep))
let pack = RequestPack::<T, dyn Write>{ req: Decode::decode(req), write, sys };
T::decode(&mut &buf[..]).handle_req(pack)
}
fn same(&self, AtomCtx(buf, ctx): AtomCtx, buf2: &[u8]) -> bool {
T::decode(&mut &buf[..]).same(ctx, &T::decode(&mut &buf2[..]))
fn same(&self, AtomCtx(buf, _, ctx): AtomCtx, a2: &api::Atom) -> bool {
T::decode(&mut &buf[..]).same(ctx, &T::decode(&mut &a2.data[8..]))
}
fn command(&self, AtomCtx(buf, ctx): AtomCtx<'_>) -> ProjectResult<Option<GenExpr>> {
fn command(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> OrcRes<Option<GenExpr>> {
T::decode(&mut &buf[..]).command(ctx)
}
fn drop(&self, AtomCtx(buf, ctx): AtomCtx) {
let string_self = T::decode(&mut &buf[..]).print(ctx);
eprintln!("Received drop signal for non-drop atom {string_self:?}")
fn serialize(&self, AtomCtx(buf, _, _): AtomCtx<'_>, write: &mut dyn Write) -> Vec<ExprTicket> {
T::decode(&mut &buf[..]).encode(write);
Vec::new()
}
fn deserialize(&self, ctx: SysCtx, data: &[u8], refs: &[ExprTicket]) -> api::Atom {
assert!(refs.is_empty(), "Refs found when deserializing thin atom");
T::decode(&mut &data[..])._factory().build(ctx)
}
fn drop(&self, AtomCtx(buf, _, ctx): AtomCtx) {
let string_self = T::decode(&mut &buf[..]).print(ctx.clone());
writeln!(ctx.logger, "Received drop signal for non-drop atom {string_self:?}");
}
}
pub trait ThinAtom: AtomCard<Data = Self> + Coding + Send + Sync + 'static {
pub trait ThinAtom: AtomCard<Data = Self> + Atomic<Variant = ThinVariant> + Coding + Send + Sync + 'static {
#[allow(unused_variables)]
fn call(&self, arg: ExprHandle) -> GenExpr { bot(ErrNotCallable) }
fn call(&self, arg: ExprHandle) -> GenExpr { bot(err_not_callable()) }
#[allow(unused_variables)]
fn same(&self, ctx: SysCtx, other: &Self) -> bool {
let tname = type_name::<Self>();
eprintln!("Override ThinAtom::same for {tname} if it can be generated during parsing");
writeln!(ctx.logger, "Override ThinAtom::same for {tname} if it can appear in macro input");
false
}
fn handle_req(&self, ctx: SysCtx, pck: impl ReqPck<Self>);
fn handle_req(&self, pck: impl ReqPck<Self>);
#[allow(unused_variables)]
fn command(&self, ctx: SysCtx) -> ProjectResult<Option<GenExpr>> { Err(Arc::new(ErrNotCallable)) }
fn command(&self, ctx: SysCtx) -> OrcRes<Option<GenExpr>> { Err(vec![err_not_command()]) }
#[allow(unused_variables)]
fn print(&self, ctx: SysCtx) -> String { format!("ThinAtom({})", type_name::<Self>()) }
}