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
}