jweinst1
4/7/2017 - 9:14 PM

cloningvcfix.rs


use std::fmt;
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);
    }
}

#[derive(Clone)]
pub enum MushRoom {
	Int(i32),
	Bool(bool),
	List(Vec<MushRoom>),
	Func(fn(Vec<MushRoom>) -> MushRoom)
}

impl MushRoom {
    pub fn repr(value:&MushRoom) -> String {
		match *value {
			MushRoom::Int(i) => format!("{}", i),
			MushRoom::Bool(b) => format!("{}", b),
			MushRoom::Func(f) => format!("{:?}", f),
			MushRoom::List(ref l) => {
				let mut fmt_str = "[ ".to_string();
				for elem in l {
					fmt_str += MushRoom::repr(elem).as_str();
					fmt_str += " ";
				}
				fmt_str += "]";
				fmt_str
			}
		}
	}
}


impl fmt::Debug for MushRoom {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "{}", MushRoom::repr(self))
	}
}

impl fmt::Display for MushRoom {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

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

fn main() {
   let mut g = Env::new();
   g.set("foo".to_string(), MushRoom::List(vec![MushRoom::Int(8)]));
   println!("{}", g.get("foo".to_string())); //[ 8 ]
   let mut h = g.create_child();
   h.set("d".to_string(), MushRoom::Int(8));
   println!("{}", h.get("foo".to_string())); //[ 8 ]
}