package eta.runtime.stg;

import java.io.Serializable;

import eta.runtime.stg.Capability;
import eta.runtime.stg.TSO;
import eta.runtime.thunk.Thunk;
import eta.runtime.message.MessageBlackHole;

import static eta.runtime.RuntimeLogging.barf;

public abstract class Closure implements Serializable {

    public abstract Closure enter(StgContext context);

    public Closure getEvaluated() { return null; }

    public Closure evaluate(StgContext context) {
        Closure eval = getEvaluated();
        if (eval == null) {
            if (Thread.interrupted()) {
                context.myCapability.idleLoop(false);
            }
            return enter(context);
        } else {
            return eval;
        }
    }

    /* Applications */
    public Closure applyV(StgContext context) {
        barf("ap_v");
        return null;
    }

    public Closure applyN(StgContext context, int n) {
        barf("ap_n");
        return null;
    }

    public Closure applyL(StgContext context, long l) {
        barf("ap_l");
        return null;
    }

    public Closure applyF(StgContext context, float f) {
        barf("ap_f");
        return null;
    }

    public Closure applyD(StgContext context, double d) {
        barf("ap_d");
        return null;
    }

    public Closure applyO(StgContext context, Object o) {
        barf("ap_o");
        return null;
    }

    public Closure applyP(StgContext context, Closure p) {
        barf("ap_p");
        return null;
    }

    public Closure applyPV(StgContext context, Closure p) {
        barf("ap_pv");
        return null;
    }

    public Closure applyPP(StgContext context, Closure p1, Closure p2) {
        barf("ap_pp");
        return null;
    }

    public Closure applyPPV(StgContext context, Closure p1, Closure p2) {
        barf("ap_ppv");
        return null;
    }

    public Closure applyPPP(StgContext context, Closure p1, Closure p2, Closure p3) {
        barf("ap_ppp");
        return null;
    }

    public Closure applyPPPV(StgContext context, Closure p1, Closure p2, Closure p3) {
        barf("ap_pppv");
        return null;
    }

    public Closure applyPPPP(StgContext context, Closure p1, Closure p2, Closure p3, Closure p4) {
        barf("ap_pppp");
        return null;
    }

    public Closure applyPPPPP(StgContext context, Closure p1, Closure p2, Closure p3, Closure p4, Closure p5) {
        barf("ap_ppppp");
        return null;
    }

    public Closure applyPPPPPP(StgContext context, Closure p1, Closure p2, Closure p3, Closure p4, Closure p5, Closure p6) {
        barf("ap_pppppp");
        return null;
    }
}

@@ -811,13 +811,43 @@
 rf(%22
-ap_v%22
+Cannot apply realWorld# to %22 + this
 );%0A 
@@ -946,13 +946,39 @@
 rf(%22
-ap_n%22
+Cannot apply an int to %22 + this
 );%0A 
@@ -1078,13 +1078,39 @@
 rf(%22
-ap_l%22
+Cannot apply a long to %22 + this
 );%0A 
@@ -1211,13 +1211,40 @@
 rf(%22
-ap_f%22
+Cannot apply a float to %22 + this
 );%0A 
@@ -1346,13 +1346,41 @@
 rf(%22
-ap_d%22
+Cannot apply a double to %22 + this
 );%0A 
@@ -1482,13 +1482,42 @@
 rf(%22
-ap_o%22
+Cannot apply an object to %22 + this
 );%0A 
@@ -1620,13 +1620,42 @@
 rf(%22
-ap_p%22
+Cannot apply a closure to %22 + this
 );%0A 
@@ -1759,14 +1759,57 @@
 rf(%22
-ap_pv%22
+Cannot apply a closure and realWorld# to %22 + this
 );%0A 
@@ -1926,14 +1926,43 @@
 rf(%22
-ap_pp%22
+Cannot apply 2 closures to %22 + this
 );%0A 
@@ -2080,15 +2080,58 @@
 rf(%22
-ap_ppv%22
+Cannot apply 2 closures and realWorld# to %22 + this
 );%0A 
@@ -2261,15 +2261,43 @@
 rf(%22
-ap_ppp%22
+Cannot apply 3 closures to %22 + this
 );%0A 
@@ -2428,16 +2428,58 @@
 rf(%22
-ap_pppv%22
+Cannot apply 3 closures and realWorld# to %22 + this
 );%0A 
@@ -2622,16 +2622,43 @@
 rf(%22
-ap_pppp%22
+Cannot apply 4 closures to %22 + this
 );%0A 
@@ -2814,17 +2814,43 @@
 rf(%22
-ap_ppppp%22
+Cannot apply 5 closures to %22 + this
 );%0A 
@@ -3019,18 +3019,43 @@
 rf(%22
-ap_pppppp%22
+Cannot apply 6 closures to %22 + this
 );%0A 

Update error messages for apply*()