/////////////////// Expression Trees in Rust, Again ////////// #![allow(dead_code)] #![allow(non_snake_case)] #![allow(unused_variables)] #![allow(unused_parens)] #![allow(non_camel_case_types)] use crate::E2::*; //use std::rc::Rc; use std::ops::Deref; use std::fmt::{Display,Formatter,Result}; #[derive(Copy,Clone)] enum E2<'t> { Val(i32), Plus(&'t E2<'t>,&'t E2<'t>), Times(&'t E2<'t>,&'t E2<'t>), Neg(&'t E2<'t>), } const MAXSIZE:usize = 4096*1024; // 4M nodes const Nodes:Vec = Vec::new(); fn newval(x:i32) -> usize { let len = Nodes.len(); Nodes.push(Val(x)); len } fn newplus(l:usize, r:usize) -> usize { let ref lf = Nodes[l]; let ref rt = Nodes[r]; Nodes.push(Plus(lf,rt)); Nodes.len()-1 } fn newtimes(l:usize, r:usize) -> usize { let (lf,rt) = (&Nodes[l],&Nodes[r]); Nodes.push(Times(lf,rt)); Nodes.len()-1 } fn newneg(s:usize) -> usize { let ref sub = Nodes[s]; Nodes.push(Neg(sub)); Nodes.len()-1 } struct Exprtree<'t> { nodes:Vec>, } impl<'t> Exprtree<'t> { fn new() -> Exprtree<'t> { Exprtree { nodes:Vec::new() } } fn newval(&mut self, x:i32) -> usize { let leng = self.nodes.len(); self.nodes.push(Val(x)); leng } } /* fn newtimes(&mut self, l:usize, r:usize) -> usize { let leng = self.nodes.len(); let lf = self.nodes[l]; let rt = self.nodes[r]; let e = Times(&lf,&rt); self.nodes.push(e); leng } }// imple Exprtree */ /* impl Deref for Expr { type Target = Expr; fn deref(&self) -> &Target { match self { Plus(x,y) => Plus( _ => self } }//deref }// imple Deref */ fn eval(e:&E2) -> i32 { match *e { Val(x) => x, // x is a ref because e is Plus(x,y) => eval(x) + eval(y), // deref coercion works nicely here Times(x,y) => eval(x) * eval(y), Neg(x) => -1 * eval(x), }//match }//eval impl<'t> Display for E2<'t> { fn fmt(&self, f: &mut Formatter<'_>) -> Result // required by trait { match self { Val(x) => write!(f,"{}",x), Plus(x,y) => write!(f,"({}+{})",x,y), Times(x,y) => write!(f,"{}*{}",x,y), Neg(Neg(x)) => write!(f,"{}",x), Neg(x) => write!(f,"-{}",x), }//match } }// impl Display for E2 /////////////////////// main fn main() { // keep in global vector? let (v1,v2,v3) = (&Val(2), &Val(3), &Val(5)); let ref e1 = Times(v2,v3); let ref e2 = Plus(v1,e1); let ref e3 = Neg(e2); let ref e4 = Neg(e3); println!("value of {} is {}",e3,eval(e3)); println!("value of {} is {}",e4,eval(e4)); // keep "global" vector in main: let mut nodes:Vec = Vec::new(); // let ee = newplus(newval(8),newtimes(newval(10),newneg(newval(2)))); println!("length of Nodes: {}",Nodes.len()); let ee3 = newval(8); println!("length of Nodes: {}",Nodes.len()); let ref ne = Nodes[ee3]; // println!("value of {} is {}",ne,eval(ne)); }//main