package eta.runtime.stg;

import java.io.Serializable;

import eta.runtime.stg.Capability;
import eta.runtime.stg.StgTSO;
import eta.runtime.thunk.StgThunk;
import eta.runtime.message.MessageBlackHole;
import static eta.runtime.RtsMessages.barf;

public class StgClosure implements Serializable {

    public void enter(StgContext context) {
        context.R(1, this);
    }

    public StgClosure getEvaluated() { return null; }

    public void evaluate(StgContext context) {
        StgClosure eval = getEvaluated();
        if (eval == null) {
            enter(context);
        } else {
            context.R(1, eval);
        }
    }

    public void doUpdateThunk(Capability cap, StgTSO tso) {
        cap.checkBlockingQueues(tso);
    }
    public boolean blackHole(StgThunk bh, Capability cap,
                             MessageBlackHole msg) { return false; }
    public boolean isFizzledSpark() { return true; }

    /* Applications */
    public void applyV(StgContext context) {
        barf("ap_v");
    }

    public void applyN(StgContext context, int n) {
        barf("ap_n");
    }

    public void applyL(StgContext context, long l) {
        barf("ap_l");
    }

    public void applyF(StgContext context, float f) {
        barf("ap_f");
    }

    public void applyD(StgContext context, double d) {
        barf("ap_d");
    }

    public void applyO(StgContext context, Object o) {
        barf("ap_o");
    }

    public void applyP(StgContext context, StgClosure p) {
        barf("ap_p");
    }

    public void applyPV(StgContext context, StgClosure p) {
        barf("ap_pv");
    }

    public void applyPP(StgContext context, StgClosure p1, StgClosure p2) {
        barf("ap_pp");
    }

    public void applyPPV(StgContext context, StgClosure p1, StgClosure p2) {
        barf("ap_ppv");
    }

    public void applyPPP(StgContext context, StgClosure p1, StgClosure p2, StgClosure p3) {
        barf("ap_ppp");
    }

    public void applyPPPV(StgContext context, StgClosure p1, StgClosure p2, StgClosure p3) {
        barf("ap_pppv");
    }

    public void applyPPPP(StgContext context, StgClosure p1, StgClosure p2, StgClosure p3, StgClosure p4) {
        barf("ap_pppp");
    }

    public void applyPPPPP(StgContext context, StgClosure p1, StgClosure p2, StgClosure p3, StgClosure p4, StgClosure p5) {
        barf("ap_ppppp");
    }

    public void applyPPPPPP(StgContext context, StgClosure p1, StgClosure p2, StgClosure p3, StgClosure p4, StgClosure p5, StgClosure p6) {
        barf("ap_pppppp");
    }
}

@@ -247,16 +247,25 @@
 %0Apublic 
+abstract 
 class St
@@ -311,20 +311,35 @@
  public 
-void
+abstract StgClosure
  enter(S
@@ -360,44 +360,9 @@
 ext)
- %7B%0A        context.R(1, this);%0A    %7D
+;
 %0A%0A  
@@ -425,20 +425,26 @@
  public 
-void
+StgClosure
  evaluat
@@ -549,16 +549,23 @@
         
+return 
 enter(co
@@ -605,26 +605,19 @@
     
-context.R(1,
+return
  eval
-)
 ;%0A  
@@ -946,28 +946,34 @@
 %0A    public 
-void
+StgClosure
  applyV(StgC
@@ -1026,28 +1026,34 @@
 %0A    public 
-void
+StgClosure
  applyN(StgC
@@ -1113,28 +1113,34 @@
 %0A    public 
-void
+StgClosure
  applyL(StgC
@@ -1201,28 +1201,34 @@
 %0A    public 
-void
+StgClosure
  applyF(StgC
@@ -1290,28 +1290,34 @@
 %0A    public 
-void
+StgClosure
  applyD(StgC
@@ -1380,28 +1380,34 @@
 %0A    public 
-void
+StgClosure
  applyO(StgC
@@ -1470,28 +1470,34 @@
 %0A    public 
-void
+StgClosure
  applyP(StgC
@@ -1564,28 +1564,34 @@
 %0A    public 
-void
+StgClosure
  applyPV(Stg
@@ -1656,36 +1656,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPP(StgCont
@@ -1768,36 +1768,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPPV(StgCon
@@ -1882,36 +1882,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPPP(StgCon
@@ -2011,36 +2011,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPPPV(StgCo
@@ -2142,36 +2142,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPPPP(StgCo
@@ -2288,36 +2288,42 @@
   %7D%0A%0A    public 
-void
+StgClosure
  applyPPPPP(StgC
@@ -2459,20 +2459,26 @@
  public 
-void
+StgClosure
  applyPP

Return StgClosure from enter()