Skip to content

Instantly share code, notes, and snippets.

@sdleffler
Last active March 11, 2017 14:54
Show Gist options
  • Save sdleffler/46700a8add454bc23cdb399a766cb273 to your computer and use it in GitHub Desktop.
Save sdleffler/46700a8add454bc23cdb399a766cb273 to your computer and use it in GitHub Desktop.
`type_operators!` concrete definitions for the `tarpit-rs` Rust type-level Smallfuck interpreter.
// `Bit` trait and `T` and `F` types.
pub trait Bit {
fn reify() -> bool;
}
pub struct F;
pub struct T;
impl Bit for F {
fn reify() -> bool {
false
}
}
impl Bit for T {
fn reify() -> bool {
true
}
}
// `List` trait and `Nil` and `Cons<H, T>` types.
pub trait List {
fn reify() -> BitVec;
}
pub struct Nil;
pub struct Cons<B: Bit, L: List = Nil>(PhantomData<B>, PhantomData<L>);
impl List for Nil {
fn reify() -> BitVec {
BitVec::new()
}
}
impl<B: Bit, L: List> List for Cons<B, L> {
#[allow(non_snake_case)]
fn reify() -> BitVec {
let B = <B>::reify();
let L = <L>::reify();
{
let mut tail = L;
tail.push(B);
tail
}
}
}
// `ProgramTy` trait and `Empty`, `Left<P>`, `Right<P>`, `Flip<P>`, and `Loop<P, Q>` types.
pub trait ProgramTy {
fn reify() -> Program;
}
pub struct Empty;
pub struct Left<P: ProgramTy = Empty>(PhantomData<P>);
pub struct Right<P: ProgramTy = Empty>(PhantomData<P>);
pub struct Flip<P: ProgramTy = Empty>(PhantomData<P>);
pub struct Loop<P: ProgramTy = Empty, Q: ProgramTy = Empty>(PhantomData<P>, PhantomData<Q>);
impl ProgramTy for Empty {
fn reify() -> Program {
Program::Empty
}
}
impl<P: ProgramTy> ProgramTy for Left<P> {
#[allow(non_snake_case)]
fn reify() -> Program {
let P = <P>::reify();
Program::Left(Box::new(P))
}
}
impl<P: ProgramTy> ProgramTy for Right<P> {
#[allow(non_snake_case)]
fn reify() -> Program {
let P = <P>::reify();
Program::Right(Box::new(P))
}
}
impl<P: ProgramTy> ProgramTy for Flip<P> {
#[allow(non_snake_case)]
fn reify() -> Program {
let P = <P>::reify();
Program::Flip(Box::new(P))
}
}
impl<P: ProgramTy, Q: ProgramTy> ProgramTy for Loop<P, Q> {
#[allow(non_snake_case)]
fn reify() -> Program {
let P = <P>::reify();
let Q = <Q>::reify();
Program::Loop(Box::new((P, Q)))
}
}
// `StateTy` trait and `St` type.
pub trait StateTy {
fn reify() -> StateTyOut;
}
pub struct St<L: List, C: Bit, R: List>(PhantomData<L>, PhantomData<C>, PhantomData<R>);
impl<L: List, C: Bit, R: List> StateTy for St<L, C, R> {
#[allow(non_snake_case)]
fn reify() -> StateTyOut {
let L = <L>::reify();
let C = <C>::reify();
let R = <R>::reify();
{
let mut bits = L;
let loc = bits.len();
bits.push(C);
bits.extend(R.into_iter().rev());
StateTyOut {
loc: loc,
bits: bits,
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment