Last active
March 11, 2017 14:54
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// `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