Advertisement
ttldtor

Untitled

Dec 4th, 2014
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.28 KB | None | 0 0
  1. /*
  2. Compile time Brainfuck implementation in Rust using types (not macros; the two
  3. macros are just for convenience)
  4.  
  5. In short, it uses trait impls as Prolog-like terms, and rustc's type inference
  6. does unification.  All impls are for the same dummy type; both 'input' and
  7. 'output' arguments are generic parameters.
  8. */
  9.  
  10. #![feature(macro_rules)]
  11. #![allow(unused_variables)]
  12. #![allow(dead_code)]
  13. use std::default::Default;
  14. use std::fmt::{Show, Formatter};
  15.  
  16. struct Nothing; // the dummy type
  17.  
  18. trait Nice : Default + Show {}
  19.  
  20. trait Church : Nice {
  21.     fn as_int(self) -> int;
  22. }
  23. #[deriving(Default)]
  24. struct Zero;
  25. #[deriving(Default)]
  26. struct Succ<P: Church>;
  27.  
  28. impl Nice for Zero {}
  29. impl Church for Zero {
  30.     fn as_int(self) -> int { 0 }
  31. }
  32. impl<P: Church> Nice for Succ<P> {}
  33. impl<P: Church> Church for Succ<P> {
  34.     fn as_int(self) -> int {
  35.         let p: P = Default::default();
  36.         p.as_int() + 1
  37.     }
  38. }
  39.  
  40. // not sure why I can't just impl<N: Church> Show for N; it gives a crate error
  41. impl Show for Zero {
  42.     fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
  43.         write!(fmt, "0")
  44.     }
  45. }
  46. impl<P: Church> Show for Succ<P> {
  47.     fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
  48.         write!(fmt, "{}", self.as_int())
  49.     }
  50. }
  51.  
  52. // our integers are infinitely ranged, because this is easiest to implement; 0
  53. // decrements to 0
  54.  
  55. trait PlusOne<A: Church, R: Church> {}
  56. impl<P: Church> PlusOne<P, Succ<P>> for Nothing {}
  57.  
  58.  
  59. trait MinusOne<A: Church, R: Church> {}
  60. impl<P: Church> MinusOne<Succ<P>, P> for Nothing {}
  61. impl MinusOne<Zero, Zero> for Nothing {}
  62.  
  63.  
  64.  
  65.  
  66.  
  67. trait ConsCell : Nice {}
  68.  
  69. #[deriving(Default)]
  70. struct Nil;
  71. #[deriving(Default)]
  72. struct Cons<A: Nice, B: ConsCell>;
  73.  
  74. impl<A: Nice, B: ConsCell> ConsCell for Cons<A, B> {}
  75. impl<A: Nice, B: ConsCell> Nice for Cons<A, B> {}
  76. impl ConsCell for Nil {}
  77. impl Nice for Nil {}
  78.  
  79.  
  80. impl Show for Nil {
  81.     fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
  82.         write!(fmt, "Nil")
  83.     }
  84. }
  85. impl<A: Nice, B: ConsCell> Show for Cons<A, B> {
  86.     fn fmt(&self, fmt: &mut Formatter) -> Result<(), std::fmt::Error> {
  87.         let a: A = Default::default();
  88.         let b: B = Default::default();
  89.         write!(fmt, "({}, {})", a, b)
  90.     }
  91. }
  92.  
  93. // append(a -> b):
  94. //    appends this to the end of the list
  95. trait Append<A: ConsCell, B: Nice, R: ConsCell> {}
  96. impl<B: Nice>
  97.     Append<Nil, B, Cons<B, Nil>> for Nothing {}
  98. impl<Car: Nice, Cdr: ConsCell, B: Nice, R: ConsCell, N>
  99.     Append<Cons<Car, Cdr>, B, Cons<Car, R>> for Nothing
  100.     where N: Append<Cdr, B, R> {}
  101.  
  102. // rol(a -> b):
  103. //    rotates the list to the left, e.g. cons(1, cons(2, cons(3, nil))) ->
  104. //                                       cons(2, cons(3, cons(1, nil)))
  105. trait Rol<A: ConsCell, R: ConsCell> {}
  106. impl<Car: Nice, Cdr: ConsCell, R: ConsCell, N>
  107.     Rol<Cons<Car, Cdr>, R> for Nothing
  108.     where N: Append<Cdr, Car, R> {}
  109.  
  110. // removelast(a -> b, l)
  111. //    removes and returns the last element
  112. trait RemoveLast<A: ConsCell, R: ConsCell, L: Nice> {}
  113. impl<L: Nice>
  114.     RemoveLast<Cons<L, Nil>, Nil, L> for Nothing {}
  115. impl<Fst: Nice, Snd: Nice, Rest: ConsCell, L: Nice, R: ConsCell, N>
  116.     RemoveLast<Cons<Fst, Cons<Snd, Rest>>, Cons<Fst, R>, L> for Nothing
  117.     where N: RemoveLast<Cons<Snd, Rest>, R, L> {}
  118.  
  119.  
  120. // ror(a -> b):
  121. //    rotates the list to the right
  122. trait Ror<A: ConsCell, R: ConsCell> {}
  123. impl<A: ConsCell, R: ConsCell, L: Nice, N>
  124.     Ror<A, Cons<L, R>> for Nothing
  125.     where N: RemoveLast<A, R, L> {}
  126.  
  127. trait BFInsn : Nice {}
  128. macro_rules! define_insn(($n:ident) => {
  129.     #[deriving(Default, Show)]
  130.     struct $n;
  131.     impl Nice for $n {}
  132. })
  133. define_insn!(BFPlus)
  134. define_insn!(BFMinus)
  135. define_insn!(BFLeft)
  136. define_insn!(BFRight)
  137. define_insn!(BFOutput)
  138.  
  139. #[deriving(Default, Show)]
  140. struct BFLoop<InnerInsns: ConsCell>;
  141. impl<II: ConsCell> Nice for BFLoop<II> {}
  142.  
  143. // bf(state, insns, output -> newstate, newoutput)
  144. trait BF<State: ConsCell, Insns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell> {}
  145. // State is a ConsCell of Church numerals, where the BF pointer is always in
  146. // the first position: to move the pointer, we instead rotate the entire
  147. // memory, as this is easier to implement.  Insns is a ConsCell of BFInsns.
  148.  
  149. // +
  150. impl<Car: Church, Cdr: ConsCell, OtherInsns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, CarPlusOne: Church, N1, N2>
  151.     BF<Cons<Car, Cdr>, Cons<BFPlus, OtherInsns>, Output, NewState, NewOutput>
  152.     for Nothing where
  153.         N1: BF<Cons<CarPlusOne, Cdr>, OtherInsns, Output, NewState, NewOutput>,
  154.         N2: PlusOne<Car, CarPlusOne> {}
  155.  
  156. // -
  157. impl<Car: Church, Cdr: ConsCell, OtherInsns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, CarMinusOne: Church, N1, N2>
  158.     BF<Cons<Car, Cdr>, Cons<BFMinus, OtherInsns>, Output, NewState, NewOutput>
  159.     for Nothing where
  160.         N1: BF<Cons<CarMinusOne, Cdr>, OtherInsns, Output, NewState, NewOutput>,
  161.         N2: MinusOne<Car, CarMinusOne> {}
  162.  
  163. // <
  164. impl<State: ConsCell, OtherInsns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, MiddleState: ConsCell, N1, N2>
  165.     BF<State, Cons<BFLeft, OtherInsns>, Output, NewState, NewOutput>
  166.     for Nothing where
  167.         N1: Ror<State, MiddleState>,
  168.         N2: BF<MiddleState, OtherInsns, Output, NewState, NewOutput> {}
  169.  
  170. // >
  171. impl<State: ConsCell, OtherInsns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, MiddleState: ConsCell, N1, N2>
  172.     BF<State, Cons<BFRight, OtherInsns>, Output, NewState, NewOutput>
  173.     for Nothing where
  174.         N1: Rol<State, MiddleState>,
  175.         N2: BF<MiddleState, OtherInsns, Output, NewState, NewOutput> {}
  176.  
  177. // .
  178. impl<Car: Church, Cdr: ConsCell, OtherInsns: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, N>
  179.     BF<Cons<Car, Cdr>, Cons<BFOutput, OtherInsns>, Output, NewState, Cons<Car, NewOutput>>
  180.     for Nothing where
  181.         N: BF<Cons<Car, Cdr>, OtherInsns, Output, NewState, NewOutput> {}
  182.  
  183. // [] (current cell is zero)
  184. impl<Cdr: ConsCell, Inner: ConsCell, PastLoop: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, N>
  185.     BF<Cons<Zero, Cdr>, Cons<BFLoop<Inner>, PastLoop>, Output, NewState, NewOutput>
  186.     for Nothing where
  187.         N: BF<Cons<Zero, Cdr>, PastLoop, Output, NewState, NewOutput> {}
  188.  
  189. // [] (current cell is nonzero)
  190. impl<P: Church, Cdr: ConsCell, Inner: ConsCell, PastLoop: ConsCell, Output: ConsCell, NewState: ConsCell, NewOutput: ConsCell, MiddleState: ConsCell, MiddleOutput: ConsCell, N1, N2>
  191.     BF<Cons<Succ<P>, Cdr>, Cons<BFLoop<Inner>, PastLoop>, Output, NewState, NewOutput>
  192.     for Nothing where
  193.         // run one iteration
  194.         N1: BF<Cons<Succ<P>, Cdr>, Inner, Output, MiddleState, MiddleOutput>,
  195.         // repeat
  196.         N2: BF<MiddleState, Cons<BFLoop<Inner>, PastLoop>, MiddleOutput, NewState, NewOutput> {}
  197.  
  198. // reached the end of input?
  199. impl<State: ConsCell, Output: ConsCell>
  200.     BF<State, Nil, Output, State, Output> for Nothing {}
  201.  
  202. // helpers to more easily specify the input instructions (can't have a macro
  203. // that evaluates to a type)
  204. fn cons<Car: Nice, Cdr: ConsCell>(car: Car, cdr: Cdr) -> Cons<Car, Cdr> {
  205.     Default::default()
  206. }
  207. fn bf_loop<InnerInsns: ConsCell>(ii: InnerInsns) -> BFLoop<InnerInsns> {
  208.     BFLoop
  209. }
  210. macro_rules! list_literal[
  211.     ($a:expr, $($b:expr),*) => {cons($a, list_literal![$($b),*])};
  212.     ($a:expr) => {cons($a, Nil)};
  213.     () => {Nil};
  214. ]
  215. /*
  216.  
  217. */
  218.  
  219. fn main() {
  220.     // +++[->++<]+.>.
  221.     let insns = list_literal![
  222.         BFPlus,
  223.         BFPlus,
  224.         BFPlus,
  225.         bf_loop(list_literal![BFMinus, BFRight, BFPlus, BFPlus, BFLeft]),
  226.         BFPlus,
  227.         // Uncomment this to get 'overflow evaluating' errors
  228.         // bf_loop(list_literal![]),
  229.         BFOutput,
  230.         BFRight,
  231.         BFOutput
  232.     ];
  233.     let state = list_literal![Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero];
  234.  
  235.  
  236.     fn print_bf<State: ConsCell, Insns: ConsCell, N, NewState: ConsCell, NewOutput: ConsCell>(state: State, insns: Insns)
  237.         where N: BF<State, Insns, Nil, NewState, NewOutput> {
  238.         let ns: NewState = Default::default();
  239.         println!("final state: {}", ns);
  240.         let no: NewOutput = Default::default();
  241.         println!("final output: {}", no);
  242.     }
  243.     print_bf(state, insns);
  244.  
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement