Macro system done in theory
too afraid to begin debugging, resting for a moment
This commit is contained in:
@@ -15,7 +15,7 @@ use futures::{FutureExt, StreamExt};
|
||||
use orchid_api_derive::Coding;
|
||||
use orchid_api_traits::{Coding, Decode, Encode, Request, enc_vec};
|
||||
use orchid_base::clone;
|
||||
use orchid_base::error::{OrcErr, OrcRes, mk_err};
|
||||
use orchid_base::error::{OrcErrv, OrcRes, mk_errv, mk_errv_floating};
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format};
|
||||
use orchid_base::interner::Interner;
|
||||
use orchid_base::location::Pos;
|
||||
@@ -24,6 +24,7 @@ use orchid_base::reqnot::Requester;
|
||||
use trait_set::trait_set;
|
||||
|
||||
use crate::api;
|
||||
use crate::conv::ToExpr;
|
||||
// use crate::error::{ProjectError, ProjectResult};
|
||||
use crate::expr::{Expr, ExprData, ExprHandle, ExprKind};
|
||||
use crate::gen_expr::GExpr;
|
||||
@@ -92,7 +93,7 @@ pub struct ForeignAtom {
|
||||
}
|
||||
impl ForeignAtom {
|
||||
pub fn pos(&self) -> Pos { self.pos.clone() }
|
||||
pub fn ctx(&self) -> SysCtx { self.expr.ctx.clone() }
|
||||
pub fn ctx(&self) -> &SysCtx { &self.expr.ctx }
|
||||
pub fn ex(self) -> Expr {
|
||||
let (handle, pos) = (self.expr.clone(), self.pos.clone());
|
||||
let data = ExprData { pos, kind: ExprKind::Atom(ForeignAtom { ..self }) };
|
||||
@@ -110,6 +111,9 @@ impl ForeignAtom {
|
||||
.await?;
|
||||
Some(M::Response::decode(Pin::new(&mut &rep[..])).await)
|
||||
}
|
||||
pub async fn downcast<T: AtomicFeatures>(self) -> Result<TypAtom<T>, NotTypAtom> {
|
||||
TypAtom::downcast(self.ex().handle()).await
|
||||
}
|
||||
}
|
||||
impl fmt::Display for ForeignAtom {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Atom::{:?}", self.atom) }
|
||||
@@ -122,6 +126,9 @@ impl Format for ForeignAtom {
|
||||
FmtUnit::from_api(&self.ctx().reqnot().request(api::ExtAtomPrint(self.atom.clone())).await)
|
||||
}
|
||||
}
|
||||
impl ToExpr for ForeignAtom {
|
||||
async fn to_expr(self) -> GExpr { self.ex().to_expr().await }
|
||||
}
|
||||
|
||||
pub struct NotTypAtom {
|
||||
pub pos: Pos,
|
||||
@@ -130,11 +137,11 @@ pub struct NotTypAtom {
|
||||
pub ctx: SysCtx,
|
||||
}
|
||||
impl NotTypAtom {
|
||||
pub async fn mk_err(&self) -> OrcErr {
|
||||
mk_err(
|
||||
pub async fn mk_err(&self) -> OrcErrv {
|
||||
mk_errv(
|
||||
self.ctx.i().i("Not the expected type").await,
|
||||
format!("This expression is not a {}", self.typ.name()),
|
||||
[self.pos.clone().into()],
|
||||
[self.pos.clone()],
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -216,10 +223,12 @@ impl<A: AtomCard> Default for MethodSetBuilder<A> {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TypAtom<A: AtomicFeatures> {
|
||||
pub data: ForeignAtom,
|
||||
pub untyped: ForeignAtom,
|
||||
pub value: A::Data,
|
||||
}
|
||||
impl<A: AtomicFeatures> TypAtom<A> {
|
||||
pub fn ctx(&self) -> &SysCtx { self.untyped.ctx() }
|
||||
pub fn i(&self) -> &Interner { self.ctx().i() }
|
||||
pub async fn downcast(expr: Rc<ExprHandle>) -> Result<Self, NotTypAtom> {
|
||||
match Expr::from_handle(expr).atom().await {
|
||||
Err(expr) => Err(NotTypAtom {
|
||||
@@ -242,9 +251,9 @@ impl<A: AtomicFeatures> TypAtom<A> {
|
||||
pub async fn request<M: AtomMethod>(&self, req: M) -> M::Response
|
||||
where A: Supports<M> {
|
||||
M::Response::decode(Pin::new(
|
||||
&mut &(self.data.ctx().reqnot().request(api::Fwd(
|
||||
self.data.atom.clone(),
|
||||
Sym::parse(M::NAME, self.data.ctx().i()).await.unwrap().tok().to_api(),
|
||||
&mut &(self.untyped.ctx().reqnot().request(api::Fwd(
|
||||
self.untyped.atom.clone(),
|
||||
Sym::parse(M::NAME, self.untyped.ctx().i()).await.unwrap().tok().to_api(),
|
||||
enc_vec(&req).await,
|
||||
)))
|
||||
.await
|
||||
@@ -257,6 +266,9 @@ impl<A: AtomicFeatures> Deref for TypAtom<A> {
|
||||
type Target = A::Data;
|
||||
fn deref(&self) -> &Self::Target { &self.value }
|
||||
}
|
||||
impl<A: AtomicFeatures> ToExpr for TypAtom<A> {
|
||||
async fn to_expr(self) -> GExpr { self.untyped.to_expr().await }
|
||||
}
|
||||
|
||||
pub struct AtomCtx<'a>(pub &'a [u8], pub Option<api::AtomId>, pub SysCtx);
|
||||
impl FmtCtx for AtomCtx<'_> {
|
||||
@@ -317,10 +329,10 @@ impl Format for AtomFactory {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn err_not_callable(i: &Interner) -> OrcErr {
|
||||
mk_err(i.i("This atom is not callable").await, "Attempted to apply value as function", [])
|
||||
pub async fn err_not_callable(i: &Interner) -> OrcErrv {
|
||||
mk_errv_floating(i.i("This atom is not callable").await, "Attempted to apply value as function")
|
||||
}
|
||||
|
||||
pub async fn err_not_command(i: &Interner) -> OrcErr {
|
||||
mk_err(i.i("This atom is not a command").await, "Settled on an inactionable value", [])
|
||||
pub async fn err_not_command(i: &Interner) -> OrcErrv {
|
||||
mk_errv_floating(i.i("This atom is not a command").await, "Settled on an inactionable value")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user