1pub mod list;
2pub mod logic;
3pub mod rc;
4pub mod arith;
5#[cfg(feature = "const")] pub mod set;
6
7mod if_impl;
8pub use if_impl::{If,Cond};
9
10use crate::{LispId, engine::*};
11use typenum as tn;
12
13use std::default::Default;
14
15#[derive(Debug,Default)]
25pub struct Is;
26defun!{ Is {} }
27
28#[cfg(not(feature = "const"))]
29impl<L,R> FunCall< sexpr!{L, R} > for Is
30where L: LispId,
31 R: LispId,
32 L::Id: tn::IsEqual<R::Id>,
33 <L::Id as tn::IsEqual<R::Id>>::Output: Default,
34{
35 type Result = <L::Id as tn::IsEqual<R::Id>>::Output;
36}
37
38#[cfg(feature = "const")]
39impl<L,R> FunCall< sexpr!{L, R} > for Is
40where L:LispId,
41 R:LispId,
42 IdIsEqual<L::Id, R::Id>: AsTypeBool
43{
44 type Result = <IdIsEqual<L::Id, R::Id> as AsTypeBool>::TypeBool;
45}
46
47pub struct IdIsEqual<L,R>(std::marker::PhantomData<(L,R)>);
48
49#[cfg(feature = "const")]
50impl<const LID:u128, const RID:u128> AsTypeBool
51for IdIsEqual<crate::ConstId<LID>, crate::ConstId<RID>>
52where ConstBool<{LID == RID}>: AsTypeBool {
53 type TypeBool = <ConstBool<{LID == RID}> as AsTypeBool>::TypeBool;
54}
55
56pub trait AsTypeBool {
57 type TypeBool: tn::marker_traits::Bit;
58}
59
60impl AsTypeBool for ConstBool<true> {
61 type TypeBool = tn::True;
62}
63
64impl AsTypeBool for ConstBool<false> {
65 type TypeBool = tn::False;
66}
67
68pub struct ConstBool<const X:bool>;
69
70impl<T> FunCalc<T> for Is where Is: FunCall<T>, <Is as FunCall<T>>::Result: Default {
71 type Result = <Is as FunCall<T>>::Result;
72 #[inline(always)]
73 fn calc(self, _:T)->Self::Result { Default::default() }
74}
75
76#[derive(Debug,Default)]
77pub struct IsNot;
78defun_nocalc!{() IsNot {
79 (L,R) {_:L, _:R} => {logic::Not, {Is, @L, @R}};
80}}
81
82#[test]
83fn test_is() {
84 #[derive(Debug,Default)] struct A;
85 #[derive(Debug,Default)] struct B;
86 literal!{A; B}
87
88 let _: eval!{If, {Is, A, B}, A, B } = B;
89 let _: eval!{If, {Is, tn::True, tn::True}, A, B} = A;
90 let _: eval!{If, {Is, A, A}, A, B} = A;
91 let _: eval!{If, {Is, B, B}, A, B} = A;
92
93 fn assert_b<X:LispId>() where sexpr!{If, {Is, @X, B}, A, B}: Eval<Result = A> {
94 }
95
96 assert_b::<B>();
97}
98
99#[test]
100fn test_is_not() {
101 #[derive(Debug,Default)] struct A;
102 #[derive(Debug,Default)] struct B;
103 literal!{A; B}
104
105 let _: eval!{If, {IsNot, A, B}, A, B } = A;
106 let _: eval!{If, {IsNot, tn::True, tn::True}, A, B} = B;
107}
108
109#[test]
110fn test_partial() {
111 #[derive(Debug,Default)] struct A;
112 #[derive(Debug,Default)] struct B;
113 literal!{A; B}
114
115 let _: eval!{If, {{Partial, Is, A}, B}, A, B } = B;
116 let _: eval!{If, {Is, tn::True, tn::True}, A, B} = A;
117}
118#[derive(Debug,Default)]
123pub struct Ret;
124literal!{Ret}
125
126impl Call for Ret { type Conv=cc::Func; }
127impl<T,U> FunCall < sexpr!{T; U} > for Ret {
128 type Result = T;
129}
130
131impl<T,U> FunCalc < sexpr!{T; U} > for Ret {
132 type Result = T;
133 fn calc(self, sexpr_pat!{x:T; _:U}: sexpr!{T; U})-> T {
134 x
135 }
136}
137
138#[derive(Debug,Default)]
149pub struct Partial;
150defmacro!{Partial {
151 (Prefix) {; Prefix} => {Ret, @PartialImpl<Prefix>};
152}}
153impl<Prefix, QPrefix>
154SynCalc< Prefix, QPrefix > for Partial
155{
156 type Result = PartialImpl<Prefix>;
157 #[inline(always)]
158 fn syn_calc(self, _:QPrefix)->Self::Result {
159 PartialImpl(std::marker::PhantomData)
160 }
161}
162
163#[derive(Debug,Default)]
168pub struct Phantom;
169defmacro!{Phantom {}}
170
171impl<Arg:Eval> SynCall<sexpr!{Arg}> for Phantom {
172 type Result = std::marker::PhantomData<Arg::Result>;
173}
174
175impl<Arg:Eval,QArg> SynCalc<sexpr!{Arg},QArg> for Phantom {
176 type Result = std::marker::PhantomData<Arg::Result>;
177 #[inline(always)]
178 fn syn_calc(self, _:QArg)->Self::Result { std::marker::PhantomData }
179}
180
181
182
183#[derive(Debug,Default)]
184pub struct Quote;
185defun_nocalc!{() Quote {
186 (Arg) {_:Arg} => {Ret, @crate::Quote<Arg>};
187}}
188
189
190#[derive(Debug)]
191pub struct PartialImpl<Prefix>(std::marker::PhantomData<Prefix>);
192defun_nocalc!{(Prefix) PartialImpl<Prefix> {}}
193
194impl<T> Default for PartialImpl<T> {
195 #[inline(always)]
196 fn default()->Self { PartialImpl(std::marker::PhantomData) }
197}
198
199impl<T> From<()> for PartialImpl<T> {
200 #[inline(always)]
201 fn from(_:())->Self { Default::default() }
202}
203
204impl<Prefix, Tail> FunCall< Tail > for PartialImpl<Prefix>
205where sexpr!{list::Concat, @Prefix, {list::Map, Quote, @Tail}}: Eval,
206 eval!{list::Concat, @Prefix, {list::Map, Quote, @Tail}}: Eval
207{
208 type Result = <eval!{list::Concat, @Prefix, {list::Map, Quote, @Tail}} as Eval>::Result;
209}