forked from Orchid/orchid
New plans for macros
About to move them completely to stdlib
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, OnceLock};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use derive_destructure::destructure;
|
||||
use orchid_api::atom::Atom;
|
||||
use orchid_api::expr::{Acquire, Clause, Expr, ExprTicket, Inspect, Release};
|
||||
use orchid_base::error::{errv_from_apiv, errv_to_apiv, OrcErr};
|
||||
use orchid_base::interner::{deintern, Tok};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::reqnot::Requester;
|
||||
|
||||
use crate::atom::{AtomFactory, AtomicFeatures, ForeignAtom};
|
||||
use crate::error::{err_from_apiv, errv_to_apiv, DynProjectError, ProjectErrorObj};
|
||||
use crate::system::{DynSystem, SysCtx};
|
||||
use crate::api;
|
||||
use crate::atom::{AtomFactory, ForeignAtom, ToAtom};
|
||||
use crate::system::SysCtx;
|
||||
|
||||
#[derive(destructure)]
|
||||
pub struct ExprHandle {
|
||||
pub tk: ExprTicket,
|
||||
pub tk: api::ExprTicket,
|
||||
pub ctx: SysCtx,
|
||||
}
|
||||
impl ExprHandle {
|
||||
pub(crate) fn from_args(ctx: SysCtx, tk: ExprTicket) -> Self { Self { ctx, tk } }
|
||||
pub(crate) fn into_tk(self) -> ExprTicket {
|
||||
pub(crate) fn from_args(ctx: SysCtx, tk: api::ExprTicket) -> Self { Self { ctx, tk } }
|
||||
pub(crate) fn into_tk(self) -> api::ExprTicket {
|
||||
let (tk, ..) = self.destructure();
|
||||
tk
|
||||
}
|
||||
@@ -27,12 +27,12 @@ impl ExprHandle {
|
||||
}
|
||||
impl Clone for ExprHandle {
|
||||
fn clone(&self) -> Self {
|
||||
self.ctx.reqnot.notify(Acquire(self.ctx.id, self.tk));
|
||||
self.ctx.reqnot.notify(api::Acquire(self.ctx.id, self.tk));
|
||||
Self { ctx: self.ctx.clone(), tk: self.tk }
|
||||
}
|
||||
}
|
||||
impl Drop for ExprHandle {
|
||||
fn drop(&mut self) { self.ctx.reqnot.notify(Release(self.ctx.id, self.tk)) }
|
||||
fn drop(&mut self) { self.ctx.reqnot.notify(api::Release(self.ctx.id, self.tk)) }
|
||||
}
|
||||
|
||||
#[derive(Clone, destructure)]
|
||||
@@ -45,15 +45,21 @@ impl OwnedExpr {
|
||||
pub fn get_data(&self) -> &GenExpr {
|
||||
self.val.get_or_init(|| {
|
||||
Box::new(GenExpr::from_api(
|
||||
self.handle.ctx.reqnot.request(Inspect(self.handle.tk)).expr,
|
||||
self.handle.ctx.reqnot.request(api::Inspect(self.handle.tk)).expr,
|
||||
&self.handle.ctx,
|
||||
))
|
||||
})
|
||||
}
|
||||
pub fn foreign_atom(self) -> Result<ForeignAtom, Self> {
|
||||
pub fn foreign_atom(self) -> Result<ForeignAtom<'static>, Self> {
|
||||
if let GenExpr { clause: GenClause::Atom(_, atom), pos: position } = self.get_data() {
|
||||
let (atom, position) = (atom.clone(), position.clone());
|
||||
return Ok(ForeignAtom { expr: self.handle, atom, pos: position });
|
||||
return Ok(ForeignAtom {
|
||||
ctx: self.handle.ctx.clone(),
|
||||
expr: Some(self.handle),
|
||||
char_marker: PhantomData,
|
||||
pos: position,
|
||||
atom,
|
||||
});
|
||||
}
|
||||
Err(self)
|
||||
}
|
||||
@@ -69,13 +75,13 @@ pub struct GenExpr {
|
||||
pub clause: GenClause,
|
||||
}
|
||||
impl GenExpr {
|
||||
pub fn to_api(&self, sys: &dyn DynSystem) -> Expr {
|
||||
Expr { location: self.pos.to_api(), clause: self.clause.to_api(sys) }
|
||||
pub fn to_api(&self, ctx: SysCtx) -> api::Expr {
|
||||
api::Expr { location: self.pos.to_api(), clause: self.clause.to_api(ctx) }
|
||||
}
|
||||
pub fn into_api(self, sys: &dyn DynSystem) -> Expr {
|
||||
Expr { location: self.pos.to_api(), clause: self.clause.into_api(sys) }
|
||||
pub fn into_api(self, ctx: SysCtx) -> api::Expr {
|
||||
api::Expr { location: self.pos.to_api(), clause: self.clause.into_api(ctx) }
|
||||
}
|
||||
pub fn from_api(api: Expr, ctx: &SysCtx) -> Self {
|
||||
pub fn from_api(api: api::Expr, ctx: &SysCtx) -> Self {
|
||||
Self { pos: Pos::from_api(&api.location), clause: GenClause::from_api(api.clause, ctx) }
|
||||
}
|
||||
}
|
||||
@@ -89,60 +95,59 @@ pub enum GenClause {
|
||||
Seq(Box<GenExpr>, Box<GenExpr>),
|
||||
Const(Tok<Vec<Tok<String>>>),
|
||||
NewAtom(AtomFactory),
|
||||
Atom(ExprTicket, Atom),
|
||||
Bottom(ProjectErrorObj),
|
||||
Atom(api::ExprTicket, api::Atom),
|
||||
Bottom(Vec<OrcErr>),
|
||||
}
|
||||
impl GenClause {
|
||||
pub fn to_api(&self, sys: &dyn DynSystem) -> Clause {
|
||||
pub fn to_api(&self, ctx: SysCtx) -> api::Clause {
|
||||
match self {
|
||||
Self::Call(f, x) => Clause::Call(Box::new(f.to_api(sys)), Box::new(x.to_api(sys))),
|
||||
Self::Seq(a, b) => Clause::Seq(Box::new(a.to_api(sys)), Box::new(b.to_api(sys))),
|
||||
Self::Lambda(arg, body) => Clause::Lambda(*arg, Box::new(body.to_api(sys))),
|
||||
Self::Arg(arg) => Clause::Arg(*arg),
|
||||
Self::Const(name) => Clause::Const(name.marker()),
|
||||
Self::Bottom(err) => Clause::Bottom(errv_to_apiv([err.clone()])),
|
||||
Self::NewAtom(fac) => Clause::NewAtom(fac.clone().build(sys)),
|
||||
Self::Atom(tk, atom) => Clause::Atom(*tk, atom.clone()),
|
||||
Self::Call(f, x) =>
|
||||
api::Clause::Call(Box::new(f.to_api(ctx.clone())), Box::new(x.to_api(ctx))),
|
||||
Self::Seq(a, b) => api::Clause::Seq(Box::new(a.to_api(ctx.clone())), Box::new(b.to_api(ctx))),
|
||||
Self::Lambda(arg, body) => api::Clause::Lambda(*arg, Box::new(body.to_api(ctx))),
|
||||
Self::Arg(arg) => api::Clause::Arg(*arg),
|
||||
Self::Const(name) => api::Clause::Const(name.marker()),
|
||||
Self::Bottom(err) => api::Clause::Bottom(errv_to_apiv(err)),
|
||||
Self::NewAtom(fac) => api::Clause::NewAtom(fac.clone().build(ctx)),
|
||||
Self::Atom(tk, atom) => api::Clause::Atom(*tk, atom.clone()),
|
||||
Self::Slot(_) => panic!("Slot is forbidden in const tree"),
|
||||
}
|
||||
}
|
||||
pub fn into_api(self, sys: &dyn DynSystem) -> Clause {
|
||||
pub fn into_api(self, ctx: SysCtx) -> api::Clause {
|
||||
match self {
|
||||
Self::Call(f, x) => Clause::Call(Box::new(f.into_api(sys)), Box::new(x.into_api(sys))),
|
||||
Self::Seq(a, b) => Clause::Seq(Box::new(a.into_api(sys)), Box::new(b.into_api(sys))),
|
||||
Self::Lambda(arg, body) => Clause::Lambda(arg, Box::new(body.into_api(sys))),
|
||||
Self::Arg(arg) => Clause::Arg(arg),
|
||||
Self::Slot(extk) => Clause::Slot(extk.handle.into_tk()),
|
||||
Self::Const(name) => Clause::Const(name.marker()),
|
||||
Self::Bottom(err) => Clause::Bottom(errv_to_apiv([err])),
|
||||
Self::NewAtom(fac) => Clause::NewAtom(fac.clone().build(sys)),
|
||||
Self::Atom(tk, atom) => Clause::Atom(tk, atom),
|
||||
Self::Call(f, x) =>
|
||||
api::Clause::Call(Box::new(f.into_api(ctx.clone())), Box::new(x.into_api(ctx))),
|
||||
Self::Seq(a, b) =>
|
||||
api::Clause::Seq(Box::new(a.into_api(ctx.clone())), Box::new(b.into_api(ctx))),
|
||||
Self::Lambda(arg, body) => api::Clause::Lambda(arg, Box::new(body.into_api(ctx))),
|
||||
Self::Arg(arg) => api::Clause::Arg(arg),
|
||||
Self::Slot(extk) => api::Clause::Slot(extk.handle.into_tk()),
|
||||
Self::Const(name) => api::Clause::Const(name.marker()),
|
||||
Self::Bottom(err) => api::Clause::Bottom(errv_to_apiv(err.iter())),
|
||||
Self::NewAtom(fac) => api::Clause::NewAtom(fac.clone().build(ctx)),
|
||||
Self::Atom(tk, atom) => api::Clause::Atom(tk, atom),
|
||||
}
|
||||
}
|
||||
pub fn from_api(api: Clause, ctx: &SysCtx) -> Self {
|
||||
pub fn from_api(api: api::Clause, ctx: &SysCtx) -> Self {
|
||||
match api {
|
||||
Clause::Arg(id) => Self::Arg(id),
|
||||
Clause::Lambda(arg, body) => Self::Lambda(arg, Box::new(GenExpr::from_api(*body, ctx))),
|
||||
Clause::NewAtom(_) => panic!("Clause::NewAtom should never be received, only sent"),
|
||||
Clause::Bottom(s) => Self::Bottom(err_from_apiv(&s, &ctx.reqnot)),
|
||||
Clause::Call(f, x) => Self::Call(
|
||||
Box::new(GenExpr::from_api(*f, ctx)),
|
||||
Box::new(GenExpr::from_api(*x, ctx)),
|
||||
),
|
||||
Clause::Seq(a, b) => Self::Seq(
|
||||
Box::new(GenExpr::from_api(*a, ctx)),
|
||||
Box::new(GenExpr::from_api(*b, ctx)),
|
||||
),
|
||||
Clause::Const(name) => Self::Const(deintern(name)),
|
||||
Clause::Slot(exi) => Self::Slot(OwnedExpr::new(ExprHandle::from_args(ctx.clone(), exi))),
|
||||
Clause::Atom(tk, atom) => Self::Atom(tk, atom),
|
||||
api::Clause::Arg(id) => Self::Arg(id),
|
||||
api::Clause::Lambda(arg, body) => Self::Lambda(arg, Box::new(GenExpr::from_api(*body, ctx))),
|
||||
api::Clause::NewAtom(_) => panic!("Clause::NewAtom should never be received, only sent"),
|
||||
api::Clause::Bottom(s) => Self::Bottom(errv_from_apiv(&s)),
|
||||
api::Clause::Call(f, x) =>
|
||||
Self::Call(Box::new(GenExpr::from_api(*f, ctx)), Box::new(GenExpr::from_api(*x, ctx))),
|
||||
api::Clause::Seq(a, b) =>
|
||||
Self::Seq(Box::new(GenExpr::from_api(*a, ctx)), Box::new(GenExpr::from_api(*b, ctx))),
|
||||
api::Clause::Const(name) => Self::Const(deintern(name)),
|
||||
api::Clause::Slot(exi) => Self::Slot(OwnedExpr::new(ExprHandle::from_args(ctx.clone(), exi))),
|
||||
api::Clause::Atom(tk, atom) => Self::Atom(tk, atom),
|
||||
}
|
||||
}
|
||||
}
|
||||
fn inherit(clause: GenClause) -> GenExpr { GenExpr { pos: Pos::Inherit, clause } }
|
||||
|
||||
pub fn sym_ref(path: Tok<Vec<Tok<String>>>) -> GenExpr { inherit(GenClause::Const(path)) }
|
||||
pub fn atom<A: AtomicFeatures>(atom: A) -> GenExpr { inherit(GenClause::NewAtom(atom.factory())) }
|
||||
pub fn atom<A: ToAtom>(atom: A) -> GenExpr { inherit(GenClause::NewAtom(atom.to_atom_factory())) }
|
||||
|
||||
pub fn seq(ops: impl IntoIterator<Item = GenExpr>) -> GenExpr {
|
||||
fn recur(mut ops: impl Iterator<Item = GenExpr>) -> Option<GenExpr> {
|
||||
@@ -169,5 +174,5 @@ pub fn call(v: impl IntoIterator<Item = GenExpr>) -> GenExpr {
|
||||
.expect("Empty call expression")
|
||||
}
|
||||
|
||||
pub fn bot<E: DynProjectError>(msg: E) -> GenExpr { inherit(GenClause::Bottom(Arc::new(msg))) }
|
||||
pub fn bot_obj(e: ProjectErrorObj) -> GenExpr { inherit(GenClause::Bottom(e)) }
|
||||
pub fn bot(e: OrcErr) -> GenExpr { botv(vec![e]) }
|
||||
pub fn botv(ev: Vec<OrcErr>) -> GenExpr { inherit(GenClause::Bottom(ev)) }
|
||||
|
||||
Reference in New Issue
Block a user