// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }
// 
// Path: src/chap7/FuncEvaluator.java
// @Reviser public static interface EnvEx extends Environment {
//     void putNew(String name, Object value);
//     Environment where(String name);
//     void setOuter(Environment e);
// }


import java.util.HashMap;
import chap6.Environment;
import chap7.FuncEvaluator.EnvEx;
package chap7;

public class NestedEnv implements Environment {
    protected HashMap<String,Object> values;
    protected Environment outer;
    public NestedEnv() { this(null); }
    public NestedEnv(Environment e) {
        values = new HashMap<String,Object>();
        outer = e;
    }
    public void setOuter(Environment e) { outer = e; }
    public Object get(String name) {
        Object v = values.get(name);
        if (v == null && outer != null)
            return outer.get(name);
        else
            return v;
    }
    public void putNew(String name, Object value) { values.put(name, value); }
    public void put(String name, Object value) {
        Environment e = where(name);
        if (e == null)
            e = this;
// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }
// 
// Path: src/chap7/FuncEvaluator.java
// @Reviser public static interface EnvEx extends Environment {
//     void putNew(String name, Object value);
//     Environment where(String name);
//     void setOuter(Environment e);
// }


// Path: src/chap7/NestedEnv.java
import java.util.HashMap;
import chap6.Environment;
import chap7.FuncEvaluator.EnvEx;

package chap7;

public class NestedEnv implements Environment {
    protected HashMap<String,Object> values;
    protected Environment outer;
    public NestedEnv() { this(null); }
    public NestedEnv(Environment e) {
        values = new HashMap<String,Object>();
        outer = e;
    }
    public void setOuter(Environment e) { outer = e; }
    public Object get(String name) {
        Object v = values.get(name);
        if (v == null && outer != null)
            return outer.get(name);
        else
            return v;
    }
    public void putNew(String name, Object value) { values.put(name, value); }
    public void put(String name, Object value) {
        Environment e = where(name);
        if (e == null)
            e = this;
        ((EnvEx)e).putNew(name, value);