// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }
// 
// Path: src/chap8/Natives.java
// public class Natives {
//     public Environment environment(Environment env) {
//         appendNatives(env);
//         return env;
//     }
//     protected void appendNatives(Environment env) {
//         append(env, "print", Natives.class, "print", Object.class);
//         append(env, "read", Natives.class, "read");
//         append(env, "length", Natives.class, "length", String.class);
//         append(env, "toInt", Natives.class, "toInt", Object.class);
//         append(env, "currentTime", Natives.class, "currentTime");
//     }
//     protected void append(Environment env, String name, Class<?> clazz,
//                           String methodName, Class<?> ... params) {
//         Method m;
//         try {
//             m = clazz.getMethod(methodName, params);
//         } catch (Exception e) {
//             throw new StoneException("cannot find a native function: "
//                                      + methodName);
//         }
//         env.put(name, new NativeFunction(methodName, m));
//     }
// 
//     // native methods
//     public static int print(Object obj) {
//         System.out.println(obj.toString());
//         return 0;
//     }
//     public static String read() {
//         return JOptionPane.showInputDialog(null);
//     }
//     public static int length(String s) { return s.length(); }
//     public static int toInt(Object value) {
//         if (value instanceof String)
//             return Integer.parseInt((String)value);
//         else if (value instanceof Integer)
//             return ((Integer)value).intValue();
//         else
//             throw new NumberFormatException(value.toString());
//     }
//     private static long startTime = System.currentTimeMillis();
//     public static int currentTime() {
//         return (int)(System.currentTimeMillis() - startTime);
//     }
// }
// 
// Path: src/chap11/EnvOptimizer.java
// @Reviser public static interface EnvEx2 extends Environment {
//     Symbols symbols();
//     void put(int nest, int index, Object value);
//     Object get(int nest, int index);
//     void putNew(String name, Object value);
//     Environment where(String name);
// }


import chap6.Environment;
import chap8.Natives;
import chap11.EnvOptimizer.EnvEx2;
package chap14;

public class TypedNatives extends Natives {
    protected TypeEnv typeEnv;
    public TypedNatives(TypeEnv te) { typeEnv = te; }
    protected void append(Environment env, String name, Class<?> clazz,
                          String methodName, TypeInfo type, Class<?> ... params)
    {
        append(env, name, clazz, methodName, params);
// Path: src/chap6/Environment.java
// public interface Environment {
//     void put(String name, Object value);
//     Object get(String name);
// }
// 
// Path: src/chap8/Natives.java
// public class Natives {
//     public Environment environment(Environment env) {
//         appendNatives(env);
//         return env;
//     }
//     protected void appendNatives(Environment env) {
//         append(env, "print", Natives.class, "print", Object.class);
//         append(env, "read", Natives.class, "read");
//         append(env, "length", Natives.class, "length", String.class);
//         append(env, "toInt", Natives.class, "toInt", Object.class);
//         append(env, "currentTime", Natives.class, "currentTime");
//     }
//     protected void append(Environment env, String name, Class<?> clazz,
//                           String methodName, Class<?> ... params) {
//         Method m;
//         try {
//             m = clazz.getMethod(methodName, params);
//         } catch (Exception e) {
//             throw new StoneException("cannot find a native function: "
//                                      + methodName);
//         }
//         env.put(name, new NativeFunction(methodName, m));
//     }
// 
//     // native methods
//     public static int print(Object obj) {
//         System.out.println(obj.toString());
//         return 0;
//     }
//     public static String read() {
//         return JOptionPane.showInputDialog(null);
//     }
//     public static int length(String s) { return s.length(); }
//     public static int toInt(Object value) {
//         if (value instanceof String)
//             return Integer.parseInt((String)value);
//         else if (value instanceof Integer)
//             return ((Integer)value).intValue();
//         else
//             throw new NumberFormatException(value.toString());
//     }
//     private static long startTime = System.currentTimeMillis();
//     public static int currentTime() {
//         return (int)(System.currentTimeMillis() - startTime);
//     }
// }
// 
// Path: src/chap11/EnvOptimizer.java
// @Reviser public static interface EnvEx2 extends Environment {
//     Symbols symbols();
//     void put(int nest, int index, Object value);
//     Object get(int nest, int index);
//     void putNew(String name, Object value);
//     Environment where(String name);
// }


// Path: src/chap14/TypedNatives.java
import chap6.Environment;
import chap8.Natives;
import chap11.EnvOptimizer.EnvEx2;

package chap14;

public class TypedNatives extends Natives {
    protected TypeEnv typeEnv;
    public TypedNatives(TypeEnv te) { typeEnv = te; }
    protected void append(Environment env, String name, Class<?> clazz,
                          String methodName, TypeInfo type, Class<?> ... params)
    {
        append(env, name, clazz, methodName, params);
        int index = ((EnvEx2)env).symbols().find(name);