import edu.rice.cs.mint.runtime.*;

public class EscapeSample3 {
    public static separable void m() { }
    public static separable void n() { }

    public static void test1() {
        Code<Integer> c1 = <| 1 |>;
        Code<Void> c2 = <| { m(); n(); } |>;
        Code<Void> c = <| {
            int i=`(c1);
            `c2;
            System.out.println("i="+i);
        } |>;
        System.out.println (c.run ());
    }

//    public static void test2() {
//        Code<?> c1 = <| 1 |>;
//        Code<?> c2 = <| { m(); n(); } |>;
//        Code<Void> c = <| {
//            int i=`(c1); // ERROR
//            `c2; // ERROR
//            System.out.println("i="+i);
//        } |>;
//        System.out.println (c.run ());
//    }
    
    public static interface SepIntFun {
        public separable int apply(int x);
    }

    public static separable void test3() {
        Code<Integer> c1 = <| 1 |>;
        Code<Void> c2 = <| { m(); n(); } |>;
        Code<Void> c = <| {
            int i=`(c1);
            `c1; // WARNING
            `c2;
            System.out.println("i="+i);
        } |>;
    }

//    public static void test4() {
//        final Code<Integer> c1 = <| 1 |>;
//        final Code<Void> c2 = <| { m(); n(); } |>;
//        Code<? extends SepIntFun> c = <| new SepIntFun() {
//            public separable int apply(int x) {
//                int i=`(c1); // ERROR
//                `c1; // WARNING/ERROR
//                `c2; // ERROR
//                System.out.println("i="+i); // ERROR
//                return i;
//            }
//        } |>;
//        SepIntFun sif = c.run();
//        System.out.println(sif.apply(0));
//    }

    public static void test5() {
        final SafeCode<Integer> c1 = <| 1 |>;
        final SafeCode<Void> c2 = <| { m(); n(); } |>;
        Code<? extends SepIntFun> c = <| new SepIntFun() {
            public separable int apply(int x) {
                int i=`(c1);
                `c1; // WARNING
                `c2;
                return i;
            }
        } |>;
        SepIntFun sif = c.run();
        System.out.println(sif.apply(0));
    }

//    public static void test6() {
//        final SafeCode<?> c1 = <| 1 |>;
//        final SafeCode<?> c2 = <| { m(); n(); } |>;
//        Code<? extends SepIntFun> c = <| new SepIntFun() {
//            public separable int apply(int x) {
//                int i=`(c1); // ERROR
//                `c2; // ERROR
//                return i;
//            }
//        } |>;
//        SepIntFun sif = c.run();
//        System.out.println(sif.apply(0));
//    }
    
    public static void main (String [] args) {
        test5();
    }
}
