Advertisement
Guest User

Untitled

a guest
Jul 3rd, 2015
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.94 KB | None | 0 0
  1. use std::fmt::Display;
  2. use std::fmt::Formatter;
  3. use std::fmt::Error;
  4.  
  5. //#[allow(dead_code)]
  6. #[derive(Copy,Clone)]
  7. enum Opb {
  8. PAIR,
  9. ADD,
  10. SUB,
  11. MUL,
  12. DIV,
  13. TYP,
  14. EQ
  15. }
  16.  
  17. impl Display for Opb {
  18. fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
  19. match *self {
  20. Opb::PAIR => write!(f, ","),
  21. Opb::ADD => write!(f, "+"),
  22. Opb::SUB => write!(f, "-"),
  23. Opb::MUL => write!(f, "*"),
  24. Opb::DIV => write!(f, "/"),
  25. Opb::TYP => write!(f, ":"),
  26. Opb::EQ => write!(f, "=")
  27. }
  28. }
  29. }
  30.  
  31. #[derive(Copy,Clone)]
  32. enum Opu {
  33. NOP,
  34. COMMUTE,
  35. RDIST
  36. }
  37.  
  38. impl Display for Opu {
  39. fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
  40. match *self {
  41. Opu::COMMUTE => write!(f, "commute"),
  42. Opu::NOP => write!(f, "nop"),
  43. Opu::RDIST => write!(f, "rdist")
  44. }
  45. }
  46. }
  47.  
  48. #[derive(Clone)]
  49. enum Expr {
  50. Name(&'static str),
  51. Int(i32),
  52. BinOp(Box<Expr>, Opb, Box<Expr>),
  53. UOp(Box<Expr>,Opu)
  54. }
  55.  
  56. impl Display for Expr {
  57. fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
  58. match *self {
  59. Expr::Name(ref s) => write!(f, "{}", s),
  60. Expr::Int(ref i) => write!(f, "{}", i),
  61. Expr::BinOp(ref l,ref op,ref r) => write!(f, "({} {} {})", l, op, r),
  62. Expr::UOp(ref l,ref op) => write!(f, "({} {})", l, op)
  63. }
  64. }
  65. }
  66.  
  67. ////Relatively straightforward because nothing is copied
  68. // (a op b) -> (b op a)
  69. fn commute(expr: Expr) -> Expr {
  70. match expr {
  71. Expr::BinOp(l, op, r) => Expr::BinOp(r, op, l),
  72. _ => expr
  73. }
  74. }
  75.  
  76. ////This was rather tricky because of the boxes, and copying and cloning
  77. // ( (ll opl rl) op r) -> ( (ll op r) opl (rl op r) )
  78. fn rdistrib(expr: Expr) -> Expr {
  79. match expr.clone() {
  80. Expr::BinOp(l, op, r) =>
  81. match (*l).clone() {
  82. Expr::BinOp(ll, opl, rl) =>
  83. Expr::BinOp(
  84. Box::new(
  85. Expr::BinOp(
  86. Box::new((*ll).clone()),
  87. op,
  88. Box::new((*r).clone()),
  89. )
  90. ),
  91. opl,
  92. Box::new(
  93. Expr::BinOp(
  94. Box::new((*rl).clone()),
  95. op,
  96. Box::new((*r).clone()),
  97. )
  98. ),
  99. ),
  100. _ => expr
  101. },
  102. _ => expr
  103. }
  104. }
  105.  
  106. ////Remove the tedium of constructing binops
  107. fn do_opb(expr1: Expr, op: Opb, expr2: Expr) -> Expr {
  108. let x = Expr::BinOp(Box::new(expr1.clone()), op, Box::new(expr2.clone()));
  109. println!("{}", x);
  110. x
  111. }
  112.  
  113. fn do_reduce(expr1: Expr) -> Expr {
  114. match expr1.clone() {
  115. Expr::UOp(x, uo) => {
  116. match uo {
  117. Opu::COMMUTE => commute(*x),
  118. Opu::RDIST => rdistrib(*x),
  119. Opu::NOP => *x
  120. }
  121. },
  122. _ => expr1
  123. }
  124. }
  125.  
  126. fn do_opu(expr1: Expr, op: Opu) -> Expr {
  127. let mut x = Expr::UOp(Box::new(expr1.clone()), op);
  128. x = do_reduce(x);
  129. println!("{}", x);
  130. x
  131. }
  132.  
  133. ////Simple test of garbage collection free symbolic manipulation
  134. fn main() {
  135. let mut x0 : Expr = Expr::Name("a");
  136. x0 = do_opb(x0, Opb::TYP, Expr::Name("t"));
  137. x0 = do_opb(x0, Opb::PAIR, Expr::Name("z"));
  138. x0 = do_opb(x0, Opb::ADD, Expr::Int(1));
  139. x0 = do_opu(x0, Opu::COMMUTE);
  140. x0 = do_opb(x0, Opb::MUL, Expr::Name("b"));
  141. x0 = do_opu(x0, Opu::RDIST);
  142. x0 = do_opb(x0, Opb::EQ, Expr::Name("c"));
  143. x0 = do_opb(x0, Opb::ADD, Expr::Int(42));
  144. x0 = do_opu(x0, Opu::RDIST);
  145. x0 = do_opb(x0, Opb::DIV, Expr::Int(2));
  146. x0 = do_opu(x0, Opu::RDIST);
  147. do_opu(x0, Opu::NOP);
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement