Skip to content

Instantly share code, notes, and snippets.

@ClarkeRemy
Last active October 23, 2024 04:19
Show Gist options
  • Save ClarkeRemy/8e6176d841ce0f36c262c1119c694c3f to your computer and use it in GitHub Desktop.
Save ClarkeRemy/8e6176d841ce0f36c262c1119c694c3f to your computer and use it in GitHub Desktop.
Compile Time Boolean formula Interpreter
use std::marker::PhantomData;
enum Ast{};
enum Eval{};
trait Mode {}
impl Mode for Ast {}
impl Mode for Eval {}
trait Boolean{}
trait Formula{ type Output : Boolean + Formula; }
enum True{}
impl Boolean for True{}
impl Formula for True {type Output = Self;}
enum False{}
impl Boolean for False{}
impl Formula for False {type Output = Self;}
// ast
struct And<L : Formula, R : Formula, M : Mode = Ast>(core::convert::Infallible, core::marker::PhantomData<(*const M, fn(L,R))>);
// eval
impl<L: Formula, R : Formula> Formula for And<L , R>
where
And<L::Output,R::Output, Eval> : Formula
{
type Output = <And<L::Output,R::Output, Eval> as Formula>::Output ;
}
impl Formula for And<True , True , Eval> { type Output = True;}
impl Formula for And<False, True , Eval> { type Output = False;}
impl Formula for And<True , False, Eval> { type Output = False;}
impl Formula for And<False, False, Eval> { type Output = False;}
// ast
struct Or<L : Formula, R : Formula, M : Mode = Ast>(core::convert::Infallible, core::marker::PhantomData<(*const M, fn(L,R))>);
// eval
impl<L: Formula, R : Formula> Formula for Or<L , R>
where Or<L::Output,R::Output, Eval> : Formula
{
type Output = <Or<L::Output, R::Output, Eval> as Formula>::Output ;
}
impl Formula for Or<True , True , Eval> { type Output = True;}
impl Formula for Or<False, True , Eval> { type Output = True;}
impl Formula for Or<True , False, Eval> { type Output = True;}
impl Formula for Or<False, False, Eval> { type Output = False;}
struct Not<T : Formula, M : Mode = Ast>(core::convert::Infallible, core::marker::PhantomData<(M, fn(T))>);
impl<T:Formula> Formula for Not<T>
where Not<T::Output, Eval> : Formula
{
type Output = <Not<T::Output, Eval> as Formula>::Output;
}
impl Formula for Not<True, Eval> {type Output = False;}
impl Formula for Not<False,Eval> {type Output = True;}
const fn proof<F : Formula<Output = True>>() {}
const _0 : () = proof::<Not<Not<Or<False, And<True, And<True, True>>>>>>();
@itspacrat
Copy link

itspacrat commented Oct 23, 2024

new web dev lang is coming along nicely

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment