New macro system and stdlib additions
This commit is contained in:
@@ -6,12 +6,13 @@ use orchid_base::error::{OrcErr, OrcErrv};
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::reqnot::Requester;
|
||||
use orchid_base::{match_mapping, tl_cache};
|
||||
|
||||
use crate::api;
|
||||
use crate::atom::{AtomFactory, ToAtom};
|
||||
use crate::context::ctx;
|
||||
use crate::expr::Expr;
|
||||
use crate::system::SysCtx;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GExpr {
|
||||
@@ -19,29 +20,32 @@ pub struct GExpr {
|
||||
pub pos: Pos,
|
||||
}
|
||||
impl GExpr {
|
||||
pub async fn api_return(self, ctx: SysCtx) -> api::Expression {
|
||||
/// Release notifications will not be sent for the slots. Use this with
|
||||
/// messages that imply ownership transfer
|
||||
pub async fn serialize(self) -> api::Expression {
|
||||
if let GExprKind::Slot(ex) = self.kind {
|
||||
let hand = ex.handle();
|
||||
mem::drop(ex);
|
||||
api::Expression {
|
||||
location: api::Location::SlotTarget,
|
||||
kind: match Rc::try_unwrap(hand) {
|
||||
Ok(h) => api::ExpressionKind::Slot { tk: h.serialize(), by_value: true },
|
||||
Err(rc) => api::ExpressionKind::Slot { tk: rc.tk, by_value: false },
|
||||
},
|
||||
// an instance is leaked here, we must take ownership of it when we receive this
|
||||
kind: api::ExpressionKind::Slot(hand.serialize().await),
|
||||
}
|
||||
} else {
|
||||
api::Expression {
|
||||
location: api::Location::Inherit,
|
||||
kind: self.kind.api_return(ctx).boxed_local().await,
|
||||
kind: self.kind.serialize().boxed_local().await,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn at(self, pos: Pos) -> Self { GExpr { pos, kind: self.kind } }
|
||||
pub async fn create(self) -> Expr {
|
||||
Expr::deserialize(ctx().reqnot().request(api::Create(self.serialize().await)).await).await
|
||||
}
|
||||
}
|
||||
impl Format for GExpr {
|
||||
async fn print<'a>(&'a self, c: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {
|
||||
self.kind.print(c).await
|
||||
self.kind.print(c).boxed_local().await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,21 +61,21 @@ pub enum GExprKind {
|
||||
Bottom(OrcErrv),
|
||||
}
|
||||
impl GExprKind {
|
||||
pub async fn api_return(self, ctx: SysCtx) -> api::ExpressionKind {
|
||||
pub async fn serialize(self) -> api::ExpressionKind {
|
||||
match_mapping!(self, Self => api::ExpressionKind {
|
||||
Call(
|
||||
f => Box::new(f.api_return(ctx.clone()).await),
|
||||
x => Box::new(x.api_return(ctx).await)
|
||||
f => Box::new(f.serialize().await),
|
||||
x => Box::new(x.serialize().await)
|
||||
),
|
||||
Seq(
|
||||
a => Box::new(a.api_return(ctx.clone()).await),
|
||||
b => Box::new(b.api_return(ctx).await)
|
||||
a => Box::new(a.serialize().await),
|
||||
b => Box::new(b.serialize().await)
|
||||
),
|
||||
Lambda(arg, body => Box::new(body.api_return(ctx).await)),
|
||||
Lambda(arg, body => Box::new(body.serialize().await)),
|
||||
Arg(arg),
|
||||
Const(name.to_api()),
|
||||
Bottom(err.to_api()),
|
||||
NewAtom(fac.clone().build(ctx).await),
|
||||
NewAtom(fac.clone().build().await),
|
||||
} {
|
||||
Self::Slot(_) => panic!("processed elsewhere")
|
||||
})
|
||||
@@ -118,7 +122,7 @@ pub fn seq(deps: impl IntoIterator<Item = GExpr>, val: GExpr) -> GExpr {
|
||||
|
||||
pub fn arg(n: u64) -> GExpr { inherit(GExprKind::Arg(n)) }
|
||||
|
||||
pub fn lambda(n: u64, b: GExpr) -> GExpr { inherit(GExprKind::Lambda(n, Box::new(b))) }
|
||||
pub fn lambda(n: u64, [b]: [GExpr; 1]) -> GExpr { inherit(GExprKind::Lambda(n, Box::new(b))) }
|
||||
|
||||
pub fn call(f: GExpr, argv: impl IntoIterator<Item = GExpr>) -> GExpr {
|
||||
(argv.into_iter()).fold(f, |f, x| inherit(GExprKind::Call(Box::new(f), Box::new(x))))
|
||||
|
||||
Reference in New Issue
Block a user