// Path: src/stone/ast/BlockStmnt.java
// public class BlockStmnt extends ASTList {
//     public BlockStmnt(List<ASTree> c) { super(c); }
// }
// 
// Path: src/stone/ast/ParameterList.java
// public class ParameterList extends ASTList {
//     public ParameterList(List<ASTree> c) { super(c); }
//     public String name(int i) { return ((ASTLeaf)child(i)).token().getText(); }
//     public int size() { return numChildren(); }
// }
// 
// Path: src/chap11/ArrayEnv.java
// public class ArrayEnv implements Environment {
//     protected Object[] values;
//     protected Environment outer;
//     public ArrayEnv(int size, Environment out) {
//         values = new Object[size];
//         outer = out;
//     }
//     public Symbols symbols() { throw new StoneException("no symbols"); }
//     public Object get(int nest, int index) {
//         if (nest == 0)
//             return values[index];
//         else if (outer == null)
//             return null;
//         else
//             return ((EnvEx2)outer).get(nest - 1, index);
//     }
//     public void put(int nest, int index, Object value) {
//         if (nest == 0)
//             values[index] = value;
//         else if (outer == null)
//             throw new StoneException("no outer environment");
//         else
//             ((EnvEx2)outer).put(nest - 1, index, value);
//     }
//     public Object get(String name) { error(name); return null; }
//     public void put(String name, Object value) { error(name); }
//     public void putNew(String name, Object value) { error(name); }
//     public Environment where(String name) { error(name); return null; }
//     public void setOuter(Environment e) { outer = e; }
//     private void error(String name) {
//         throw new StoneException("cannot access by name: " + name);
//     }
// }
// 
// Path: src/chap11/OptFunction.java
// public class OptFunction extends Function {
//     protected int size;
//     public OptFunction(ParameterList parameters, BlockStmnt body,
//                        Environment env, int memorySize)
//     {
//         super(parameters, body, env);
//         size = memorySize;
//     }
//     @Override public Environment makeEnv() { return new ArrayEnv(size, env); }
// }
// 
// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }


import stone.ast.BlockStmnt;
import stone.ast.ParameterList;
import chap11.ArrayEnv;
import chap11.OptFunction;
import chap6.Environment;
package chap12;

public class OptMethod extends OptFunction {
    OptStoneObject self;
    public OptMethod(ParameterList parameters, BlockStmnt body,
                     Environment env, int memorySize, OptStoneObject self)
    {
        super(parameters, body, env, memorySize);
        this.self = self;
    }
    @Override public Environment makeEnv() {
// Path: src/stone/ast/BlockStmnt.java
// public class BlockStmnt extends ASTList {
//     public BlockStmnt(List<ASTree> c) { super(c); }
// }
// 
// Path: src/stone/ast/ParameterList.java
// public class ParameterList extends ASTList {
//     public ParameterList(List<ASTree> c) { super(c); }
//     public String name(int i) { return ((ASTLeaf)child(i)).token().getText(); }
//     public int size() { return numChildren(); }
// }
// 
// Path: src/chap11/ArrayEnv.java
// public class ArrayEnv implements Environment {
//     protected Object[] values;
//     protected Environment outer;
//     public ArrayEnv(int size, Environment out) {
//         values = new Object[size];
//         outer = out;
//     }
//     public Symbols symbols() { throw new StoneException("no symbols"); }
//     public Object get(int nest, int index) {
//         if (nest == 0)
//             return values[index];
//         else if (outer == null)
//             return null;
//         else
//             return ((EnvEx2)outer).get(nest - 1, index);
//     }
//     public void put(int nest, int index, Object value) {
//         if (nest == 0)
//             values[index] = value;
//         else if (outer == null)
//             throw new StoneException("no outer environment");
//         else
//             ((EnvEx2)outer).put(nest - 1, index, value);
//     }
//     public Object get(String name) { error(name); return null; }
//     public void put(String name, Object value) { error(name); }
//     public void putNew(String name, Object value) { error(name); }
//     public Environment where(String name) { error(name); return null; }
//     public void setOuter(Environment e) { outer = e; }
//     private void error(String name) {
//         throw new StoneException("cannot access by name: " + name);
//     }
// }
// 
// Path: src/chap11/OptFunction.java
// public class OptFunction extends Function {
//     protected int size;
//     public OptFunction(ParameterList parameters, BlockStmnt body,
//                        Environment env, int memorySize)
//     {
//         super(parameters, body, env);
//         size = memorySize;
//     }
//     @Override public Environment makeEnv() { return new ArrayEnv(size, env); }
// }
// 
// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }


// Path: src/chap12/OptMethod.java
import stone.ast.BlockStmnt;
import stone.ast.ParameterList;
import chap11.ArrayEnv;
import chap11.OptFunction;
import chap6.Environment;

package chap12;

public class OptMethod extends OptFunction {
    OptStoneObject self;
    public OptMethod(ParameterList parameters, BlockStmnt body,
                     Environment env, int memorySize, OptStoneObject self)
    {
        super(parameters, body, env, memorySize);
        this.self = self;
    }
    @Override public Environment makeEnv() {
        ArrayEnv e = new ArrayEnv(size, env);