New macro system and stdlib additions
This commit is contained in:
@@ -4,14 +4,13 @@ use std::pin::Pin;
|
||||
use dyn_clone::DynClone;
|
||||
use never::Never;
|
||||
use orchid_base::error::{OrcErrv, OrcRes, mk_errv};
|
||||
use orchid_base::interner::Interner;
|
||||
use orchid_base::location::Pos;
|
||||
use trait_set::trait_set;
|
||||
|
||||
use crate::atom::{AtomicFeatures, ForeignAtom, TAtom, ToAtom};
|
||||
use crate::context::i;
|
||||
use crate::expr::Expr;
|
||||
use crate::gen_expr::{GExpr, atom, bot};
|
||||
use crate::system::{SysCtx, downcast_atom};
|
||||
|
||||
pub trait TryFromExpr: Sized {
|
||||
fn try_from_expr(expr: Expr) -> impl Future<Output = OrcRes<Self>>;
|
||||
@@ -27,18 +26,14 @@ impl<T: TryFromExpr, U: TryFromExpr> TryFromExpr for (T, U) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn err_not_atom(pos: Pos, i: &Interner) -> OrcErrv {
|
||||
mk_errv(i.i("Expected an atom").await, "This expression is not an atom", [pos])
|
||||
}
|
||||
|
||||
async fn err_type(pos: Pos, i: &Interner) -> OrcErrv {
|
||||
mk_errv(i.i("Type error").await, "The atom is a different type than expected", [pos])
|
||||
async fn err_not_atom(pos: Pos) -> OrcErrv {
|
||||
mk_errv(i().i("Expected an atom").await, "This expression is not an atom", [pos])
|
||||
}
|
||||
|
||||
impl TryFromExpr for ForeignAtom {
|
||||
async fn try_from_expr(expr: Expr) -> OrcRes<Self> {
|
||||
match expr.atom().await {
|
||||
Err(ex) => Err(err_not_atom(ex.data().await.pos.clone(), ex.ctx().i()).await),
|
||||
Err(ex) => Err(err_not_atom(ex.data().await.pos.clone()).await),
|
||||
Ok(f) => Ok(f),
|
||||
}
|
||||
}
|
||||
@@ -47,27 +42,34 @@ impl TryFromExpr for ForeignAtom {
|
||||
impl<A: AtomicFeatures> TryFromExpr for TAtom<A> {
|
||||
async fn try_from_expr(expr: Expr) -> OrcRes<Self> {
|
||||
let f = ForeignAtom::try_from_expr(expr).await?;
|
||||
match downcast_atom::<A>(f).await {
|
||||
match f.clone().downcast::<A>().await {
|
||||
Ok(a) => Ok(a),
|
||||
Err(f) => Err(err_type(f.pos(), f.ctx().i()).await),
|
||||
Err(e) => Err(e.mk_err().await),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromExpr for SysCtx {
|
||||
async fn try_from_expr(expr: Expr) -> OrcRes<Self> { Ok(expr.ctx()) }
|
||||
}
|
||||
|
||||
pub trait ToExpr {
|
||||
fn to_expr(self) -> impl Future<Output = GExpr>;
|
||||
fn to_gen(self) -> impl Future<Output = GExpr>;
|
||||
fn to_expr(self) -> impl Future<Output = Expr>
|
||||
where Self: Sized {
|
||||
async { self.to_gen().await.create().await }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToExprDyn {
|
||||
fn to_expr_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = GExpr> + 'a>>
|
||||
fn to_gen_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = GExpr> + 'a>>
|
||||
where Self: 'a;
|
||||
|
||||
fn to_expr_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = Expr> + 'a>>
|
||||
where Self: 'a;
|
||||
}
|
||||
impl<T: ToExpr> ToExprDyn for T {
|
||||
fn to_expr_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = GExpr> + 'a>>
|
||||
fn to_gen_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = GExpr> + 'a>>
|
||||
where Self: 'a {
|
||||
Box::pin(self.to_gen())
|
||||
}
|
||||
fn to_expr_dyn<'a>(self: Box<Self>) -> Pin<Box<dyn Future<Output = Expr> + 'a>>
|
||||
where Self: 'a {
|
||||
Box::pin(self.to_expr())
|
||||
}
|
||||
@@ -76,35 +78,39 @@ trait_set! {
|
||||
pub trait ClonableToExprDyn = ToExprDyn + DynClone;
|
||||
}
|
||||
impl ToExpr for Box<dyn ToExprDyn> {
|
||||
async fn to_expr(self) -> GExpr { self.to_expr_dyn().await }
|
||||
async fn to_gen(self) -> GExpr { self.to_gen_dyn().await }
|
||||
async fn to_expr(self) -> Expr { self.to_expr_dyn().await }
|
||||
}
|
||||
impl ToExpr for Box<dyn ClonableToExprDyn> {
|
||||
async fn to_expr(self) -> GExpr { self.to_expr_dyn().await }
|
||||
async fn to_gen(self) -> GExpr { self.to_gen_dyn().await }
|
||||
async fn to_expr(self) -> Expr { self.to_expr_dyn().await }
|
||||
}
|
||||
impl Clone for Box<dyn ClonableToExprDyn> {
|
||||
fn clone(&self) -> Self { dyn_clone::clone_box(&**self) }
|
||||
}
|
||||
|
||||
impl ToExpr for GExpr {
|
||||
async fn to_expr(self) -> GExpr { self }
|
||||
async fn to_gen(self) -> GExpr { self }
|
||||
async fn to_expr(self) -> Expr { self.create().await }
|
||||
}
|
||||
impl ToExpr for Expr {
|
||||
async fn to_expr(self) -> GExpr { self.slot() }
|
||||
async fn to_gen(self) -> GExpr { self.slot() }
|
||||
async fn to_expr(self) -> Expr { self }
|
||||
}
|
||||
|
||||
impl<T: ToExpr> ToExpr for OrcRes<T> {
|
||||
async fn to_expr(self) -> GExpr {
|
||||
async fn to_gen(self) -> GExpr {
|
||||
match self {
|
||||
Err(e) => bot(e),
|
||||
Ok(t) => t.to_expr().await,
|
||||
Ok(t) => t.to_gen().await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: ToAtom> ToExpr for A {
|
||||
async fn to_expr(self) -> GExpr { atom(self) }
|
||||
async fn to_gen(self) -> GExpr { atom(self) }
|
||||
}
|
||||
|
||||
impl ToExpr for Never {
|
||||
async fn to_expr(self) -> GExpr { match self {} }
|
||||
async fn to_gen(self) -> GExpr { match self {} }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user