forked from Orchid/orchid
Began implementing fully isomorphic macros
Like Rust's Proc macros. Now we have preprocessor recursion to worry about. I also made a cool macro for enums
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
use std::any::{type_name, Any, TypeId};
|
||||
use std::io::Write;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use orchid_api::ExprTicket;
|
||||
use orchid_api_traits::{enc_vec, Coding, Decode};
|
||||
use orchid_api_traits::{enc_vec, Coding};
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::name::Sym;
|
||||
|
||||
use crate::api;
|
||||
use crate::atom::{
|
||||
err_not_callable, err_not_command, get_info, AtomCard, AtomCtx, AtomDynfo, AtomFactory, Atomic,
|
||||
AtomicFeaturesImpl, AtomicVariant, ReqPck, RequestPack,
|
||||
err_not_callable, err_not_command, get_info, AtomCard, AtomCtx, AtomDynfo, AtomFactory, MethodSet, Atomic, AtomicFeaturesImpl, AtomicVariant
|
||||
};
|
||||
use crate::expr::{bot, ExprHandle, GenExpr};
|
||||
use crate::expr::{bot, Expr, ExprHandle};
|
||||
use crate::system::SysCtx;
|
||||
|
||||
pub struct ThinVariant;
|
||||
@@ -25,11 +23,13 @@ impl<A: ThinAtom + Atomic<Variant = ThinVariant>> AtomicFeaturesImpl<ThinVariant
|
||||
api::Atom { drop: None, data: buf, owner: ctx.id }
|
||||
})
|
||||
}
|
||||
fn _info() -> Self::_Info {
|
||||
ThinAtomDynfo(Self::reg_reqs())
|
||||
}
|
||||
type _Info = ThinAtomDynfo<Self>;
|
||||
const _INFO: &'static Self::_Info = &ThinAtomDynfo(PhantomData);
|
||||
}
|
||||
|
||||
pub struct ThinAtomDynfo<T: ThinAtom>(PhantomData<T>);
|
||||
pub struct ThinAtomDynfo<T: ThinAtom>(MethodSet<T>);
|
||||
impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
fn print(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> String {
|
||||
T::decode(&mut &buf[..]).print(ctx)
|
||||
@@ -37,32 +37,29 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
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: api::ExprTicket) -> GenExpr {
|
||||
fn call(&self, AtomCtx(buf, _, ctx): AtomCtx, arg: api::ExprTicket) -> Expr {
|
||||
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
|
||||
}
|
||||
fn call_ref(&self, AtomCtx(buf, _, ctx): AtomCtx, arg: api::ExprTicket) -> GenExpr {
|
||||
fn call_ref(&self, AtomCtx(buf, _, ctx): AtomCtx, arg: api::ExprTicket) -> Expr {
|
||||
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
|
||||
}
|
||||
fn handle_req(
|
||||
&self,
|
||||
AtomCtx(buf, _, sys): AtomCtx,
|
||||
key: Sym,
|
||||
req: &mut dyn std::io::Read,
|
||||
write: &mut dyn Write,
|
||||
) {
|
||||
let pack = RequestPack::<T, dyn Write> { req: Decode::decode(req), write, sys };
|
||||
T::decode(&mut &buf[..]).handle_req(pack)
|
||||
rep: &mut dyn Write,
|
||||
) -> bool {
|
||||
self.0.dispatch(&T::decode(&mut &buf[..]), sys, key, req, rep)
|
||||
}
|
||||
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<'_>) -> OrcRes<Option<GenExpr>> {
|
||||
fn command(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> OrcRes<Option<Expr>> {
|
||||
T::decode(&mut &buf[..]).command(ctx)
|
||||
}
|
||||
fn serialize(&self, AtomCtx(buf, ..): AtomCtx<'_>, write: &mut dyn Write) -> Vec<ExprTicket> {
|
||||
T::decode(&mut &buf[..]).encode(write);
|
||||
fn serialize(&self, actx: AtomCtx<'_>, write: &mut dyn Write) -> Vec<api::ExprTicket> {
|
||||
T::decode(&mut &actx.0[..]).encode(write);
|
||||
Vec::new()
|
||||
}
|
||||
fn deserialize(&self, ctx: SysCtx, data: &[u8], refs: &[ExprTicket]) -> api::Atom {
|
||||
fn deserialize(&self, ctx: SysCtx, data: &[u8], refs: &[api::ExprTicket]) -> api::Atom {
|
||||
assert!(refs.is_empty(), "Refs found when deserializing thin atom");
|
||||
T::decode(&mut &data[..])._factory().build(ctx)
|
||||
}
|
||||
@@ -76,16 +73,9 @@ pub trait ThinAtom:
|
||||
AtomCard<Data = Self> + Atomic<Variant = ThinVariant> + Coding + Send + Sync + 'static
|
||||
{
|
||||
#[allow(unused_variables)]
|
||||
fn call(&self, arg: ExprHandle) -> GenExpr { bot(err_not_callable()) }
|
||||
fn call(&self, arg: ExprHandle) -> Expr { bot([err_not_callable()]) }
|
||||
#[allow(unused_variables)]
|
||||
fn same(&self, ctx: SysCtx, other: &Self) -> bool {
|
||||
let tname = type_name::<Self>();
|
||||
writeln!(ctx.logger, "Override ThinAtom::same for {tname} if it can appear in macro input");
|
||||
false
|
||||
}
|
||||
fn handle_req(&self, pck: impl ReqPck<Self>);
|
||||
#[allow(unused_variables)]
|
||||
fn command(&self, ctx: SysCtx) -> OrcRes<Option<GenExpr>> { Err(vec![err_not_command()]) }
|
||||
fn command(&self, ctx: SysCtx) -> OrcRes<Option<Expr>> { Err(err_not_command().into()) }
|
||||
#[allow(unused_variables)]
|
||||
fn print(&self, ctx: SysCtx) -> String { format!("ThinAtom({})", type_name::<Self>()) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user