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:
2024-10-14 00:13:09 +02:00
parent 84cbcdd4fe
commit 3a3ae98aff
66 changed files with 2302 additions and 1164 deletions

View File

@@ -3,19 +3,19 @@ use orchid_base::intern;
use orchid_base::location::Pos;
use crate::atom::{AtomicFeatures, ToAtom, TypAtom};
use crate::expr::{atom, botv, ExprHandle, GenExpr, OwnedExpr};
use crate::expr::{atom, bot, Expr};
use crate::system::downcast_atom;
pub trait TryFromExpr: Sized {
fn try_from_expr(expr: ExprHandle) -> OrcRes<Self>;
fn try_from_expr(expr: Expr) -> OrcRes<Self>;
}
impl TryFromExpr for OwnedExpr {
fn try_from_expr(expr: ExprHandle) -> OrcRes<Self> { Ok(OwnedExpr::new(expr)) }
impl TryFromExpr for Expr {
fn try_from_expr(expr: Expr) -> OrcRes<Self> { Ok(expr) }
}
impl<T: TryFromExpr, U: TryFromExpr> TryFromExpr for (T, U) {
fn try_from_expr(expr: ExprHandle) -> OrcRes<Self> {
fn try_from_expr(expr: Expr) -> OrcRes<Self> {
Ok((T::try_from_expr(expr.clone())?, U::try_from_expr(expr)?))
}
}
@@ -29,31 +29,30 @@ fn err_type(pos: Pos) -> OrcErr {
}
impl<'a, A: AtomicFeatures> TryFromExpr for TypAtom<'a, A> {
fn try_from_expr(expr: ExprHandle) -> OrcRes<Self> {
OwnedExpr::new(expr)
.foreign_atom()
.map_err(|ex| vec![err_not_atom(ex.pos.clone())])
.and_then(|f| downcast_atom(f).map_err(|f| vec![err_type(f.pos)]))
fn try_from_expr(expr: Expr) -> OrcRes<Self> {
(expr.foreign_atom())
.map_err(|ex| err_not_atom(ex.pos.clone()).into())
.and_then(|f| downcast_atom(f).map_err(|f| err_type(f.pos).into()))
}
}
pub trait ToExpr {
fn to_expr(self) -> GenExpr;
fn to_expr(self) -> Expr;
}
impl ToExpr for GenExpr {
fn to_expr(self) -> GenExpr { self }
impl ToExpr for Expr {
fn to_expr(self) -> Expr { self }
}
impl<T: ToExpr> ToExpr for OrcRes<T> {
fn to_expr(self) -> GenExpr {
fn to_expr(self) -> Expr {
match self {
Err(e) => botv(e),
Err(e) => bot(e),
Ok(t) => t.to_expr(),
}
}
}
impl<A: ToAtom> ToExpr for A {
fn to_expr(self) -> GenExpr { atom(self) }
fn to_expr(self) -> Expr { atom(self) }
}