smpli 0.4.0

Interpreter for the SMPL language
Documentation
use std::collections::HashMap;

use super::value::{ Value, ReferableValue };

#[derive(Debug)]
pub struct Env {
    env: HashMap<String, ReferableValue>,
    tmp_store: HashMap<String, ReferableValue>,
}

impl Env {
    pub fn new() -> Env {
        Env {
            env: HashMap::new(),
            tmp_store: HashMap::new(),
        }
    }

    pub fn fork(&self) -> Env {
        let env = self.env
            .iter()
            .map(|(key, referable)| {
                (key.clone(), referable.hard_clone())
            }).collect();

        let tmp_store = self.tmp_store
            .iter()
            .map(|(key, referable)| {
                (key.clone(), referable.hard_clone())
            }).collect();

        Env {
            env: env,
            tmp_store: tmp_store,
        }
    }

    pub fn map_value(&mut self, name: String, value: Value) -> Option<Value> {
        self.env
            .insert(name, ReferableValue::new(value))
            .map(|rv| rv.clone_value())
    }

    pub fn map_tmp(&mut self, name: String, value: Value) -> Option<Value> {
        self.tmp_store
            .insert(name, ReferableValue::new(value))
            .map(|rv| rv.clone_value())
    }

    pub fn get_value(&self, name: &str) -> Option<Value> {
        self.env.get(name).map(|r| r.clone_value())
    }

    pub fn ref_value(&self, name: &str) -> Option<ReferableValue> {
        self.env.get(name).map(|r| r.ref_clone())
    }

    pub fn get_tmp(&self, name: &str) -> Option<Value> {
        self.tmp_store.get(name).map(|r| r.clone_value())
    }

    pub fn ref_tmp(&self, name: &str) -> Option<ReferableValue> {
        self.tmp_store.get(name).map(|r| r.ref_clone())
    }

    pub fn get(&self, name: &str) -> Option<Value> {
        self.get_value(name).or(self.get_tmp(name))
    }

    pub fn get_ref(&self, name: &str) -> Option<ReferableValue> {
        self.ref_value(name).or(self.ref_tmp(name))
    }

    pub fn wipe_tmps(&mut self) {
        self.tmp_store.clear();
    }
}