jweinst1
4/8/2017 - 11:38 PM

funcvaluemushroom.rs

use std::fmt;


#[derive(Clone, Debug)]
pub enum MushRoom {
	Int(i32),
	Bool(bool),
	Plus(Vec<MushRoom>),
	Sub(Vec<MushRoom>)
}

impl MushRoom {

    fn int(self) -> i32 {
       match self {
           MushRoom::Int(i) => i,
           _ => 0
       }
   }
   
   fn bool(self) -> bool {
       match self {
           MushRoom::Bool(b) => b,
           _ => false
       }
   }

   fn call(self) -> MushRoom {
       match self {
           MushRoom::Plus(l) => {
               let mut total = 0;
               for elem in l {
                   total += elem.call().int();
               }
               MushRoom::Int(total)
           },
           MushRoom::Sub(l) => {
               if l.is_empty() {
                   return MushRoom::Int(0);
               }
               let mut total = l[0].int();
               for i in 1..l.len()-1 {
                   total -= l[i].call().int();
               }
               MushRoom::Int(total)
           },
           _ => self
       }
   }
}



impl fmt::Display for MushRoom {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    	match *self {
			MushRoom::Int(i) => write!(f, "{}", i),
			MushRoom::Bool(b) => write!(f, "{}", b),
			_ => write!(f, "(cmd)")
		}
    }
}

impl PartialEq for MushRoom {
    fn eq(&self, other: &MushRoom) -> bool {
        format!("{:?}", self) == format!("{:?}", other)
    }
    
    fn ne(&self, other: &MushRoom) -> bool {
        format!("{:?}", self) != format!("{:?}", other)
    }
}

use std::collections::HashMap;


pub struct Env {
    vars: HashMap<String, MushRoom>,
    parent:Vec<Env>
}

impl Env {

    pub fn new() -> Env {
        Env{vars:HashMap::new(), parent:Vec::with_capacity(1)}
    }
    
    pub fn create_child(self) -> Env {
        let mut newchild = Env::new();
        newchild.parent.push(self);
        newchild
    }
    
    pub fn has_parent(&self) -> bool {
        !self.parent.is_empty()
    }
    
    pub fn get(&self, key:String) -> MushRoom {
        match self.vars.get(&key) {
            Some(i) => i.clone(),
            None => return if self.has_parent() {self.parent[0].get(key)} else {MushRoom::Bool(false)}
        }
    }
    
    pub fn set(&mut self, key:String, val:MushRoom) {
        self.vars.insert(key, val);
    }
    
    pub fn has(&self, key:String) -> bool {
        self.vars.contains_key(&key)
    }
    
    pub fn del(&mut self, key:String) {
        self.vars.remove(&key);
    }
}

fn main() {
    let g = MushRoom::Sub(vec![MushRoom::Int(1).call(), MushRoom::Int(1)]);
    println!("2 - 2 is {}", g.call());
    //2 + 2 is 2
}